mirror of https://github.com/halo-dev/halo-admin
parent
fd56f24b1f
commit
dae208f543
|
@ -1,5 +1,4 @@
|
|||
export { default as BlankLayout } from "./BlankLayout.vue";
|
||||
export { default as BasicLayout } from "./BasicLayout.vue";
|
||||
export { default as SystemSettingsLayout } from "./SystemSettingsLayout.vue";
|
||||
export { default as UserProfileLayout } from "./UserProfileLayout.vue";
|
||||
export { default as PluginLayout } from "./PluginLayout.vue";
|
||||
|
|
|
@ -4,7 +4,7 @@ const textClassification = {
|
|||
inner:
|
||||
"inline-flex items-center w-full relative box-border border border-gray-300 formkit-invalid:border-red-500 h-9 rounded-base overflow-hidden focus-within:border-primary mt-2 sm:mt-0",
|
||||
input:
|
||||
"outline-0 bg-white antialiased resize-none w-full text-black block transition-all appearance-none h-9 px-3 text-sm",
|
||||
"outline-0 bg-white antialiased resize-none w-full text-black block transition-all appearance-none h-full px-3 text-sm",
|
||||
};
|
||||
|
||||
const boxClassification = {
|
||||
|
@ -74,8 +74,10 @@ const theme: Record<string, Record<string, string>> = {
|
|||
"datetime-local": textClassification,
|
||||
textarea: {
|
||||
...textClassification,
|
||||
inner:
|
||||
"inline-flex items-center w-full relative box-border border border-gray-300 formkit-invalid:border-red-500 h-32 rounded-base overflow-hidden focus-within:border-primary mt-2 sm:mt-0",
|
||||
input:
|
||||
"outline-0 bg-white antialiased w-full text-black block transition-all appearance-none h-32 px-3 py-2 text-sm",
|
||||
"outline-0 bg-white antialiased w-full text-black block transition-all appearance-none h-full px-3 py-2 text-sm",
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -1,72 +0,0 @@
|
|||
<script lang="ts" setup>
|
||||
import { VButton } from "@halo-dev/components";
|
||||
import { inject, ref } from "vue";
|
||||
import type { Ref } from "vue";
|
||||
import { apiClient } from "@halo-dev/admin-shared";
|
||||
import type { User } from "@halo-dev/api-client";
|
||||
|
||||
interface FormState {
|
||||
state: {
|
||||
password: string;
|
||||
password_confirm?: string;
|
||||
};
|
||||
submitting: boolean;
|
||||
}
|
||||
|
||||
const user = inject<Ref<User>>("user");
|
||||
const currentUser = inject<User>("currentUser");
|
||||
|
||||
const formState = ref<FormState>({
|
||||
state: {
|
||||
password: "",
|
||||
password_confirm: "",
|
||||
},
|
||||
submitting: false,
|
||||
});
|
||||
|
||||
const handleChangePassword = async () => {
|
||||
try {
|
||||
formState.value.submitting = true;
|
||||
if (user?.value.metadata.name === currentUser?.metadata.name) {
|
||||
await apiClient.user.changePassword("-", formState.value.state);
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
} finally {
|
||||
formState.value.submitting = false;
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<template>
|
||||
<FormKit
|
||||
id="password-form"
|
||||
v-model="formState.state"
|
||||
:actions="false"
|
||||
type="form"
|
||||
@submit="handleChangePassword"
|
||||
>
|
||||
<FormKit
|
||||
label="新密码"
|
||||
name="password"
|
||||
type="password"
|
||||
validation="required"
|
||||
></FormKit>
|
||||
<FormKit
|
||||
label="确认密码"
|
||||
name="password_confirm"
|
||||
type="password"
|
||||
validation="required|confirm"
|
||||
></FormKit>
|
||||
</FormKit>
|
||||
|
||||
<div class="pt-5">
|
||||
<div class="flex justify-start">
|
||||
<VButton
|
||||
:loading="formState.submitting"
|
||||
type="secondary"
|
||||
@click="$formkit.submit('password-form')"
|
||||
>修改密码
|
||||
</VButton>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
|
@ -1,37 +0,0 @@
|
|||
<script lang="ts" setup>
|
||||
import { VButton } from "@halo-dev/components";
|
||||
import { inject } from "vue";
|
||||
import type { Ref } from "vue";
|
||||
import type { User } from "@halo-dev/api-client";
|
||||
|
||||
const user = inject<Ref<User>>("user");
|
||||
</script>
|
||||
<template>
|
||||
<FormKit v-if="user" id="user-form" :actions="false" type="form">
|
||||
<FormKit
|
||||
v-model="user.metadata.name"
|
||||
label="用户名"
|
||||
type="text"
|
||||
validation="required"
|
||||
></FormKit>
|
||||
<FormKit
|
||||
v-model="user.spec.displayName"
|
||||
label="显示名称"
|
||||
type="text"
|
||||
validation="required"
|
||||
></FormKit>
|
||||
<FormKit
|
||||
v-model="user.spec.email"
|
||||
label="电子邮箱"
|
||||
type="email"
|
||||
validation="required"
|
||||
></FormKit>
|
||||
<FormKit v-model="user.spec.bio" label="描述" type="textarea"></FormKit>
|
||||
</FormKit>
|
||||
|
||||
<div class="pt-5">
|
||||
<div class="flex justify-start">
|
||||
<VButton type="secondary">保存</VButton>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
|
@ -1,10 +1,11 @@
|
|||
<script lang="ts" setup>
|
||||
import { BasicLayout } from "../layouts";
|
||||
import { IconUpload, VButton, VTabbar } from "@halo-dev/components";
|
||||
import { apiClient, BasicLayout } from "@halo-dev/admin-shared";
|
||||
import { IconUpload, VButton, VSpace, VTabbar } from "@halo-dev/components";
|
||||
import { onMounted, provide, ref, watch } from "vue";
|
||||
import { useRoute, useRouter } from "vue-router";
|
||||
import { apiClient } from "../utils/api-client";
|
||||
import type { User } from "@halo-dev/api-client";
|
||||
import UserEditingModal from "../components/UserEditingModal.vue";
|
||||
import UserPasswordChangeModal from "../components/UserPasswordChangeModal.vue";
|
||||
|
||||
const tabs = [
|
||||
{
|
||||
|
@ -17,19 +18,11 @@ const tabs = [
|
|||
label: "个人令牌",
|
||||
routeName: "PersonalAccessTokens",
|
||||
},
|
||||
{
|
||||
id: "profile-modification",
|
||||
label: "资料修改",
|
||||
routeName: "ProfileModification",
|
||||
},
|
||||
{
|
||||
id: "password-change",
|
||||
label: "密码修改",
|
||||
routeName: "PasswordChange",
|
||||
},
|
||||
];
|
||||
|
||||
const user = ref<User>();
|
||||
const editingModal = ref(false);
|
||||
const passwordChangeModal = ref(false);
|
||||
|
||||
const { params } = useRoute();
|
||||
|
||||
|
@ -75,16 +68,26 @@ const handleTabChange = (id: string) => {
|
|||
</script>
|
||||
<template>
|
||||
<BasicLayout>
|
||||
<UserEditingModal
|
||||
v-model:visible="editingModal"
|
||||
:user="user"
|
||||
@close="handleFetchUser"
|
||||
/>
|
||||
<UserPasswordChangeModal
|
||||
v-model:visible="passwordChangeModal"
|
||||
:user="user"
|
||||
@close="handleFetchUser"
|
||||
/>
|
||||
<header class="bg-white">
|
||||
<div class="h-48 bg-gradient-to-r from-gray-800 to-red-500"></div>
|
||||
<div class="px-4 sm:px-6 lg:px-8">
|
||||
<div class="-mt-12 flex items-end space-x-5 sm:-mt-16">
|
||||
<div class="flex">
|
||||
<div class="bg-white h-24 w-24 sm:h-32 sm:w-32">
|
||||
<div class="h-24 w-24 sm:h-32 sm:w-32">
|
||||
<img
|
||||
:src="user?.spec?.avatar"
|
||||
alt="Avatar"
|
||||
class="h-full w-full rounded-full ring-4 ring-white drop-shadow-lg"
|
||||
class="h-full w-full rounded-full bg-white ring-4 ring-white drop-shadow-lg"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -95,11 +98,35 @@ const handleTabChange = (id: string) => {
|
|||
<h1 class="truncate text-xl font-bold text-gray-900">
|
||||
<span class="mr-1">{{ user?.spec?.displayName }}</span>
|
||||
</h1>
|
||||
<h2 class="text-gray-600">@{{ user?.metadata.name }}</h2>
|
||||
</div>
|
||||
<div
|
||||
class="justify-stretch mt-6 hidden flex-col space-y-3 sm:flex-row sm:space-y-0 sm:space-x-4 md:flex"
|
||||
>
|
||||
<VButton type="default">退出登录</VButton>
|
||||
<FloatingDropdown>
|
||||
<VButton type="default">编辑</VButton>
|
||||
<template #popper>
|
||||
<div class="w-48 p-2">
|
||||
<VSpace class="w-full" direction="column">
|
||||
<VButton
|
||||
v-close-popper
|
||||
block
|
||||
type="secondary"
|
||||
@click="editingModal = true"
|
||||
>
|
||||
修改资料
|
||||
</VButton>
|
||||
<VButton
|
||||
v-close-popper
|
||||
block
|
||||
@click="passwordChangeModal = true"
|
||||
>
|
||||
修改密码
|
||||
</VButton>
|
||||
</VSpace>
|
||||
</div>
|
||||
</template>
|
||||
</FloatingDropdown>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
|
@ -1,13 +1,7 @@
|
|||
import {
|
||||
BasicLayout,
|
||||
BlankLayout,
|
||||
definePlugin,
|
||||
UserProfileLayout,
|
||||
} from "@halo-dev/admin-shared";
|
||||
import { BasicLayout, BlankLayout, definePlugin } from "@halo-dev/admin-shared";
|
||||
import UserProfileLayout from "./layouts/UserProfileLayout.vue";
|
||||
import UserList from "./UserList.vue";
|
||||
import UserDetail from "./UserDetail.vue";
|
||||
import ProfileModification from "./ProfileModification.vue";
|
||||
import PasswordChange from "./PasswordChange.vue";
|
||||
import PersonalAccessTokens from "./PersonalAccessTokens.vue";
|
||||
import Login from "./Login.vue";
|
||||
import { IconUserSettings } from "@halo-dev/components";
|
||||
|
@ -42,22 +36,13 @@ export default definePlugin({
|
|||
{
|
||||
path: ":name",
|
||||
component: UserProfileLayout,
|
||||
name: "User",
|
||||
children: [
|
||||
{
|
||||
path: "detail",
|
||||
name: "UserDetail",
|
||||
component: UserDetail,
|
||||
},
|
||||
{
|
||||
path: "profile-modification",
|
||||
name: "ProfileModification",
|
||||
component: ProfileModification,
|
||||
},
|
||||
{
|
||||
path: "password-change",
|
||||
name: "PasswordChange",
|
||||
component: PasswordChange,
|
||||
},
|
||||
{
|
||||
path: "tokens",
|
||||
name: "PersonalAccessTokens",
|
||||
|
|
Loading…
Reference in New Issue