zhangsq пре 8 месеци
родитељ
комит
01034efccf

+ 3 - 2
src/api/InventoryReview.js

@@ -12,7 +12,8 @@ export default {
 		return request('reject', data, 'post')
 	},
 	// 驳回
-	reject(data) {
+	pass(data) {
 		return request('pass', data, 'post')
-	},
+	}
 }
+``

+ 22 - 0
src/api/resourceAudit.js

@@ -0,0 +1,22 @@
+import { baseRequest } from '@/utils/newRequest'
+
+const request = (url, ...arg) => baseRequest(`/api/webapp/disk/` + url, ...arg)
+
+export default {
+	// 获取资管理审核括列表
+	page(data) {
+		return request('courseauditrecord/page', data, 'get')
+	},
+	//资源管理添加
+	add(data = {}) {
+		return request('courseauditrecord/add', data, 'post')
+	},
+	//发布
+	release(data = {}) {
+		return request('courseinfo/add', data, 'post')
+	},
+	//更新状态(审核/删除/恢复)
+	updateStatus(data = {}) {
+		return request('courseauditrecord/updateStatus', data, 'post')
+	}
+}

+ 202 - 202
src/components/customPagination.vue

@@ -44,238 +44,238 @@
 </template>
 
 <script setup>
-import { ref, computed, watch } from 'vue'
-import { LeftOutlined, RightOutlined } from '@ant-design/icons-vue'
-const props = defineProps({
-	total: {
-		type: Number,
-		required: true,
-		default: 0
-	},
-	pageSize: {
-		type: Number,
-		default: 10
-	},
-	current: {
-		type: Number,
-		default: 1
-	},
-	pageSizeOptions: {
-		type: Array,
-		default: () => ['10', '20', '30', '40', '50', '200', '500']
-	},
-	showQuickJumper: {
-		type: Boolean,
-		default: false
-	},
-	showSizeChanger: {
-		type: Boolean
-	},
-	hideOnSinglePage: {
-		type: Boolean,
-		default: false
-	},
-	showTotal: {
-		type: Function,
-		default: () => ''
-	},
-	size: {
-		type: String,
-		default: ''
-	}
-})
+	import { ref, computed, watch } from 'vue'
+	import { LeftOutlined, RightOutlined } from '@ant-design/icons-vue'
+	const props = defineProps({
+		total: {
+			type: Number,
+			required: true,
+			default: 0
+		},
+		pageSize: {
+			type: Number,
+			default: 10
+		},
+		current: {
+			type: Number,
+			default: 1
+		},
+		pageSizeOptions: {
+			type: Array,
+			default: () => ['10', '20', '30', '40', '50', '200', '500']
+		},
+		showQuickJumper: {
+			type: Boolean,
+			default: false
+		},
+		showSizeChanger: {
+			type: Boolean
+		},
+		hideOnSinglePage: {
+			type: Boolean,
+			default: false
+		},
+		showTotal: {
+			type: Function,
+			default: () => ''
+		},
+		size: {
+			type: String,
+			default: ''
+		}
+	})
 
-const emit = defineEmits(['change', 'showSizeChange'])
-const currentPage = ref(props.current)
-const pageSize = ref(String(props.pageSize))
-const totalNum = ref(props.total)
-const inputIndex = ref('')
-const isShowSizeChanger = ref(false)
+	const emit = defineEmits(['change', 'showSizeChange'])
+	const currentPage = ref(props.current)
+	const pageSize = ref(String(props.pageSize))
+	const totalNum = ref(props.total)
+	const inputIndex = ref('')
+	const isShowSizeChanger = ref(false)
 
-const pageRangeStart = ref(1)
+	const pageRangeStart = ref(1)
 
