Skip to content

Commit e4e58bc

Browse files
feat: user-login
1 parent b00ad14 commit e4e58bc

File tree

19 files changed

+1301
-8
lines changed

19 files changed

+1301
-8
lines changed
File renamed without changes.

ui/src/views/login/components/LoginLayout.vue renamed to ui/src/layout/login-layout/LoginLayout.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ const loginImage = computed(() => {
7979
return `${fileURL.value}`
8080
} else {
8181
const imgName = getThemeImg(theme.themeInfo?.theme)
82-
const imgPath = `../../../assets/theme/${imgName}.jpg`
82+
const imgPath = `../../assets/theme/${imgName}.jpg`
8383
const imageUrl = new URL(imgPath, import.meta.url).href
8484
return imageUrl
8585
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
<template>
2+
<div class="login-warp flex-center">
3+
<div class="login-container w-full h-full">
4+
<div class="flex-center w-full h-full">
5+
<slot></slot>
6+
</div>
7+
</div>
8+
</div>
9+
</template>
10+
<script setup lang="ts">
11+
import { computed } from 'vue'
12+
import { getThemeImg } from '@/utils/theme'
13+
import useStore from '@/stores'
14+
import { useLocalStorage } from '@vueuse/core'
15+
import { langList, localeConfigKey, getBrowserLang } from '@/locales/index'
16+
defineProps({
17+
lang: {
18+
type: Boolean,
19+
default: true,
20+
},
21+
})
22+
const { user, theme } = useStore()
23+
24+
const changeLang = (lang: string) => {
25+
useLocalStorage(localeConfigKey, getBrowserLang()).value = lang
26+
window.location.reload()
27+
}
28+
29+
const currentLanguage = computed(() => {
30+
return langList.value?.filter((v: any) => v.value === user.getLanguage())?.[0]?.label
31+
})
32+
33+
const fileURL = computed(() => {
34+
if (theme.themeInfo?.loginImage) {
35+
if (typeof theme.themeInfo?.loginImage === 'string') {
36+
return theme.themeInfo?.loginImage
37+
} else {
38+
return URL.createObjectURL(theme.themeInfo?.loginImage)
39+
}
40+
} else {
41+
return ''
42+
}
43+
})
44+
45+
const loginImage = computed(() => {
46+
if (theme.themeInfo?.loginImage) {
47+
return `${fileURL.value}`
48+
} else {
49+
const imgName = getThemeImg(theme.themeInfo?.theme)
50+
const imgPath = `../../assets/theme/${imgName}.jpg`
51+
const imageUrl = new URL(imgPath, import.meta.url).href
52+
return imageUrl
53+
}
54+
})
55+
</script>
56+
<style lang="scss" scoped>
57+
.login-warp {
58+
height: 100vh;
59+
}
60+
</style>

ui/src/request/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ instance.interceptors.response.use(
4747
}
4848
if (
4949
!response.config.url.includes('/valid') &&
50-
!response.config.url.includes('/function_lib/debug')
50+
!response.config.url.includes('/tool/debug')
5151
) {
5252
MsgError(response.data.message)
5353
return Promise.reject(response.data)

ui/src/router/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@ router.beforeEach(
2525
return
2626
}
2727
const { user, login } = useStore()
28-
const notAuthRouteNameList = ['register', 'login', 'forgot_password', 'reset_password', 'Chat']
2928

29+
const notAuthRouteNameList = ['login', 'ForgotPassword', 'ResetPassword', 'Chat', 'UserLogin']
3030
if (!notAuthRouteNameList.includes(to.name ? to.name.toString() : '')) {
3131
if (to.query && to.query.token) {
3232
localStorage.setItem('token', to.query.token.toString())

ui/src/router/routes.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,13 @@ export const routes: Array<RouteRecordRaw> = [
2424
component: () => import('@/views/chat/index.vue'),
2525
},
2626

27+
// 对话用户登录
28+
{
29+
path: '/user-login/:accessToken',
30+
name: 'UserLogin',
31+
component: () => import('@/views/chat/user-login/index.vue'),
32+
},
33+
2734
{
2835
path: '/login',
2936
name: 'login',
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
<template>
2+
<UserLoginLayout>
3+
<LoginContainer :subTitle="$t('theme.defaultSlogan')">
4+
<h2 class="mb-24">{{ $t('views.login.resetPassword') }}</h2>
5+
<el-form
6+
class="reset-password-form"
7+
ref="resetPasswordFormRef"
8+
:model="resetPasswordForm"
9+
:rules="rules"
10+
>
11+
<div class="mb-24">
12+
<el-form-item prop="password">
13+
<el-input
14+
type="password"
15+
size="large"
16+
class="input-item"
17+
v-model="resetPasswordForm.password"
18+
:placeholder="$t('views.login.loginForm.password.placeholder')"
19+
show-password
20+
>
21+
</el-input>
22+
</el-form-item>
23+
</div>
24+
<div class="mb-24">
25+
<el-form-item prop="re_password">
26+
<el-input
27+
type="password"
28+
size="large"
29+
class="input-item"
30+
v-model="resetPasswordForm.re_password"
31+
:placeholder="$t('views.login.loginForm.re_password.placeholder')"
32+
show-password
33+
>
34+
</el-input>
35+
</el-form-item>
36+
</div>
37+
</el-form>
38+
<el-button size="large" type="primary" class="w-full" @click="resetPassword">{{
39+
$t('common.confirm')
40+
}}</el-button>
41+
<div class="operate-container mt-12">
42+
<el-button
43+
size="large"
44+
class="register"
45+
@click="router.push('/login')"
46+
link
47+
type="primary"
48+
icon="ArrowLeft"
49+
>
50+
{{ $t('views.login.buttons.backLogin') }}
51+
</el-button>
52+
</div>
53+
</LoginContainer>
54+
</UserLoginLayout>
55+
</template>
56+
<script setup lang="ts">
57+
import { ref, onMounted } from 'vue'
58+
import type { ResetPasswordRequest } from '@/api/type/user'
59+
import LoginContainer from '@/layout/login-layout/LoginContainer.vue'
60+
import UserLoginLayout from '@/layout/login-layout/UserLoginLayout.vue'
61+
import { useRouter, useRoute } from 'vue-router'
62+
import { MsgSuccess } from '@/utils/message'
63+
import type { FormInstance, FormRules } from 'element-plus'
64+
import UserApi from '@/api/user/user'
65+
import { t } from '@/locales'
66+
const router = useRouter()
67+
const route = useRoute()
68+
const {
69+
params: { code, email },
70+
} = route
71+
const resetPasswordForm = ref<ResetPasswordRequest>({
72+
password: '',
73+
re_password: '',
74+
email: '',
75+
code: '',
76+
})
77+
78+
onMounted(() => {
79+
if (code && email) {
80+
resetPasswordForm.value.code = code as string
81+
resetPasswordForm.value.email = email as string
82+
} else {
83+
router.push('forgot_password')
84+
}
85+
})
86+
87+
const rules = ref<FormRules<ResetPasswordRequest>>({
88+
password: [
89+
{
90+
required: true,
91+
message: t('views.login.loginForm.re_password.requiredMessage'),
92+
trigger: 'blur',
93+
},
94+
{
95+
min: 6,
96+
max: 20,
97+
message: t('views.login.loginForm.password.lengthMessage'),
98+
trigger: 'blur',
99+
},
100+
],
101+
re_password: [
102+
{
103+
required: true,
104+
message: t('views.login.loginForm.re_password.requiredMessage'),
105+
trigger: 'blur',
106+
},
107+
{
108+
min: 6,
109+
max: 20,
110+
message: t('views.login.loginForm.password.lengthMessage'),
111+
trigger: 'blur',
112+
},
113+
{
114+
validator: (rule, value, callback) => {
115+
if (resetPasswordForm.value.password != resetPasswordForm.value.re_password) {
116+
callback(new Error(t('views.login.loginForm.re_password.validatorMessage')))
117+
} else {
118+
callback()
119+
}
120+
},
121+
trigger: 'blur',
122+
},
123+
],
124+
})
125+
const resetPasswordFormRef = ref<FormInstance>()
126+
const loading = ref<boolean>(false)
127+
const resetPassword = () => {
128+
resetPasswordFormRef.value
129+
?.validate()
130+
.then(() => UserApi.resetPassword(resetPasswordForm.value, loading))
131+
.then(() => {
132+
MsgSuccess(t('common.modifySuccess'))
133+
router.push({ name: 'login' })
134+
})
135+
}
136+
</script>
137+
<style lang="scss" scoped></style>
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
<template>
2+
<UserLoginLayout>
3+
<LoginContainer :subTitle="$t('theme.defaultSlogan')">
4+
<h2 class="mb-24">{{ $t('views.login.resetPassword') }}</h2>
5+
<el-form
6+
class="reset-password-form"
7+
ref="resetPasswordFormRef"
8+
:model="resetPasswordForm"
9+
:rules="rules"
10+
>
11+
<div class="mb-24">
12+
<el-form-item prop="password">
13+
<el-input
14+
type="password"
15+
size="large"
16+
class="input-item"
17+
v-model="resetPasswordForm.password"
18+
:placeholder="$t('views.login.loginForm.password.placeholder')"
19+
show-password
20+
>
21+
</el-input>
22+
</el-form-item>
23+
</div>
24+
<div class="mb-24">
25+
<el-form-item prop="re_password">
26+
<el-input
27+
type="password"
28+
size="large"
29+
class="input-item"
30+
v-model="resetPasswordForm.re_password"
31+
:placeholder="$t('views.login.loginForm.re_password.placeholder')"
32+
show-password
33+
>
34+
</el-input>
35+
</el-form-item>
36+
</div>
37+
</el-form>
38+
<el-button size="large" type="primary" class="w-full" @click="resetPassword">{{
39+
$t('common.confirm')
40+
}}</el-button>
41+
<div class="operate-container mt-12">
42+
<el-button
43+
size="large"
44+
class="register"
45+
@click="router.push('/login')"
46+
link
47+
type="primary"
48+
icon="ArrowLeft"
49+
>
50+
{{ $t('views.login.buttons.backLogin') }}
51+
</el-button>
52+
</div>
53+
</LoginContainer>
54+
</UserLoginLayout>
55+
</template>
56+
<script setup lang="ts">
57+
import { ref, onMounted } from 'vue'
58+
import LoginContainer from '@/layout/login-layout/LoginContainer.vue'
59+
import UserLoginLayout from '@/layout/login-layout/UserLoginLayout.vue'
60+
import type { ResetPasswordRequest } from '@/api/type/user'
61+
import { useRouter, useRoute } from 'vue-router'
62+
import { MsgSuccess } from '@/utils/message'
63+
import type { FormInstance, FormRules } from 'element-plus'
64+
import UserApi from '@/api/user/user-manage'
65+
import { t } from '@/locales'
66+
const router = useRouter()
67+
const route = useRoute()
68+
const {
69+
params: { code, email },
70+
} = route
71+
const resetPasswordForm = ref<ResetPasswordRequest>({
72+
password: '',
73+
re_password: '',
74+
email: '',
75+
code: '',
76+
})
77+
78+
onMounted(() => {
79+
if (code && email) {
80+
resetPasswordForm.value.code = code as string
81+
resetPasswordForm.value.email = email as string
82+
} else {
83+
router.push('forgot_password')
84+
}
85+
})
86+
87+
const rules = ref<FormRules<ResetPasswordRequest>>({
88+
password: [
89+
{
90+
required: true,
91+
message: t('views.login.loginForm.re_password.requiredMessage'),
92+
trigger: 'blur',
93+
},
94+
{
95+
min: 6,
96+
max: 20,
97+
message: t('views.login.loginForm.password.lengthMessage'),
98+
trigger: 'blur',
99+
},
100+
],
101+
re_password: [
102+
{
103+
required: true,
104+
message: t('views.login.loginForm.re_password.requiredMessage'),
105+
trigger: 'blur',
106+
},
107+
{
108+
min: 6,
109+
max: 20,
110+
message: t('views.login.loginForm.password.lengthMessage'),
111+
trigger: 'blur',
112+
},
113+
{
114+
validator: (rule, value, callback) => {
115+
if (resetPasswordForm.value.password != resetPasswordForm.value.re_password) {
116+
callback(new Error(t('views.login.loginForm.re_password.validatorMessage')))
117+
} else {
118+
callback()
119+
}
120+
},
121+
trigger: 'blur',
122+
},
123+
],
124+
})
125+
const resetPasswordFormRef = ref<FormInstance>()
126+
const loading = ref<boolean>(false)
127+
const resetPassword = () => {
128+
resetPasswordFormRef.value
129+
?.validate()
130+
.then(() => UserApi.resetPassword(resetPasswordForm.value, loading))
131+
.then(() => {
132+
MsgSuccess(t('common.modifySuccess'))
133+
router.push({ name: 'login' })
134+
})
135+
}
136+
</script>
137+
<style lang="scss" scoped></style>

0 commit comments

Comments
 (0)