feat: chat

This commit is contained in:
wangdan-fit2cloud 2025-06-13 11:00:15 +08:00
parent 336d77ff87
commit 625b4d6b5d
4 changed files with 107 additions and 105 deletions

View File

@ -83,23 +83,23 @@
</el-dialog> </el-dialog>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import {ref} from 'vue' import { ref } from 'vue'
import type {ResetCurrentUserPasswordRequest} from '@/api/type/user' import type { ResetCurrentUserPasswordRequest } from '@/api/type/user'
import type {FormInstance, FormRules} from 'element-plus' import type { FormInstance, FormRules } from 'element-plus'
import UserApi from '@/api/user/user-manage' import UserApi from '@/api/user/user-manage'
import useStore from '@/stores' import useStore from '@/stores'
import {useRouter} from 'vue-router' import { useRouter } from 'vue-router'
import {t} from '@/locales' import { t } from '@/locales'
const router = useRouter() const router = useRouter()
const {user} = useStore() const { login } = useStore()
const resetPasswordDialog = ref<boolean>(false) const resetPasswordDialog = ref<boolean>(false)
const resetPasswordForm = ref<ResetCurrentUserPasswordRequest>({ const resetPasswordForm = ref<ResetCurrentUserPasswordRequest>({
code: '', code: '',
password: '', password: '',
re_password: '' re_password: '',
}) })
const resetPasswordFormRef1 = ref<FormInstance>() const resetPasswordFormRef1 = ref<FormInstance>()
@ -114,26 +114,26 @@ const rules1 = ref<FormRules<ResetCurrentUserPasswordRequest>>({
{ {
required: true, required: true,
message: t('views.login.enterPassword'), message: t('views.login.enterPassword'),
trigger: 'blur' trigger: 'blur',
}, },
{ {
min: 6, min: 6,
max: 20, max: 20,
message: t('views.user.userForm.form.password.lengthMessage'), message: t('views.user.userForm.form.password.lengthMessage'),
trigger: 'blur' trigger: 'blur',
} },
], ],
re_password: [ re_password: [
{ {
required: true, required: true,
message: t('views.user.userForm.form.re_password.requiredMessage'), message: t('views.user.userForm.form.re_password.requiredMessage'),
trigger: 'blur' trigger: 'blur',
}, },
{ {
min: 6, min: 6,
max: 20, max: 20,
message: t('views.user.userForm.form.password.lengthMessage'), message: t('views.user.userForm.form.password.lengthMessage'),
trigger: 'blur' trigger: 'blur',
}, },
{ {
validator: (rule, value, callback) => { validator: (rule, value, callback) => {
@ -143,9 +143,9 @@ const rules1 = ref<FormRules<ResetCurrentUserPasswordRequest>>({
callback() callback()
} }
}, },
trigger: 'blur' trigger: 'blur',
} },
] ],
}) })
// const rules2 = ref<FormRules<ResetCurrentUserPasswordRequest>>({ // const rules2 = ref<FormRules<ResetCurrentUserPasswordRequest>>({
// // @ts-ignore // // @ts-ignore
@ -186,7 +186,7 @@ const open = () => {
resetPasswordForm.value = { resetPasswordForm.value = {
//code: '', //code: '',
password: '', password: '',
re_password: '' re_password: '',
} }
resetPasswordDialog.value = true resetPasswordDialog.value = true
resetPasswordFormRef1.value?.resetFields() resetPasswordFormRef1.value?.resetFields()
@ -194,17 +194,16 @@ const open = () => {
} }
const resetPassword = () => { const resetPassword = () => {
resetPasswordFormRef1.value?.validate().then(() => { resetPasswordFormRef1.value?.validate().then(() => {
return UserApi.resetCurrentPassword(resetPasswordForm.value) return UserApi.resetCurrentPassword(resetPasswordForm.value).then(() => {
.then(() => { login.logout()
user.logout() router.push({ name: 'login' })
router.push({name: 'login'}) })
})
}) })
} }
const close = () => { const close = () => {
resetPasswordDialog.value = false resetPasswordDialog.value = false
} }
defineExpose({open, close}) defineExpose({ open, close })
</script> </script>
<style lang="scss" scope></style> <style lang="scss" scope></style>

View File