-const isDisabled = (type) => {
-	switch (type) {
-		case 'leftOutLined':
-			return currentPage.value === 1
-		case 'rightOutlined':
-			return currentPage.value === totalPage.value
-		default:
-			break
+	const isDisabled = (type) => {
+		switch (type) {
+			case 'leftOutLined':
+				return currentPage.value === 1
+			case 'rightOutlined':
+				return currentPage.value === totalPage.value
+			default:
+				break
+		}
 	}
-}
 
-const handleSizeChange = (size) => {
-	pageRangeStart.value = 1
-	currentPage.value = 1
-	emit('showSizeChange', currentPage.value, Number(size))
-}
+	const handleSizeChange = (size) => {
+		pageRangeStart.value = 1
+		currentPage.value = 1
+		emit('showSizeChange', currentPage.value, Number(size))
+	}
 
-watch(
-	() => props.total,
-	(val) => {
-		totalNum.value = val
-		isShowSizeChanger.value = props.showSizeChanger ? true : val > 50
-	},
-	{ immediate: true }
-)
+	watch(
+		() => props.total,
+		(val) => {
+			totalNum.value = val
+			isShowSizeChanger.value = props.showSizeChanger ? true : val > 50
+		},
+		{ immediate: true }
+	)
 
-watch(
-	() => props.pageSize,
-	(val) => {
-		pageSize.value = String(val)
-	}
-)
+	watch(
+		() => props.pageSize,
+		(val) => {
+			pageSize.value = String(val)
+		}
+	)
 
-watch(
-	() => props.current,
-	(val) => {
-		if (val === 1) {
-			quickJumpPage(1)
+	watch(
+		() => props.current,
+		(val) => {
+			if (val === 1) {
+				quickJumpPage(1)
+			}
 		}
-	}
-)
+	)
 
-const pageRangeEnd = computed(() => Math.min(pageRangeStart.value + 9, totalPage.value))
+	const pageRangeEnd = computed(() => Math.min(pageRangeStart.value + 9, totalPage.value))
 
-const pageRangeArr = computed(() => {
-	const start = pageRangeStart.value
-	const end = pageRangeEnd.value
-	const pages = []
-	for (let i = start; i <= end; i++) {
-		pages.push(i)
-	}
-	return pages
-})
+	const pageRangeArr = computed(() => {
+		const start = pageRangeStart.value
+		const end = pageRangeEnd.value
+		const pages = []
+		for (let i = start; i <= end; i++) {
+			pages.push(i)
+		}
+		return pages
+	})
 
-const totalPage = computed(() => {
-	return !totalNum.value ? 1 : Math.ceil(totalNum.value / pageSize.value)
-})
+	const totalPage = computed(() => {
+		return !totalNum.value ? 1 : Math.ceil(totalNum.value / pageSize.value)
+	})
 
-// 点击页码
-const jumpCurrentPage = (page) => {
-	// 不重复请求
-	if (page === currentPage.value) return
-	if (page === totalPage.value) {
-		currentPage.value = page
-		emit('change', currentPage.value)
-	} else {
-		if (page >= 1 && page < totalPage.value) {
+	// 点击页码
+	const jumpCurrentPage = (page) => {
+		// 不重复请求
+		if (page === currentPage.value) return
+		if (page === totalPage.value) {
 			currentPage.value = page
-			if ((page <= pageRangeStart.value && page !== 1) || page >= pageRangeEnd.value) {
-				pageRangeStart.value = Math.max(1, page - 5)
-			}
 			emit('change', currentPage.value)
+		} else {
+			if (page >= 1 && page < totalPage.value) {
+				currentPage.value = page
+				if ((page <= pageRangeStart.value && page !== 1) || page >= pageRangeEnd.value) {
+					pageRangeStart.value = Math.max(1, page - 5)
+				}
+				emit('change', currentPage.value)
+			}
 		}
 	}
-}
-// 上一页
-const previousPage = () => {
-	if (currentPage.value > 1) {
-		currentPage.value--
-		if (currentPage.value < pageRangeStart.value) {
-			pageRangeStart.value = Math.max(1, currentPage.value - 5)
+	// 上一页
+	const previousPage = () => {
+		if (currentPage.value > 1) {
+			currentPage.value--
+			if (currentPage.value < pageRangeStart.value) {
+				pageRangeStart.value = Math.max(1, currentPage.value - 5)
+			}
+			emit('change', currentPage.value)
 		}
-		emit('change', currentPage.value)
 	}
-}
-// 下一页
-const nextPage = () => {
-	if (currentPage.value < totalPage.value) {
-		currentPage.value++
-		if (currentPage.value > pageRangeEnd.value && currentPage.value !== totalNum.value) {
-			pageRangeStart.value = Math.max(1, currentPage.value - 5)
+	// 下一页
+	const nextPage = () => {
+		if (currentPage.value < totalPage.value) {
+			currentPage.value++
+			if (currentPage.value > pageRangeEnd.value && currentPage.value !== totalNum.value) {
+				pageRangeStart.value = Math.max(1, currentPage.value - 5)
+			}
+			emit('change', currentPage.value)
 		}
-		emit('change', currentPage.value)
 	}
-}
 
-// 快速跳转
-const quickJumpPage = (pageIndex) => {
-	let index = Number(pageIndex)
-	let isInteger = Number.isInteger(index)
-	if (!index || !isInteger) {
-		inputIndex.value = ''
-		return
-	} else {
-		pageRangeStart.value = 1
-		if (index >= 1 && index < totalPage.value) {
-			pageRangeStart.value = Math.max(1, index - 5)
-			currentPage.value = index
+	// 快速跳转
+	const quickJumpPage = (pageIndex) => {
+		let index = Number(pageIndex)
+		let isInteger = Number.isInteger(index)
+		if (!index || !isInteger) {
+			inputIndex.value = ''
+			return
 		} else {
-			if (index >= totalPage.value) {
-				if (totalPage.value < 10) {
+			pageRangeStart.value = 1
+			if (index >= 1 && index < totalPage.value) {
+				pageRangeStart.value = Math.max(1, index - 5)
+				currentPage.value = index
+			} else {
+				if (index >= totalPage.value) {
+					if (totalPage.value < 10) {
+						pageRangeStart.value = 1
+					} else {
+						pageRangeStart.value = totalPage.value - (totalPage.value % 10) - 4
+					}
+					currentPage.value = totalPage.value
+				} else if (index < 1) {
 					pageRangeStart.value = 1
-				} else {
-					pageRangeStart.value = totalPage.value - (totalPage.value % 10) - 4
+					currentPage.value = 1
 				}
-				currentPage.value = totalPage.value
-			} else if (index < 1) {
-				pageRangeStart.value = 1
-				currentPage.value = 1
 			}
+			inputIndex.value = ''
 		}
-		inputIndex.value = ''
+		emit('change', currentPage.value)
 	}
-	emit('change', currentPage.value)
-}
 </script>
-<style  scoped>
-.pagination {
-	user-select: none;
-	display: flex;
-	align-items: center;
-	flex-wrap: wrap;
-}
-.icon {
-	font-size: 12px;
-}
+<style scoped>
+	.pagination {
+		user-select: none;
+		display: flex;
+		align-items: center;
+		flex-wrap: wrap;
+	}
+	.icon {
+		font-size: 12px;
+	}
 
-.ant-btn-link {
-	color: #212325;
-	font-size: 12px;
-	&:hover {
+	.ant-btn-link {
+		color: #212325;
+		font-size: 12px;
+		&:hover {
+			color: #4458fe;
+		}
+	}
+	.ant-btn-link[disabled],
+	.ant-btn-link[disabled]:hover,
+	.ant-btn-link[disabled]:focus,
+	.ant-btn-link[disabled]:active {
+		color: rgba(0, 0, 0, 0.25);
+	}
+	.pagination span.active {
+		color: #4458fe;
+	}
+	:deep(.ant-select select) {
+		border-radius: 6px;
+	}
+	.pageIndex {
+		display: inline-block;
+		min-width: 32px;
+		height: 30px;
+		line-height: 30px;
+		text-align: center;
+		cursor: pointer;
+		border-radius: 6px;
+		font-size: 14px;
+		padding: 0 6px;
+	}
+	.pageIndex:hover {
 		color: #4458fe;
 	}
-}
-.ant-btn-link[disabled],
-.ant-btn-link[disabled]:hover,
-.ant-btn-link[disabled]:focus,
-.ant-btn-link[disabled]:active {
-	color: rgba(0, 0, 0, 0.25);
-}
-.pagination span.active {
-	color: #4458fe;
-}
-:deep(.ant-select select) {
-	border-radius: 6px;
-}
-.pageIndex {
-	display: inline-block;
-	min-width: 32px;
-	height: 30px;
-	line-height: 30px;
-	text-align: center;
-	cursor: pointer;
-	border-radius: 6px;
-	font-size: 14px;
-	padding: 0 6px;
-}
-.pageIndex:hover {
-	color: #4458fe;
-}
-.sizeChanger {
-	margin-left: 8px;
-}
-.jumpPage {
-	margin-left: 8px;
-}
-.toInputIndex {
-	width: 48px;
-	margin: 0 8px;
-}
-.disabledBgc {
-	color: rgba(0, 0, 0, 0.25);
-	cursor: not-allowed;
-}
+	.sizeChanger {
+		margin-left: 8px;
+	}
+	.jumpPage {
+		margin-left: 8px;
+	}
+	.toInputIndex {
+		width: 48px;
+		margin: 0 8px;
+	}
+	.disabledBgc {
+		color: rgba(0, 0, 0, 0.25);
+		cursor: not-allowed;
+	}
 </style>

+ 7 - 0
src/style/index.less

@@ -371,6 +371,13 @@ a, button, input, textarea {
 		display: none;
 	}
 }
+.dis-flex-end {
+	display: flex;
+	justify-content: flex-end;
+}
+.margin-top {
+	margin-top: 15px;
+}
 
 /* 最大化后的退出按钮 */
 .main-maximize-exit {

+ 0 - 7
src/views/InventoryReview/index.vue

@@ -299,13 +299,6 @@
 		height: 40px;
 		margin-right: 8px;
 	}
-	.dis-flex-end {
-		display: flex;
-		justify-content: flex-end;
-	}
-	.margin-top {
-		margin-top: 15px;
-	}
 
 	@media (max-width: 768px) {
 		.resource-item {

+ 210 - 181
src/views/myResources/index.vue

@@ -1,11 +1,11 @@
 <template>
 	<a-card>
 		<!-- 标签页 -->
-		<a-tabs v-model:activeKey="activeKey" @change="tabChange">
-			<a-tab-pane key="unpublished" tab="未发布"></a-tab-pane>
-			<a-tab-pane key="pending" tab="待审核"></a-tab-pane>
-			<a-tab-pane key="published" tab="已发布"></a-tab-pane>
-			<a-tab-pane key="recycle" tab="回收站"></a-tab-pane>
+		<a-tabs v-model:activeKey="formState.verifyStatus" @change="tabChange">
+			<a-tab-pane key="0" tab="未发布"></a-tab-pane>
+			<a-tab-pane key="1" tab="待审核"></a-tab-pane>
+			<a-tab-pane key="2" tab="已发布"></a-tab-pane>
+			<a-tab-pane key="4" tab="回收站"></a-tab-pane>
 		</a-tabs>
 
 		<!-- 搜索和操作区域 -->
@@ -23,34 +23,44 @@
 		<!-- 表格 -->
 		<a-table
 			:columns="currentColumns"
-			:data-source="currentDataSource"
+			:data-source="dataSource"
 			:pagination="false"
+			:loading="loading"
+			bordered
 			:row-key="(record) => record.id"
 		>
-			<template #bodyCell="{ column, record }">
+			<template #bodyCell="{ column, text, record }">
+				<template
+					v-if="
+						['fileName', 'collegeIdName', 'majorIdName', 'courseTypeName', 'suffix', 'uploadTime'].includes(
+							column.dataIndex
+						)
+					"
+				>
+					<div class="multiLine-ellipsis" :title="text">{{ text || '-' }}</div>
+				</template>
 				<!-- 状态列 -->
-				<template v-if="column.key === 'status'">
-					<span v-if="record.status === 'processing'">
+				<template v-if="column.key === 'verifyStatus'">
+					<span v-if="record.verifyStatus === '0'">
 						<a-badge status="processing" text="处理中" />
 					</span>
-					<span v-else-if="record.status === 'uploaded'">
+					<span v-else-if="record.verifyStatus === 'uploaded'">
 						<a-badge status="success" text="已上传" />
 					</span>
-					<span v-else-if="record.status === 'pending'">
+					<span v-else-if="record.verifyStatus === '1'">
 						<a-badge status="default" text="待审核" />
 					</span>
-					<span v-else-if="record.status === 'published'">
+					<span v-else-if="record.verifyStatus === '2'">
 						<a-badge status="success" text="已发布" />
 					</span>
-					<span v-else-if="record.status === 'deleted'">
+					<span v-else-if="record.verifyStatus === '4'">
 						<a-badge status="error" text="已删除" />
 					</span>
 				</template>
-
 				<!-- 操作列 -->
 				<template v-else-if="column.key === 'action'">
 					<div class="editable-cell">
-						<template v-if="activeKey === 'unpublished'">
+						<template v-if="formState.verifyStatus === '0'">
 							<a @click="handlePublish(record)">发布</a>
 							<a-divider type="vertical" />
 							<a-dropdown>
@@ -66,9 +76,6 @@
 										<a-menu-item>
 											<a href="javascript:;">下载</a>
 										</a-menu-item>
-										<a-menu-item>
-											<a href="javascript:;">编辑</a>
-										</a-menu-item>
 										<a-menu-item>
 											<a href="javascript:;">删除</a>
 										</a-menu-item>
@@ -77,7 +84,7 @@
 							</a-dropdown>
 						</template>
 
-						<template v-else-if="activeKey === 'pending'">
+						<template v-else-if="formState.verifyStatus === '1'">
 							<a @click="handleAudit(record)">审核</a>
 							<a-divider type="vertical" />
 							<a-dropdown>
@@ -88,14 +95,20 @@
 								<template #overlay>
 									<a-menu>
 										<a-menu-item>
-											<a href="javascript:;">查看</a>
+											<a href="javascript:;">播放</a>
+										</a-menu-item>
+										<a-menu-item>
+											<a href="javascript:;">下载</a>
+										</a-menu-item>
+										<a-menu-item>
+											<a href="javascript:;">删除</a>
 										</a-menu-item>
 									</a-menu>
 								</template>
 							</a-dropdown>
 						</template>
 
-						<template v-else-if="activeKey === 'published'">
+						<template v-else-if="formState.verifyStatus === '2'">
 							<a @click="handlePermission(record)">权限</a>
 							<a-divider type="vertical" />
 							<a-dropdown>
@@ -106,10 +119,13 @@
 								<template #overlay>
 									<a-menu>
 										<a-menu-item>
-											<a href="javascript:;">查看</a>
+											<a href="javascript:;">播放</a>
+										</a-menu-item>
+										<a-menu-item>
+											<a href="javascript:;">下载</a>
 										</a-menu-item>
 										<a-menu-item>
-											<a href="javascript:;">编辑</a>
+											<a href="javascript:;" @click="edit(record)">编辑</a>
 										</a-menu-item>
 										<a-menu-item>
 											<a href="javascript:;">删除</a>
@@ -119,7 +135,7 @@
 							</a-dropdown>
 						</template>
 
-						<template v-else-if="activeKey === 'recycle'">
+						<template v-else-if="formState.verifyStatus === '4'">
 							<a @click="handleRestore(record)">恢复</a>
 							<a-divider type="vertical" />
 							<a-dropdown>
@@ -130,7 +146,13 @@
 								<template #overlay>
 									<a-menu>
 										<a-menu-item>
-											<a href="javascript:;">彻底删除</a>
+											<a href="javascript:;">播放</a>
+										</a-menu-item>
+										<a-menu-item>
+											<a href="javascript:;">下载</a>
+										</a-menu-item>
+										<a-menu-item>
+											<a href="javascript:;">删除</a>
 										</a-menu-item>
 									</a-menu>
 								</template>
@@ -140,113 +162,104 @@
 				</template>
 			</template>
 		</a-table>
-
-		<!-- 上传资源模态框 -->
-		<a-modal v-model:visible="uploadModalVisible" title="上传资源" @ok="handleUploadOk" @cancel="handleUploadCancel">
-			<a-upload
-				:multiple="true"
-				:before-upload="beforeUpload"
-				:file-list="fileList"
-				:remove="handleRemove"
-				:on-change="handleChange"
-			>
-				<div class="upload-area">
-					<a-icon type="cloud-upload" style="font-size: 60px; color: #3ca9f5"></a-icon>
-					<p>将文件拖到此处或点击上传</p>
-					<p>按住Ctrl可同时多选,支持上传PPT/word/excel/pdf/mp4/zip/rar,单个文件不能超过2G</p>
-				</div>
-			</a-upload>
-
-			<!-- 文件上传状态展示 -->
-			<ul v-if="fileList.length">
-				<li v-for="(file, index) in fileList" :key="index" class="file-item">
-					<span>{{ file.name }}</span>
-					<a-progress :percent="file.percent || 0" />
-					<span v-if="file.status === 'done'">已完成</span>
-					<span v-else-if="file.status === 'error'">上传失败</span>
-					<span v-else-if="file.status === 'uploading'">上传中...</span>
-				</li>
-			</ul>
-		</a-modal>
-		<releaseModal v-if="releaseVisible" @close="releaseVisible = false"></releaseModal>
+		<div class="dis-flex-end margin-top">
+			<CustomPagination
+				:total="pagination.total"
+				:current="pagination.pageNum"
+				:pageSize="pagination.pageSize"
+				:showQuickJumper="true"
+				:showSizeChanger="true"
+				:showTotal="(total) => `共 ${total} 条数据`"
+				@change="handlePageChange"
+				@showSizeChange="handlePageSizeChange"
+			/>
+		</div>
+		<!-- 资源上传模态框 -->
+		<resourceUpload
+			:visible="uploadModalVisible"
+			@close="uploadModalVisible = false"
+			@getList="getList"
+		></resourceUpload>
+		<!-- 发布模态框 -->
+		<releaseModal
+			:isState="isState"
+			v-if="releaseVisible"
+			@close="releaseVisible = false"
+			@confirm="confirm"
+		></releaseModal>
 	</a-card>
 </template>
 
 <script setup>
-	import { ref } from 'vue'
+	import { ref, onMounted } from 'vue'
 	import { DownOutlined } from '@ant-design/icons-vue'
-	import { Modal, Upload } from 'ant-design-vue'
 	import releaseModal from './releaseModal.vue'
+	import resourceUpload from './resourceUpload.vue'
+	import resourceAuditApi from '@/api/resourceAudit.js'
+	import CustomPagination from '@/components/customPagination.vue'
+
+	import tool from '@/utils/tool'
+	const headers = ref({
+		token: tool.data.get('TOKEN')
+	})
+	const action = ref('http://192.168.31.80:9003/api/webapp/dev/file/uploadMinioReturnId')
 	// 数据源
-	const dataSource = ref([
-		{
-			id: 1,
-			name: '资源名称资源名称',
-			format: 'mp4',
-			uploadTime: '2020-11-25 23:26:08',
-			status: 'processing', // processing, uploaded, pending, published, deleted
-			department: '航空理论系',
-			major: '商务服务',
-			courseType: '选修'
-		},
-		{
-			id: 2,
-			name: '资源名称资源名称',
-			format: 'mp4',
-			uploadTime: '2020-11-25 23:26:08',
-			status: 'pending', // processing, uploaded, pending, published, deleted
-			department: '航空理论系1',
-			major: '商务服务',
-			courseType: '选修'
-		},
-		{
-			id: 3,
-			name: '资源名称资源名称',
-			format: 'mp4',
-			uploadTime: '2020-11-25 23:26:08',
-			status: 'published', // processing, uploaded, pending, published, deleted
-			department: '航空理论系2',
-			major: '商务服务',
-			courseType: '选修'
-		}
-	])
+	const dataSource = ref([])
 
-	// 当前激活的标签页
-	const activeKey = ref('unpublished')
+	// const activeKey = ref('0')
 	//发布按钮状态
 	const releaseVisible = ref(false)
+	const loading = ref(false) // 列表loading
+
+	const isState = ref(0) // 列表loading
 
 	// 搜索值
 	const searchValue = ref('')
 
+	const pagination = reactive({
+		pageSize: 10,
+		pageNum: 1,
+		total: 0
+	})
+	const formState = reactive({
+		fileName: null,
+		verifyStatus: '0',
+		resourcesId: null
+	})
 	// 列定义
 	const columnsUnpublished = [
 		{
 			title: '编号',
-			dataIndex: 'id',
-			key: 'id'
+			align: 'center',
+			dataIndex: 'fileId',
+			key: 'fileId'
 		},
 		{
 			title: '资源名称',
-			dataIndex: 'name',
-			key: 'name'
+			align: 'center',
+			dataIndex: 'fileName',
+			key: 'fileName'
 		},
 		{
 			title: '课件格式',
-			dataIndex: 'format',
-			key: 'format'
+			align: 'center',
+			dataIndex: 'suffix',
+			key: 'suffix'
 		},
 		{
 			title: '上传时间',
 			dataIndex: 'uploadTime',
+			align: 'center',
 			key: 'uploadTime'
 		},
 		{
 			title: '状态',
-			key: 'status'
+			align: 'center',
+			key: 'verifyStatus'
 		},
 		{
 			title: '操作',
+			align: 'center',
 			key: 'action'
 		}
 	]
@@ -255,44 +268,53 @@
 		{
 			title: '编号',
 			dataIndex: 'id',
+			align: 'center',
 			key: 'id'
 		},
 		{
 			title: '资源名称',
-			dataIndex: 'name',
-			key: 'name'
+			align: 'center',
+			dataIndex: 'fileName',
+			key: 'fileName'
 		},
 		{
 			title: '所属院系',
-			dataIndex: 'department',
-			key: 'department'
+			align: 'center',
+			dataIndex: 'collegeIdName',
+			key: 'collegeIdName'
 		},
 		{
 			title: '所属专业',
-			dataIndex: 'major',
-			key: 'major'
+			align: 'center',
+			dataIndex: 'majorIdName',
+			key: 'majorIdName'
 		},
 		{
 			title: '课程类型',
-			dataIndex: 'courseType',
-			key: 'courseType'
+			align: 'center',
+			dataIndex: 'courseTypeName',
+			key: 'courseTypeName'
 		},
 		{
 			title: '课件格式',
-			dataIndex: 'format',
-			key: 'format'
+			align: 'center',
+			dataIndex: 'suffix',
+			key: 'suffix'
 		},
 		{
 			title: '上传时间',
+			align: 'center',
 			dataIndex: 'uploadTime',
 			key: 'uploadTime'
 		},
 		{
 			title: '状态',
-			key: 'status'
+			align: 'center',
+			key: 'verifyStatus'
 		},
 		{
 			title: '操作',
+			align: 'center',
 			key: 'action'
 		}
 	]
@@ -301,35 +323,45 @@
 	const columnsRecycle = [...columnsPending]
 
 	const currentColumns = computed(() => {
-		switch (activeKey.value) {
-			case 'unpublished':
+		switch (formState.verifyStatus) {
+			case '0':
 				return columnsUnpublished
-			case 'pending':
+			case '1':
 				return columnsPending
-			case 'published':
+			case '2':
 				return columnsPublished
-			case 'recycle':
+			case '4':
 				return columnsRecycle
 			default:
 				return []
 		}
 	})
-
-	const currentDataSource = computed(() => {
-		return dataSource.value.filter((item) => {
-			if (activeKey.value === 'unpublished') {
-				return ['processing', 'uploaded'].includes(item.status)
-			} else if (activeKey.value === 'pending') {
-				return item.status === 'pending'
-			} else if (activeKey.value === 'published') {
-				return item.status === 'published'
-			} else if (activeKey.value === 'recycle') {
-				return item.status === 'deleted'
-			}
-			return false
-		})
-	})
-
+	const getListData = () => {
+		loading.value = true
+		let params = {
+			current: pagination.pageNum,
+			size: pagination.pageSize,
+			verifyStatus: formState.verifyStatus,
+			fileName: formState.fileName
+		}
+		resourceAuditApi
+			.page(params)
+			.then((res) => {
+				console.log(res, '资源审核列表')
+				dataSource.value = res.data.records
+				pagination.total = res.data.total
+				loading.value = false
+			})
+			.catch((err) => {
+				console.log(err)
+				dataSource.value = []
+				pagination.total = 0
+				loading.value = false
+			})
+	}
+	const getList = () => {
+		getListData()
+	}
 	// 方法
 	const handleSearch = () => {
 		console.log('Search:', searchValue.value)
@@ -339,17 +371,41 @@
 		searchValue.value = ''
 	}
 	const tabChange = () => {
-		// dataSource.value = []
-	}
-
-	const handleUpload = () => {
-		console.log('Upload Resource')
+		dataSource.value = []
+		getListData()
 	}
-
+	const publishedData = ref()
+	//发布
 	const handlePublish = (record) => {
-		console.log('Publish:', record)
+		publishedData.value = record
+		isState.value = 0
 		releaseVisible.value = true
 	}
+	//发布确定
+	const confirm = (obj) => {
+		console.log(obj, '传回来的数据')
+		let params = {
+			courseAuditId: publishedData.value.courseAuditId,
+			fileId: publishedData.value.fileId,
+			collegeId: publishedData.value.collegeId,
+			majorId: publishedData.value.majorId,
+			courseType: obj.courseType,
+			courseName: obj.courseName,
+			courseDesc: obj.courseDesc,
+			coverImageId: obj.coverImageId
+		}
+		resourceAuditApi
+			.release(params)
+			.then((res) => {
+				console.log(res, '资源审核列表')
+			})
+			.catch((err) => {
+				console.log(err)
+				dataSource.value = []
+				pagination.total = 0
+				loading.value = false
+			})
+	}
 
 	const handleAudit = (record) => {
 		console.log('Audit:', record)
@@ -362,63 +418,36 @@
 	const handleRestore = (record) => {
 		console.log('Restore:', record)
 	}
+	//课程编辑
+	const edit = (record) => {
+		console.log('Restore:', record)
+		releaseVisible.value = true
+		isState.value = 1
+	}
 
 	// 上传资源模态框
 	const uploadModalVisible = ref(false)
 
-	// 文件列表
-	const fileList = ref([])
 
 	// 显示上传模态框
 	const showUploadModal = () => {
 		uploadModalVisible.value = true
 	}
-
-	// 关闭模态框
-	const handleUploadCancel = () => {
-		uploadModalVisible.value = false
-		fileList.value = []
-	}
-
-	// 确认上传
-	const handleUploadOk = () => {
-		// 这里可以添加实际的上传逻辑
-		console.log('Upload confirmed:', fileList.value)
-		uploadModalVisible.value = false
-		fileList.value = []
-	}
-
-	// 上传前的钩子函数
-	const beforeUpload = (file) => {
-		const isLt2G = file.size / 1024 / 1024 / 1024 < 2
-		if (!isLt2G) {
-			Modal.error({ content: '文件大小不能超过 2GB!' })
-		}
-		return isLt2G
+	// 翻页
+	const handlePageChange = (page) => {
+		pagination.pageNum = page
+		getListData()
 	}
-
-	// 移除文件
-	const handleRemove = (file) => {
-		const index = fileList.value.indexOf(file)
-		const newFileList = fileList.value.slice()
-		newFileList.splice(index, 1)
-		fileList.value = newFileList
+	// 每页条数
+	const handlePageSizeChange = (pageNum, size) => {
+		pagination.pageNum = 1
+		pagination.pageSize = size
+		getListData()
 	}
 
-	// 文件状态改变时的处理函数
-	const handleChange = ({ file, fileList: newFileList }) => {
-		fileList.value = newFileList
-
-		if (file.status === 'uploading') {
-			file.percent = 0
-		}
-
-		if (file.status === 'done') {
-			Modal.success({ content: '文件上传成功' })
-		} else if (file.status === 'error') {
-			Modal.error({ content: '文件上传失败' })
-		}
-	}
+	onMounted(() => {
+		getListData()
+	})
 </script>
 
 <style scoped>

+ 76 - 25
src/views/myResources/releaseModal.vue

@@ -1,16 +1,21 @@
 <template>
 	<!-- 上传资源模态框 -->
-	<a-modal v-model:visible="uploadModalVisible" title="上传资源" @ok="handleUploadOk" @cancel="handleUploadCancel">
+	<a-modal
+		:title="isState == 0 ? '发布课程' : '编辑课程'"
+		style="width: 800px"
+		v-model:visible="uploadModalVisible"
+		@ok="handleUploadOk"
+		@cancel="handleUploadCancel"
+	>
 		<a-form :model="uploadForm" :label-col="{ span: 6 }" :wrapper-col="{ span: 16 }">
-			<a-form-item label="资源名称" name="resourceName">
+			<!-- <a-form-item label="资源名称" name="resourceName">
 				<a-input v-model:value="uploadForm.resourceName" placeholder="请输入资源名称" />
-			</a-form-item>
+			</a-form-item> -->
 
 			<a-form-item label="资源类型" name="resourceType">
 				<a-select v-model:value="uploadForm.resourceType" placeholder="请选择资源类型">
 					<a-select-option value="type1">类型1</a-select-option>
 					<a-select-option value="type2">类型2</a-select-option>
-					<!-- 其他选项 -->
 				</a-select>
 			</a-form-item>
 
@@ -18,15 +23,22 @@
 				<a-input v-model:value="uploadForm.courseName" placeholder="请输入课程名称" />
 			</a-form-item>
 
-			<a-form-item label="课程介绍" name="courseDescription">
-				<a-textarea v-model:value="uploadForm.courseDescription" placeholder="请输入课程介绍" :rows="4" />
+			<a-form-item label="课程介绍" name="courseDesc">
+				<a-textarea v-model:value="uploadForm.courseDesc" placeholder="请输入课程介绍" :rows="4" />
 			</a-form-item>
 
-			<a-form-item label="上传封面" name="coverImage">
+			<a-form-item label="上传封面" name="coverImageId">
+				<div style="margin-bottom: 10px">
+					<a-button type="primary" @click="chooseFile" :disabled="coverFileList.length > 0">选择图片</a-button>
+					<span style="margin-left: 10px">仅支持上传jpg/png格式文件,单个文件不能超过500kb</span>
+				</div>
 				<a-upload
+					ref="upload"
 					:before-upload="beforeUploadCover"
 					:file-list="coverFileList"
 					:remove="handleRemoveCover"
+					:headers="headers"
+					:action="action"
 					:on-change="handleChangeCover"
 					list-type="picture-card"
 				>
@@ -50,18 +62,32 @@
 		</ul>
 	</a-modal>
 </template>
+
 <script setup>
 	import { ref, reactive } from 'vue'
 	import { Modal, Upload } from 'ant-design-vue'
 	import { PlusOutlined } from '@ant-design/icons-vue'
-	const emit = defineEmits(['close'])
+	import tool from '@/utils/tool'
+	const props = defineProps({
+		isState: {
+			type: Number,
+			required: true,
+			default: 0
+		}
+	})
+	const headers = ref({
+		token: tool.data.get('TOKEN')
+	})
+	const action = ref('http://192.168.31.80:9003/api/webapp/dev/file/uploadMinioReturnId')
+	const emit = defineEmits(['close', 'confirm'])
+
 	// 表单数据
 	const uploadForm = reactive({
-		resourceName: '',
-		resourceType: '',
-		courseName: '',
-		courseDescription: '',
-		coverImage: ''
+		// resourceName: null,
+		resourceType: null,
+		courseName: null,
+		courseDesc: null,
+		coverImageId: null
 	})
 
 	// 封面文件列表
@@ -72,18 +98,18 @@
 
 	// 显示上传模态框
 	// const showUploadModal = () => {
-	// 	uploadModalVisible.value = true
+	//   uploadModalVisible.value = true
 	// }
 
 	// 关闭模态框
 	const handleUploadCancel = () => {
 		uploadModalVisible.value = false
 		Object.assign(uploadForm, {
-			resourceName: '',
-			resourceType: '',
-			courseName: '',
-			courseDescription: '',
-			coverImage: ''
+			// resourceName: null,
+			resourceType: null,
+			courseName: null,
+			courseDesc: null,
+			coverImageId: null
 		})
 		fileList.value = []
 		coverFileList.value = []
@@ -93,14 +119,15 @@
 	// 确认上传
 	const handleUploadOk = () => {
 		// 这里可以添加实际的上传逻辑
-		console.log('Upload confirmed:', uploadForm, fileList.value, coverFileList.value)
+		console.log('Upload confirmed:', uploadForm.fileId, fileList.value, coverFileList.value)
+		emit('confirm', uploadForm)
 		uploadModalVisible.value = false
 		Object.assign(uploadForm, {
-			resourceName: '',
-			resourceType: '',
-			courseName: '',
-			courseDescription: '',
-			coverImage: ''
+			// resourceName: null,
+			resourceType: null,
+			courseName: null,
+			courseDesc: null,
+			coverImageId: null
 		})
 		fileList.value = []
 		coverFileList.value = []
@@ -125,13 +152,37 @@
 		const newFileList = coverFileList.value.slice()
 		newFileList.splice(index, 1)
 		coverFileList.value = newFileList
+		// 如果移除的是当前封面文件,则清空coverImageId
+		if (uploadForm.coverImageId === file.id) {
+			uploadForm.coverImageId = null
+		}
 	}
 
 	// 封面文件状态改变时的处理函数
 	const handleChangeCover = ({ file, fileList: newFileList }) => {
+		if (file.status === 'done') {
+			// 上传成功,获取文件ID
+			const fileId = file.response?.data || file.id
+			console.log('上传成功,获取文件ID', fileId)
+			if (fileId) {
+				uploadForm.coverImageId = fileId
+			}
+		}
+		if (file.status === 'error') {
+			// 延迟移除,确保用户能看到错误提示
+			setTimeout(() => {
+				coverFileList.value = coverFileList.value.filter((f) => f.uid !== file.uid)
+			}, 1500)
+		}
 		coverFileList.value = newFileList
 	}
+
+	// 选择文件按钮点击事件
+	const chooseFile = () => {
+		document.querySelector('.ant-upload input').click()
+	}
 </script>
+
 <style scoped>
 	.upload-area {
 		border: 2px dashed #3ca9f5;

+ 142 - 0
src/views/myResources/resourceUpload.vue

@@ -0,0 +1,142 @@
+<template>
+	<!-- 上传资源模态框 -->
+	<a-modal v-model:visible="uploadModalVisible" title="上传资源" @ok="handleUploadOk" @cancel="handleUploadCancel">
+		<a-upload
+			:multiple="true"
+			:before-upload="beforeUpload"
+			:headers="headers"
+			:action="action"
+			:file-list="fileList"
+			:remove="handleRemove"
+			accept=".ppt,.pptx,.doc,.docx,.xls,.xlsx,.pdf,.mp4,.zip,.rar"
+			:on-change="handleChange"
+		>
+			<div class="upload-area">
+				<a-icon type="cloud-upload" style="font-size: 60px; color: #3ca9f5"></a-icon>
+				<p>将文件拖到此处或点击上传</p>
+				<p>按住Ctrl可同时多选,支持上传PPT/word/excel/pdf/mp4/zip/rar,单个文件不能超过2G</p>
+			</div>
+		</a-upload>
+		<!-- 文件上传状态展示 -->
+		<ul v-if="fileList.length">
+			<li v-for="(file, index) in fileList" :key="index" class="file-item">
+				<span>{{ file.name }}</span>
+				<a-progress :percent="file.percent || 0" />
+				<span v-if="file.response?.code == '200'">已完成</span>
+				<span v-if="file.response?.code == '500'">上传失败</span>
+				<span v-if="file.status === 'uploading'">上传中...</span>
+			</li>
+		</ul>
+	</a-modal>
+</template>
+
+<script setup>
+	import { ref, reactive } from 'vue'
+	import { Modal, Upload } from 'ant-design-vue'
+	import resourceAuditApi from '@/api/resourceAudit.js'
+	const emit = defineEmits(['close', 'getList'])
+	const formState = reactive({
+		resourcesId: null
+	})
+	// 上传资源模态框
+	const uploadModalVisible = ref(true)
+
+	// 文件列表
+	const fileList = ref([])
+
+	// 关闭模态框
+	const handleUploadCancel = () => {
+		// uploadModalVisible.value = false
+		emit('close')
+		fileList.value = []
+	}
+
+	// 确认上传
+	const handleUploadOk = () => {
+		// 这里可以添加实际的上传逻辑
+		console.log('Upload confirmed:', fileList.value)
+		// uploadModalVisible.value = false
+		emit('close')
+		fileList.value = []
+		resourceAuditApi
+			.add({ fileId: formState.resourcesId })
+			.then((res) => {
+				emit('getList')
+			})
+			.catch((err) => {
+				console.log(err)
+			})
+	}
+	// 上传前的钩子函数
+	const beforeUpload = (file) => {
+		const isLt2G = file.size / 1024 / 1024 / 1024 < 2
+		if (!isLt2G) {
+			Modal.error({ content: '文件大小不能超过 2GB!' })
+		}
+		return isLt2G
+	}
+
+	// 移除文件
+	const handleRemove = (file) => {
+		const index = fileList.value.indexOf(file)
+		const newFileList = fileList.value.slice()
+		newFileList.splice(index, 1)
+		fileList.value = newFileList
+		// 如果移除的是当前封面文件,则清空coverImageId
+		if (formState.resourcesId === file.id) {
+			formState.resourcesId = null
+		}
+	}
+
+	// 文件状态改变时的处理函数
+	const handleChange = ({ file, fileList: newFileList }) => {
+		if (newFileList.length > 1) {
+			fileList.value = [newFileList[0]] // 只保留最新上传的文件
+			Modal.error({ content: '只能上传一个文件!' })
+			return
+		}
+
+		if (file.response?.code == 200) {
+			// 上传成功,获取文件ID
+			const fileId = file.response?.data || file.id
+			console.log('上传成功,获取文件ID', fileId)
+			if (fileId) {
+				formState.resourcesId = fileId
+			}
+		}
+		fileList.value = newFileList
+		if (file.status === 'uploading') {
+			file.percent = Math.floor(file.percent)
+		}
+		if (file.response?.code == 200) {
+			file.percent = 100
+			Modal.success({ content: '文件上传成功' })
+		} else if (file.response?.code == 500) {
+			Modal.error({ content: '文件上传失败' })
+			file.percent = 0
+		}
+	}
+</script>
+
+<style scoped>
+	.upload-area {
+		border: 2px dashed #3ca9f5;
+		padding: 40px;
+		text-align: center;
+	}
+
+	.upload-area p {
+		margin: 10px 0;
+	}
+
+	.file-item {
+		display: flex;
+		align-items: center;
+		margin: 10px 0;
+	}
+
+	.file-item .ant-progress {
+		flex: 1;
+		margin: 0 10px;
+	}
+</style>

+ 225 - 34
src/views/taskProgress/index.vue

@@ -4,52 +4,107 @@
 		<a-card title="筛选条件" :bordered="false">
 			<!-- 院系选择 -->
 			<div class="filter-group">
-				<span class="filter-label">所选院系:</span>
-				<a-radio-group v-model:value="selectedDepartment" button-style="solid">
-					<a-radio-button value="全部">全部</a-radio-button>
-					<a-radio-button value="航空理论系">航空理论系</a-radio-button>
-					<a-radio-button value="军事理论系">军事理论系</a-radio-button>
-					<a-radio-button value="政治工作系">政治工作系</a-radio-button>
-					<a-radio-button value="机务工程系">机务工程系</a-radio-button>
-					<a-radio-button value="航空机务系">航空机务系</a-radio-button>
-				</a-radio-group>
+				<div class="filter-groups">
+					<span class="filter-label">所选院系:</span>
+					<a-radio-group
+						v-model:value="selectedDepartment"
+						button-style="solid"
+						:class="{ expanded: isDepartmentExpanded }"
+					>
+						<a-radio-button class="border-r" value="全部">全部</a-radio-button>
+						<a-radio-button
+							class="border-r"
+							v-for="dept in departments"
+							:key="dept"
+							:value="dept"
+							v-show="isDepartmentExpanded || dept === isDepartmentExpanded"
+							>{{ dept }}</a-radio-button
+						>
+					</a-radio-group>
+				</div>
+
+				<a-link style="margin-left: 10px; width: 5%" @click="toggleDepartmentOptions">{{
+					isDepartmentExpanded ? '收起' : '展开'
+				}}</a-link>
 			</div>
+
 			<!-- 课程选择 -->
 			<div class="filter-group" style="margin-top: 16px">
-				<span class="filter-label">所选课程:</span>
-				<a-radio-group v-model:value="selectedCourse" button-style="solid">
-					<a-radio-button value="全部">全部</a-radio-button>
-					<a-radio-button value="初级飞行训练">初级飞行训练</a-radio-button>
-					<a-radio-button value="高级飞行训练">高级飞行训练</a-radio-button>
-					<a-radio-button value="实弹训练">实弹训练</a-radio-button>
-					<a-radio-button value="低空战术飞行">低空战术飞行</a-radio-button>
-				</a-radio-group>
+				<div class="filter-groups">
+					<span class="filter-label">所选课程:</span>
+					<a-radio-group v-model:value="selectedCourse" button-style="solid" :class="{ expanded: isCourseExpanded }">
+						<a-radio-button class="border-r" value="全部">全部</a-radio-button>
+						<a-radio-button
+							class="border-r"
+							v-for="course in courses"
+							:key="course"
+							:value="course"
+							v-show="isCourseExpanded || course === selectedCourse"
+							>{{ course }}</a-radio-button
+						>
+					</a-radio-group>
+				</div>
+				<a-link style="margin-left: 10px; width: 5%" @click="toggleCourseOptions">{{
+					isCourseExpanded ? '收起' : '展开'
+				}}</a-link>
 			</div>
 
 			<!-- 课程类型选择 -->
 			<div class="filter-group" style="margin-top: 16px">
-				<span class="filter-label">课程类型:</span>
-				<a-radio-group v-model:value="selectedCourseType" button-style="solid">
-					<a-radio-button value="全部">全部</a-radio-button>
-					<a-radio-button value="热门资源">热门资源</a-radio-button>
-				</a-radio-group>
+				<div class="filter-groups">
+					<span class="filter-label">课程类型:</span>
+					<a-radio-group
+						v-model:value="selectedCourseType"
+						button-style="solid"
+						:class="{ expanded: isCourseTypeExpanded }"
+					>
+						<a-radio-button class="border-r" value="全部">全部</a-radio-button>
+						<a-radio-button
+							class="border-r"
+							v-for="type in courseTypes"
+							:key="type"
+							:value="type"
+							v-show="isCourseTypeExpanded || type === selectedCourseType"
+							>{{ type }}</a-radio-button
+						>
+					</a-radio-group>
+				</div>
+
+				<a-link style="margin-left: 10px; width: 5%" @click="toggleCourseTypeOptions">{{
+					isCourseTypeExpanded ? '收起' : '展开'
+				}}</a-link>
 			</div>
 
 			<!-- 课件格式选择 -->
 			<div class="filter-group" style="margin-top: 16px">
-				<span class="filter-label">课件格式:</span>
-				<a-radio-group v-model:value="selectedFileType" button-style="solid">
-					<a-radio-button value="全部">全部</a-radio-button>
-					<a-radio-button value="word">Word</a-radio-button>
-					<a-radio-button value="excel">Excel</a-radio-button>
-					<a-radio-button value="pdf">PDF</a-radio-button>
-				</a-radio-group>
+				<div class="filter-groups">
+					<span class="filter-label">课件格式:</span>
+					<a-radio-group
+						v-model:value="selectedFileType"
+						button-style="solid"
+						:class="{ expanded: isFileTypeExpanded }"
+					>
+						<a-radio-button class="border-r" value="全部">全部</a-radio-button>
+						<a-radio-button
+							class="border-r"
+							v-for="format in fileFormats"
+							:key="format"
+							:value="format"
+							v-show="isFileTypeExpanded || format === selectedFileType"
+							>{{ format }}</a-radio-button
+						>
+					</a-radio-group>
+				</div>
+
+				<a-link style="margin-left: 10px; width: 5%" @click="toggleFileTypeOptions">{{
+					isFileTypeExpanded ? '收起' : '展开'
+				}}</a-link>
 			</div>
 
 			<!-- 已选条件展示 -->
 			<div style="margin-top: 20px">
 				已选条件:
-				<a-tag closable v-for="tag in selectedTags" :key="tag" @close="handleTagClose(tag)">
+				<a-tag class="border-r" closable v-for="tag in selectedTags" :key="tag" @close="handleTagClose(tag)">
 					{{ tag }}
 				</a-tag>
 				<a-link style="margin-left: 10px" @click="clearFilters">清除筛选</a-link>
@@ -66,10 +121,10 @@
 					<a-input-search placeholder="输入资源关键词" style="margin-left: auto; width: 300px" @search="onSearch" />
 				</div>
 				<a-row :gutter="16">
-					<a-col :span="8" v-for="(resource, index) in filteredResources" :key="index">
+					<a-col :span="6" v-for="(resource, index) in filteredResources" :key="index">
 						<a-card :title="resource.title" style="margin-bottom: 16px">
 							<template #cover>
-								<img alt="example" :src="resource.cover" style="height: 150px" />
+								<img alt="example" :src="resource.cover" style="height: 200px" />
 							</template>
 							<p>{{ resource.description }}</p>
 							<p>来源学校: {{ resource.school }}</p>
@@ -111,6 +166,42 @@
 
 	// 模拟数据
 	const resources = [
+		{
+			title: '学术交流英语',
+			description: '学术交流英语描述',
+			school: '来源学校',
+			author: '姓名',
+			date: '05-22 10:49',
+			views: '10000',
+			cover: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png'
+		},
+		{
+			title: '学术交流英语',
+			description: '学术交流英语描述',
+			school: '来源学校',
+			author: '姓名',
+			date: '05-22 10:49',
+			views: '10000',
+			cover: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png'
+		},
+		{
+			title: '学术交流英语',
+			description: '学术交流英语描述',
+			school: '来源学校',
+			author: '姓名',
+			date: '05-22 10:49',
+			views: '10000',
+			cover: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png'
+		},
+		{
+			title: '学术交流英语',
+			description: '学术交流英语描述',
+			school: '来源学校',
+			author: '姓名',
+			date: '05-22 10:49',
+			views: '10000',
+			cover: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png'
+		},
 		{
 			title: '学术交流英语',
 			description: '学术交流英语描述',
@@ -120,16 +211,29 @@
 			views: '10000',
 			cover: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png'
 		}
-		// 更多资源项...
 	]
 
 	const recommendedResources = [
+		{
+			title: '资源名称',
+			date: '05-22',
+			views: '10000'
+		},
+		{
+			title: '资源名称',
+			date: '05-22',
+			views: '10000'
+		},
+		{
+			title: '资源名称',
+			date: '05-22',
+			views: '10000'
+		},
 		{
 			title: '资源名称',
 			date: '05-22',
 			views: '10000'
 		}
-		// 更多推荐资源项...
 	]
 
 	// 筛选条件
@@ -139,6 +243,28 @@
 	const selectedFileType = ref('全部')
 	const searchKeyword = ref('')
 
+	const departments = ['航空理论系', '军事理论系', '政治工作系', '机务工程系', '航空机务系']
+	const courses = [
+		'初级飞行训练',
+		'高级飞行训练',
+		'实弹训练',
+		'低空战术飞行',
+		'跨区转场训练',
+		'空气动力学',
+		'航空气象学',
+		'航空电子设备',
+		'飞机结构与系统',
+		'空军作战指挥',
+		'战场态势感知',
+		'模拟对抗训练',
+		'军队政治工作',
+		'军事理论',
+		'战斗精神培育',
+		'机型改装训练',
+		'应急程序训练'
+	]
+	const courseTypes = ['热门资源', '名师资源', '必修', '选修']
+	const fileFormats = ['ppt', 'word', 'excel', 'pdf', 'mp4', 'zip', 'rar']
 	const selectedTags = ref([])
 	watch(
 		[selectedDepartment, selectedCourse, selectedCourseType, selectedFileType],
@@ -152,6 +278,7 @@
 		},
 		{ immediate: true }
 	)
+
 	// 过滤资源
 	const filteredResources = computed(() => {
 		return resources.filter((resource) => {
@@ -187,6 +314,28 @@
 		console.log('search:', value)
 		// 这里可以添加搜索逻辑
 	}
+
+	// 展开/收起状态
+	const isDepartmentExpanded = ref(false)
+	const isCourseExpanded = ref(false)
+	const isCourseTypeExpanded = ref(false)
+	const isFileTypeExpanded = ref(false)
+
+	const toggleDepartmentOptions = () => {
+		isDepartmentExpanded.value = !isDepartmentExpanded.value
+	}
+
+	const toggleCourseOptions = () => {
+		isCourseExpanded.value = !isCourseExpanded.value
+	}
+
+	const toggleCourseTypeOptions = () => {
+		isCourseTypeExpanded.value = !isCourseTypeExpanded.value
+	}
+
+	const toggleFileTypeOptions = () => {
+		isFileTypeExpanded.value = !isFileTypeExpanded.value
+	}
 </script>
 
 <style scoped>
@@ -195,11 +344,21 @@
 	}
 
 	.filter-group {
+		width: 100%;
+		display: flex;
+		align-items: center;
+		justify-content: space-between;
+		padding-bottom: 10px;
+		border-bottom: 1px solid #e8e8e8;
+	}
+	.filter-groups {
+		width: 100%;
 		display: flex;
 		align-items: center;
 	}
 
 	.filter-label {
+		width: 6%;
 		margin-right: 10px;
 	}
 
@@ -208,4 +367,36 @@
 		flex-wrap: wrap;
 		margin-top: 8px;
 	}
+
+	.border-r {
+		border-radius: 20px;
+		margin-right: 10px;
+		border: 0 !important;
+	}
+
+	:deep(.ant-radio-button-wrapper::before) {
+		display: none !important;
+	}
+
+	.filter-group .ant-link {
+		margin-left: 10px;
+		font-size: 14px;
+		color: #1890ff;
+	}
+
+	.filter-group .ant-link:hover {
+		text-decoration: underline;
+	}
+
+	.filter-group .ant-radio-group {
+		display: flex;
+		flex-wrap: wrap;
+		max-height: 40px; /* 根据需要调整 */
+		overflow: hidden;
+		transition: max-height 0.3s ease;
+	}
+
+	.filter-group .ant-radio-group.expanded {
+		max-height: none;
+	}
 </style>