课程模块部分bug修复
This commit is contained in:
@ -20,11 +20,11 @@
|
||||
/>
|
||||
</a-form-item>
|
||||
|
||||
<a-button class="custom-button" @click="showModal">新增用户</a-button>
|
||||
<a-button class="custom-button" @click="showModal">新增管理员</a-button>
|
||||
<!--新增用户-->
|
||||
<a-modal
|
||||
v-model:open="openUser"
|
||||
title="新增用户"
|
||||
title="新增管理员"
|
||||
@ok="handleOk"
|
||||
:footer="null"
|
||||
>
|
||||
@ -375,22 +375,22 @@ const beforeUpload: UploadProps['beforeUpload'] = file => {
|
||||
// 自定义上传处理
|
||||
const handleUpload = async ({ file }: { file: File }) => {
|
||||
const form = new FormData();
|
||||
form.append('file', file); // 只保留file字段在formData中
|
||||
form.append('file', file);
|
||||
|
||||
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
|
||||
|
||||
if (res.code === 1) {
|
||||
formData.value.userAvatar = res.data;
|
||||
previewImage.value = URL.createObjectURL(file);
|
||||
message.success('上传成功');
|
||||
@ -405,29 +405,29 @@ const handleUpload = async ({ file }: { file: File }) => {
|
||||
}
|
||||
};
|
||||
|
||||
// 编辑表单实时处理函数
|
||||
|
||||
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();
|
||||
@ -516,7 +516,7 @@ const handleSearchPhoneInput = (e: any) => {
|
||||
|
||||
// 新增 onKeyDown 事件处理函数
|
||||
const handleKeyDown = (e: KeyboardEvent) => {
|
||||
// 允许控制键(如删除、左右方向键等)
|
||||
|
||||
const allowedKeys = [
|
||||
'Backspace',
|
||||
'Delete',
|
||||
@ -525,13 +525,13 @@ const handleKeyDown = (e: KeyboardEvent) => {
|
||||
'Tab',
|
||||
];
|
||||
|
||||
// 阻止非数字和非允许按键
|
||||
|
||||
if (!/[0-9]/.test(e.key) && !allowedKeys.includes(e.key)) {
|
||||
e.preventDefault();
|
||||
}
|
||||
};
|
||||
|
||||
// 实时校验逻辑
|
||||
|
||||
const formData = ref({
|
||||
nickName: '',
|
||||
userAvatar: '',
|
||||
@ -590,8 +590,8 @@ const columns = [
|
||||
key: 'id',
|
||||
fixed: 'left',
|
||||
align: 'center',
|
||||
sorter: true, // 添加排序功能
|
||||
sortDirections: ['ascend', 'descend'] // 允许升序降序
|
||||
sorter: true,
|
||||
sortDirections: ['ascend', 'descend']
|
||||
},
|
||||
|
||||
{
|
||||
@ -630,8 +630,8 @@ const columns = [
|
||||
key: 'phoneNumber',
|
||||
width: 80,
|
||||
align: 'center',
|
||||
sorter: true, // 添加排序功能
|
||||
sortDirections: ['ascend', 'descend'] // 允许升序降序
|
||||
sorter: true,
|
||||
sortDirections: ['ascend', 'descend']
|
||||
},
|
||||
{
|
||||
title: '邀请码',
|
||||
@ -639,8 +639,8 @@ const columns = [
|
||||
key: 'invitationCode',
|
||||
width: 70,
|
||||
align: 'center',
|
||||
sorter: true, // 添加排序功能
|
||||
sortDirections: ['ascend', 'descend'] // 允许升序降序
|
||||
sorter: true,
|
||||
sortDirections: ['ascend', 'descend']
|
||||
},
|
||||
{
|
||||
title: '上级ID',
|
||||
@ -648,8 +648,8 @@ const columns = [
|
||||
key: 'parentUserId',
|
||||
width: 40,
|
||||
align: 'center',
|
||||
sorter: true, // 添加排序功能
|
||||
sortDirections: ['ascend', 'descend'] // 允许升序降序
|
||||
sorter: true,
|
||||
sortDirections: ['ascend', 'descend']
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
@ -670,7 +670,7 @@ const pagination = ref({
|
||||
pageSizeOptions: ['10', '20', '50', '100']
|
||||
});
|
||||
//编辑用户表单
|
||||
// 新增编辑表单校验规则
|
||||
|
||||
const editFormRules = {
|
||||
nickName: [
|
||||
{
|
||||
@ -721,13 +721,13 @@ 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 editFormRef = ref();
|
||||
|
||||
// 修改后的分页处理函数
|
||||
const handleTableChange = (pag: any, _: any, sorter: any) => {
|
||||
// 处理排序参数
|
||||
let sortField = "id"; // 默认排序字段
|
||||
let sortOrder = "ascend"; // 默认排序方式
|
||||
|
||||
let sortField = "id";
|
||||
let sortOrder = "ascend";
|
||||
|
||||
if (sorter.field) {
|
||||
sortField = sorter.field;
|
||||
@ -738,8 +738,8 @@ const handleTableChange = (pag: any, _: any, sorter: any) => {
|
||||
...searchParams.value,
|
||||
current: pag.current,
|
||||
pageSize: pag.pageSize,
|
||||
sortField: sortField, // 设置排序字段
|
||||
sortOrder: sortOrder // 设置排序方式
|
||||
sortField: sortField,
|
||||
sortOrder: sortOrder
|
||||
};
|
||||
|
||||
pagination.value.current = pag.current;
|
||||
@ -749,7 +749,7 @@ const handleTableChange = (pag: any, _: any, sorter: any) => {
|
||||
};
|
||||
|
||||
|
||||
// 修改获取用户列表方法
|
||||
|
||||
const getUserList = async () => {
|
||||
loading.value = true;
|
||||
try {
|
||||
@ -771,7 +771,7 @@ const getUserList = async () => {
|
||||
superUserList: item.superHostList? item.superHostList.join(', ') : '无'
|
||||
};
|
||||
});
|
||||
// 更新分页信息
|
||||
|
||||
pagination.value.total = res.data.total;
|
||||
pagination.value.current = res.data.current;
|
||||
pagination.value.pageSize = res.data.size;
|
||||
@ -796,14 +796,11 @@ interface User {
|
||||
parentUserId:number
|
||||
}
|
||||
|
||||
const tableData = ref<User[]>([]); // 明确元素类型为User[]
|
||||
const tableData = ref<User[]>([]);
|
||||
|
||||
const searchPhone = ref(""); // 手机号搜索参数
|
||||
const searchPhone = ref("");
|
||||
|
||||
// 修改5: 删除原有的searchId变量
|
||||
// const searchId = ref(""); // 删除这行
|
||||
|
||||
// 修改6: 替换原有的handleIdSearch方法
|
||||
const handlePhoneSearch = async () => {
|
||||
if (!searchPhone.value) {
|
||||
message.warning('请输入手机号');
|
||||
@ -821,7 +818,7 @@ const handlePhoneSearch = async () => {
|
||||
const storedToken = localStorage.getItem('token');
|
||||
if (!storedToken) throw new Error('未找到登录信息');
|
||||
|
||||
// 修改7: 使用phoneNumber作为查询参数
|
||||
|
||||
const res: { code: number; data: any; message: any } = await myAxios.post(
|
||||
"/userInfo/page",
|
||||
{
|
||||
@ -857,9 +854,9 @@ const handlePhoneSearch = async () => {
|
||||
}
|
||||
};
|
||||
|
||||
// 修改8: 更新reset方法
|
||||
|
||||
const reset = () => {
|
||||
searchPhone.value = ""; // 清空手机号搜索
|
||||
searchPhone.value = "";
|
||||
searchParams.value = {
|
||||
current: 1,
|
||||
pageSize: 10,
|
||||
@ -868,7 +865,7 @@ const reset = () => {
|
||||
userRole: null,
|
||||
phoneNumber: null
|
||||
};
|
||||
getUserList(); // 重新加载列表
|
||||
getUserList();
|
||||
};
|
||||
|
||||
|
||||
@ -882,13 +879,13 @@ const rowSelection = {
|
||||
selectedRowKeys.value = selectedKeys;
|
||||
},
|
||||
selectedRowKeys: selectedRowKeys,
|
||||
// 添加getCheckboxProps方法,根据用户角色决定是否禁用复选框
|
||||
|
||||
getCheckboxProps: (record: User) => ({
|
||||
disabled: record.userRole !== 'admin', // 只有admin用户可以选择
|
||||
disabled: record.userRole !== 'admin',
|
||||
name: record.id.toString(),
|
||||
}),
|
||||
};
|
||||
// 修改删除用户方法,添加确认弹窗
|
||||
|
||||
const confirmDeleteUser = (id: number) => {
|
||||
Modal.confirm({
|
||||
title: '确认删除用户',
|
||||
@ -897,7 +894,7 @@ const confirmDeleteUser = (id: number) => {
|
||||
okType: 'danger',
|
||||
cancelText: '取消',
|
||||
onOk() {
|
||||
return deleteUser(id); // 调用实际删除方法
|
||||
return deleteUser(id);
|
||||
},
|
||||
onCancel() {
|
||||
console.log('用户取消删除');
|
||||
@ -905,7 +902,7 @@ const confirmDeleteUser = (id: number) => {
|
||||
});
|
||||
};
|
||||
|
||||
// 修改批量删除方法,添加确认弹窗
|
||||
|
||||
const batchDelete = async () => {
|
||||
if (selectedRowKeys.value.length === 0) {
|
||||
message.warning('请先选择要删除的用户');
|
||||
@ -952,7 +949,7 @@ const batchDelete = async () => {
|
||||
});
|
||||
};
|
||||
|
||||
// 原有的deleteUser方法保持不变(执行实际删除操作)
|
||||
|
||||
const deleteUser = async (id: number) => {
|
||||
try {
|
||||
const storedToken = localStorage.getItem('token');
|
||||
@ -1000,13 +997,11 @@ const editForm = ref({
|
||||
SuperUserList: ''
|
||||
});
|
||||
|
||||
// 修改showDrawer方法
|
||||
|
||||
// 编辑状态下的头像上传状态
|
||||
const editUploadLoading = ref(false);
|
||||
const editPreviewImage = ref('');
|
||||
|
||||
// 编辑时的自定义上传处理
|
||||
|
||||
const handleEditUpload = async ({ file }: { file: File }) => {
|
||||
const form = new FormData();
|
||||
form.append('file', file);
|
||||
@ -1058,15 +1053,14 @@ const showDrawer = (record: any) => {
|
||||
const toggleEditMode = () => {
|
||||
isEditMode.value = !isEditMode.value;
|
||||
};
|
||||
//保存修改的用户信息
|
||||
//保存修改的用户信息
|
||||
|
||||
const handleSave = async () => {
|
||||
try {
|
||||
// 检查密码是否修改且符合规则
|
||||
|
||||
if (editForm.value.userPassword) {
|
||||
const password = editForm.value.userPassword;
|
||||
|
||||
// 验证密码规则:必须包含数字、大写字母和小写字母
|
||||
|
||||
const hasNumber = /\d/.test(password);
|
||||
const hasUpperCase = /[A-Z]/.test(password);
|
||||
const hasLowerCase = /[a-z]/.test(password);
|
||||
@ -1080,19 +1074,19 @@ const handleSave = async () => {
|
||||
const storedToken = localStorage.getItem('token');
|
||||
if (!storedToken) throw new Error('未找到登录信息');
|
||||
|
||||
// 处理空值转换
|
||||
|
||||
const processValue = (value: any) => {
|
||||
if (value === "" || value === "无") return null; // 将空字符串和"无"转为null
|
||||
if (value === "" || value === "无") return null;
|
||||
return value;
|
||||
};
|
||||
|
||||
// 处理数字类型字段
|
||||
|
||||
const processNumber = (value: any) => {
|
||||
const num = Number(value);
|
||||
return isNaN(num) ? null : num;
|
||||
};
|
||||
|
||||
// 构建请求体
|
||||
|
||||
const payload = {
|
||||
id: editForm.value.id,
|
||||
nickName: processValue(editForm.value.nickName),
|
||||
@ -1110,7 +1104,7 @@ const handleSave = async () => {
|
||||
: []
|
||||
};
|
||||
|
||||
// 清理undefined字段
|
||||
|
||||
const cleanPayload = Object.fromEntries(
|
||||
Object.entries(payload).filter(([_, v]) => v !== undefined)
|
||||
);
|
||||
@ -1129,7 +1123,7 @@ const handleSave = async () => {
|
||||
await getUserList();
|
||||
const updatedUser = tableData.value.find(item => item.id === editForm.value.id);
|
||||
if (updatedUser) {
|
||||
selectedUser.value = { ...updatedUser }; // 关键更新
|
||||
selectedUser.value = { ...updatedUser };
|
||||
}
|
||||
isEditMode.value = false;
|
||||
} else {
|
||||
@ -1142,7 +1136,7 @@ const handleSave = async () => {
|
||||
};
|
||||
|
||||
|
||||
//新增用户
|
||||
|
||||
const openUser = ref<boolean>(false);
|
||||
const formRef = ref();
|
||||
|
||||
@ -1157,7 +1151,7 @@ const showModal = () => {
|
||||
userAccount: '',
|
||||
userPassword: ''
|
||||
};
|
||||
// 重置预览图片
|
||||
|
||||
previewImage.value = '';
|
||||
};
|
||||
|
||||
@ -1206,12 +1200,12 @@ const handleSubmit = async () => {
|
||||
formRef.value?.resetFields();
|
||||
getUserList();
|
||||
} else {
|
||||
// 使用提取函数处理错误信息
|
||||
|
||||
const errorMsg = extractErrorMessage(res.message);
|
||||
message.error(`${errorMsg}`);
|
||||
}
|
||||
} catch (error: any) {
|
||||
// 使用提取函数处理错误信息
|
||||
|
||||
let errorMsg = error.response?.message || error.message;
|
||||
errorMsg = extractErrorMessage(errorMsg);
|
||||
message.error(`${errorMsg}`);
|
||||
@ -1225,7 +1219,7 @@ const handleSubmit = async () => {
|
||||
.action-btn {
|
||||
padding: 0 8px;
|
||||
}
|
||||
/* 分割线样式 */
|
||||
|
||||
:deep(.ant-divider-vertical) {
|
||||
border-color: rgba(0, 0, 0, 0.15);
|
||||
height: 1.2em;
|
||||
@ -1316,46 +1310,14 @@ const handleSubmit = async () => {
|
||||
color: #1890ff;
|
||||
}
|
||||
|
||||
.code {
|
||||
font-family: monospace;
|
||||
background: #f5f5f5;
|
||||
padding: 2px 6px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
|
||||
.role-tag {
|
||||
margin-left: 8px;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.relation-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 12px 0;
|
||||
}
|
||||
|
||||
.relation-icon {
|
||||
font-size: 20px;
|
||||
color: #52c41a;
|
||||
margin-right: 16px;
|
||||
}
|
||||
|
||||
.relation-group {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.relation-label {
|
||||
display: inline-block;
|
||||
width: 80px;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.relation-value {
|
||||
color: #333;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
/* 角色颜色映射 */
|
||||
:root {
|
||||
--role-user: #87d068;
|
||||
--role-admin: #f50;
|
||||
@ -1507,7 +1469,7 @@ const handleSubmit = async () => {
|
||||
border-color: #fa8c16;
|
||||
}
|
||||
|
||||
/* 保持输入框原有样式不变 */
|
||||
|
||||
.custom-search :deep(.ant-input) {
|
||||
border-right-color: #ffa940;
|
||||
}
|
||||
|
Reference in New Issue
Block a user