From a74f46e6a42600a02e253a3293d1ef65161009d4 Mon Sep 17 00:00:00 2001 From: mayiming <1627832236@qq.com> Date: Mon, 3 Nov 2025 11:27:59 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E7=AE=A1=E7=90=86=E7=B3=BB?= =?UTF-8?q?=E7=BB=9F=E6=95=B4=E4=BD=93=E7=BB=93=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/views/baseoverview/BaseOverView.vue | 4 +- .../onlinecourse/onlineCourseView.vue | 1084 ++++++++++++++++- .../caseresource/setting/caseSettingView.vue | 11 +- .../src/views/community/CommunityView.vue | 499 -------- .../src/views/devproject/devprojectView.vue | 4 +- management/src/views/meeting/meetingView.vue | 8 +- management/src/views/publish/QuillEditor.vue | 21 +- .../views/socialservice/img/serviceimg.vue | 13 +- 8 files changed, 1092 insertions(+), 552 deletions(-) delete mode 100644 management/src/views/community/CommunityView.vue diff --git a/management/src/views/baseoverview/BaseOverView.vue b/management/src/views/baseoverview/BaseOverView.vue index 1602b45f..9ea50af9 100644 --- a/management/src/views/baseoverview/BaseOverView.vue +++ b/management/src/views/baseoverview/BaseOverView.vue @@ -224,8 +224,8 @@ const beforeUpload: UploadProps['beforeUpload'] = (rawFile) => { ElMessage.error('仅支持JPG/PNG/WEBP格式的图片'); return false; } - if (rawFile.size / 1024 / 1024 > 5) { - ElMessage.error('图片大小不能超过5MB'); + if (rawFile.size / 1024 / 1024 > 20) { + ElMessage.error('图片大小不能超过20MB'); return false; } console.log("图片校验成功"); diff --git a/management/src/views/caseresource/onlinecourse/onlineCourseView.vue b/management/src/views/caseresource/onlinecourse/onlineCourseView.vue index a91a4794..a60fd897 100644 --- a/management/src/views/caseresource/onlinecourse/onlineCourseView.vue +++ b/management/src/views/caseresource/onlinecourse/onlineCourseView.vue @@ -1,7 +1,7 @@ @@ -277,12 +630,18 @@ import { ElForm, ElFormItem, ElInputNumber, + ElPagination, + ElDatePicker, + ElSelect, + ElOption, + ElAvatar, + UploadFile, } from 'element-plus'; -import { Edit, Delete, Plus, Search, Folder, Document } from '@element-plus/icons-vue'; +import { Edit, Delete, Plus, Search, Folder, Document, Upload } from '@element-plus/icons-vue'; import type { UploadProps } from 'element-plus'; import zhCn from 'element-plus/dist/locale/zh-cn.mjs'; -/* ==================== 类型定义 ==================== */ +/* 类型定义 */ interface Course { id: number; title: string; @@ -331,7 +690,96 @@ interface ContentListRes { data: CourseContent[]; } -/* ==================== 课程列表 ==================== */ +// 拓展资源相关类型 +interface CourseResource { + id?: number; + course_id: number; + title: string; + resource_url: string; + size: number; + sort: number; +} + +interface ListResourceReq { + course_id: number; + page: number; + page_size: number; +} + +interface ResourceListResponse { + total: number; + list: CourseResource[]; + page: number; + page_size: number; +} + +interface SaveResourceReq extends Omit { + id?: number; +} + +// 课程活动相关类型 +interface CourseActivity { + id?: number; + course_id: number; + title: string; + activity_type: 1 | 2 | 3 | 4; // 1-作业,2-考试,3-讨论,4-直播 + content?: string; + start_time?: string; + end_time?: string; + sort: number; +} + +interface ListActivityReq { + course_id: number; + page: number; + page_size: number; +} + +interface ActivityListResponse { + total: number; + list: CourseActivity[]; + page: number; + page_size: number; +} + +// 课程教师相关类型 +interface CourseTeacher { + id?: number; + course_id: number; + teacher_id: number; + name: string; + title?: string; + avatar?: string; + intro?: string; + sort: number; +} + +interface ListTeacherReq { + course_id: number; + page: number; + page_size: number; +} + +interface TeacherListResponse { + total: number; + list: CourseTeacher[]; + page: number; + page_size: number; +} + +// 文件上传响应类型 +interface UploadResponse { + code: number; + data: { + filename: string; + size: number; + type: string; + url: string; + }; + message: string; +} + +/* 课程列表 */ const loading = ref(true); const tableData = ref([]); const currentPage = ref(1); @@ -396,7 +844,7 @@ const handleDelete = (row: Course) => { }).catch(() => ElMessage.info('已取消')); }; -/* ==================== 编辑抽屉 ==================== */ +/* 编辑抽屉 */ const drawerVisible = ref(false); const isSubmitting = ref(false); const defaultFormState = () => ({ @@ -414,15 +862,30 @@ const handleEdit = (row: Course) => { form.value = { ...row, status: 1 }; drawerVisible.value = true; loadCourseContent(row.id); + fetchResourceList(row.id); // 加载资源列表 + fetchActivityList(row.id); // 加载活动列表 + fetchTeacherList(row.id); // 加载教师列表 }; const handleDrawerClose = () => { drawerVisible.value = false; form.value = defaultFormState(); contentTree.value = []; + // 重置资源相关状态 + resourceList.value = []; + resourceTotal.value = 0; + resourceCurrentPage.value = 1; + // 重置活动相关状态 + activityList.value = []; + activityTotal.value = 0; + activityCurrentPage.value = 1; + // 重置教师相关状态 + teacherList.value = []; + teacherTotal.value = 0; + teacherCurrentPage.value = 1; }; -/* ==================== 课程内容管理(直接使用后端树形数据) ==================== */ +/* 课程内容管理 */ const contentLoading = ref(false); const contentTree = ref([]); @@ -601,13 +1064,12 @@ const submitCourse = async () => { }; /* 封面上传 */ -const handleCoverSuccess: UploadProps['onSuccess'] = (res) => { - const url = res.data?.url; - if (url) { - form.value.cover_url = url; - ElMessage.success('上传成功'); +const handleCoverSuccess: UploadProps['onSuccess'] = (res: UploadResponse) => { + if (res.code === 200 && res.data?.url) { + form.value.cover_url = res.data.url; + ElMessage.success(res.message || '上传成功'); } else { - ElMessage.error('上传失败'); + ElMessage.error(res.message || '上传失败'); } }; const beforeCoverUpload: UploadProps['beforeUpload'] = (file) => { @@ -616,6 +1078,583 @@ const beforeCoverUpload: UploadProps['beforeUpload'] = (file) => { return ok; }; const handleCoverError = () => ElMessage.error('上传失败'); + +/* 拓展资源管理 */ +// 资源列表相关状态 +const resourceList = ref([]); +const resourceLoading = ref(false); +const resourceTotal = ref(0); +const resourceCurrentPage = ref(1); +const resourcePageSize = ref(10); + +// 资源编辑弹窗状态 +const resourceDialog = ref<{ + visible: boolean; + isEdit: boolean; + saving: boolean; + form: Partial; + fileList: UploadFile[]; +}>({ + visible: false, + isEdit: false, + saving: false, + form: { course_id: 0, title: '', resource_url: '', size: 0, sort: 0 }, + fileList: [], +}); + +// 格式化文件大小(KB转MB/GB) +const formatFileSize = (size: number) => { + if (size < 1024) return `${size} KB`; + if (size < 1024 * 1024) return `${(size / 1024).toFixed(2)} MB`; + return `${(size / 1024 / 1024).toFixed(2)} GB`; +}; + +// 打开资源编辑弹窗 +const openResourceDialog = (isEdit: boolean, resource?: CourseResource) => { + resourceDialog.value = { + visible: true, + isEdit, + saving: false, + form: isEdit && resource + ? { ...resource, course_id: form.value.id! } + : { course_id: form.value.id!, title: '', resource_url: '', size: 0, sort: 0 }, + fileList: [], + }; +}; + +// 关闭资源弹窗 +const closeResourceDialog = () => { + resourceDialog.value.visible = false; + resourceDialog.value.fileList = []; +}; + +// 获取资源列表 +const fetchResourceList = async (courseId: number) => { + resourceLoading.value = true; + try { + const reqData: ListResourceReq = { + course_id: courseId, + page: resourceCurrentPage.value, + page_size: resourcePageSize.value, + }; + + const response = await fetch('http://localhost:8080/api/course-resource/list', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify(reqData), + }); + + if (!response.ok) throw new Error('获取资源列表失败'); + const data: ResourceListResponse = await response.json(); + resourceList.value = data.list || []; + resourceTotal.value = data.total || 0; + } catch (e) { + ElMessage.error(`加载拓展资源失败: ${(e as Error).message}`); + resourceList.value = []; + } finally { + resourceLoading.value = false; + } +}; + +// 资源分页变更 +const handleResourceSizeChange = (val: number) => { + resourcePageSize.value = val; + resourceCurrentPage.value = 1; + fetchResourceList(form.value.id!); +}; +const handleResourceCurrentChange = (val: number) => { + resourceCurrentPage.value = val; + fetchResourceList(form.value.id!); +}; + +// 资源上传相关 +const handleResourceUploadSuccess: UploadProps['onSuccess'] = (res: UploadResponse) => { + if (res.code === 200 && res.data?.url) { + resourceDialog.value.form.resource_url = res.data.url; + resourceDialog.value.form.size = res.data.size; + ElMessage.success(res.message || '文件上传成功'); + } else { + ElMessage.error(res.message || '文件上传失败'); + } +}; + +const beforeResourceUpload: UploadProps['beforeUpload'] = (file) => { + // 限制文件大小200MB + const maxSize = 200 * 1024 * 1024; + if (file.size > maxSize) { + ElMessage.error('文件大小不能超过200MB'); + return false; + } + return true; +}; + +const handleResourceUploadError = () => ElMessage.error('文件上传失败,请重试'); + +// 保存资源(新增/编辑) +const saveResource = async () => { + const { form } = resourceDialog.value; + if (!form.title?.trim()) return ElMessage.warning('请输入资源标题'); + if (!form.resource_url) return ElMessage.warning('请上传资源文件'); + if (!form.course_id) return ElMessage.error('课程ID丢失'); + + resourceDialog.value.saving = true; + try { + const payload: SaveResourceReq = { + course_id: form.course_id, + title: form.title, + resource_url: form.resource_url, + size: form.size || 0, + sort: form.sort || 0, + }; + if (resourceDialog.value.isEdit && form.id) payload.id = form.id; + + const url = 'http://localhost:8080/api/course-resource'; + const method = resourceDialog.value.isEdit ? 'PUT' : 'POST'; + + const resp = await fetch(url, { + method, + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify(payload), + }); + + if (!resp.ok) throw new Error(resourceDialog.value.isEdit ? '更新资源失败' : '新增资源失败'); + + ElMessage.success(resourceDialog.value.isEdit ? '资源更新成功' : '资源添加成功'); + closeResourceDialog(); + fetchResourceList(form.course_id); + } catch (e) { + ElMessage.error((e as Error).message); + } finally { + resourceDialog.value.saving = false; + } +}; + +// 删除资源 +const deleteResource = (resource: CourseResource) => { + ElMessageBox.confirm(`确定删除资源“${resource.title}”吗?`, '警告', { type: 'warning' }) + .then(async () => { + if (!resource.id) return ElMessage.error('资源ID丢失'); + + const resp = await fetch(`http://localhost:8080/api/course-resource/${resource.id}`, { method: 'DELETE' }); + if (!resp.ok) throw new Error('删除资源失败'); + + ElMessage.success('资源删除成功'); + fetchResourceList(form.value.id!); + }) + .catch(() => {}); +}; + +// 更新资源排序 +const updateResourceSort = async (resource: CourseResource) => { + if (!resource.id) return ElMessage.error('资源ID丢失'); + try { + const resp = await fetch('http://localhost:8080/api/course-resource', { + method: 'PUT', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ id: resource.id, sort: resource.sort }), + }); + if (!resp.ok) throw new Error('排序更新失败'); + ElMessage.success('排序已更新'); + } catch (e) { + ElMessage.error((e as Error).message); + fetchResourceList(form.value.id!); + } +}; + +/* 课程活动管理 */ +// 活动类型映射 +const activityTypeMap = { + 1: { label: '作业', type: 'primary' }, + 2: { label: '考试', type: 'danger' }, + 3: { label: '讨论', type: 'success' }, + 4: { label: '直播', type: 'warning' }, +}; + +// 活动列表相关状态 +const activityList = ref([]); +const activityLoading = ref(false); +const activityTotal = ref(0); +const activityCurrentPage = ref(1); +const activityPageSize = ref(10); + +// 活动编辑弹窗状态 +const activityDialog = ref<{ + visible: boolean; + isEdit: boolean; + saving: boolean; + form: Partial; +}>({ + visible: false, + isEdit: false, + saving: false, + form: { course_id: 0, title: '', activity_type: 1, content: '', start_time: '', end_time: '', sort: 0 }, +}); + +// 打开活动编辑弹窗 +const openActivityDialog = (isEdit: boolean, activity?: CourseActivity) => { + activityDialog.value = { + visible: true, + isEdit, + saving: false, + form: isEdit && activity + ? { ...activity, course_id: form.value.id! } + : { course_id: form.value.id!, title: '', activity_type: 1, content: '', start_time: '', end_time: '', sort: 0 }, + }; +}; + +// 关闭活动弹窗 +const closeActivityDialog = () => { + activityDialog.value.visible = false; +}; + +// 获取活动列表 +const fetchActivityList = async (courseId: number) => { + activityLoading.value = true; + try { + const reqData: ListActivityReq = { + course_id: courseId, + page: activityCurrentPage.value, + page_size: activityPageSize.value, + }; + + const response = await fetch('http://localhost:8080/api/course-activity/list', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify(reqData), + }); + + if (!response.ok) throw new Error('获取活动列表失败'); + const data: ActivityListResponse = await response.json(); + activityList.value = data.list || []; + activityTotal.value = data.total || 0; + } catch (e) { + ElMessage.error(`加载课程活动失败: ${(e as Error).message}`); + activityList.value = []; + } finally { + activityLoading.value = false; + } +}; + +// 活动分页变更 +const handleActivitySizeChange = (val: number) => { + activityPageSize.value = val; + activityCurrentPage.value = 1; + fetchActivityList(form.value.id!); +}; +const handleActivityCurrentChange = (val: number) => { + activityCurrentPage.value = val; + fetchActivityList(form.value.id!); +}; + +const formatTimeMinus8Hours = (time) => { + if (!time) return ''; + const date = new Date(time); + date.setUTCHours(date.getUTCHours() - 8); // 基于UTC减8小时(更精准) + + const year = date.getUTCFullYear(); + const month = String(date.getUTCMonth() + 1).padStart(2, '0'); + const day = String(date.getUTCDate()).padStart(2, '0'); + const hours = String(date.getUTCHours()).padStart(2, '0'); + const minutes = String(date.getUTCMinutes()).padStart(2, '0'); + const seconds = String(date.getUTCSeconds()).padStart(2, '0'); + + return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`; +}; +// 保存活动(新增/编辑) +const saveActivity = async () => { + const { form } = activityDialog.value; + if (!form.title?.trim()) return ElMessage.warning('请输入活动标题'); + if (!form.course_id) return ElMessage.error('课程ID丢失'); + if (form.activity_type === undefined) return ElMessage.warning('请选择活动类型'); + + activityDialog.value.saving = true; + try { + const payload: any = { + course_id: form.course_id, + title: form.title, + activity_type: form.activity_type, + content: form.content, + start_time: form.start_time, + end_time: form.end_time, + sort: form.sort || 0, + }; + if (activityDialog.value.isEdit && form.id) payload.id = form.id; + + const formatTimeMinus8Hours = (time: string | Date | undefined) => { + if (!time) return ''; // 未传时间返回空(或根据业务设为null) + + const date = new Date(time); + // 减去8小时(毫秒数计算) + date.setTime(date.getTime() - 8 * 60 * 60 * 1000); + + // 提取各部分并补零,确保格式符合 2006-01-02 15:04:05 + const year = date.getFullYear(); + const month = String(date.getMonth() + 1).padStart(2, '0'); + const day = String(date.getDate()).padStart(2, '0'); + const hours = String(date.getHours()).padStart(2, '0'); + const minutes = String(date.getMinutes()).padStart(2, '0'); + const seconds = String(date.getSeconds()).padStart(2, '0'); + + return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`; + }; + + // 处理 start_time 和 end_time(覆盖原有值) + payload.start_time = formatTimeMinus8Hours(payload.start_time); + payload.end_time = formatTimeMinus8Hours(payload.end_time); + + const url = 'http://localhost:8080/api/course-activity'; + const method = activityDialog.value.isEdit ? 'PUT' : 'POST'; + + const resp = await fetch(url, { + method, + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify(payload), + }); + + if (!resp.ok) throw new Error(activityDialog.value.isEdit ? '更新活动失败' : '新增活动失败'); + + ElMessage.success(activityDialog.value.isEdit ? '活动更新成功' : '活动添加成功'); + closeActivityDialog(); + fetchActivityList(form.course_id); + } catch (e) { + ElMessage.error((e as Error).message); + } finally { + activityDialog.value.saving = false; + } +}; + +// 删除活动 +const deleteActivity = (activity: CourseActivity) => { + ElMessageBox.confirm(`确定删除活动“${activity.title}”吗?`, '警告', { type: 'warning' }) + .then(async () => { + if (!activity.id) return ElMessage.error('活动ID丢失'); + + const resp = await fetch(`http://localhost:8080/api/course-activity/${activity.id}`, { method: 'DELETE' }); + if (!resp.ok) throw new Error('删除活动失败'); + + ElMessage.success('活动删除成功'); + fetchActivityList(form.value.id!); + }) + .catch(() => {}); +}; + +// 更新活动排序 +const updateActivitySort = async (activity: CourseActivity) => { + if (!activity.id) return ElMessage.error('活动ID丢失'); + try { + const resp = await fetch('http://localhost:8080/api/course-activity', { + method: 'PUT', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ id: activity.id, sort: activity.sort }), + }); + if (!resp.ok) throw new Error('排序更新失败'); + ElMessage.success('排序已更新'); + } catch (e) { + ElMessage.error((e as Error).message); + fetchActivityList(form.value.id!); + } +}; + +/* 课程教师管理 */ +// 教师列表相关状态 +const teacherList = ref([]); +const teacherLoading = ref(false); +const teacherTotal = ref(0); +const teacherCurrentPage = ref(1); +const teacherPageSize = ref(10); + +// 教师编辑弹窗状态 +const teacherDialog = ref<{ + visible: boolean; + isEdit: boolean; + saving: boolean; + form: Partial; + fileList: UploadFile[]; +}>({ + visible: false, + isEdit: false, + saving: false, + form: { course_id: 0, teacher_id: 0, name: '', title: '', avatar: '', intro: '', sort: 0 }, + fileList: [], +}); + +// 打开教师编辑弹窗 +const openTeacherDialog = (isEdit: boolean, teacher?: CourseTeacher) => { + teacherDialog.value = { + visible: true, + isEdit, + saving: false, + form: isEdit && teacher + ? { ...teacher, course_id: form.value.id! } + : { course_id: form.value.id!, teacher_id: 0, name: '', title: '', avatar: '', intro: '', sort: 0 }, + fileList: [], + }; +}; + +// 关闭教师弹窗 +const closeTeacherDialog = () => { + teacherDialog.value.visible = false; + teacherDialog.value.fileList = []; +}; + +// 获取教师列表 +const fetchTeacherList = async (courseId: number) => { + teacherLoading.value = true; + try { + const reqData: ListTeacherReq = { + course_id: courseId, + page: teacherCurrentPage.value, + page_size: teacherPageSize.value, + }; + + const response = await fetch('http://localhost:8080/api/course-teacher/list', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify(reqData), + }); + + if (!response.ok) throw new Error('获取教师列表失败'); + const data: TeacherListResponse = await response.json(); + teacherList.value = data.list || []; + teacherTotal.value = data.total || 0; + } catch (e) { + ElMessage.error(`加载教学团队失败: ${(e as Error).message}`); + teacherList.value = []; + } finally { + teacherLoading.value = false; + } +}; + +// 教师分页变更 +const handleTeacherSizeChange = (val: number) => { + teacherPageSize.value = val; + teacherCurrentPage.value = 1; + fetchTeacherList(form.value.id!); +}; +const handleTeacherCurrentChange = (val: number) => { + teacherCurrentPage.value = val; + fetchTeacherList(form.value.id!); +}; + +// 教师头像上传相关 +const handleTeacherAvatarSuccess: UploadProps['onSuccess'] = (res: UploadResponse) => { + if (res.code === 200 && res.data?.url) { + teacherDialog.value.form.avatar = res.data.url; + ElMessage.success(res.message || '头像上传成功'); + } else { + ElMessage.error(res.message || '头像上传失败'); + } +}; + +const beforeTeacherAvatarUpload: UploadProps['beforeUpload'] = (file) => { + // 限制文件大小5MB + const maxSize = 5 * 1024 * 1024; + if (file.size > maxSize) { + ElMessage.error('头像大小不能超过5MB'); + return false; + } + + // 限制文件类型 + const fileType = file.type; + if (!fileType.startsWith('image/')) { + ElMessage.error('请上传图片格式文件'); + return false; + } + + return true; +}; + +const handleTeacherAvatarError = () => ElMessage.error('头像上传失败,请重试'); + +// 保存教师(新增/编辑)- 核心调整:使用POST并传递所有字段 +const saveTeacher = async () => { + const { form, isEdit } = teacherDialog.value; + // 验证必填字段 + if (!form.name?.trim()) return ElMessage.warning('请输入教师姓名'); + if (form.teacher_id === undefined || form.teacher_id <= 0) return ElMessage.warning('请输入有效的教师ID'); + if (!form.course_id) return ElMessage.error('课程ID丢失'); + if (isEdit && !form.id) return ElMessage.error('教师ID丢失'); // 编辑时必须有id + + teacherDialog.value.saving = true; + try { + // 构建包含所有字段的请求体 + const payload: any = { + id: form.id, // 编辑时必传,新增时可省略 + course_id: form.course_id, + teacher_id: form.teacher_id, + name: form.name, + title: form.title || '', + avatar: form.avatar || '', + intro: form.intro || '', + sort: form.sort || 0 + }; + + // 区分请求方法:新增用POST,修改用PUT + const url = 'http://localhost:8080/api/course-teacher'; + const method = isEdit ? 'PUT' : 'POST'; + + const resp = await fetch(url, { + method, + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify(payload), + }); + + if (!resp.ok) { + const error = await resp.json(); + throw new Error(error.message || (isEdit ? '更新教师失败' : '新增教师失败')); + } + + ElMessage.success(isEdit ? '教师信息更新成功' : '教师添加成功'); + closeTeacherDialog(); + fetchTeacherList(form.course_id); + } catch (e) { + ElMessage.error((e as Error).message); + } finally { + teacherDialog.value.saving = false; + } +}; + +// 删除教师 +const deleteTeacher = (teacher: CourseTeacher) => { + ElMessageBox.confirm(`确定删除教师“${teacher.name}”吗?`, '警告', { type: 'warning' }) + .then(async () => { + if (!teacher.id) return ElMessage.error('教师ID丢失'); + + const resp = await fetch(`http://localhost:8080/api/course-teacher/${teacher.id}`, { method: 'DELETE' }); + if (!resp.ok) throw new Error('删除教师失败'); + + ElMessage.success('教师删除成功'); + fetchTeacherList(form.value.id!); + }) + .catch(() => {}); +}; + +// 更新教师排序 +const updateTeacherSort = async (teacher: CourseTeacher) => { + if (!teacher.id) return ElMessage.error('教师ID丢失'); + try { + const resp = await fetch('http://localhost:8080/api/course-teacher', { + method: 'PUT', // 排序更新属于修改操作,用PUT + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ + id: teacher.id, + sort: teacher.sort, + course_id: teacher.course_id, + // 确保传递其他必要字段(如果接口要求完整字段) + teacher_id: teacher.teacher_id, + name: teacher.name, + title: teacher.title || '', + avatar: teacher.avatar || '', + intro: teacher.intro || '' + }), + }); + if (!resp.ok) throw new Error('排序更新失败'); + ElMessage.success('排序已更新'); + } catch (e) { + ElMessage.error((e as Error).message); + fetchTeacherList(form.value.id!); + } +}; + +/* 资源、活动和教师管理样式补充 */ +.resource-table .el-table__header-wrapper th, +.activity-table .el-table__header-wrapper th, +.teacher-table .el-table__header-wrapper th { + background-color: #fafafa !important; +} +.el-upload--picture-card { width: 178px; height: 178px; } +.resource-dialog .el-form-item, +.activity-dialog .el-form-item, +.teacher-dialog .el-form-item { margin-bottom: 20px; } + \ No newline at end of file diff --git a/management/src/views/caseresource/setting/caseSettingView.vue b/management/src/views/caseresource/setting/caseSettingView.vue index cdbc4545..2eec1af9 100644 --- a/management/src/views/caseresource/setting/caseSettingView.vue +++ b/management/src/views/caseresource/setting/caseSettingView.vue @@ -9,7 +9,7 @@

封面图上传

-

建议上传16:9比例图片,支持JPG/PNG/WEBP格式,大小不超过5MB

+

建议上传16:9比例图片,支持JPG/PNG/WEBP格式,大小不超过20MB

@@ -40,7 +40,7 @@

点击或拖拽图片至此处上传

-

支持JPG/PNG/WEBP,最大5MB,建议16:9比例

+

支持JPG/PNG/WEBP,最大20MB,建议16:9比例

@@ -99,15 +99,16 @@ const fetchCoverImage = async () => { } }; -// 上传前校验 +// 上传前校验(修改为20MB限制) const beforeUpload: UploadProps['beforeUpload'] = (rawFile) => { const allowTypes = ['image/jpeg', 'image/png', 'image/webp']; if (!allowTypes.includes(rawFile.type)) { ElMessage.error('仅支持JPG/PNG/WEBP格式的图片'); return false; } - if (rawFile.size / 1024 / 1024 > 5) { - ElMessage.error('图片大小不能超过5MB'); + // 改为20MB限制(20 * 1024 * 1024 字节) + if (rawFile.size / 1024 / 1024 > 20) { + ElMessage.error('图片大小不能超过20MB'); return false; } console.log("图片校验成功"); diff --git a/management/src/views/community/CommunityView.vue b/management/src/views/community/CommunityView.vue deleted file mode 100644 index fa396a38..00000000 --- a/management/src/views/community/CommunityView.vue +++ /dev/null @@ -1,499 +0,0 @@ - - - - - diff --git a/management/src/views/devproject/devprojectView.vue b/management/src/views/devproject/devprojectView.vue index 0e82a3e3..a6dfb6bb 100644 --- a/management/src/views/devproject/devprojectView.vue +++ b/management/src/views/devproject/devprojectView.vue @@ -225,8 +225,8 @@ const beforeUpload: UploadProps['beforeUpload'] = (rawFile) => { ElMessage.error('仅支持JPG/PNG/WEBP格式的图片'); return false; } - if (rawFile.size / 1024 / 1024 > 5) { - ElMessage.error('图片大小不能超过5MB'); + if (rawFile.size / 1024 / 1024 > 20) { + ElMessage.error('图片大小不能超过20MB'); return false; } console.log("图片校验成功"); diff --git a/management/src/views/meeting/meetingView.vue b/management/src/views/meeting/meetingView.vue index a217a0c6..960ee8e9 100644 --- a/management/src/views/meeting/meetingView.vue +++ b/management/src/views/meeting/meetingView.vue @@ -999,9 +999,9 @@ const beforeAvatarUpload: UploadProps['beforeUpload'] = (rawFile) => { ElMessage.error('请上传图片文件!'); return false; } - const isLt5M = rawFile.size / 1024 / 1024 < 5; + const isLt5M = rawFile.size / 1024 / 1024 < 20; if (!isLt5M) { - ElMessage.error('图片大小不能超过 5MB!'); + ElMessage.error('图片大小不能超过 20MB!'); } return isImage && isLt5M; }; @@ -1064,8 +1064,8 @@ const beforePageImageUpload: UploadProps['beforeUpload'] = (rawFile) => { ElMessage.error('仅支持JPG/PNG/WEBP格式的图片'); return false; } - if (rawFile.size / 1024 / 1024 > 5) { - ElMessage.error('图片大小不能超过5MB'); + if (rawFile.size / 1024 / 1024 > 20) { + ElMessage.error('图片大小不能超过20MB'); return false; } return true; diff --git a/management/src/views/publish/QuillEditor.vue b/management/src/views/publish/QuillEditor.vue index 3e45c4a6..0f3dba9d 100644 --- a/management/src/views/publish/QuillEditor.vue +++ b/management/src/views/publish/QuillEditor.vue @@ -39,22 +39,7 @@ 新闻 - - - 案例资源 - - - - 社区服务 - - - - 学生获奖 - - - - 论文发表 - +
@@ -252,8 +237,8 @@ const beforeCoverUpload: UploadProps['beforeUpload'] = (rawFile) => { ElMessage.error('仅支持JPG/PNG/WEBP格式的图片'); return false; } - if (rawFile.size / 1024 / 1024 > 5) { - ElMessage.error('图片大小不能超过5MB'); + if (rawFile.size / 1024 / 1024 > 20) { + ElMessage.error('图片大小不能超过20MB'); return false; } return true; diff --git a/management/src/views/socialservice/img/serviceimg.vue b/management/src/views/socialservice/img/serviceimg.vue index d71bce61..e810ec81 100644 --- a/management/src/views/socialservice/img/serviceimg.vue +++ b/management/src/views/socialservice/img/serviceimg.vue @@ -9,7 +9,8 @@

封面图上传

-

建议上传16:9比例图片,支持JPG/PNG/WEBP格式,大小不超过5MB

+ +

建议上传16:9比例图片,支持JPG/PNG/WEBP格式,大小不超过20MB

@@ -40,7 +41,8 @@

点击或拖拽图片至此处上传

-

支持JPG/PNG/WEBP,最大5MB,建议16:9比例

+ +

支持JPG/PNG/WEBP,最大20MB,建议16:9比例

@@ -99,15 +101,16 @@ const fetchCoverImage = async () => { } }; -// 上传前校验 +// 上传前校验(修改大小限制为20MB) const beforeUpload: UploadProps['beforeUpload'] = (rawFile) => { const allowTypes = ['image/jpeg', 'image/png', 'image/webp']; if (!allowTypes.includes(rawFile.type)) { ElMessage.error('仅支持JPG/PNG/WEBP格式的图片'); return false; } - if (rawFile.size / 1024 / 1024 > 5) { - ElMessage.error('图片大小不能超过5MB'); + // 核心修改:5MB → 20MB(20 * 1024 * 1024字节) + if (rawFile.size / 1024 / 1024 > 20) { + ElMessage.error('图片大小不能超过20MB'); // 修改错误提示文字 return false; } console.log("图片校验成功");