课程模块部分bug修复

This commit is contained in:
2025-07-02 09:43:17 +08:00
parent 927b200cf2
commit 06debc411c
24 changed files with 418 additions and 456 deletions

View File

@ -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;
}