完善用户管理和登录的表单校验
This commit is contained in:
parent
6cbd8f93e6
commit
0336f21f83
|
@ -10,15 +10,13 @@
|
||||||
<div class="input-box">
|
<div class="input-box">
|
||||||
|
|
||||||
<input class="password" :type="type" placeholder="密码" v-model="userPassword"/>
|
<input class="password" :type="type" placeholder="密码" v-model="userPassword"/>
|
||||||
<div @click="showPwd">
|
<!-- <div @click="showPwd">-->
|
||||||
<!-- 隐藏图标 -->
|
<!-- <img src="../assets/login/hidePassword.png" v-show="!showPassword" alt=""/>-->
|
||||||
<img src="../assets/login/hidePassword.png" v-show="showPassword === false" alt=""/>
|
<!-- <img src="../assets/login/showPassword.png" v-show="showPassword" alt=""/>-->
|
||||||
<!-- 显示图标 -->
|
<!-- </div>-->
|
||||||
<img src="../assets/login/showPassword.png" v-show="showPassword === true" alt=""/>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="error-messages" v-if="userPassword && passwordErrors.length">
|
<div class="error-messages" v-if="userPassword && passwordErrors.length">
|
||||||
<!-- <div class="error-messages" v-if="false">-->
|
<!-- <div class="error-messages" v-if="false">-->
|
||||||
<div v-for="error in passwordErrors" :key="error" class="error-message">
|
<div v-for="error in passwordErrors" :key="error" class="error-message">
|
||||||
{{ error }}
|
{{ error }}
|
||||||
</div>
|
</div>
|
||||||
|
@ -45,7 +43,7 @@ const store = userStore()
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
|
|
||||||
//默认闭眼图标
|
//默认闭眼图标
|
||||||
let showPassword = ref(false)
|
// let showPassword = ref(false)
|
||||||
//登录密码隐藏
|
//登录密码隐藏
|
||||||
let type = ref('password')
|
let type = ref('password')
|
||||||
const userAccount = ref('');
|
const userAccount = ref('');
|
||||||
|
@ -137,14 +135,14 @@ const onLogin = async () => {
|
||||||
/**
|
/**
|
||||||
* 显示密码
|
* 显示密码
|
||||||
*/
|
*/
|
||||||
const showPwd = () => {
|
// const showPwd = () => {
|
||||||
showPassword.value = !showPassword.value
|
// showPassword.value = !showPassword.value
|
||||||
if (showPassword.value == false) {
|
// if (showPassword.value == false) {
|
||||||
type.value = 'password'
|
// type.value = 'password'
|
||||||
} else {
|
// } else {
|
||||||
type.value = 'text'
|
// type.value = 'text'
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
/>
|
/>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<a-button type="primary" @click="showModal">新增用户</a-button>
|
<a-button type="primary" @click="showModal">新增用户</a-button>
|
||||||
<!-- 新增用户-->
|
<!-- 新增用户-->
|
||||||
<a-modal
|
<a-modal
|
||||||
v-model:open="openUser"
|
v-model:open="openUser"
|
||||||
title="新增用户"
|
title="新增用户"
|
||||||
|
@ -41,7 +41,21 @@
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
|
|
||||||
<a-form-item label="头像" name="userAvatar">
|
<a-form-item label="头像" name="userAvatar">
|
||||||
<a-input v-model:value="formData.userAvatar" />
|
<a-upload
|
||||||
|
name="file"
|
||||||
|
list-type="picture-card"
|
||||||
|
class="avatar-uploader"
|
||||||
|
:show-upload-list="false"
|
||||||
|
:before-upload="beforeUpload"
|
||||||
|
:custom-request="handleUpload"
|
||||||
|
>
|
||||||
|
<img v-if="formData.userAvatar" :src="previewImage" alt="avatar" style="width: 100%"/>
|
||||||
|
<div v-else>
|
||||||
|
<loading-outlined v-if="uploadLoading"></loading-outlined>
|
||||||
|
<plus-outlined v-else></plus-outlined>
|
||||||
|
<div class="ant-upload-text">上传头像</div>
|
||||||
|
</div>
|
||||||
|
</a-upload>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
|
|
||||||
<a-form-item label="手机号" name="phoneNumber">
|
<a-form-item label="手机号" name="phoneNumber">
|
||||||
|
@ -119,9 +133,9 @@
|
||||||
:loading="loading"
|
:loading="loading"
|
||||||
:row-selection="rowSelection"
|
:row-selection="rowSelection"
|
||||||
:pagination="pagination"
|
:pagination="pagination"
|
||||||
bordered
|
bordered
|
||||||
rowKey="id"
|
rowKey="id"
|
||||||
@change="handleTableChange"
|
@change="handleTableChange"
|
||||||
>
|
>
|
||||||
<template #bodyCell="{ column, record }">
|
<template #bodyCell="{ column, record }">
|
||||||
<template v-if="column.key === 'userAvatar'">
|
<template v-if="column.key === 'userAvatar'">
|
||||||
|
@ -161,24 +175,83 @@
|
||||||
<a-form
|
<a-form
|
||||||
v-if="isEditMode"
|
v-if="isEditMode"
|
||||||
:model="editForm"
|
:model="editForm"
|
||||||
|
:rules="editFormRules"
|
||||||
|
ref="editFormRef"
|
||||||
:label-col="{ span: 6 }"
|
:label-col="{ span: 6 }"
|
||||||
:wrapper-col="{ span: 16 }"
|
:wrapper-col="{ span: 16 }"
|
||||||
>
|
>
|
||||||
<!-- 可编辑表单 -->
|
<!-- 可编辑表单 -->
|
||||||
<a-form-item label="昵称">
|
<a-form-item label="昵称" name="nickName">
|
||||||
<a-input v-model:value="editForm.nickName" />
|
<a-input
|
||||||
|
v-model:value="editForm.nickName"
|
||||||
|
:maxlength="6"
|
||||||
|
@input="handleEditNicknameInput"
|
||||||
|
@keypress="handleMaxLength(6)"
|
||||||
|
>
|
||||||
|
<template #suffix>
|
||||||
|
<span v-if="editForm.nickName.length > 0" class="input-tip">
|
||||||
|
{{ editForm.nickName.length }}/6
|
||||||
|
<span v-if="editForm.nickName.length > 6" class="error-tip">(超过最大长度)</span>
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
</a-input>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<a-form-item label="头像URL">
|
|
||||||
<a-input v-model:value="editForm.userAvatar" />
|
<a-form-item label="头像" name="userAvatar">
|
||||||
|
<a-upload
|
||||||
|
name="file"
|
||||||
|
list-type="picture-card"
|
||||||
|
class="avatar-uploader"
|
||||||
|
:show-upload-list="false"
|
||||||
|
:before-upload="beforeUpload"
|
||||||
|
:custom-request="handleEditUpload"
|
||||||
|
>
|
||||||
|
<img v-if="editForm.userAvatar" :src="editPreviewImage" alt="avatar" style="width: 100%"/>
|
||||||
|
<div v-else>
|
||||||
|
<loading-outlined v-if="editUploadLoading"></loading-outlined>
|
||||||
|
<plus-outlined v-else></plus-outlined>
|
||||||
|
<div class="ant-upload-text">上传头像</div>
|
||||||
|
</div>
|
||||||
|
</a-upload>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<a-form-item label="手机号">
|
|
||||||
<a-input v-model:value="editForm.phoneNumber" />
|
|
||||||
|
<a-form-item label="手机号" name="phoneNumber">
|
||||||
|
<a-input
|
||||||
|
v-model:value="editForm.phoneNumber"
|
||||||
|
:maxlength="11"
|
||||||
|
@input="handleEditPhoneInput"
|
||||||
|
>
|
||||||
|
<template #suffix>
|
||||||
|
<span v-if="editForm.phoneNumber.length > 0" class="input-tip">
|
||||||
|
{{ editForm.phoneNumber.length }}/11
|
||||||
|
<span v-if="editForm.phoneNumber.length > 11" class="error-tip">(超过最大长度)</span>
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
</a-input>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<a-form-item label="账户">
|
<a-form-item label="账户">
|
||||||
<a-input v-model:value="editForm.userAccount" disabled />
|
<a-input v-model:value="editForm.userAccount" disabled />
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<a-form-item label="密码">
|
<a-form-item label="密码" name="userPassword">
|
||||||
<a-input v-model:value="editForm.userPassword" />
|
<a-input
|
||||||
|
v-model:value="editForm.userPassword"
|
||||||
|
type="password"
|
||||||
|
:maxlength="10"
|
||||||
|
@input="handleEditPasswordInput"
|
||||||
|
@keypress="handleMaxLength(10)"
|
||||||
|
>
|
||||||
|
<template #suffix>
|
||||||
|
<span v-if="editForm.userPassword.length > 0" class="input-tip">
|
||||||
|
{{ editForm.userPassword.length }}/10
|
||||||
|
<div class="password-strength">
|
||||||
|
<span :class="{ 'strength-ok': editHasLower }">小写字母</span>
|
||||||
|
<span :class="{ 'strength-ok': editHasUpper }">大写字母</span>
|
||||||
|
<span :class="{ 'strength-ok': editHasNumber }">数字</span>
|
||||||
|
</div>
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
</a-input>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<a-form-item label="邀请码">
|
<a-form-item label="邀请码">
|
||||||
<a-input v-model:value="editForm.invitationCode" />
|
<a-input v-model:value="editForm.invitationCode" />
|
||||||
|
@ -191,7 +264,7 @@
|
||||||
</a-select>
|
</a-select>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<a-form-item label="上级用户ID">
|
<a-form-item label="上级用户ID">
|
||||||
<a-input-number v-model:value="editForm.parentUserId" />
|
<a-input-number v-model:value="editForm.parentUserId" :min="0" />
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<a-form-item label="上级用户列表">
|
<a-form-item label="上级用户列表">
|
||||||
<a-input
|
<a-input
|
||||||
|
@ -222,9 +295,9 @@
|
||||||
<span class="info-label">账户信息</span>
|
<span class="info-label">账户信息</span>
|
||||||
<div class="account-detail">
|
<div class="account-detail">
|
||||||
<span>{{ selectedUser.userAccount }}</span>
|
<span>{{ selectedUser.userAccount }}</span>
|
||||||
<!-- <a-tag class="role-tag">-->
|
<!-- <a-tag class="role-tag">-->
|
||||||
<!-- {{ roleMap[editForm.userRole] }}-->
|
<!-- {{ roleMap[editForm.userRole] }}-->
|
||||||
<!-- </a-tag>-->
|
<!-- </a-tag>-->
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -263,12 +336,94 @@
|
||||||
import { onMounted, ref,computed } from "vue";
|
import { onMounted, ref,computed } from "vue";
|
||||||
import myAxios from "../../api/myAxios.ts";
|
import myAxios from "../../api/myAxios.ts";
|
||||||
import { message } from "ant-design-vue";
|
import { message } from "ant-design-vue";
|
||||||
|
import { PlusOutlined, LoadingOutlined } from '@ant-design/icons-vue';
|
||||||
|
import type { UploadProps } from 'ant-design-vue';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
UserOutlined,
|
UserOutlined,
|
||||||
IdcardOutlined,
|
IdcardOutlined,
|
||||||
SmileOutlined,
|
SmileOutlined,
|
||||||
PhoneOutlined,
|
PhoneOutlined,
|
||||||
} from '@ant-design/icons-vue';
|
} from '@ant-design/icons-vue';
|
||||||
|
const uploadLoading = ref(false);
|
||||||
|
const previewImage = ref('');
|
||||||
|
// 上传前校验
|
||||||
|
const beforeUpload: UploadProps['beforeUpload'] = file => {
|
||||||
|
const isImage = file.type.startsWith('image/');
|
||||||
|
if (!isImage) {
|
||||||
|
message.error('只能上传图片文件!');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const isLt5M = file.size / 1024 / 1024 < 5;
|
||||||
|
if (!isLt5M) {
|
||||||
|
message.error('图片大小不能超过5MB!');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 自定义上传处理
|
||||||
|
const handleUpload = async ({ file }: { file: File }) => {
|
||||||
|
const form = new FormData();
|
||||||
|
form.append('file', file); // 只保留file字段在formData中
|
||||||
|
|
||||||
|
try {
|
||||||
|
uploadLoading.value = true;
|
||||||
|
const storedToken = localStorage.getItem('token');
|
||||||
|
|
||||||
|
// 根据接口文档修改请求地址和参数
|
||||||
|
const res:any = await myAxios.post('/file/upload?biz=avatar', form, {
|
||||||
|
headers: {
|
||||||
|
Authorization: storedToken,
|
||||||
|
// 保留由浏览器自动生成的内容类型
|
||||||
|
}
|
||||||
|
});
|
||||||
|
console.log(res)
|
||||||
|
// 根据响应结构调整(假设返回data直接是URL)
|
||||||
|
if (res.code === 1) { // 注意文档中响应状态码是200
|
||||||
|
formData.value.userAvatar = res.data;
|
||||||
|
previewImage.value = URL.createObjectURL(file);
|
||||||
|
message.success('上传成功');
|
||||||
|
} else {
|
||||||
|
message.error(res.message || '上传失败');
|
||||||
|
}
|
||||||
|
} catch (error:any) {
|
||||||
|
console.error('上传失败详情:', error);
|
||||||
|
message.error(`上传失败:${error.response?.data?.error || error.message}`);
|
||||||
|
} finally {
|
||||||
|
uploadLoading.value = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 编辑表单实时处理函数
|
||||||
|
const handleEditNicknameInput = (e: any) => {
|
||||||
|
// 限制最大长度并实时提示
|
||||||
|
const trimmedValue = e.target.value.trim().slice(0, 6);
|
||||||
|
editForm.value.nickName = trimmedValue;
|
||||||
|
// 触发表单校验
|
||||||
|
editFormRef.value?.validateField('nickName');
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleEditPhoneInput = (e: any) => {
|
||||||
|
// 过滤非数字字符并限制长度
|
||||||
|
const numericValue = e.target.value.replace(/\D/g, '').slice(0, 11);
|
||||||
|
editForm.value.phoneNumber = numericValue;
|
||||||
|
// 触发手机号格式校验
|
||||||
|
editFormRef.value?.validateField('phoneNumber');
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleEditPasswordInput = (e: any) => {
|
||||||
|
// 限制密码长度
|
||||||
|
editForm.value.userPassword = e.target.value.slice(0, 10);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 通用最大长度处理函数
|
||||||
|
const handleMaxLength = (max: number) => (e: KeyboardEvent) => {
|
||||||
|
if (e.target instanceof HTMLInputElement && e.target.value.length >= max) {
|
||||||
|
e.preventDefault();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
// 新增角色颜色映射
|
// 新增角色颜色映射
|
||||||
// const roleColorMap = {
|
// const roleColorMap = {
|
||||||
|
@ -487,7 +642,59 @@ const pagination = ref({
|
||||||
showTotal: (total: number) => `共 ${total} 条`,
|
showTotal: (total: number) => `共 ${total} 条`,
|
||||||
pageSizeOptions: ['10', '20', '50', '100']
|
pageSizeOptions: ['10', '20', '50', '100']
|
||||||
});
|
});
|
||||||
|
//编辑用户表单
|
||||||
|
// 新增编辑表单校验规则
|
||||||
|
const editFormRules = {
|
||||||
|
nickName: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请输入昵称',
|
||||||
|
trigger: ['input', 'blur']
|
||||||
|
},
|
||||||
|
{
|
||||||
|
min: 1,
|
||||||
|
max: 6,
|
||||||
|
message: '昵称长度需为1-6位',
|
||||||
|
trigger: ['input', 'blur']
|
||||||
|
}
|
||||||
|
],
|
||||||
|
phoneNumber: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请输入手机号',
|
||||||
|
trigger: ['input', 'blur']
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pattern: /^1[3-9]\d{9}$/,
|
||||||
|
message: '必须是有效的11位手机号',
|
||||||
|
trigger: ['input', 'blur']
|
||||||
|
}
|
||||||
|
],
|
||||||
|
userPassword: [
|
||||||
|
{
|
||||||
|
min: 6,
|
||||||
|
max: 10,
|
||||||
|
message: '长度需为6-10位',
|
||||||
|
trigger: ['input', 'blur']
|
||||||
|
},
|
||||||
|
{
|
||||||
|
validator: (_: any, value: string) => {
|
||||||
|
if (value && !/(?=.*[a-z])(?=.*[A-Z])(?=.*\d)/.test(value)) {
|
||||||
|
return Promise.reject('必须包含大小写字母和数字');
|
||||||
|
}
|
||||||
|
return Promise.resolve();
|
||||||
|
},
|
||||||
|
trigger: ['input', 'blur']
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
// 编辑表单的密码强度计算
|
||||||
|
const editHasLower = computed(() => /[a-z]/.test(editForm.value.userPassword))
|
||||||
|
const editHasUpper = computed(() => /[A-Z]/.test(editForm.value.userPassword))
|
||||||
|
const editHasNumber = computed(() => /\d/.test(editForm.value.userPassword))
|
||||||
|
|
||||||
|
const editFormRef = ref(); // 添加表单引用
|
||||||
|
|
||||||
const handleTableChange = (pag: any, sorter: any) => {
|
const handleTableChange = (pag: any, sorter: any) => {
|
||||||
searchParams.value = {
|
searchParams.value = {
|
||||||
|
@ -675,12 +882,46 @@ const editForm = ref({
|
||||||
// };
|
// };
|
||||||
|
|
||||||
// 修改showDrawer方法
|
// 修改showDrawer方法
|
||||||
|
|
||||||
|
// 编辑状态下的头像上传状态
|
||||||
|
const editUploadLoading = ref(false);
|
||||||
|
const editPreviewImage = ref('');
|
||||||
|
|
||||||
|
// 编辑时的自定义上传处理
|
||||||
|
const handleEditUpload = async ({ file }: { file: File }) => {
|
||||||
|
const form = new FormData();
|
||||||
|
form.append('file', file);
|
||||||
|
|
||||||
|
try {
|
||||||
|
editUploadLoading.value = true;
|
||||||
|
const storedToken = localStorage.getItem('token');
|
||||||
|
|
||||||
|
const res: any = await myAxios.post('/file/upload?biz=avatar', form, {
|
||||||
|
headers: {
|
||||||
|
Authorization: storedToken,
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (res.code === 1) {
|
||||||
|
editForm.value.userAvatar = res.data;
|
||||||
|
editPreviewImage.value = URL.createObjectURL(file);
|
||||||
|
message.success('头像更新成功');
|
||||||
|
} else {
|
||||||
|
message.error(res.message || '头像上传失败');
|
||||||
|
}
|
||||||
|
} catch (error: any) {
|
||||||
|
console.error('编辑头像上传失败:', error);
|
||||||
|
message.error(`上传失败:${error.response?.data?.error || error.message}`);
|
||||||
|
} finally {
|
||||||
|
editUploadLoading.value = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
const showDrawer = (record: any) => {
|
const showDrawer = (record: any) => {
|
||||||
selectedUser.value = record;
|
selectedUser.value = record;
|
||||||
editForm.value = {
|
editForm.value = {
|
||||||
id: record.id,
|
id: record.id,
|
||||||
nickName: record.nickName,
|
nickName: record.nickName,
|
||||||
userAvatar: record.userAvatar,
|
userAvatar: record.userAvatar||'',
|
||||||
phoneNumber: record.phoneNumber,
|
phoneNumber: record.phoneNumber,
|
||||||
userAccount: record.userAccount,
|
userAccount: record.userAccount,
|
||||||
userPassword: record.userPassword,
|
userPassword: record.userPassword,
|
||||||
|
@ -704,13 +945,44 @@ const handleSave = async () => {
|
||||||
const storedToken = localStorage.getItem('token');
|
const storedToken = localStorage.getItem('token');
|
||||||
if (!storedToken) throw new Error('未找到登录信息');
|
if (!storedToken) throw new Error('未找到登录信息');
|
||||||
|
|
||||||
// 构建符合接口要求的请求体
|
// 处理空值转换
|
||||||
const payload = {
|
const processValue = (value: any) => {
|
||||||
...editForm.value,
|
if (value === "" || value === "无") return null; // 将空字符串和"无"转为null
|
||||||
SuperUserList: editForm.value.SuperUserList.split(',').map(Number)
|
return value;
|
||||||
};
|
};
|
||||||
|
|
||||||
const res:any = await myAxios.post('/userInfo/update', payload, {
|
// 处理数字类型字段
|
||||||
|
const processNumber = (value: any) => {
|
||||||
|
const num = Number(value);
|
||||||
|
return isNaN(num) ? null : num;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 构建请求体
|
||||||
|
const payload = {
|
||||||
|
id: editForm.value.id,
|
||||||
|
nickName: processValue(editForm.value.nickName),
|
||||||
|
userAvatar: processValue(editForm.value.userAvatar),
|
||||||
|
phoneNumber: processValue(editForm.value.phoneNumber),
|
||||||
|
userAccount: editForm.value.userAccount, // 保持禁用状态的值
|
||||||
|
userPassword: editForm.value.userPassword || undefined, // 密码为空时不修改
|
||||||
|
invitationCode: processValue(editForm.value.invitationCode),
|
||||||
|
userRole: editForm.value.userRole || 'user',
|
||||||
|
parentUserId: processNumber(editForm.value.parentUserId),
|
||||||
|
SuperUserList: editForm.value.SuperUserList
|
||||||
|
? editForm.value.SuperUserList.split(',')
|
||||||
|
.map(item => processNumber(item.trim()))
|
||||||
|
.filter(num => num !== null)
|
||||||
|
: []
|
||||||
|
};
|
||||||
|
|
||||||
|
// 清理undefined字段
|
||||||
|
const cleanPayload = Object.fromEntries(
|
||||||
|
Object.entries(payload).filter(([_, v]) => v !== undefined)
|
||||||
|
);
|
||||||
|
|
||||||
|
console.log("最终请求体:", JSON.stringify(cleanPayload, null, 2));
|
||||||
|
|
||||||
|
const res:any = await myAxios.post('/userInfo/update', cleanPayload, {
|
||||||
headers: {
|
headers: {
|
||||||
Authorization: storedToken,
|
Authorization: storedToken,
|
||||||
'Content-Type': 'application/json'
|
'Content-Type': 'application/json'
|
||||||
|
@ -719,20 +991,16 @@ const handleSave = async () => {
|
||||||
|
|
||||||
if (res.code === 1) {
|
if (res.code === 1) {
|
||||||
message.success('更新成功');
|
message.success('更新成功');
|
||||||
// 更新本地数据
|
|
||||||
Object.assign(selectedUser.value, editForm.value);
|
|
||||||
// 刷新表格数据
|
|
||||||
await getUserList();
|
await getUserList();
|
||||||
isEditMode.value = false;
|
isEditMode.value = false;
|
||||||
} else {
|
} else {
|
||||||
message.error(res.message || '更新失败');
|
message.error(res.message || '更新失败');
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error:any) {
|
||||||
console.error('更新失败:', error);
|
console.error('更新失败:', error);
|
||||||
message.error('更新失败,请检查网络');
|
message.error(error.response?.data?.message || '更新失败,请检查网络');
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
//新增用户
|
//新增用户
|
||||||
const openUser = ref<boolean>(false);
|
const openUser = ref<boolean>(false);
|
||||||
const formRef = ref();
|
const formRef = ref();
|
||||||
|
@ -993,4 +1261,56 @@ const reset = () => {
|
||||||
.strength-ok::before {
|
.strength-ok::before {
|
||||||
background: #52c41a !important;
|
background: #52c41a !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.avatar-uploader :deep(.ant-upload) {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.ant-upload-text {
|
||||||
|
margin-top: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-tip {
|
||||||
|
font-size: 0.875rem;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
|
||||||
|
.error-tip {
|
||||||
|
color: #f5222d;
|
||||||
|
margin-left: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.password-strength {
|
||||||
|
margin-top: 4px;
|
||||||
|
font-size: 0.875rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.strength-ok {
|
||||||
|
color: #52c41a;
|
||||||
|
}
|
||||||
|
|
||||||
|
.avatar-uploader {
|
||||||
|
width: 100%;
|
||||||
|
max-width: 200px;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.avatar-uploader .ant-upload {
|
||||||
|
border: 1px dashed #d9d9d9;
|
||||||
|
border-radius: 6px;
|
||||||
|
cursor: pointer;
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.avatar-uploader .ant-upload:hover {
|
||||||
|
border-color: #40a9ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.avatar-uploader img {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
Loading…
Reference in New Issue
Block a user