feat: 添加部门管理
This commit is contained in:
67
src/views/account-settings/components/AccountSafe.vue
Normal file
67
src/views/account-settings/components/AccountSafe.vue
Normal file
@@ -0,0 +1,67 @@
|
||||
<script setup lang="ts">
|
||||
import { deviceDetection, hideTextAtIndex } from "@pureadmin/utils";
|
||||
import { useUserInfo } from "../utils/hooks";
|
||||
defineOptions({
|
||||
name: "AccountSafe"
|
||||
});
|
||||
|
||||
const { handleReset, handlePhone, handleEmail, userInfo } = useUserInfo();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div
|
||||
:class="[
|
||||
'min-w-[180px]',
|
||||
deviceDetection() ? 'max-w-[100%]' : 'max-w-[70%]'
|
||||
]"
|
||||
>
|
||||
<h3 class="my-8">账户安全</h3>
|
||||
<div class="flex items-center">
|
||||
<div class="flex-1">
|
||||
<p>账号密码</p>
|
||||
<el-text class="mx-1" type="info" />
|
||||
</div>
|
||||
<el-button type="primary" text @click="handleReset(userInfo)"
|
||||
>修改</el-button
|
||||
>
|
||||
</div>
|
||||
<el-divider />
|
||||
<div class="flex items-center">
|
||||
<div class="flex-1">
|
||||
<p>绑定号码</p>
|
||||
<el-text class="mx-1" type="info">
|
||||
已经绑定手机:{{
|
||||
hideTextAtIndex(userInfo.phone, { start: 3, end: 6 })
|
||||
}}
|
||||
</el-text>
|
||||
</div>
|
||||
<el-button type="primary" text @click="handlePhone(userInfo)"
|
||||
>修改</el-button
|
||||
>
|
||||
</div>
|
||||
<el-divider />
|
||||
<div class="flex items-center">
|
||||
<div class="flex-1">
|
||||
<p>绑定邮箱</p>
|
||||
<el-text class="mx-1" type="info"
|
||||
>已绑定邮箱:{{
|
||||
hideTextAtIndex(userInfo.email, {
|
||||
start: 3,
|
||||
end: userInfo.email.indexOf("@") - 1
|
||||
})
|
||||
}}
|
||||
</el-text>
|
||||
</div>
|
||||
<el-button type="primary" text @click="handleEmail(userInfo)"
|
||||
>修改</el-button
|
||||
>
|
||||
</div>
|
||||
<el-divider />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.el-divider--horizontal {
|
||||
border-top: 0.1px var(--el-border-color) var(--el-border-style);
|
||||
}
|
||||
</style>
|
||||
163
src/views/account-settings/components/Profile.vue
Normal file
163
src/views/account-settings/components/Profile.vue
Normal file
@@ -0,0 +1,163 @@
|
||||
<script setup lang="ts">
|
||||
import { ref } from "vue";
|
||||
import { message } from "@/utils/message";
|
||||
import type { FormInstance } from "element-plus";
|
||||
import ReCropperPreview from "@/components/ReCropperPreview";
|
||||
import { deviceDetection } from "@pureadmin/utils";
|
||||
import uploadLine from "@iconify-icons/ri/upload-line";
|
||||
import { postUploadAvatarAPI, putUpdateBaseUserInfoAPI } from "@/api/user";
|
||||
import { useUserStoreHook } from "@/store/modules/user";
|
||||
import { userInfoKey } from "@/utils/auth";
|
||||
import { storageLocal } from "@pureadmin/utils";
|
||||
import { useUserInfo } from "../utils/hooks";
|
||||
defineOptions({
|
||||
name: "Profile"
|
||||
});
|
||||
|
||||
const { userInfo, getUserInfo } = useUserInfo();
|
||||
const imgSrc = ref("");
|
||||
const cropperBlob = ref();
|
||||
const cropRef = ref();
|
||||
const uploadRef = ref();
|
||||
const isShow = ref(false);
|
||||
const userInfoFormRef = ref<FormInstance>();
|
||||
|
||||
const disabledDate = (time: Date) => {
|
||||
return time.getTime() > Date.now();
|
||||
};
|
||||
|
||||
const onChange = uploadFile => {
|
||||
const reader = new FileReader();
|
||||
reader.onload = e => {
|
||||
imgSrc.value = e.target.result as string;
|
||||
isShow.value = true;
|
||||
};
|
||||
reader.readAsDataURL(uploadFile.raw);
|
||||
};
|
||||
|
||||
const handleClose = () => {
|
||||
cropRef.value.hidePopover();
|
||||
uploadRef.value.clearFiles();
|
||||
isShow.value = false;
|
||||
};
|
||||
|
||||
const onCropper = ({ blob }) => (cropperBlob.value = blob);
|
||||
|
||||
const handleSubmitImage = async () => {
|
||||
const res = await postUploadAvatarAPI(userInfo.id, {
|
||||
file: cropperBlob.value
|
||||
});
|
||||
if (res.code === 200) {
|
||||
message("更新头像成功", { type: "success" });
|
||||
userInfo.avatar = `/file/${res.data.id}`;
|
||||
const user = storageLocal().getItem<object>(userInfoKey);
|
||||
storageLocal().setItem(userInfoKey, {
|
||||
...user,
|
||||
avatar: `/file/${res.data.id}`
|
||||
});
|
||||
useUserStoreHook().SET_AVATAR(`/file/${res.data.id}`);
|
||||
handleClose();
|
||||
} else {
|
||||
message("更新头像失败", { type: "error" });
|
||||
}
|
||||
};
|
||||
|
||||
// 更新信息
|
||||
const onSubmit = async (formEl: FormInstance) => {
|
||||
await formEl.validate(async (valid, fields) => {
|
||||
if (valid) {
|
||||
let updateForm = {
|
||||
name: userInfo.nickname,
|
||||
gender: userInfo.gender
|
||||
};
|
||||
const res = await putUpdateBaseUserInfoAPI(updateForm);
|
||||
if (res.code === 200) {
|
||||
message(res.msg, { type: "success" });
|
||||
await getUserInfo();
|
||||
} else {
|
||||
message(res.msg, { type: "error" });
|
||||
}
|
||||
} else {
|
||||
console.log("error submit!", fields);
|
||||
}
|
||||
});
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div
|
||||
:class="[
|
||||
'min-w-[180px]',
|
||||
deviceDetection() ? 'max-w-[100%]' : 'max-w-[70%]'
|
||||
]"
|
||||
>
|
||||
<h3 class="my-8">个人信息</h3>
|
||||
<el-form ref="userInfoFormRef" label-position="top" :model="userInfo">
|
||||
<el-form-item label="头像">
|
||||
<el-avatar :size="80" :src="userInfo.avatar" />
|
||||
<el-upload
|
||||
ref="uploadRef"
|
||||
accept="image/*"
|
||||
action="#"
|
||||
:limit="1"
|
||||
:auto-upload="false"
|
||||
:show-file-list="false"
|
||||
:on-change="onChange"
|
||||
>
|
||||
<el-button plain class="ml-4">
|
||||
<IconifyIconOffline :icon="uploadLine" />
|
||||
<span class="ml-2">更新头像</span>
|
||||
</el-button>
|
||||
</el-upload>
|
||||
</el-form-item>
|
||||
<el-form-item label="账号" prop="userId">
|
||||
<el-input
|
||||
v-model="userInfo.username"
|
||||
placeholder="请输入账号~"
|
||||
disabled
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
label="姓名"
|
||||
prop="name"
|
||||
:rules="[
|
||||
{
|
||||
required: true,
|
||||
message: '请输入用户姓名~',
|
||||
trigger: 'blur'
|
||||
}
|
||||
]"
|
||||
>
|
||||
<el-input v-model="userInfo.nickname" placeholder="请输入姓名~" />
|
||||
</el-form-item>
|
||||
<el-form-item label="性别" prop="gender">
|
||||
<el-radio-group v-model="userInfo.gender" class="ml-4">
|
||||
<el-radio :value="1" size="default">男</el-radio>
|
||||
<el-radio :value="0" size="default">女</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-button type="primary" @click="onSubmit(userInfoFormRef)">
|
||||
更新信息
|
||||
</el-button>
|
||||
</el-form>
|
||||
<el-dialog
|
||||
v-model="isShow"
|
||||
width="40%"
|
||||
title="编辑头像"
|
||||
destroy-on-close
|
||||
:closeOnClickModal="false"
|
||||
:before-close="handleClose"
|
||||
:fullscreen="deviceDetection()"
|
||||
>
|
||||
<ReCropperPreview ref="cropRef" :imgSrc="imgSrc" @cropper="onCropper" />
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button bg text @click="handleClose">取消</el-button>
|
||||
<el-button bg text type="primary" @click="handleSubmitImage">
|
||||
确定
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
Reference in New Issue
Block a user