@ -2,11 +2,11 @@
<el-dropdown trigger="click" type="primary"> <el-dropdown trigger="click" type="primary">
<div class="flex-center cursor"> <div class="flex-center cursor">
<el-avatar :size="30"> <el-avatar :size="30">
<img src="@/assets/user-icon.svg" style="width: 54%" alt=""/> <img src="@/assets/user-icon.svg" style="width: 54%" alt="" />
</el-avatar> </el-avatar>
<span class="ml-8 color-text-primary">{{ user.userInfo?.username }}</span> <span class="ml-8 color-text-primary">{{ user.userInfo?.username }}</span>
<el-icon class="el-icon--right"> <el-icon class="el-icon--right">
<CaretBottom/> <CaretBottom />
</el-icon> </el-icon>
</div> </div>
@ -15,19 +15,16 @@
<div class="userInfo flex align-center"> <div class="userInfo flex align-center">
<div class="mr-12 flex align-center"> <div class="mr-12 flex align-center">
<el-avatar :size="30"> <el-avatar :size="30">
<img src="@/assets/user-icon.svg" style="width: 54%" alt=""/> <img src="@/assets/user-icon.svg" style="width: 54%" alt="" />
</el-avatar> </el-avatar>
</div> </div>
<div style="width: 90%"> <div style="width: 90%">
<p class="bold mb-4" style="font-size: 14px">{{ user.userInfo?.username }}</p> <p class="bold mb-4" style="font-size: 14px">{{ user.userInfo?.username }}</p>
<template <template v-if="user.userInfo?.role && user.userInfo.role.length > 0">
v-if="user.userInfo?.role && user.userInfo.role.length > 0"
>
<el-tag size="small" class="default-tag">{{ user.userInfo?.role[0] }}</el-tag> <el-tag size="small" class="default-tag">{{ user.userInfo?.role[0] }}</el-tag>
<el-tag size="small" class="default-tag ml-4" v-if="user.userInfo?.role?.length > 1" <el-tag size="small" class="default-tag ml-4" v-if="user.userInfo?.role?.length > 1"
>+{{ user.userInfo?.role?.length - 1 }} >+{{ user.userInfo?.role?.length - 1 }}
</el-tag </el-tag>
>
</template> </template>
</div> </div>
</div> </div>
@ -44,7 +41,7 @@
<div class="flex-between w-full" style="line-height: 22px; padding: 12px 11px"> <div class="flex-between w-full" style="line-height: 22px; padding: 12px 11px">
<span> {{ $t('layout.language') }}</span> <span> {{ $t('layout.language') }}</span>
<el-icon> <el-icon>
<ArrowRight/> <ArrowRight />
</el-icon> </el-icon>
</div> </div>
@ -58,14 +55,14 @@
class="flex-between" class="flex-between"
> >
<span :class="lang.value === user.userInfo?.language ? 'primary' : ''">{{ <span :class="lang.value === user.userInfo?.language ? 'primary' : ''">{{
lang.label lang.label
}}</span> }}</span>
<el-icon <el-icon
:class="lang.value === user.userInfo?.language ? 'primary' : ''" :class="lang.value === user.userInfo?.language ? 'primary' : ''"
v-if="lang.value === user.userInfo?.language" v-if="lang.value === user.userInfo?.language"
> >
<Check/> <Check />
</el-icon> </el-icon>
</el-dropdown-item> </el-dropdown-item>
</el-dropdown-menu> </el-dropdown-menu>
@ -89,24 +86,24 @@
</el-dropdown-menu> </el-dropdown-menu>
</template> </template>
</el-dropdown> </el-dropdown>
<APIKeyDialog :user-id="user.userInfo?.id" ref="APIKeyDialogRef"/> <APIKeyDialog :user-id="user.userInfo?.id" ref="APIKeyDialogRef" />
<ResetPassword ref="resetPasswordRef"></ResetPassword> <ResetPassword ref="resetPasswordRef"></ResetPassword>
<!-- <AboutDialog ref="AboutDialogRef"></AboutDialog> <!-- <AboutDialog ref="AboutDialogRef"></AboutDialog>
--> -->
<!-- <UserPwdDialog ref="UserPwdDialogRef" /> --> <!-- <UserPwdDialog ref="UserPwdDialogRef" /> -->
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import {ref, onMounted} from 'vue' import { ref, onMounted } from 'vue'
import useStore from '@/stores' import useStore from '@/stores'
import {useRouter} from 'vue-router' import { useRouter } from 'vue-router'
import ResetPassword from './ResetPassword.vue' import ResetPassword from './ResetPassword.vue'
// import AboutDialog from './AboutDialog.vue' // import AboutDialog from './AboutDialog.vue'
// import UserPwdDialog from '@/views/user-manage/component/UserPwdDialog.vue' // import UserPwdDialog from '@/views/user-manage/component/UserPwdDialog.vue'
import APIKeyDialog from './APIKeyDialog.vue' import APIKeyDialog from './APIKeyDialog.vue'
import {ComplexPermission} from '@/utils/permission/type' import { ComplexPermission } from '@/utils/permission/type'
import {langList} from '@/locales/index' import { langList } from '@/locales/index'
const {user} = useStore() const { user, login } = useStore()
const router = useRouter() const router = useRouter()
const AboutDialogRef = ref() const AboutDialogRef = ref()
@ -131,8 +128,8 @@ const openResetPassword = () => {
} }
const logout = () => { const logout = () => {
user.logout().then(() => { login.logout().then(() => {
router.push({name: 'login'}) router.push({ name: 'login' })
}) })
} }

