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>
|
||||
176
src/views/account-settings/index.vue
Normal file
176
src/views/account-settings/index.vue
Normal file
@@ -0,0 +1,176 @@
|
||||
<script setup lang="ts">
|
||||
import { useRouter } from "vue-router";
|
||||
import { ref, onBeforeMount, computed } from "vue";
|
||||
import { ReText } from "@/components/ReText";
|
||||
import Avatar from "@/assets/user.png";
|
||||
import Profile from "./components/Profile.vue";
|
||||
import AccountSafe from "./components/AccountSafe.vue";
|
||||
import { useGlobal, deviceDetection } from "@pureadmin/utils";
|
||||
import { useUserStoreHook } from "@/store/modules/user";
|
||||
import { useDataThemeChange } from "@/layout/hooks/useDataThemeChange";
|
||||
import LaySidebarTopCollapse from "@/layout/components/lay-sidebar/components/SidebarTopCollapse.vue";
|
||||
|
||||
import leftLine from "@iconify-icons/ri/arrow-left-s-line";
|
||||
import ProfileIcon from "@iconify-icons/ri/user-3-line";
|
||||
import AccountSafeIcon from "@iconify-icons/ri/profile-line";
|
||||
|
||||
defineOptions({
|
||||
name: "AccountSettings"
|
||||
});
|
||||
|
||||
const router = useRouter();
|
||||
const isOpen = ref(deviceDetection() ? false : true);
|
||||
const { $storage } = useGlobal<GlobalPropertiesApi>();
|
||||
onBeforeMount(() => {
|
||||
useDataThemeChange().dataThemeChange($storage.layout?.overallStyle);
|
||||
});
|
||||
|
||||
/** 用户名 */
|
||||
const username = computed(() => {
|
||||
return useUserStoreHook()?.username;
|
||||
});
|
||||
/** 用户头像 */
|
||||
const userAvatar = computed(() => {
|
||||
console.log(useUserStoreHook()?.avatar);
|
||||
if (useUserStoreHook()?.avatar) {
|
||||
return useUserStoreHook()?.avatar;
|
||||
} else {
|
||||
}
|
||||
return Avatar;
|
||||
});
|
||||
/**用户账号 */
|
||||
const nickname = computed(() => {
|
||||
return useUserStoreHook()?.nickname;
|
||||
});
|
||||
const panes = [
|
||||
{
|
||||
key: "profile",
|
||||
label: "个人信息",
|
||||
icon: ProfileIcon,
|
||||
component: Profile
|
||||
},
|
||||
{
|
||||
key: "accountSafe",
|
||||
label: "账户安全",
|
||||
icon: AccountSafeIcon,
|
||||
component: AccountSafe
|
||||
}
|
||||
];
|
||||
const witchPane = ref("profile");
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<el-container class="h-full">
|
||||
<el-aside
|
||||
v-if="isOpen"
|
||||
class="pure-account-settings overflow-hidden px-2 dark:!bg-[var(--el-bg-color)] border-r-[1px] border-[var(--pure-border-color)]"
|
||||
:width="deviceDetection() ? '180px' : '240px'"
|
||||
>
|
||||
<el-menu :default-active="witchPane" class="pure-account-settings-menu">
|
||||
<el-menu-item
|
||||
class="hover:!transition-all hover:!duration-200 hover:!text-base !h-[50px]"
|
||||
@click="router.go(-1)"
|
||||
>
|
||||
<div class="flex items-center">
|
||||
<IconifyIconOffline :icon="leftLine" />
|
||||
<span class="ml-2">返回</span>
|
||||
</div>
|
||||
</el-menu-item>
|
||||
<div class="flex items-center ml-8 mt-4 mb-4">
|
||||
<el-avatar :size="48" :src="userAvatar" />
|
||||
<div class="ml-4 flex flex-col max-w-[130px]">
|
||||
<ReText class="font-bold !self-baseline">
|
||||
{{ username }}
|
||||
</ReText>
|
||||
<ReText class="!self-baseline" type="info">
|
||||
{{ nickname }}
|
||||
</ReText>
|
||||
</div>
|
||||
</div>
|
||||
<el-menu-item
|
||||
v-for="item in panes"
|
||||
:key="item.key"
|
||||
:index="item.key"
|
||||
@click="
|
||||
() => {
|
||||
witchPane = item.key;
|
||||
if (deviceDetection()) {
|
||||
isOpen = !isOpen;
|
||||
}
|
||||
}
|
||||
"
|
||||
>
|
||||
<div class="flex items-center z-10">
|
||||
<el-icon><IconifyIconOffline :icon="item.icon" /></el-icon>
|
||||
<span>{{ item.label }}</span>
|
||||
</div>
|
||||
</el-menu-item>
|
||||
</el-menu>
|
||||
</el-aside>
|
||||
<el-main>
|
||||
<LaySidebarTopCollapse
|
||||
v-if="deviceDetection()"
|
||||
class="px-0"
|
||||
:is-active="isOpen"
|
||||
@toggleClick="isOpen = !isOpen"
|
||||
/>
|
||||
<component
|
||||
:is="panes.find(item => item.key === witchPane).component"
|
||||
:class="[!deviceDetection() && 'ml-[120px]']"
|
||||
/>
|
||||
</el-main>
|
||||
</el-container>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
.pure-account-settings {
|
||||
background: var(--pure-theme-menu-bg) !important;
|
||||
}
|
||||
|
||||
.pure-account-settings-menu {
|
||||
background-color: transparent;
|
||||
border: none;
|
||||
|
||||
.el-menu-item {
|
||||
height: 48px !important;
|
||||
color: var(--pure-theme-menu-text);
|
||||
background-color: transparent !important;
|
||||
transition: color 0.2s;
|
||||
|
||||
&:hover {
|
||||
color: var(--pure-theme-menu-title-hover) !important;
|
||||
}
|
||||
|
||||
&.is-active {
|
||||
color: #fff !important;
|
||||
|
||||
&:hover {
|
||||
color: #fff !important;
|
||||
}
|
||||
|
||||
&::before {
|
||||
position: absolute;
|
||||
inset: 0 8px;
|
||||
margin: 4px 0;
|
||||
clear: both;
|
||||
content: "";
|
||||
background: var(--el-color-primary);
|
||||
border-radius: 3px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
body[layout] {
|
||||
.el-menu--vertical .is-active {
|
||||
color: #fff !important;
|
||||
transition: color 0.2s;
|
||||
|
||||
&:hover {
|
||||
color: #fff !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
349
src/views/account-settings/utils/hooks.tsx
Normal file
349
src/views/account-settings/utils/hooks.tsx
Normal file
@@ -0,0 +1,349 @@
|
||||
import { message } from "@/utils/message";
|
||||
import { addDialog } from "@/components/ReDialog";
|
||||
import { reactive, ref, onMounted, watch } from "vue";
|
||||
import { ElForm, ElFormItem, ElInput, ElProgress } from "element-plus";
|
||||
import type { UserInfo } from "types/user";
|
||||
import { getUserInfoAPI } from "@/api/login";
|
||||
import {
|
||||
putUpdateEmailAPI,
|
||||
putUpdatePasswordAPI,
|
||||
putUpdatePhoneAPI
|
||||
} from "@/api/user";
|
||||
import { isAllEmpty, isEmail, isPhone, storageLocal } from "@pureadmin/utils";
|
||||
import { zxcvbn } from "@zxcvbn-ts/core";
|
||||
import { setUserInfo, userInfoKey } from "@/utils/auth";
|
||||
|
||||
export const useUserInfo = () => {
|
||||
/** 密码正则(密码格式应为8-18位数字、字母、符号的任意两种组合) */
|
||||
const REGEXP_PWD =
|
||||
/^(?![0-9]+$)(?![a-z]+$)(?![A-Z]+$)(?!([^(0-9a-zA-Z)]|[()])+$)(?!^.*[\u4E00-\u9FA5].*$)([^(0-9a-zA-Z)]|[()]|[a-z]|[A-Z]|[0-9]){8,18}$/;
|
||||
|
||||
const pwdProgress = [
|
||||
{ color: "#e74242", text: "非常弱" },
|
||||
{ color: "#EFBD47", text: "弱" },
|
||||
{ color: "#ffa500", text: "一般" },
|
||||
{ color: "#1bbf1b", text: "强" },
|
||||
{ color: "#008000", text: "非常强" }
|
||||
];
|
||||
// 当前密码强度(0-4)
|
||||
const curScore = ref();
|
||||
const ruleFormRef = ref();
|
||||
/**密码表单 */
|
||||
const passwordForm = reactive({
|
||||
oldPassword: "",
|
||||
newPassword: ""
|
||||
});
|
||||
/**联系方式表单 */
|
||||
const phoneForm = reactive({
|
||||
password: "",
|
||||
phone: ""
|
||||
});
|
||||
/**邮箱*/
|
||||
const emailForm = reactive({
|
||||
password: "",
|
||||
email: ""
|
||||
});
|
||||
const userInfo = reactive<UserInfo>({
|
||||
id: "",
|
||||
username: "",
|
||||
gender: 1,
|
||||
avatar: "",
|
||||
email: "",
|
||||
nickname: "",
|
||||
phone: "",
|
||||
status: 0,
|
||||
create_time: "",
|
||||
update_time: "",
|
||||
roles: [],
|
||||
permissions: []
|
||||
});
|
||||
/**获取个人信息 */
|
||||
const getUserInfo = async () => {
|
||||
const res = await getUserInfoAPI();
|
||||
if (res.success) {
|
||||
Object.assign(userInfo, res.data);
|
||||
const user = storageLocal().getItem<object>(userInfoKey);
|
||||
storageLocal().setItem(userInfoKey, {
|
||||
...user,
|
||||
avatar: res.data.avatar,
|
||||
nickname: res.data.nickname
|
||||
});
|
||||
setUserInfo(res.data);
|
||||
}
|
||||
};
|
||||
|
||||
/**组件挂载执行 */
|
||||
onMounted(async () => {
|
||||
await getUserInfo();
|
||||
});
|
||||
watch(
|
||||
passwordForm,
|
||||
({ newPassword }) =>
|
||||
(curScore.value = isAllEmpty(newPassword)
|
||||
? -1
|
||||
: zxcvbn(newPassword).score)
|
||||
);
|
||||
/**密码校验规则 */
|
||||
const passwordRule = [
|
||||
{
|
||||
validator: (rule, value, callback) => {
|
||||
if (value === "") {
|
||||
callback(new Error("请输入新密码~"));
|
||||
} else if (!REGEXP_PWD.test(value)) {
|
||||
callback(
|
||||
new Error("密码格式应为8-18位数字、字母、符号的任意两种组合~")
|
||||
);
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
},
|
||||
trigger: "blur"
|
||||
}
|
||||
];
|
||||
/**手机好校验规则 */
|
||||
const phoneRule = [
|
||||
{
|
||||
validator: (rule, value, callback) => {
|
||||
if (value === "") {
|
||||
callback(new Error("请输入手机号码~"));
|
||||
} else if (!isPhone(value)) {
|
||||
callback(new Error("请输入正确的手机号码格式~"));
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
},
|
||||
trigger: "blur"
|
||||
}
|
||||
];
|
||||
/**邮箱校验规则 */
|
||||
const emailRule = [
|
||||
{
|
||||
validator: (rule, value, callback) => {
|
||||
if (value === "") {
|
||||
callback(new Error("请输入邮箱~"));
|
||||
} else if (!isEmail(value)) {
|
||||
callback(new Error("请输入正确的邮箱格式~"));
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
},
|
||||
trigger: "blur"
|
||||
}
|
||||
];
|
||||
/** 重置密码 */
|
||||
const handleReset = (row: UserInfo) => {
|
||||
addDialog({
|
||||
title: `重置 ${row.username}--${row.nickname} 的密码`,
|
||||
width: "30%",
|
||||
draggable: true,
|
||||
closeOnClickModal: false,
|
||||
contentRenderer: () => (
|
||||
<div>
|
||||
<ElForm ref={ruleFormRef} model={passwordForm}>
|
||||
<ElFormItem
|
||||
prop="oldPassword"
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
message: "请输入旧密码~",
|
||||
trigger: "blur"
|
||||
}
|
||||
]}
|
||||
>
|
||||
<ElInput
|
||||
clearable
|
||||
show-password
|
||||
type="password"
|
||||
v-model={passwordForm.oldPassword}
|
||||
placeholder="请输入旧密码~"
|
||||
/>
|
||||
</ElFormItem>
|
||||
<ElFormItem prop="newPassword" rules={passwordRule}>
|
||||
<ElInput
|
||||
clearable
|
||||
show-password
|
||||
type="password"
|
||||
v-model={passwordForm.newPassword}
|
||||
placeholder="请输入新密码~"
|
||||
/>
|
||||
</ElFormItem>
|
||||
</ElForm>
|
||||
<div class="mt-4 flex">
|
||||
{pwdProgress.map(({ color, text }, idx) => (
|
||||
<div
|
||||
class="w-[19vw]"
|
||||
style={{ marginLeft: idx !== 0 ? "4px" : 0 }}
|
||||
>
|
||||
<ElProgress
|
||||
striped
|
||||
striped-flow
|
||||
duration={curScore.value === idx ? 6 : 0}
|
||||
percentage={curScore.value >= idx ? 100 : 0}
|
||||
color={color}
|
||||
stroke-width={10}
|
||||
show-text={false}
|
||||
/>
|
||||
<p
|
||||
class="text-center"
|
||||
style={{ color: curScore.value === idx ? color : "" }}
|
||||
>
|
||||
{text}
|
||||
</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
),
|
||||
closeCallBack: () => passwordForm,
|
||||
beforeSure: done => {
|
||||
ruleFormRef.value.validate(async (valid: any) => {
|
||||
if (valid) {
|
||||
// 表单规则校验通过
|
||||
const res = await putUpdatePasswordAPI(passwordForm);
|
||||
if (res.code === 200) {
|
||||
done();
|
||||
message(res.msg, {
|
||||
type: "success"
|
||||
});
|
||||
} else {
|
||||
message(res.msg, {
|
||||
type: "error"
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**更新手机号 */
|
||||
const handlePhone = (row: UserInfo) => {
|
||||
phoneForm.phone = row.phone;
|
||||
addDialog({
|
||||
title: `更新 ${row.username}--${row.nickname} 的联系号码`,
|
||||
width: "30%",
|
||||
draggable: true,
|
||||
closeOnClickModal: false,
|
||||
contentRenderer: () => (
|
||||
<div>
|
||||
<ElForm ref={ruleFormRef} model={phoneForm}>
|
||||
<ElFormItem
|
||||
prop="password"
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
message: "请输入密码~",
|
||||
trigger: "blur"
|
||||
}
|
||||
]}
|
||||
>
|
||||
<ElInput
|
||||
clearable
|
||||
show-password
|
||||
type="password"
|
||||
v-model={phoneForm.password}
|
||||
placeholder="请输入密码~"
|
||||
/>
|
||||
</ElFormItem>
|
||||
<ElFormItem prop="phone" rules={phoneRule}>
|
||||
<ElInput
|
||||
clearable
|
||||
type="text"
|
||||
v-model={phoneForm.phone}
|
||||
placeholder="请输入手机号~"
|
||||
/>
|
||||
</ElFormItem>
|
||||
</ElForm>
|
||||
</div>
|
||||
),
|
||||
closeCallBack: () => phoneForm,
|
||||
beforeSure: done => {
|
||||
ruleFormRef.value.validate(async (valid: any) => {
|
||||
if (valid) {
|
||||
// 表单规则校验通过
|
||||
const res = await putUpdatePhoneAPI(phoneForm);
|
||||
if (res.code === 200) {
|
||||
done();
|
||||
message(res.msg, {
|
||||
type: "success"
|
||||
});
|
||||
} else {
|
||||
message(res.msg, {
|
||||
type: "error"
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
/**更新邮箱 */
|
||||
const handleEmail = (row: UserInfo) => {
|
||||
emailForm.email = row.email;
|
||||
addDialog({
|
||||
title: `更新 ${row.username}--${row.nickname} 的联系邮箱`,
|
||||
width: "30%",
|
||||
draggable: true,
|
||||
closeOnClickModal: false,
|
||||
contentRenderer: () => (
|
||||
<div>
|
||||
<ElForm ref={ruleFormRef} model={emailForm}>
|
||||
<ElFormItem
|
||||
prop="password"
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
message: "请输入密码~",
|
||||
trigger: "blur"
|
||||
}
|
||||
]}
|
||||
>
|
||||
<ElInput
|
||||
clearable
|
||||
show-password
|
||||
type="password"
|
||||
v-model={emailForm.password}
|
||||
placeholder="请输入密码~"
|
||||
/>
|
||||
</ElFormItem>
|
||||
<ElFormItem prop="email" rules={emailRule}>
|
||||
<ElInput
|
||||
clearable
|
||||
type="text"
|
||||
v-model={emailForm.email}
|
||||
placeholder="请输入联系邮箱~"
|
||||
/>
|
||||
</ElFormItem>
|
||||
</ElForm>
|
||||
</div>
|
||||
),
|
||||
closeCallBack: () => emailForm,
|
||||
beforeSure: done => {
|
||||
ruleFormRef.value.validate(async (valid: any) => {
|
||||
if (valid) {
|
||||
// 表单规则校验通过
|
||||
const res = await putUpdateEmailAPI(emailForm);
|
||||
if (res.code === 200) {
|
||||
done();
|
||||
message(res.msg, {
|
||||
type: "success"
|
||||
});
|
||||
} else {
|
||||
message(res.msg, {
|
||||
type: "error"
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
return {
|
||||
userInfo,
|
||||
getUserInfo,
|
||||
handleReset,
|
||||
handlePhone,
|
||||
handleEmail
|
||||
};
|
||||
};
|
||||
Reference in New Issue
Block a user