后台界面

czq
2991692032 3 weeks ago
parent 6921e89a77
commit 65855dbb88

@ -54,6 +54,11 @@ export const adminApi = {
return request.delete(`/admin/posts/${postId}`)
},
// 永久删除帖子
permanentDeletePost(postId: number): Promise<ApiResponse> {
return request.delete(`/admin/posts/${postId}/permanent`)
},
// 获取评论列表
getCommentList(params: {
page?: number

@ -70,6 +70,7 @@ export interface Post {
viewCount: number
likeCount: number
commentCount: number
status?: number // 帖子状态0-删除, 1-正常, 2-置顶
isLiked?: boolean
createdAt: string
updatedAt?: string

@ -158,26 +158,293 @@
/>
</div>
<!-- 其他管理模块的占位符 -->
<!-- 帖子管理 -->
<div v-if="activeMenu === 'posts'" class="posts-content">
<h2>帖子管理</h2>
<p>帖子管理功能开发中...</p>
<div class="table-toolbar">
<el-input
v-model="postSearch"
placeholder="搜索帖子..."
style="width: 300px"
@input="searchPosts"
/>
<el-select v-model="postCategoryFilter" placeholder="分类筛选" @change="searchPosts">
<el-option label="全部" :value="null" />
<el-option
v-for="category in categories"
:key="category.id"
:label="category.name"
:value="category.id"
/>
</el-select>
<el-select v-model="postStatusFilter" placeholder="状态筛选" @change="searchPosts">
<el-option label="全部" :value="null" />
<el-option label="正常" :value="1" />
<el-option label="置顶" :value="2" />
<el-option label="已删除" :value="0" />
</el-select>
</div>
<el-table :data="posts" style="width: 100%">
<el-table-column prop="id" label="ID" width="80" />
<el-table-column prop="title" label="标题" width="200" show-overflow-tooltip />
<el-table-column prop="nickname" label="作者" width="120" />
<el-table-column prop="categoryName" label="分类" width="100" />
<el-table-column prop="viewCount" label="浏览" width="80" />
<el-table-column prop="likeCount" label="点赞" width="80" />
<el-table-column prop="commentCount" label="评论" width="80" />
<el-table-column prop="status" label="状态" width="100">
<template #default="scope">
<el-tag :type="getPostStatusType(scope.row.status)">
{{ getPostStatusText(scope.row.status) }}
</el-tag>
</template>
</el-table-column>
<el-table-column prop="createdAt" label="发布时间" width="180" />
<el-table-column label="操作" width="250">
<template #default="scope">
<!-- 已删除的帖子显示恢复按钮 -->
<template v-if="scope.row.status === 0">
<el-button
size="small"
type="success"
@click="restorePost(scope.row)"
>
恢复
</el-button>
<el-button
size="small"
type="danger"
@click="permanentDeletePost(scope.row)"
>
永久删除
</el-button>
</template>
<!-- 正常和置顶的帖子显示置顶和删除按钮 -->
<template v-else>
<el-button
size="small"
:type="scope.row.status === 2 ? 'warning' : 'primary'"
@click="togglePostTop(scope.row)"
>
{{ scope.row.status === 2 ? '取消置顶' : '置顶' }}
</el-button>
<el-button
size="small"
type="danger"
@click="deletePost(scope.row)"
>
删除
</el-button>
</template>
</template>
</el-table-column>
</el-table>
<el-pagination
v-model:current-page="postPage"
v-model:page-size="postPageSize"
:total="postTotal"
@current-change="loadPosts"
layout="total, prev, pager, next"
/>
</div>
<!-- 评论管理 -->
<div v-if="activeMenu === 'comments'" class="comments-content">
<h2>评论管理</h2>
<p>评论管理功能开发中...</p>
<div class="table-toolbar">
<el-input
v-model="commentSearch"
placeholder="搜索评论..."
style="width: 300px"
@input="searchComments"
/>
<el-select v-model="commentStatusFilter" placeholder="状态筛选" @change="searchComments">
<el-option label="全部" :value="null" />
<el-option label="正常" :value="1" />
<el-option label="已删除" :value="0" />
</el-select>
</div>
<el-table :data="comments" style="width: 100%">
<el-table-column prop="id" label="ID" width="80" />
<el-table-column prop="content" label="内容" width="300" show-overflow-tooltip />
<el-table-column prop="nickname" label="评论者" width="120" />
<el-table-column prop="postTitle" label="所属帖子" width="200" show-overflow-tooltip />
<el-table-column prop="likeCount" label="点赞" width="80" />
<el-table-column prop="status" label="状态" width="100">
<template #default="scope">
<el-tag :type="scope.row.status === 1 ? 'success' : 'danger'">
{{ scope.row.status === 1 ? '正常' : '已删除' }}
</el-tag>
</template>
</el-table-column>
<el-table-column prop="createdAt" label="发布时间" width="180" />
<el-table-column label="操作" width="120">
<template #default="scope">
<el-button
size="small"
type="danger"
@click="deleteComment(scope.row)"
>
删除
</el-button>
</template>
</el-table-column>
</el-table>
<el-pagination
v-model:current-page="commentPage"
v-model:page-size="commentPageSize"
:total="commentTotal"
@current-change="loadComments"
layout="total, prev, pager, next"
/>
</div>
<!-- 分类管理 -->
<div v-if="activeMenu === 'categories'" class="categories-content">
<h2>分类管理</h2>
<p>分类管理功能开发中...</p>
<div class="table-toolbar">
<el-button type="primary" @click="showCreateCategoryDialog">
<el-icon><Plus /></el-icon>
新增分类
</el-button>
</div>
<el-table :data="categories" style="width: 100%">
<el-table-column prop="id" label="ID" width="80" />
<el-table-column prop="name" label="分类名称" width="150" />
<el-table-column prop="description" label="描述" width="200" show-overflow-tooltip />
<el-table-column prop="icon" label="图标" width="80" />
<el-table-column prop="sort" label="排序" width="80" />
<el-table-column prop="status" label="状态" width="100">
<template #default="scope">
<el-tag :type="scope.row.status === 1 ? 'success' : 'danger'">
{{ scope.row.status === 1 ? '启用' : '禁用' }}
</el-tag>
</template>
</el-table-column>
<el-table-column prop="createdAt" label="创建时间" width="180" />
<el-table-column label="操作" width="200">
<template #default="scope">
<el-button
size="small"
type="primary"
@click="editCategory(scope.row)"
>
编辑
</el-button>
<el-button
size="small"
type="danger"
@click="deleteCategory(scope.row)"
>
删除
</el-button>
</template>
</el-table-column>
</el-table>
</div>
<!-- 资源管理 -->
<div v-if="activeMenu === 'resources'" class="resources-content">
<h2>资源管理</h2>
<p>资源管理功能开发中...</p>
<div class="table-toolbar">
<el-input
v-model="resourceSearch"
placeholder="搜索资源..."
style="width: 300px"
@input="searchResources"
/>
<el-select v-model="resourceCategoryFilter" placeholder="分类筛选" @change="searchResources">
<el-option label="全部" :value="null" />
<el-option
v-for="category in categories"
:key="category.id"
:label="category.name"
:value="category.id"
/>
</el-select>
<el-select v-model="resourceStatusFilter" placeholder="状态筛选" @change="searchResources">
<el-option label="全部" :value="null" />
<el-option label="正常" :value="1" />
<el-option label="已删除" :value="0" />
</el-select>
</div>
<el-table :data="resources" style="width: 100%">
<el-table-column prop="id" label="ID" width="80" />
<el-table-column prop="title" label="标题" width="200" show-overflow-tooltip />
<el-table-column prop="nickname" label="上传者" width="120" />
<el-table-column prop="categoryName" label="分类" width="100" />
<el-table-column prop="fileType" label="文件类型" width="120" />
<el-table-column prop="fileSize" label="文件大小" width="100">
<template #default="scope">
{{ formatFileSize(scope.row.fileSize) }}
</template>
</el-table-column>
<el-table-column prop="downloadCount" label="下载" width="80" />
<el-table-column prop="likeCount" label="点赞" width="80" />
<el-table-column prop="status" label="状态" width="100">
<template #default="scope">
<el-tag :type="scope.row.status === 1 ? 'success' : 'danger'">
{{ scope.row.status === 1 ? '正常' : '已删除' }}
</el-tag>
</template>
</el-table-column>
<el-table-column prop="createdAt" label="上传时间" width="180" />
<el-table-column label="操作" width="120">
<template #default="scope">
<el-button
size="small"
type="danger"
@click="deleteResource(scope.row)"
>
删除
</el-button>
</template>
</el-table-column>
</el-table>
<el-pagination
v-model:current-page="resourcePage"
v-model:page-size="resourcePageSize"
:total="resourceTotal"
@current-change="loadResources"
layout="total, prev, pager, next"
/>
</div>
<!-- 分类编辑对话框 -->
<el-dialog
v-model="categoryDialogVisible"
:title="isEditingCategory ? '编辑分类' : '新增分类'"
width="500px"
>
<el-form :model="categoryForm" :rules="categoryRules" ref="categoryFormRef" label-width="80px">
<el-form-item label="分类名称" prop="name">
<el-input v-model="categoryForm.name" placeholder="请输入分类名称" />
</el-form-item>
<el-form-item label="描述" prop="description">
<el-input v-model="categoryForm.description" type="textarea" placeholder="请输入分类描述" />
</el-form-item>
<el-form-item label="图标" prop="icon">
<el-input v-model="categoryForm.icon" placeholder="请输入图标(如:📚)" />
</el-form-item>
<el-form-item label="排序" prop="sort">
<el-input-number v-model="categoryForm.sort" :min="1" :max="100" />
</el-form-item>
<el-form-item label="状态" prop="status">
<el-radio-group v-model="categoryForm.status">
<el-radio :label="1">启用</el-radio>
<el-radio :label="0">禁用</el-radio>
</el-radio-group>
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="categoryDialogVisible = false">取消</el-button>
<el-button type="primary" @click="saveCategoryForm" :loading="isSavingCategory">
{{ isEditingCategory ? '更新' : '创建' }}
</el-button>
</span>
</template>
</el-dialog>
</div>
</div>
</div>
@ -193,7 +460,8 @@ import {
Document,
ChatDotRound,
FolderOpened,
Files
Files,
Plus
} from '@element-plus/icons-vue'
import { useUserStore } from '@/stores/user'
import { adminApi } from '@/api/admin'
@ -206,6 +474,28 @@ interface SystemStats {
totalResources?: number
}
//
interface Category {
id: number
name: string
description?: string
icon?: string
sort: number
status: number
createdAt?: string
updatedAt?: string
}
//
interface CategoryForm {
id: number | null
name: string
description: string
icon: string
sort: number
status: number
}
const router = useRouter()
const userStore = useUserStore()
@ -216,13 +506,58 @@ const activeMenu = ref('dashboard')
const stats = ref<SystemStats>({})
//
const users = ref([])
const users = ref<any[]>([])
const userSearch = ref('')
const userRoleFilter = ref(null)
const userPage = ref(1)
const userPageSize = ref(10)
const userTotal = ref(0)
//
const posts = ref<any[]>([])
const postSearch = ref('')
const postCategoryFilter = ref<number | null>(null)
const postStatusFilter = ref<number | null>(null)
const postPage = ref(1)
const postPageSize = ref(10)
const postTotal = ref(0)
//
const comments = ref<any[]>([])
const commentSearch = ref('')
const commentStatusFilter = ref<number | null>(null)
const commentPage = ref(1)
const commentPageSize = ref(10)
const commentTotal = ref(0)
//
const categories = ref<Category[]>([])
const categoryDialogVisible = ref(false)
const isEditingCategory = ref(false)
const categoryForm = ref<CategoryForm>({
id: null,
name: '',
description: '',
icon: '',
sort: 1,
status: 1
})
const categoryRules = ref({
name: [{ required: true, message: '请输入分类名称', trigger: 'blur' }],
sort: [{ required: true, message: '请输入排序', trigger: 'blur' }]
})
const categoryFormRef = ref(null)
const isSavingCategory = ref(false)
//
const resources = ref<any[]>([])
const resourceSearch = ref('')
const resourceCategoryFilter = ref<number | null>(null)
const resourceStatusFilter = ref<number | null>(null)
const resourcePage = ref(1)
const resourcePageSize = ref(10)
const resourceTotal = ref(0)
//
const handleMenuSelect = (index: string) => {
activeMenu.value = index
@ -230,6 +565,14 @@ const handleMenuSelect = (index: string) => {
loadStats()
} else if (index === 'users') {
loadUsers()
} else if (index === 'posts') {
loadPosts()
} else if (index === 'comments') {
loadComments()
} else if (index === 'categories') {
loadCategories()
} else if (index === 'resources') {
loadResources()
}
}
@ -263,12 +606,98 @@ const loadUsers = async () => {
}
}
//
const loadPosts = async () => {
try {
const response = await adminApi.getPostList({
page: postPage.value,
size: postPageSize.value,
keyword: postSearch.value || undefined,
categoryId: postCategoryFilter.value || undefined,
status: postStatusFilter.value || undefined
})
if (response.code === 200) {
posts.value = response.data.list
postTotal.value = response.data.total
}
} catch (error) {
ElMessage.error('加载帖子列表失败')
}
}
//
const loadComments = async () => {
try {
const response = await adminApi.getCommentList({
page: commentPage.value,
size: commentPageSize.value,
keyword: commentSearch.value || undefined,
status: commentStatusFilter.value || undefined
})
if (response.code === 200) {
comments.value = response.data.list
commentTotal.value = response.data.total
}
} catch (error) {
ElMessage.error('加载评论列表失败')
}
}
//
const loadCategories = async () => {
try {
const response = await adminApi.getCategoryList()
if (response.code === 200) {
categories.value = response.data
}
} catch (error) {
ElMessage.error('加载分类列表失败')
}
}
//
const loadResources = async () => {
try {
const response = await adminApi.getResourceList({
page: resourcePage.value,
size: resourcePageSize.value,
keyword: resourceSearch.value || undefined,
categoryId: resourceCategoryFilter.value || undefined,
status: resourceStatusFilter.value || undefined
})
if (response.code === 200) {
resources.value = response.data.list
resourceTotal.value = response.data.total
}
} catch (error) {
ElMessage.error('加载资源列表失败')
}
}
//
const searchUsers = () => {
userPage.value = 1
loadUsers()
}
//
const searchPosts = () => {
postPage.value = 1
loadPosts()
}
//
const searchComments = () => {
commentPage.value = 1
loadComments()
}
//
const searchResources = () => {
resourcePage.value = 1
loadResources()
}
//
const toggleUserStatus = async (user: any) => {
try {
@ -304,6 +733,197 @@ const deleteUser = async (user: any) => {
}
}
//
const togglePostTop = async (post: any) => {
try {
const newStatus = post.status === 2 ? 1 : 2
const response = await adminApi.updatePostStatus(post.id, { status: newStatus })
if (response.code === 200) {
post.status = newStatus
ElMessage.success('帖子状态更新成功')
}
} catch (error) {
ElMessage.error('更新帖子状态失败')
}
}
//
const deletePost = async (post: any) => {
try {
await ElMessageBox.confirm('确定要删除该帖子吗?此操作不可恢复!', '警告', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
})
const response = await adminApi.deletePost(post.id)
if (response.code === 200) {
ElMessage.success('帖子删除成功')
loadPosts()
}
} catch (error) {
if (error !== 'cancel') {
ElMessage.error('删除帖子失败')
}
}
}
//
const restorePost = async (post: any) => {
try {
await ElMessageBox.confirm('确定要恢复该帖子吗?', '确认', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'info'
})
const response = await adminApi.updatePostStatus(post.id, { status: 1 })
if (response.code === 200) {
ElMessage.success('帖子恢复成功')
loadPosts()
}
} catch (error) {
if (error !== 'cancel') {
ElMessage.error('恢复帖子失败')
}
}
}
//
const permanentDeletePost = async (post: any) => {
try {
await ElMessageBox.confirm('确定要永久删除该帖子吗?此操作不可恢复!', '危险操作', {
confirmButtonText: '永久删除',
cancelButtonText: '取消',
type: 'error',
confirmButtonClass: 'el-button--danger'
})
const response = await adminApi.permanentDeletePost(post.id)
if (response.code === 200) {
ElMessage.success('帖子永久删除成功')
loadPosts()
}
} catch (error) {
if (error !== 'cancel') {
ElMessage.error('永久删除帖子失败')
}
}
}
//
const deleteComment = async (comment: any) => {
try {
await ElMessageBox.confirm('确定要删除该评论吗?此操作不可恢复!', '警告', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
})
const response = await adminApi.deleteComment(comment.id)
if (response.code === 200) {
ElMessage.success('评论删除成功')
loadComments()
}
} catch (error) {
if (error !== 'cancel') {
ElMessage.error('删除评论失败')
}
}
}
//
const showCreateCategoryDialog = () => {
isEditingCategory.value = false
categoryForm.value = {
id: null,
name: '',
description: '',
icon: '',
sort: 1,
status: 1
}
categoryDialogVisible.value = true
}
//
const editCategory = (category: any) => {
isEditingCategory.value = true
categoryForm.value = {
id: category.id,
name: category.name,
description: category.description,
icon: category.icon,
sort: category.sort,
status: category.status
}
categoryDialogVisible.value = true
}
//
const saveCategoryForm = async () => {
try {
isSavingCategory.value = true
let response
if (isEditingCategory.value && categoryForm.value.id) {
response = await adminApi.updateCategory(categoryForm.value.id, categoryForm.value)
} else {
response = await adminApi.createCategory(categoryForm.value)
}
if (response.code === 200) {
ElMessage.success('分类保存成功')
categoryDialogVisible.value = false
loadCategories()
}
} catch (error) {
ElMessage.error('保存分类失败')
} finally {
isSavingCategory.value = false
}
}
//
const deleteCategory = async (category: any) => {
try {
await ElMessageBox.confirm('确定要删除该分类吗?此操作不可恢复!', '警告', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
})
const response = await adminApi.deleteCategory(category.id)
if (response.code === 200) {
ElMessage.success('分类删除成功')
loadCategories()
}
} catch (error) {
if (error !== 'cancel') {
ElMessage.error('删除分类失败')
}
}
}
//
const deleteResource = async (resource: any) => {
try {
await ElMessageBox.confirm('确定要删除该资源吗?此操作不可恢复!', '警告', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
})
const response = await adminApi.deleteResource(resource.id)
if (response.code === 200) {
ElMessage.success('资源删除成功')
loadResources()
}
} catch (error) {
if (error !== 'cancel') {
ElMessage.error('删除资源失败')
}
}
}
//
const getRoleType = (role: number) => {
switch (role) {
@ -324,6 +944,34 @@ const getRoleText = (role: number) => {
}
}
//
const getPostStatusType = (status: number) => {
switch (status) {
case 1: return ''
case 2: return 'warning'
case 0: return 'danger'
default: return ''
}
}
//
const getPostStatusText = (status: number) => {
switch (status) {
case 1: return '正常'
case 2: return '置顶'
case 0: return '已删除'
default: return '未知'
}
}
//
const formatFileSize = (size: number) => {
if (size < 1024) return size + ' B'
if (size < 1024 * 1024) return (size / 1024).toFixed(1) + ' KB'
if (size < 1024 * 1024 * 1024) return (size / (1024 * 1024)).toFixed(1) + ' MB'
return (size / (1024 * 1024 * 1024)).toFixed(1) + ' GB'
}
// 退
const logout = () => {
userStore.logout()

@ -110,6 +110,7 @@
v-for="post in posts"
:key="post.id"
class="post-card card-light animate-fade-in-up"
:class="{ 'top-post': post.status === 2 }"
@click="viewPost(post.id)"
>
<div class="post-header">
@ -131,7 +132,13 @@
</div>
<div class="post-content">
<h3 class="post-title">{{ post.title }}</h3>
<h3 class="post-title">
<el-tag v-if="post.status === 2" type="danger" size="small" class="top-tag">
<el-icon><Top /></el-icon>
置顶
</el-tag>
{{ post.title }}
</h3>
<p class="post-summary">{{ post.summary }}</p>
</div>
@ -301,7 +308,8 @@ import {
Star,
School,
EditPen,
InfoFilled
InfoFilled,
Top
} from '@element-plus/icons-vue'
import { useUserStore } from '@/stores/user'
import { getPosts, getCategories, createPost, likePost } from '@/api/forum'
@ -825,6 +833,36 @@ onMounted(() => {
padding: 60px 20px;
}
/* 置顶帖子样式 */
.top-post {
border: 2px solid var(--primary-300) !important;
background: linear-gradient(135deg, rgba(168, 85, 247, 0.05), rgba(59, 130, 246, 0.05)) !important;
position: relative;
}
.top-post::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
height: 3px;
background: var(--gradient-primary);
border-radius: 12px 12px 0 0;
}
.top-tag {
margin-right: 8px !important;
font-weight: 600 !important;
background: var(--gradient-primary) !important;
border: none !important;
color: white !important;
}
.top-tag .el-icon {
margin-right: 4px !important;
}
/* 响应式设计 */
@media (max-width: 1024px) {
.forum-content {

@ -80,6 +80,12 @@ public class AdminController {
return adminService.deletePost(postId);
}
@Operation(summary = "永久删除帖子")
@DeleteMapping("/posts/{postId}/permanent")
public Result permanentDeletePost(@PathVariable Long postId) {
return adminService.permanentDeletePost(postId);
}
@Operation(summary = "获取评论列表")
@GetMapping("/comments")
public Result getCommentList(

@ -149,6 +149,11 @@ public interface PostMapper {
*/
void deletePost(Long postId);
/**
*
*/
void permanentDeletePost(Long postId);
/**
*
*/

@ -70,6 +70,11 @@ public class PostListVO {
*/
private Integer commentCount;
/**
* 0-, 1-, 2-
*/
private Byte status;
/**
*
*/

@ -46,6 +46,11 @@ public interface AdminService {
*/
Result deletePost(Long postId);
/**
*
*/
Result permanentDeletePost(Long postId);
/**
*
*/

@ -190,6 +190,23 @@ public class AdminServiceImpl implements AdminService {
}
}
@Override
public Result permanentDeletePost(Long postId) {
try {
Post post = postMapper.getPostById(postId);
if (post == null) {
return Result.error(404, "帖子不存在");
}
// 永久删除帖子(物理删除)
postMapper.permanentDeletePost(postId);
return Result.success(null, "帖子永久删除成功");
} catch (Exception e) {
log.error("永久删除帖子失败", e);
return Result.error(500, "永久删除帖子失败");
}
}
@Override
public Result getCommentList(Integer page, Integer size, String keyword, Long postId, Integer status) {
try {

@ -191,6 +191,7 @@ public class PostServiceImpl implements PostService {
.viewCount(post.getViewCount())
.likeCount(post.getLikeCount())
.commentCount(post.getCommentCount())
.status(post.getStatus())
.isLiked(isLiked)
.createdAt(post.getCreatedAt())
.build();
@ -347,6 +348,9 @@ public class PostServiceImpl implements PostService {
vo.setSummary(StrUtil.maxLength(content, 100));
}
// 确保status字段被正确复制
vo.setStatus(post.getStatus());
return vo;
}).collect(Collectors.toList());

@ -400,23 +400,27 @@ INSERT INTO `resources` (`user_id`, `title`, `description`, `file_url`, `file_si
-- 插入课程数据
INSERT INTO `courses` (`user_id`, `name`, `teacher`, `location`, `day_of_week`, `start_time`, `end_time`, `start_week`, `end_week`, `semester`, `color`, `status`) VALUES
-- 数学学院学生的课程
(2, '高等代数', '张教授', '数学学院楼201', 1, '08:00:00', '09:40:00', 1, 16, '2024-2025-2', '#409EFF', 1),
(2, '实变函数', '李老师', '数学学院楼301', 3, '14:00:00', '15:40:00', 1, 16, '2024-2025-2', '#67C23A', 1),
(2, '数学建模', '王教授', '计算中心机房', 5, '19:00:00', '21:00:00', 1, 16, '2024-2025-2', '#E6A23C', 1),
-- 计算机学院学生的课程
(3, '数据结构与算法', '赵教授', '信息学部计算机楼', 2, '10:00:00', '11:40:00', 1, 16, '2024-2025-2', '#409EFF', 1),
(3, '软件工程', '钱老师', '信息学部B楼302', 4, '14:00:00', '15:40:00', 1, 16, '2024-2025-2', '#67C23A', 1),
(3, '算法竞赛训练', 'ACM教练', '信息学部机房', 6, '19:30:00', '21:30:00', 1, 16, '2024-2025-2', '#E6A23C', 1),
-- 法学院学生的课程
(4, '民法学', '孙教授', '法学院模拟法庭', 1, '10:00:00', '11:40:00', 1, 16, '2024-2025-2', '#409EFF', 1),
(4, '法理学', '周老师', '法学院研讨室', 3, '15:50:00', '17:30:00', 1, 16, '2024-2025-2', '#67C23A', 1),
-- 经管学院学生的课程
(6, '宏观经济学', '吴教授', '经管大楼B201', 1, '08:00:00', '09:40:00', 1, 16, '2024-2025-2', '#409EFF', 1),
(6, '计量经济学', '郑老师', '经管大楼机房', 2, '10:00:00', '11:40:00', 1, 16, '2024-2025-2', '#67C23A', 1);
-- 数学专业学生(ID=3 czq2024)的课程
(3, '高等代数', '张教授', '数学学院楼201', 1, '08:00:00', '09:40:00', 1, 16, '2024-2025-2', '#409EFF', 1),
(3, '实变函数', '李老师', '数学学院楼301', 3, '14:00:00', '15:40:00', 1, 16, '2024-2025-2', '#67C23A', 1),
(3, '数学建模', '王教授', '计算中心机房', 5, '19:00:00', '21:00:00', 1, 16, '2024-2025-2', '#E6A23C', 1),
-- 计算机专业学生(ID=4 lihua_cs)的课程
(4, '数据结构与算法', '赵教授', '信息学部计算机楼', 2, '10:00:00', '11:40:00', 1, 16, '2024-2025-2', '#409EFF', 1),
(4, '软件工程', '钱老师', '信息学部B楼302', 4, '14:00:00', '15:40:00', 1, 16, '2024-2025-2', '#67C23A', 1),
(4, '算法竞赛训练', 'ACM教练', '信息学部机房', 6, '19:30:00', '21:30:00', 1, 16, '2024-2025-2', '#E6A23C', 1),
-- 法学专业学生(ID=5 wangming_law)的课程
(5, '民法学', '孙教授', '法学院模拟法庭', 1, '10:00:00', '11:40:00', 1, 16, '2024-2025-2', '#409EFF', 1),
(5, '法理学', '周老师', '法学院研讨室', 3, '15:50:00', '17:30:00', 1, 16, '2024-2025-2', '#67C23A', 1),
-- 化学专业学生(ID=6 zhangwei_chem)的课程
(6, '有机化学', '陈教授', '化学楼实验室', 2, '08:00:00', '09:40:00', 1, 16, '2024-2025-2', '#409EFF', 1),
(6, '物理化学', '刘老师', '化学楼201', 4, '14:00:00', '15:40:00', 1, 16, '2024-2025-2', '#67C23A', 1),
-- 经济学专业学生(ID=7 liuxin_econ)的课程
(7, '宏观经济学', '吴教授', '经管大楼B201', 1, '08:00:00', '09:40:00', 1, 16, '2024-2025-2', '#409EFF', 1),
(7, '计量经济学', '郑老师', '经管大楼机房', 2, '10:00:00', '11:40:00', 1, 16, '2024-2025-2', '#67C23A', 1);
-- 插入日程数据
INSERT INTO `schedules` (`user_id`, `title`, `description`, `start_time`, `end_time`, `location`, `is_all_day`, `reminder`, `color`, `status`) VALUES

@ -39,16 +39,16 @@
</where>
<choose>
<when test="sort == 'hot'">
ORDER BY view_count DESC
ORDER BY status DESC, view_count DESC
</when>
<when test="sort == 'likes'">
ORDER BY like_count DESC
ORDER BY status DESC, like_count DESC
</when>
<when test="sort == 'comments'">
ORDER BY comment_count DESC
ORDER BY status DESC, comment_count DESC
</when>
<otherwise>
ORDER BY created_at DESC
ORDER BY status DESC, created_at DESC
</otherwise>
</choose>
</select>
@ -114,16 +114,16 @@
WHERE user_id = #{userId} AND status != 0
<choose>
<when test="sort == 'hot'">
ORDER BY view_count DESC
ORDER BY status DESC, view_count DESC
</when>
<when test="sort == 'likes'">
ORDER BY like_count DESC
ORDER BY status DESC, like_count DESC
</when>
<when test="sort == 'comments'">
ORDER BY comment_count DESC
ORDER BY status DESC, comment_count DESC
</when>
<otherwise>
ORDER BY created_at DESC
ORDER BY status DESC, created_at DESC
</otherwise>
</choose>
</select>
@ -145,13 +145,13 @@
</if>
<choose>
<when test="sortBy == 'time'">
ORDER BY created_at DESC
ORDER BY status DESC, created_at DESC
</when>
<when test="sortBy == 'popularity'">
ORDER BY like_count DESC, view_count DESC
ORDER BY status DESC, like_count DESC, view_count DESC
</when>
<otherwise>
ORDER BY created_at DESC
ORDER BY status DESC, created_at DESC
</otherwise>
</choose>
</select>
@ -224,6 +224,11 @@
WHERE id = #{postId}
</update>
<delete id="permanentDeletePost">
DELETE FROM posts
WHERE id = #{postId}
</delete>
<select id="getCountByCategoryId" resultType="int">
SELECT COUNT(*)
FROM posts

Loading…
Cancel
Save