View File

@ -1,6 +1,6 @@
import { defineStore } from 'pinia' import { defineStore } from 'pinia'
import { type Ref } from 'vue' import { type Ref } from 'vue'
import loginApi from '@/api/user/login' import LoginApi from '@/api/user/login'
import type { LoginRequest } from '@/api/type/login' import type { LoginRequest } from '@/api/type/login'
import useUserStore from './user' import useUserStore from './user'
@ -30,7 +30,7 @@ const useLoginStore = defineStore('login', {
}, },
async asyncLogin(data: LoginRequest, loading?: Ref<boolean>) { async asyncLogin(data: LoginRequest, loading?: Ref<boolean>) {
return loginApi.login(data).then((ok) => { return LoginApi.login(data).then((ok) => {
this.token = ok?.data?.token this.token = ok?.data?.token
localStorage.setItem('token', ok?.data?.token) localStorage.setItem('token', ok?.data?.token)
const user = useUserStore() const user = useUserStore()
@ -38,13 +38,68 @@ const useLoginStore = defineStore('login', {
}) })
}, },
async asyncLdapLogin(data: LoginRequest, loading?: Ref<boolean>) { async asyncLdapLogin(data: LoginRequest, loading?: Ref<boolean>) {
return loginApi.ldapLogin(data).then((ok) => { return LoginApi.ldapLogin(data).then((ok) => {
this.token = ok?.data?.token this.token = ok?.data?.token
localStorage.setItem('token', ok?.data?.token) localStorage.setItem('token', ok?.data?.token)
const user = useUserStore() const user = useUserStore()
return user.profile(loading) return user.profile(loading)
}) })
}, },
async dingCallback(code: string) {
return LoginApi.getDingCallback(code).then((ok) => {
this.token = ok.data
localStorage.setItem('token', ok.data)
const user = useUserStore()
return user.profile()
})
},
async dingOauth2Callback(code: string) {
return LoginApi.getDingOauth2Callback(code).then((ok) => {
this.token = ok.data
localStorage.setItem('token', ok.data)
const user = useUserStore()
return user.profile()
})
},
async wecomCallback(code: string) {
return LoginApi.getWecomCallback(code).then((ok) => {
this.token = ok.data
localStorage.setItem('token', ok.data)
const user = useUserStore()
return user.profile()
})
},
async larkCallback(code: string) {
return LoginApi.getLarkCallback(code).then((ok) => {
this.token = ok.data
localStorage.setItem('token', ok.data)
const user = useUserStore()
return user.profile()
})
},
async logout() {
return LoginApi.logout().then(() => {
localStorage.removeItem('token')
return true
})
},
async getAuthType() {
return LoginApi.getAuthType().then((ok) => {
return ok.data
})
},
async getQrType() {
return LoginApi.getQrType().then((ok) => {
return ok.data
})
},
async getQrSource() {
return LoginApi.getQrSource().then((ok) => {
return ok.data
})
},
}, },
}) })

View File

@ -3,14 +3,16 @@ import { type Ref } from 'vue'
import type { User } from '@/api/type/user' import type { User } from '@/api/type/user'
import UserApi from '@/api/user/user' import UserApi from '@/api/user/user'
import LoginApi from '@/api/user/login' import LoginApi from '@/api/user/login'
import {cloneDeep} from 'lodash' import { cloneDeep } from 'lodash'
import ThemeApi from '@/api/system-settings/theme' import ThemeApi from '@/api/system-settings/theme'
// import { defaultPlatformSetting } from '@/utils/theme'
import { useLocalStorage } from '@vueuse/core' import { useLocalStorage } from '@vueuse/core'
// import { defaultPlatformSetting } from '@/utils/theme'
import { localeConfigKey, getBrowserLang } from '@/locales/index' import { localeConfigKey, getBrowserLang } from '@/locales/index'
import useThemeStore from './theme' import useThemeStore from './theme'
import { useElementPlusTheme } from 'use-element-plus-theme' import { useElementPlusTheme } from 'use-element-plus-theme'
import { defaultPlatformSetting } from '@/utils/theme.ts' import { defaultPlatformSetting } from '@/utils/theme.ts'
import useLoginStore from './login'
export interface userStateTypes { export interface userStateTypes {
userType: number // 1 系统操作者 2 对话用户 userType: number // 1 系统操作者 2 对话用户
@ -19,10 +21,9 @@ export interface userStateTypes {
license_is_valid: boolean license_is_valid: boolean
edition: 'CE' | 'PE' | 'EE' edition: 'CE' | 'PE' | 'EE'
themeInfo: any themeInfo: any
token: any
} }
const useLoginStore = defineStore('user', { const useUserStore = defineStore('user', {
state: (): userStateTypes => ({ state: (): userStateTypes => ({
userType: 1, // 1 系统操作者 2 对话用户 userType: 1, // 1 系统操作者 2 对话用户
userInfo: null, userInfo: null,
@ -30,7 +31,6 @@ const useLoginStore = defineStore('user', {
license_is_valid: false, license_is_valid: false,
edition: 'CE', edition: 'CE',
themeInfo: null, themeInfo: null,
token: '',
}), }),
actions: { actions: {
getLanguage() { getLanguage() {
@ -124,61 +124,12 @@ const useLoginStore = defineStore('user', {
isEE() { isEE() {
return this.edition == 'EE' && this.license_is_valid return this.edition == 'EE' && this.license_is_valid
}, },
// changeUserType(num: number, token?: string) { changeUserType(num: number, token?: string) {
// this.userType = num this.userType = num
// this.userAccessToken = token const login = useLoginStore()
// }, login.userAccessToken = token || ''
async dingCallback(code: string) {
return LoginApi.getDingCallback(code).then((ok) => {
this.token = ok.data
localStorage.setItem('token', ok.data)
return this.profile()
})
},
async dingOauth2Callback(code: string) {
return LoginApi.getDingOauth2Callback(code).then((ok) => {
this.token = ok.data
localStorage.setItem('token', ok.data)
return this.profile()
})
},
async wecomCallback(code: string) {
return LoginApi.getWecomCallback(code).then((ok) => {
this.token = ok.data
localStorage.setItem('token', ok.data)
return this.profile()
})
},
async larkCallback(code: string) {
return LoginApi.getLarkCallback(code).then((ok) => {
this.token = ok.data
localStorage.setItem('token', ok.data)
return this.profile()
})
}, },
async logout() {
return LoginApi.logout().then(() => {
localStorage.removeItem('token')
return true
})
},
async getAuthType() {
return LoginApi.getAuthType().then((ok) => {
return ok.data
})
},
async getQrType() {
return LoginApi.getQrType().then((ok) => {
return ok.data
})
},
async getQrSource() {
return LoginApi.getQrSource().then((ok) => {
return ok.data
})
},
async postUserLanguage(lang: string, loading?: Ref<boolean>) { async postUserLanguage(lang: string, loading?: Ref<boolean>) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
LoginApi.postLanguage({ language: lang }, loading) LoginApi.postLanguage({ language: lang }, loading)
@ -195,4 +146,4 @@ const useLoginStore = defineStore('user', {
}, },
}) })
export default useLoginStore export default useUserStore