Browse Source

功能提交

zhangsq 8 months ago
parent
commit
c320ce3299

+ 27 - 0
src/api/course/keyWordApi.js

@@ -0,0 +1,27 @@
+import { baseRequest } from '@/utils/request'
+
+const request = (url, ...arg) => baseRequest(`/api/webapp/disk/word/` + url, ...arg)
+
+/**
+ * key_wordApi接口管理器
+ *
+ * @author pans
+ * @date  2025/06/27 10:08
+ **/
+export default {
+	// 获取key_word分页
+	keyWordPage(data) {
+		return request('page', data, 'get')
+	},
+	// 提交key_word表单 edit为true时为编辑,默认为新增
+	keyWordSubmitForm(data, edit = false) {
+		return request(edit ? 'edit' : 'add', data)
+	},
+	// 删除key_word
+	keyWordDelete(data) {
+		return request('delete', data)
+	},
+	// 获取key_word详情
+	keyWordDetail(data) {
+		return request('detail', data, 'get')
+	}}

+ 27 - 0
src/api/course/majorApi.js

@@ -0,0 +1,27 @@
+import { baseRequest } from '@/utils/request'
+
+const request = (url, ...arg) => baseRequest(`/api/webapp/disk/major/` + url, ...arg)
+
+/**
+ * majorApi接口管理器
+ *
+ * @author pans
+ * @date  2025/06/26 10:41
+ **/
+export default {
+	// 获取major分页
+	majorPage(data) {
+		return request('page', data, 'get')
+	},
+	// 提交major表单 edit为true时为编辑,默认为新增
+	majorSubmitForm(data, edit = false) {
+		return request(edit ? 'edit' : 'add', data)
+	},
+	// 删除major
+	majorDelete(data) {
+		return request('delete', data)
+	},
+	// 获取major详情
+	majorDetail(data) {
+		return request('detail', data, 'get')
+	}}

+ 27 - 0
src/api/course/resourceFileFormatApi.js

@@ -0,0 +1,27 @@
+import { baseRequest } from '@/utils/request'
+
+const request = (url, ...arg) => baseRequest(`/api/webapp/disk/fileformat/` + url, ...arg)
+
+/**
+ * resource_file_formatApi接口管理器
+ *
+ * @author pans
+ * @date  2025/06/28 12:01
+ **/
+export default {
+	// 获取resource_file_format分页
+	resourceFileFormatPage(data) {
+		return request('page', data, 'get')
+	},
+	// 提交resource_file_format表单 edit为true时为编辑,默认为新增
+	resourceFileFormatSubmitForm(data, edit = false) {
+		return request(edit ? 'edit' : 'add', data)
+	},
+	// 删除resource_file_format
+	resourceFileFormatDelete(data) {
+		return request('delete', data)
+	},
+	// 获取resource_file_format详情
+	resourceFileFormatDetail(data) {
+		return request('detail', data, 'get')
+	}}

+ 72 - 0
src/views/course/key_word/form.vue

@@ -0,0 +1,72 @@
+<template>
+	<xn-form-container
+		:title="formData.id ? '编辑key_word' : '增加key_word'"
+		:width="700"
+		:visible="visible"
+		:destroy-on-close="true"
+		@close="onClose"
+	>
+		<a-form ref="formRef" :model="formData" :rules="formRules" layout="vertical">
+			<a-form-item label="名称:" name="wordName">
+				<a-input v-model:value="formData.wordName" placeholder="请输入名称" allow-clear />
+			</a-form-item>
+			<a-form-item label="是否热门  1 热门 0不热门:" name="popular">
+				<a-input v-model:value="formData.popular" placeholder="请输入是否热门  1 热门 0不热门" allow-clear />
+			</a-form-item>
+		</a-form>
+		<template #footer>
+			<a-button style="margin-right: 8px" @click="onClose">关闭</a-button>
+			<a-button type="primary" @click="onSubmit" :loading="submitLoading">保存</a-button>
+		</template>
+	</xn-form-container>
+</template>
+
+<script setup name="keyWordForm">
+	import { cloneDeep } from 'lodash-es'
+	import { required } from '@/utils/formRules'
+	import keyWordApi from '@/api/course/keyWordApi'
+	// 抽屉状态
+	const visible = ref(false)
+	const emit = defineEmits({ successful: null })
+	const formRef = ref()
+	// 表单数据
+	const formData = ref({})
+	const submitLoading = ref(false)
+
+	// 打开抽屉
+	const onOpen = (record) => {
+		visible.value = true
+		if (record) {
+			let recordData = cloneDeep(record)
+			formData.value = Object.assign({}, recordData)
+		}
+	}
+	// 关闭抽屉
+	const onClose = () => {
+		formRef.value.resetFields()
+		formData.value = {}
+		visible.value = false
+	}
+	// 默认要校验的
+	const formRules = {}
+	// 验证并提交数据
+	const onSubmit = () => {
+		formRef.value.validate().then(() => {
+			submitLoading.value = true
+			const formDataParam = cloneDeep(formData.value)
+			keyWordApi
+				.keyWordSubmitForm(formDataParam, formDataParam.id)
+				.then(() => {
+					onClose()
+					emit('successful')
+				})
+				.finally(() => {
+					submitLoading.value = false
+				})
+		})
+	}
+	// 抛出函数
+	defineExpose({
+		onOpen
+	})
+</script>

+ 112 - 0
src/views/course/key_word/index.vue

@@ -0,0 +1,112 @@
+<template>
+	<a-card :bordered="false">
+		<s-table
+			ref="table"
+			:columns="columns"
+			:data="loadData"
+			:alert="options.alert.show"
+			bordered
+			:row-key="(record) => record.id"
+			:tool-config="toolConfig"
+			:row-selection="options.rowSelection"
+		>
+			<template #operator class="table-operator">
+				<a-space>
+					<a-button type="primary" @click="formRef.onOpen()" >
+						<template #icon><plus-outlined /></template>
+						新增
+					</a-button>
+					<xn-batch-delete :selectedRowKeys="selectedRowKeys" @batchDelete="deleteBatchKeyWord" />
+				</a-space>
+			</template>
+			<template #bodyCell="{ column, record }">
+				<template v-if="column.dataIndex === 'action'">
+					<a-space>
+						<a @click="formRef.onOpen(record)">编辑</a>
+						<a-divider type="vertical" />
+						<a-popconfirm title="确定要删除吗?" @confirm="deleteKeyWord(record)">
+							<a-button type="link" danger size="small">删除</a-button>
+						</a-popconfirm>
+					</a-space>
+				</template>
+			</template>
+		</s-table>
+	</a-card>
+	<Form ref="formRef" @successful="table.refresh(true)" />
+</template>
+
+<script setup name="word">
+	import Form from './form.vue'
+	import keyWordApi from '@/api/course/keyWordApi'
+	const table = ref()
+	const formRef = ref()
+	const toolConfig = { refresh: true, height: true, columnSetting: true, striped: false }
+	const columns = [
+		{
+			title: '名称',
+			dataIndex: 'wordName'
+		},
+		{
+			title: '是否热门  1 热门 0不热门',
+			dataIndex: 'popular'
+		},
+		{
+			title: '操作',
+			dataIndex: 'action',
+			align: 'center',
+			width: '150px'
+		}
+	]
+	// // 操作栏通过权限判断是否显示
+	// if (hasPerm(['keyWordEdit', 'keyWordDelete'])) {
+	// 	columns.push({
+	// 		title: '操作',
+	// 		dataIndex: 'action',
+	// 		align: 'center',
+	// 		width: '150px'
+	// 	})
+	// }
+	const selectedRowKeys = ref([])
+	// 列表选择配置
+	const options = {
+		// columns数字类型字段加入 needTotal: true 可以勾选自动算账
+		alert: {
+			show: true,
+			clear: () => {
+				selectedRowKeys.value = ref([])
+			}
+		},
+		rowSelection: {
+			onChange: (selectedRowKey, selectedRows) => {
+				selectedRowKeys.value = selectedRowKey
+			}
+		}
+	}
+	const loadData = (parameter) => {
+		return keyWordApi.keyWordPage(parameter).then((data) => {
+			return data
+		})
+	}
+	// 重置
+	const reset = () => {
+		searchFormRef.value.resetFields()
+		table.value.refresh(true)
+	}
+	// 删除
+	const deleteKeyWord = (record) => {
+		let params = [
+			{
+				id: record.id
+			}
+		]
+		keyWordApi.keyWordDelete(params).then(() => {
+			table.value.refresh(true)
+		})
+	}
+	// 批量删除
+	const deleteBatchKeyWord = (params) => {
+		keyWordApi.keyWordDelete(params).then(() => {
+			table.value.clearRefreshSelected()
+		})
+	}
+</script>

+ 75 - 0
src/views/course/major/form.vue

@@ -0,0 +1,75 @@
+<template>
+	<xn-form-container
+		:title="formData.id ? '编辑major' : '增加major'"
+		:width="700"
+		:visible="visible"
+		:destroy-on-close="true"
+		@close="onClose"
+	>
+		<a-form ref="formRef" :model="formData" :rules="formRules" layout="vertical">
+			<a-form-item label="院系名称:" name="majorName">
+				<a-input v-model:value="formData.majorName" placeholder="请输入院系名称" allow-clear />
+			</a-form-item>
+			<a-form-item label="院系编码:" name="majorCode">
+				<a-input v-model:value="formData.majorCode" placeholder="请输入院系编码" allow-clear />
+			</a-form-item>
+			<a-form-item label="学院id:" name="collegeId">
+				<a-input v-model:value="formData.collegeId" placeholder="请输入学院id" allow-clear />
+			</a-form-item>
+		</a-form>
+		<template #footer>
+			<a-button style="margin-right: 8px" @click="onClose">关闭</a-button>
+			<a-button type="primary" @click="onSubmit" :loading="submitLoading">保存</a-button>
+		</template>
+	</xn-form-container>
+</template>
+
+<script setup name="majorForm">
+	import { cloneDeep } from 'lodash-es'
+	import { required } from '@/utils/formRules'
+	import majorApi from '@/api/course/majorApi'
+	// 抽屉状态
+	const visible = ref(false)
+	const emit = defineEmits({ successful: null })
+	const formRef = ref()
+	// 表单数据
+	const formData = ref({})
+	const submitLoading = ref(false)
+
+	// 打开抽屉
+	const onOpen = (record) => {
+		visible.value = true
+		if (record) {
+			let recordData = cloneDeep(record)
+			formData.value = Object.assign({}, recordData)
+		}
+	}
+	// 关闭抽屉
+	const onClose = () => {
+		formRef.value.resetFields()
+		formData.value = {}
+		visible.value = false
+	}
+	// 默认要校验的
+	const formRules = {}
+	// 验证并提交数据
+	const onSubmit = () => {
+		formRef.value.validate().then(() => {
+			submitLoading.value = true
+			const formDataParam = cloneDeep(formData.value)
+			majorApi
+				.majorSubmitForm(formDataParam, formDataParam.id)
+				.then(() => {
+					onClose()
+					emit('successful')
+				})
+				.finally(() => {
+					submitLoading.value = false
+				})
+		})
+	}
+	// 抛出函数
+	defineExpose({
+		onOpen
+	})
+</script>

+ 116 - 0
src/views/course/major/index.vue

@@ -0,0 +1,116 @@
+<template>
+	<a-card :bordered="false">
+		<s-table
+			ref="table"
+			:columns="columns"
+			:data="loadData"
+			:alert="options.alert.show"
+			bordered
+			:row-key="(record) => record.id"
+			:tool-config="toolConfig"
+			:row-selection="options.rowSelection"
+		>
+			<template #operator class="table-operator">
+				<a-space>
+					<a-button type="primary" @click="formRef.onOpen()">
+						<template #icon><plus-outlined /></template>
+						新增
+					</a-button>
+					<xn-batch-delete :selectedRowKeys="selectedRowKeys" @batchDelete="deleteBatchMajor" />
+				</a-space>
+			</template>
+			<template #bodyCell="{ column, record }">
+				<template v-if="column.dataIndex === 'action'">
+					<a-space>
+						<a @click="formRef.onOpen(record)">编辑</a>
+						<a-divider type="vertical" />
+						<a-popconfirm title="确定要删除吗?" @confirm="deleteMajor(record)">
+							<a-button type="link" danger size="small">删除</a-button>
+						</a-popconfirm>
+					</a-space>
+				</template>
+			</template>
+		</s-table>
+	</a-card>
+	<Form ref="formRef" @successful="table.refresh(true)" />
+</template>
+
+<script setup name="major">
+	import Form from './form.vue'
+	import majorApi from '@/api/course/majorApi'
+	const table = ref()
+	const formRef = ref()
+	const toolConfig = { refresh: true, height: true, columnSetting: true, striped: false }
+	const columns = [
+		{
+			title: '院系名称',
+			dataIndex: 'majorName'
+		},
+		{
+			title: '院系编码',
+			dataIndex: 'majorCode'
+		},
+		{
+			title: '学院id',
+			dataIndex: 'collegeId'
+		},
+		{
+			title: '操作',
+			dataIndex: 'action',
+			align: 'center',
+			width: '150px'
+		}
+	]
+	// // 操作栏通过权限判断是否显示
+	// if (hasPerm(['majorEdit', 'majorDelete'])) {
+	// 	columns.push({
+	// 		title: '操作',
+	// 		dataIndex: 'action',
+	// 		align: 'center',
+	// 		width: '150px'
+	// 	})
+	// }
+	const selectedRowKeys = ref([])
+	// 列表选择配置
+	const options = {
+		// columns数字类型字段加入 needTotal: true 可以勾选自动算账
+		alert: {
+			show: true,
+			clear: () => {
+				selectedRowKeys.value = ref([])
+			}
+		},
+		rowSelection: {
+			onChange: (selectedRowKey, selectedRows) => {
+				selectedRowKeys.value = selectedRowKey
+			}
+		}
+	}
+	const loadData = (parameter) => {
+		return majorApi.majorPage(parameter).then((data) => {
+			return data
+		})
+	}
+	// 重置
+	const reset = () => {
+		searchFormRef.value.resetFields()
+		table.value.refresh(true)
+	}
+	// 删除
+	const deleteMajor = (record) => {
+		let params = [
+			{
+				id: record.id
+			}
+		]
+		majorApi.majorDelete(params).then(() => {
+			table.value.refresh(true)
+		})
+	}
+	// 批量删除
+	const deleteBatchMajor = (params) => {
+		majorApi.majorDelete(params).then(() => {
+			table.value.clearRefreshSelected()
+		})
+	}
+</script>

+ 76 - 0
src/views/course/resource_file_format/form.vue

@@ -0,0 +1,76 @@
+<template>
+	<xn-form-container
+		:title="formData.id ? '编辑resource_file_format' : '增加resource_file_format'"
+		:width="700"
+		:visible="visible"
+		:destroy-on-close="true"
+		@close="onClose"
+	>
+		<a-form ref="formRef" :model="formData" :rules="formRules" layout="vertical">
+			<a-form-item label="FILE_EXTEND_NAME:" name="fileExtendName">
+				<a-input v-model:value="formData.fileExtendName" placeholder="请输入FILE_EXTEND_NAME" allow-clear />
+			</a-form-item>
+			<a-form-item label="FILE_TYPE_ID:" name="fileTypeId">
+				<a-input v-model:value="formData.fileTypeId" placeholder="请输入FILE_TYPE_ID" allow-clear />
+			</a-form-item>
+			<a-form-item label="FUNCTION_TYPE:" name="functionType">
+				<a-input v-model:value="formData.functionType" placeholder="请输入FUNCTION_TYPE" allow-clear />
+			</a-form-item>
+		</a-form>
+		<template #footer>
+			<a-button style="margin-right: 8px" @click="onClose">关闭</a-button>
+			<a-button type="primary" @click="onSubmit" :loading="submitLoading">保存</a-button>
+		</template>
+	</xn-form-container>
+</template>
+
+<script setup name="resourceFileFormatForm">
+	import { cloneDeep } from 'lodash-es'
+	import { required } from '@/utils/formRules'
+	import resourceFileFormatApi from '@/api/course/resourceFileFormatApi'
+	// 抽屉状态
+	const visible = ref(false)
+	const emit = defineEmits({ successful: null })
+	const formRef = ref()
+	// 表单数据
+	const formData = ref({})
+	const submitLoading = ref(false)
+
+	// 打开抽屉
+	const onOpen = (record) => {
+		visible.value = true
+		if (record) {
+			let recordData = cloneDeep(record)
+			formData.value = Object.assign({}, recordData)
+		}
+	}
+	// 关闭抽屉
+	const onClose = () => {
+		formRef.value.resetFields()
+		formData.value = {}
+		visible.value = false
+	}
+	// 默认要校验的
+	const formRules = {
+	}
+	// 验证并提交数据
+	const onSubmit = () => {
+		formRef.value.validate().then(() => {
+			submitLoading.value = true
+			const formDataParam = cloneDeep(formData.value)
+			resourceFileFormatApi
+				.resourceFileFormatSubmitForm(formDataParam, formDataParam.id)
+				.then(() => {
+					onClose()
+					emit('successful')
+				})
+				.finally(() => {
+					submitLoading.value = false
+				})
+		})
+	}
+	// 抛出函数
+	defineExpose({
+		onOpen
+	})
+</script>

+ 116 - 0
src/views/course/resource_file_format/index.vue

@@ -0,0 +1,116 @@
+<template>
+	<a-card :bordered="false">
+		<s-table
+			ref="table"
+			:columns="columns"
+			:data="loadData"
+			:alert="options.alert.show"
+			bordered
+			:row-key="(record) => record.id"
+			:tool-config="toolConfig"
+			:row-selection="options.rowSelection"
+		>
+			<template #operator class="table-operator">
+				<a-space>
+					<a-button type="primary" @click="formRef.onOpen()" >
+						<template #icon><plus-outlined /></template>
+						新增
+					</a-button>
+					<xn-batch-delete :selectedRowKeys="selectedRowKeys" @batchDelete="deleteBatchResourceFileFormat" />
+				</a-space>
+			</template>
+			<template #bodyCell="{ column, record }">
+				<template v-if="column.dataIndex === 'action'">
+					<a-space>
+						<a @click="formRef.onOpen(record)">编辑</a>
+						<a-divider type="vertical" />
+						<a-popconfirm title="确定要删除吗?" @confirm="deleteResourceFileFormat(record)">
+							<a-button type="link" danger size="small">删除</a-button>
+						</a-popconfirm>
+					</a-space>
+				</template>
+			</template>
+		</s-table>
+	</a-card>
+	<Form ref="formRef" @successful="table.refresh(true)" />
+</template>
+
+<script setup name="fileformat">
+	import Form from './form.vue'
+	import resourceFileFormatApi from '@/api/course/resourceFileFormatApi'
+	const table = ref()
+	const formRef = ref()
+	const toolConfig = { refresh: true, height: true, columnSetting: true, striped: false }
+	const columns = [
+		{
+			title: 'FILE_EXTEND_NAME',
+			dataIndex: 'fileExtendName'
+		},
+		{
+			title: 'FILE_TYPE_ID',
+			dataIndex: 'fileTypeId'
+		},
+		{
+			title: 'FUNCTION_TYPE',
+			dataIndex: 'functionType'
+		},
+		{
+			title: '操作',
+			dataIndex: 'action',
+			align: 'center',
+			width: '150px'
+		}
+	]
+	// // 操作栏通过权限判断是否显示
+	// if (hasPerm(['resourceFileFormatEdit', 'resourceFileFormatDelete'])) {
+	// 	columns.push({
+	// 		title: '操作',
+	// 		dataIndex: 'action',
+	// 		align: 'center',
+	// 		width: '150px'
+	// 	})
+	// }
+	const selectedRowKeys = ref([])
+	// 列表选择配置
+	const options = {
+		// columns数字类型字段加入 needTotal: true 可以勾选自动算账
+		alert: {
+			show: true,
+			clear: () => {
+				selectedRowKeys.value = ref([])
+			}
+		},
+		rowSelection: {
+			onChange: (selectedRowKey, selectedRows) => {
+				selectedRowKeys.value = selectedRowKey
+			}
+		}
+	}
+	const loadData = (parameter) => {
+		return resourceFileFormatApi.resourceFileFormatPage(parameter).then((data) => {
+			return data
+		})
+	}
+	// 重置
+	const reset = () => {
+		searchFormRef.value.resetFields()
+		table.value.refresh(true)
+	}
+	// 删除
+	const deleteResourceFileFormat = (record) => {
+		let params = [
+			{
+				id: record.id
+			}
+		]
+		resourceFileFormatApi.resourceFileFormatDelete(params).then(() => {
+			table.value.refresh(true)
+		})
+	}
+	// 批量删除
+	const deleteBatchResourceFileFormat = (params) => {
+		resourceFileFormatApi.resourceFileFormatDelete(params).then(() => {
+			table.value.clearRefreshSelected()
+		})
+	}
+</script>

+ 4 - 4
src/views/myResource/file/box/uploadFile/Box.vue

@@ -30,7 +30,6 @@
 				<DeleteOutlined class="delete-icon" v-show="pasteImg.src" @click="handleDeletePasteImg" />
 				<CloseCircleOutlined class="close-icon" @click="dropBoxShow = false" />
 			</uploader-drop>
-
 			<!-- 上传列表 -->
 			<uploader-list v-show="panelShow">
 				<template #default="props">
@@ -76,7 +75,7 @@
 </template>
 
 <script setup>
-	import { ref, computed, defineExpose, nextTick, inject, getCurrentInstance } from 'vue'
+	import { ref, computed, defineExpose, nextTick, inject, getCurrentInstance, onMounted } from 'vue'
 	import { message } from 'ant-design-vue'
 	import { useMyResourceStore } from '@/store/myResource'
 	import SparkMD5 from 'spark-md5'
@@ -127,7 +126,8 @@
 	})
 
 	const options = ref({
-		target: `${proxy.$RESOURCE_CONFIG.baseContext}/filetransfer/uploadfile`,
+		// target: `${proxy.$RESOURCE_CONFIG.baseContext}/filetransfer/uploadfile`,
+		target: `${proxy.$RESOURCE_CONFIG.baseContext}/resourceFile/uploadfile`,
 		chunkSize: 1024 * 1024,
 		fileParameterName: 'file',
 		maxChunkRetries: 3,
@@ -252,6 +252,7 @@
 	}
 
 	const handleFilesAdded = (filesSource) => {
+		console.log('filesSource.filesSource', filesSource)
 		// const inconformityFileArr = []
 		// const files = filesSource.filter((file) => {
 		// 	const isFile = isImageOrDocument(file)
@@ -404,7 +405,6 @@
 		const fileSize = file.size
 		return (isImage || isDocument) && fileSize !== 0
 	}
-
 	// 暴露方法给父组件
 	defineExpose({
 		handlePrepareUpload

+ 128 - 38
src/views/myResources/auditModal.vue

@@ -1,79 +1,169 @@
-<!-- auditModal.vue -->
 <template>
-	<a-modal v-model:visible="visibles" title="资源审核" @ok="handleOk" @cancel="handleCancel">
-		<div class="audit-content">
-			<video-player v-if="record.suffix === 'mp4'" :options="playerOptions" @ready="playerReadied"></video-player>
-			<!-- 其他格式文件的展示方式 -->
-			<div v-else-if="record.suffix === 'ppt'">PPT展示区域</div>
-			<div v-else-if="record.suffix === 'word'">Word展示区域</div>
-			<div v-else-if="record.suffix === 'pdf'">PDF展示区域</div>
-			<div v-else>其他格式文件展示区域</div>
+	<a-modal v-model:visible="visibles" title="资源信息" @cancel="handleCancel" :footer="null" width="800px">
+		<div class="audit-container">
+			<!-- 左侧 - 文件展示区域 -->
+			<div class="file-preview">
+				<video-player v-if="recordData.suffix === 'mp4'" :options="playerOptions" @ready="playerReadied"></video-player>
+				<div v-else-if="recordData.suffix === 'ppt'" class="preview-placeholder">
+					<file-ppt-filled style="font-size: 48px; color: #d24638" />
+					<p>PPT文件预览</p>
+				</div>
+				<div v-else-if="recordData.suffix === 'word'" class="preview-placeholder">
+					<file-word-filled style="font-size: 48px; color: #2b579a" />
+					<p>Word文件预览</p>
+				</div>
+				<div v-else-if="recordData.suffix === 'pdf'" class="preview-placeholder">
+					<file-pdf-filled style="font-size: 48px; color: #f40f02" />
+					<p>PDF文件预览</p>
+				</div>
+				<div v-else class="preview-placeholder">
+					<file-unknown-filled style="font-size: 48px; color: #999" />
+					<p>文件预览</p>
+				</div>
+			</div>
 
+			<!-- 右侧 - 审核信息区域 -->
 			<div class="audit-info">
-				<p><strong>授课老师:</strong>{{ record.teacherName }}</p>
-				<p><strong>所属院系:</strong>{{ record.collegeName }}</p>
-				<p><strong>所属专业:</strong>{{ record.majorName }}</p>
-				<p><strong>课程类型:</strong>{{ record.courseType }}</p>
-				<p><strong>课件格式:</strong>{{ record.suffix }}</p>
-				<p><strong>视频时长:</strong>{{ record.duration }}</p>
-				<p><strong>视频大小:</strong>{{ record.fileSize }}</p>
-				<p><strong>发布时间:</strong>{{ record.publishTime }}</p>
-				<p><strong>课程介绍:</strong>{{ record.courseDescription }}</p>
+				<div class="info-section">
+					<p><strong>上传人:</strong>{{ detailData.resourceCreaterUserName || '--' }}</p>
+					<p><strong>所属院系:</strong>{{ detailData?.collegeAllIdName || '--' }}</p>
+					<p><strong>所属专业:</strong>{{ detailData?.majorIdName || '--' }}</p>
+					<p><strong>课程类型:</strong>{{ detailData?.courseTypeName || '--' }}</p>
+					<p><strong>课件格式:</strong>{{ detailData?.suffix || '--' }}</p>
+					<p><strong>视频时长:</strong>{{ detailData?.duration || '--' }}</p>
+					<p><strong>视频大小:</strong>{{ detailData?.FILESIZE || '--' }}<span v-if="detailData?.FILESIZE">b</span></p>
+					<p><strong>发布时间:</strong>{{ detailData?.uploadTime || '--' }}</p>
+					<p><strong>课程介绍:</strong>{{ detailData?.resourceDesc || '--' }}</p>
+				</div>
 			</div>
-
-			<a-radio-group v-model:value="auditResult">
-				<a-radio :value="1">通过</a-radio>
-				<a-radio :value="0">不通过</a-radio>
-			</a-radio-group>
+		</div>
+		<div style="display: flex; justify-content: flex-end; margin-top: 10px" v-if="isAudit">
+			<a-button @click="handleAuditResult(3)" style="margin-right: 10px">不同意</a-button>
+			<a-button type="primary" @click="handleAuditResult(2)">同意</a-button>
 		</div>
 	</a-modal>
 </template>
 
 <script setup>
 	import { ref, defineProps, defineEmits, computed } from 'vue'
+	import resourceAuditApi from '@/api/resourceAudit.js'
 	// import videoPlayer from 'vue-video-player'
-
 	const props = defineProps({
-		record: Object
+		recordData: {
+			type: Object,
+			required: true,
+			default: null
+		},
+		//是否是审核
+		isAudit: {
+			type: Boolean,
+			required: true,
+			default: false
+		}
 	})
 
-	const emit = defineEmits(['confirm'])
+	const emit = defineEmits(['confirm', 'close'])
 
 	const auditResult = ref(1) // 默认为通过
+	const detailData = ref({})
 	const visibles = ref(true)
 
 	const playerOptions = computed(() => ({
 		sources: [
 			{
 				type: 'video/mp4',
-				src: props.record.filePath // 视频文件路径
+				src: props.recordData.filePath // 视频文件路径
 			}
 		],
-		poster: props.record.posterPath // 封面图片路径
+		poster: props.recordData.posterPath // 封面图片路径
 	}))
-
-	const handleOk = () => {
-		emit('confirm', { ...props.record, auditResult: auditResult.value })
-	}
-
 	const handleCancel = () => {
-		emit('update:visible', false)
+		emit('close')
+	}
+	const handleAuditResult = (val) => {
+		auditResult.value = val
+		emit('confirm', { ...props.recordData, auditResult: auditResult.value })
 	}
 
 	const playerReadied = (player) => {
 		// player ready
 	}
+	// 获取资源详情
+	const getDetail = () => {
+		resourceAuditApi.detail({ id: props.recordData.id }).then((res) => {
+			console.log(res.data, '资源详情')
+			detailData.value = res.data
+		})
+	}
+	onMounted(() => {
+		getDetail()
+	})
 </script>
-
 <style scoped>
-	.audit-content {
+	.audit-container {
+		display: flex;
+		gap: 20px;
+		height: 500px;
+		border-bottom: 1px solid #ccc;
+		padding-bottom: 10px;
+	}
+
+	.file-preview {
+		flex: 1;
+		display: flex;
+		justify-content: center;
+		align-items: center;
+		background-color: #f5f5f5;
+		border-radius: 4px;
+		overflow: hidden;
+	}
+
+	.preview-placeholder {
 		display: flex;
 		flex-direction: column;
 		align-items: center;
+		gap: 10px;
+		color: #666;
 	}
 
 	.audit-info {
-		margin-top: 20px;
-		text-align: left;
+		flex: 1;
+		display: flex;
+		flex-direction: column;
+		gap: 20px;
+	}
+
+	.info-section {
+		background: #fff;
+		border-radius: 4px;
+	}
+
+	.info-section h4 {
+		margin-bottom: 12px;
+		font-size: 16px;
+		color: #333;
+	}
+
+	.description-box {
+		padding: 12px;
+		border: 1px solid #d9d9d9;
+		border-radius: 4px;
+		max-height: 150px;
+		overflow-y: auto;
+	}
+
+	.audit-action {
+		margin-top: auto;
+		padding-top: 20px;
+		border-top: 1px dashed #d9d9d9;
+	}
+
+	/* 调整描述列表样式 */
+	:deep(.ant-descriptions-item-label) {
+		width: 100px;
+		font-weight: normal;
+	}
+	.ant-modal-footer {
+		display: none !important; /* 检查是否被覆盖 */
 	}
 </style>

+ 86 - 29
src/views/myResources/myResources.vue

@@ -2,16 +2,15 @@
 	<a-card>
 		<!-- 标签页 -->
 		<a-tabs v-model:activeKey="formState.verifyStatus" @change="tabChange">
-			<a-tab-pane key="0" tab="未发布" v-if="pageType !== 'economize'"></a-tab-pane>
+			<a-tab-pane key="0" tab="未发布" v-if="!pageType"></a-tab-pane>
 			<a-tab-pane key="1" tab="待审核"></a-tab-pane>
-			<a-tab-pane key="2" tab="已发布" v-if="pageType !== 'economize'"></a-tab-pane>
-			<a-tab-pane key="3" tab="已审核" v-if="pageType == 'economize'"></a-tab-pane>
+			<a-tab-pane key="2" tab="已发布" v-if="!pageType"></a-tab-pane>
+			<!-- <a-tab-pane key="3" tab="已审核" v-if="pageType == 'economize'"></a-tab-pane> -->
 			<a-tab-pane key="4" tab="回收站"></a-tab-pane>
 		</a-tabs>
-
 		<!-- 搜索和操作区域 -->
 		<a-row :gutter="16" style="margin-bottom: 16px">
-			<a-col :span="16">
+			<a-col :span="18">
 				<a-input v-model:value="formState.fileName" placeholder="请输入资源名称" style="width: 200px" />
 				<a-cascader
 					style="width: 200px; margin-left: 8px"
@@ -26,7 +25,7 @@
 					v-model:value="formState.courseTypeName"
 					style="width: 200px; margin-left: 8px"
 					:options="courseTypeOptions"
-					placeholder="请选择课程类型"
+					placeholder="请选择资源类型"
 				/>
 				<a-select v-model:value="formState.suffix" placeholder="课件格式" style="width: 200px; margin-left: 8px">
 					<a-select-option value="mp4">mp4</a-select-option>
@@ -34,10 +33,16 @@
 					<a-select-option value="word">word</a-select-option>
 					<a-select-option value="pdf">pdf</a-select-option>
 				</a-select>
+				<!-- <a-select
+					v-model:value="formState.suffix"
+					style="width: 200px; margin-left: 8px"
+					:options="suffixTypeOptions"
+					placeholder="请选择课件格式"
+				/> -->
 				<a-button type="primary" style="margin-left: 8px" @click="handleSearch">查询</a-button>
 				<a-button style="margin-left: 8px" @click="handleReset">重置</a-button>
 			</a-col>
-			<a-col :span="8" style="text-align: right">
+			<a-col :span="6" style="text-align: right">
 				<a-button
 					type="primary"
 					style="margin-right: 8px"
@@ -92,7 +97,7 @@
 				<!-- 操作列 -->
 				<template v-else-if="column.key === 'action'">
 					<div class="editable-cell">
-						<a v-if="formState.verifyStatus === '0' && pageType !== 'economize'" @click="handlePublish(record)">发布</a>
+						<a v-if="formState.verifyStatus === '0' && !pageType" @click="handlePublish(record)">发布</a>
 						<a v-if="formState.verifyStatus === '1' && pageType == 'economize'" @click="handleAudit(record)">审核</a>
 						<a v-if="formState.verifyStatus === '2' && pageType == 'economize'" @click="handlePermission(record)"
 							>权限</a
@@ -107,7 +112,7 @@
 							<template #overlay>
 								<a-menu>
 									<a-menu-item>
-										<a href="javascript:;">播放</a>
+										<a href="javascript:;" @click="handleView(record)">播放</a>
 									</a-menu-item>
 									<a-menu-item>
 										<a href="javascript:;">下载</a>
@@ -119,7 +124,6 @@
 										<a-popconfirm title="确认删除吗?" @confirm="resourcesDelete(record)">
 											<a href="javascript:;">删除</a>
 										</a-popconfirm>
-
 									</a-menu-item>
 								</a-menu>
 							</template>
@@ -146,7 +150,16 @@
 				/>
 			</div>
 		</div>
-
+		<!-- 权限树模态框 -->
+		<permissionTree v-if="permissionTreeVisible" @close="permissionTreeVisible = false"></permissionTree>
+		<!-- 审核播放模态框 -->
+		<auditModal
+			v-if="auditModalVisible"
+			:recordData="publishedData"
+			:isAudit="auditState"
+			@confirm="auditConfirm"
+			@close="auditModalVisible = false"
+		></auditModal>
 		<!-- 资源上传模态框 -->
 		<resourceUpload
 			v-if="uploadModalVisible"
@@ -166,6 +179,8 @@
 	import releaseModal from './releaseModal.vue'
 	import resourceUpload from './resourceUpload.vue'
 	import resourceAuditApi from '@/api/resourceAudit.js'
+	import permissionTree from './permissionTree.vue'
+	import auditModal from './auditModal.vue'
 	import CustomPagination from '@/components/customPagination.vue'
 	import tool from '@/utils/tool'
 	// eslint-disable-next-line vue/no-setup-props-destructure
@@ -179,6 +194,8 @@
 	const dataSource = ref([])
 	//发布按钮状态
 	const releaseVisible = ref(false)
+	const permissionTreeVisible = ref(false) //权限树
+	const auditModalVisible = ref(false) //播放审核
 	const isPublishBulk = ref(false) //是否批量发布
 	const loading = ref(false) // 列表loading
 	const isState = ref(0) //是否是编辑  0:新增 1:编辑
@@ -187,6 +204,7 @@
 	const searchValue = ref('')
 	//课程类型
 	const courseTypeOptions = tool.dictList('COURSE_TYPE')
+	const suffixTypeOptions = ref([])
 	const pagination = reactive({
 		pageSize: 10,
 		pageNum: 1,
@@ -203,6 +221,7 @@
 	// 添加选择状态
 	const selectedRowKeys = ref([])
 	const selectedRows = ref([])
+	const publishedData = ref([]) //当前点击数据
 	// 行选择配置
 	const rowSelection = computed(() => {
 		return {
@@ -290,29 +309,29 @@
 		{
 			title: '所属院系',
 			align: 'center',
-			dataIndex: 'collegeIdName',
-			key: 'collegeIdName'
-		},
-		{
-			title: '所属课程',
-			align: 'center',
-			dataIndex: 'collegeIdName',
-			key: 'collegeIdName'
-		},
-		{
-			title: '所属专业',
-			align: 'center',
-			dataIndex: 'majorIdName',
-			key: 'majorIdName'
+			dataIndex: 'collegeAllIdName',
+			key: 'collegeAllIdName'
 		},
+		// {
+		// 	title: '所属课程',
+		// 	align: 'center',
+		// 	dataIndex: 'collegeIdName',
+		// 	key: 'collegeIdName'
+		// },
+		// {
+		// 	title: '所属专业',
+		// 	align: 'center',
+		// 	dataIndex: 'majorIdName',
+		// 	key: 'majorIdName'
+		// },
 		{
-			title: '课程类型',
+			title: '资源类型',
 			align: 'center',
 			dataIndex: 'courseTypeName',
 			key: 'courseTypeName'
 		},
 		{
-			title: '课件格式',
+			title: '资源格式',
 			align: 'center',
 			dataIndex: 'suffix',
 			key: 'suffix'
@@ -418,7 +437,6 @@
 		dataSource.value = []
 		getListData()
 	}
-	const publishedData = ref(null) //当前点击数据
 	//发布
 	const handlePublish = (record) => {
 		publishedData.value = record
@@ -490,19 +508,58 @@
 				console.error(err)
 			})
 	}
+	const auditState = ref(null)
 	const handleAudit = (record) => {
 		console.log('Audit:', record)
+		publishedData.value = record
+		auditState.value = true
+		auditModalVisible.value = true
+	}
+	const handleView = (record) => {
+		publishedData.value = record
+		auditState.value = false
+		auditModalVisible.value = true
 	}
 
 	const handlePermission = (record) => {
 		console.log('Permission:', record)
+		permissionTreeVisible.value = true
+	}
+	const auditConfirm = (obj) => {
+		console.log('auditConfirm:', obj)
+		const params = {
+			ids: obj.id,
+			verifyStatus: obj.auditResult
+		}
+		resourceAuditApi
+			.updateStatus(params)
+			.then((res) => {
+				if (res.code == 200) {
+					auditModalVisible.value = false
+				}
+				getListData()
+			})
+			.catch((err) => {
+				console.error(err)
+			})
 	}
 
 	const handleDelete = (record) => {
 		console.log('Delete:', record)
 	}
 	const handleRestore = (record) => {
-		console.log('Restore:', record)
+		const params = {
+			ids: record.id,
+			verifyStatus: 1
+		}
+		resourceAuditApi
+			.updateStatus(params)
+			.then((res) => {
+				getListData()
+			})
+			.catch((err) => {
+				console.error(err)
+			})
 	}
 	//资源编辑
 	const edit = (record) => {

+ 245 - 0
src/views/myResources/permissionTree.vue

@@ -0,0 +1,245 @@
+<template>
+	<a-drawer
+		v-model:visible="visible"
+		title="选择组织"
+		placement="right"
+		width="50%"
+		:footer="null"
+		@close="handleCancel"
+	>
+		<!-- 左侧:树状结构成员列表 -->
+		<div class="left-panel">
+			<a-input-search
+				v-model:value="searchValue"
+				placeholder="输入组织名称"
+				style="margin-bottom: 16px"
+				@search="onSearch"
+			/>
+			<div style="padding: 15px"><InsertRowRightOutlined style="margin-right: 8px; color: #1890ff" />组织架构</div>
+			<a-tree
+				:tree-data="filteredTreeData"
+				:field-names="{ key: 'id', title: 'name', children: 'children' }"
+				:checked-keys="checkedKeys"
+				:expanded-keys="expandedKeys"
+				:auto-expand-parent="autoExpandParent"
+				checkable
+				show-icon
+				:selectable="false"
+				@check="onCheck"
+				@expand="onExpand"
+			>
+				<template #title="{ name }">
+					<span style="display: inline-flex; align-items: center">
+						<HomeOutlined style="margin-right: 8px; color: #1890ff" />
+						{{ name }}
+					</span>
+				</template>
+				<template #switcherIcon="{ expanded }">
+					<caret-down-outlined v-if="expanded" />
+					<caret-right-outlined v-else />
+				</template>
+			</a-tree>
+		</div>
+
+		<!-- 右侧:已选择成员列表 -->
+		<div class="right-panel">
+			<div class="header">
+				<span>已选 {{ selectedUsers.length }} / 30</span>
+				<a-button type="link" @click="clearSelection">清空</a-button>
+			</div>
+			<a-list item-layout="horizontal" :data-source="selectedUsers">
+				<template #renderItem="{ item }">
+					<a-list-item>
+						<a-list-item-meta>
+							<!-- <template #avatar>
+								<a-avatar :src="item.avatar" />
+							</template> -->
+							<template #title>
+								<a>{{ item.name }}</a>
+							</template>
+							<template #description>
+								<span>{{ item.department }}</span>
+							</template>
+						</a-list-item-meta>
+						<template #actions>
+							<a @click="removeUser(item)">删除</a>
+						</template>
+					</a-list-item>
+				</template>
+			</a-list>
+		</div>
+
+		<!-- 底部按钮 -->
+		<template #footer>
+			<a-space>
+				<a-button @click="handleCancel">取消</a-button>
+				<a-button type="primary" @click="handleOk">确定</a-button>
+			</a-space>
+		</template>
+	</a-drawer>
+</template>
+
+<script setup>
+	import { ref, reactive, computed, watch } from 'vue'
+	// import { HomeOutlined } from 'ant-design-vue'
+	const emit = defineEmits(['close', 'confirm'])
+	const visible = ref(true)
+	const searchValue = ref('')
+	const treeData = ref([
+		{
+			id: '1',
+			name: '一级组织1',
+			children: [
+				{
+					id: '1-1',
+					name: '二级组织1',
+					// avatar: 'https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png',
+					isLeaf: true
+				},
+				{
+					id: '1-2',
+					name: '二级组织2',
+					// avatar: 'https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png',
+					isLeaf: true
+				}
+			]
+		},
+		{
+			id: '2',
+			name: '一级组织2',
+			children: [
+				{
+					id: '2-1',
+					name: '二级组织1',
+					children: [
+						{
+							id: '2-1-1',
+							name: '三级组织1',
+							// avatar: 'https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png',
+							isLeaf: true
+						}
+					]
+				}
+			]
+		}
+	])
+	const selectedKeys = ref([])
+	const selectedUsers = ref([])
+	const checkedKeys = ref([])
+	const expandedKeys = ref(['1']) // 默认展开第一层
+	const autoExpandParent = ref(true)
+	const filteredTreeData = computed(() => {
+		const filterFn = (node) => {
+			if (node.name.includes(searchValue.value)) {
+				return true
+			}
+			if (node.children && node.children.some(filterFn)) {
+				return true
+			}
+			return false
+		}
+		return treeData.value.filter(filterFn)
+	})
+
+	// 替换原来的onSelect方法
+	const onCheck = (checkedKeysValue, { checked, node, checkedNodes }) => {
+		checkedKeys.value = checkedKeysValue
+		selectedUsers.value = checkedNodes.map((node) => ({
+			id: node.id,
+			name: node.name,
+			avatar: node.avatar || '',
+			department: findDepartmentName(node.id, treeData.value)
+		}))
+	}
+	// 查找部门名称的辅助函数
+	const findDepartmentName = (id, nodes) => {
+		// 如果是顶级节点,返回空字符串
+		if (nodes.some((node) => node.id === id)) return ''
+		for (const node of nodes) {
+			if (node.children) {
+				const found = node.children.find((child) => child.id === id)
+				if (found) return node.name
+				const result = findDepartmentName(id, node.children)
+				if (result) return result
+			}
+		}
+		return ''
+	}
+	const onExpand = (keys) => {
+		expandedKeys.value = keys
+		autoExpandParent.value = false
+	}
+
+	const onSearch = (value) => {
+		searchValue.value = value
+	}
+
+	const clearSelection = () => {
+		selectedKeys.value = []
+		selectedUsers.value = []
+		checkedKeys.value = []
+	}
+
+	const removeUser = (user) => {
+		const index = selectedUsers.value.findIndex((u) => u.id === user.id)
+		if (index !== -1) {
+			selectedUsers.value.splice(index, 1)
+			selectedKeys.value = selectedUsers.value.map((u) => u.id)
+			checkedKeys.value = selectedUsers.value.map((u) => u.id)
+		}
+		// selectedUsers.value = selectedUsers.value.filter((u) => u.id !== user.id)
+		// checkedKeys.value = selectedUsers.value.map((u) => u.id)
+	}
+
+	const showModal = () => {
+		visible.value = true
+	}
+
+	const handleOk = () => {
+		console.log('Selected Users:', selectedUsers.value)
+	}
+
+	const handleCancel = () => {
+		emit('close')
+	}
+</script>
+
+<style scoped>
+	.left-panel,
+	.right-panel {
+		display: inline-block;
+		vertical-align: top;
+		width: 48%;
+		height: calc(100vh - 200px);
+		overflow-y: auto;
+		padding: 0 10px;
+	}
+
+	.right-panel {
+		border-left: 1px solid #f0f0f0;
+	}
+
+	.header {
+		display: flex;
+		justify-content: space-between;
+		margin-bottom: 16px;
+	}
+
+	.ant-tree-switcher {
+		width: 24px;
+		height: 24px;
+		line-height: 24px;
+	}
+
+	.ant-tree-switcher-icon {
+		font-size: 12px;
+		transition: transform 0.3s;
+	}
+
+	.ant-tree-switcher_close .ant-tree-switcher-icon {
+		transform: rotate(-90deg);
+	}
+	.ant-tree-checkbox + .ant-tree-switcher {
+		margin-left: 8px;
+	}
+</style>

+ 190 - 56
src/views/myResources/resourceUpload.vue

@@ -7,10 +7,10 @@
 		@cancel="handleUploadCancel"
 		width="600px"
 	>
-		<a-form :model="formState">
-			<a-form-item label="院系" :label-col="{ span: 6 }" :wrapper-col="{ span: 18 }">
+		<a-form :model="formState" :rules="rules" ref="formRef">
+			<a-form-item label="院系" name="collegeId" :label-col="{ span: 6 }" :wrapper-col="{ span: 18 }">
 				<a-cascader
-					v-model:value="formState.majorIdName"
+					v-model:value="majorIdName"
 					:options="collegeMajorOptions"
 					:fieldNames="{ label: 'name', value: 'id', children: 'children' }"
 					placeholder="请选择院系"
@@ -19,7 +19,7 @@
 					@change="changeCollegeMajor"
 				/>
 			</a-form-item>
-			<a-form-item label="专业" :label-col="{ span: 6 }" :wrapper-col="{ span: 18 }">
+			<a-form-item label="专业" name="majorId" :label-col="{ span: 6 }" :wrapper-col="{ span: 18 }">
 				<a-select
 					v-model:value="formState.majorId"
 					style="width: 200px"
@@ -37,7 +37,7 @@
 					placeholder="请选择课程"
 				/>
 			</a-form-item> -->
-			<a-form-item label="资源类型" :label-col="{ span: 6 }" :wrapper-col="{ span: 18 }">
+			<a-form-item label="资源类型" name="courseType" :label-col="{ span: 6 }" :wrapper-col="{ span: 18 }">
 				<a-select
 					v-model:value="formState.courseType"
 					style="width: 200px"
@@ -45,7 +45,12 @@
 					placeholder="请选择资源类型"
 				/>
 			</a-form-item>
-			<a-form-item label="关键词(需添加2-5个关键词)" :label-col="{ span: 8 }" :wrapper-col="{ span: 10 }">
+			<a-form-item
+				label="关键词(需添加2-5个关键词)"
+				name="keywordValue"
+				:label-col="{ span: 8 }"
+				:wrapper-col="{ span: 10 }"
+			>
 				<div v-if="!formState.keywordValue.length" style="color: #ccc">请选择下方热门关键词</div>
 				<div v-if="formState.keywordValue.length">
 					<a-tag
@@ -113,7 +118,7 @@
 			></userSelection>
 		</a-form>
 		<template v-if="isState == 0">
-			<a-upload
+			<!-- <a-upload
 				:multiple="true"
 				:before-upload="beforeUpload"
 				:headers="headers"
@@ -129,7 +134,6 @@
 					<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>
@@ -138,7 +142,19 @@
 					<span v-if="file.response?.code == '500'">上传失败</span>
 					<span v-if="file.status === 'uploading'">上传中...</span>
 				</li>
-			</ul>
+			</ul> -->
+			<div
+				class="upload-area"
+				@click="handleUploadFileBtnClick(1)"
+				@dragover.prevent="handleDragOver"
+				@dragleave.prevent="handleDragLeave"
+				@drop.prevent="handleDrop"
+			>
+				<a-icon type="cloud-upload" style="font-size: 60px; color: #3ca9f5" />
+				<p>点击上传</p>
+				<p>按住Ctrl可同时多选,支持上传PPT/word/excel/pdf/mp4/zip/rar,单个文件不能超过2G</p>
+			</div>
+			<uploadFile></uploadFile>
 		</template>
 	</a-modal>
 </template>
@@ -149,6 +165,78 @@
 	import resourceAuditApi from '@/api/resourceAudit.js'
 	import userSelection from './userSelection.vue'
 	import coverUpload from './coverUpload/index.vue'
+	import { useMyResourceStore } from '@/store/myResource'
+	import uploadFile from '@/views/myResource/file/box/uploadFile/Box.vue'
+	const myResourceStore = useMyResourceStore()
+	const { proxy } = getCurrentInstance()
+	import {
+		getFileListByPath,
+		getFileListByType,
+		getRecoveryFile,
+		getMyShareFileList,
+		searchFile
+	} from '@/api/myResource/file'
+	// 分页数据
+	const pageData = ref({
+		currentPage: 1,
+		pageCount: 50,
+		total: 0
+	})
+	const fileType = ref(0)
+	// 当前所在路径
+	const filePath = computed(() => {
+		// return route.query.filePath ? route.query.filePath : '/'
+		return myResourceStore.getQuery.filePath ? myResourceStore.getQuery.filePath : '/'
+	})
+	// 上传文件组件参数
+	const uploadFileParams = computed(() => {
+		return {
+			filePath: myResourceStore.getQuery.filePath ? myResourceStore.getQuery.filePath : '/',
+			isDir: 0,
+			funcType: 0
+		}
+	})
+	// 拖拽相关方法
+	const handleDragOver = (e) => {
+		e.preventDefault()
+		e.currentTarget.style.borderColor = '#1890ff' // 拖拽进入时高亮边框
+	}
+
+	const handleDragLeave = (e) => {
+		e.preventDefault()
+		e.currentTarget.style.borderColor = '#3ca9f5' // 拖拽离开时恢复边框
+	}
+
+	const handleDrop = (e) => {
+		e.preventDefault()
+		e.currentTarget.style.borderColor = '#3ca9f5' // 恢复边框颜色
+		const files = e.dataTransfer.files
+		if (files.length > 0) {
+			// 触发上传逻辑(与点击事件相同)
+			handleUploadFileBtnClick(1)
+			// 如果需要直接处理文件,可以在这里添加逻辑
+			console.log('拖拽的文件列表:', files)
+		}
+	}
+	const handleUploadFileBtnClick = async (uploadWay) => {
+		proxy.$openDialog.authWeChat().then((res) => {
+			switch (res) {
+				case 'confirm': {
+					// window.$common.goAccount('/settings/account')
+					break
+				}
+				case 'go': {
+					proxy.$openBox.uploadFile({
+						params: uploadFileParams.value,
+						uploadWay,
+						serviceEl: proxy, // 使用proxy替代this
+						callType: 1 //  callType 调用此服务的方式:1 - 顶部栏,2 - 右键菜单
+					})
+					break
+				}
+			}
+		})
+	}
 	const props = defineProps({
 		isState: {
 			type: Number,
@@ -170,23 +258,24 @@
 	const courseTypeOptions = tool.dictList('COURSE_TYPE')
 	const action = ref('http://192.168.31.80:9003/api/webapp/dev/file/uploadMinioReturnId')
 	const formState = reactive({
-		userfileIds: null, //资源文件id
+		userfileIds: '1234567', //资源文件id
 		coverImage: null, //封面id
 		// courseId: null, //课程
-		majorType: null, //专业
-		courseType: null, //课程类型
+		// majorType: null, //专业
+		courseType: null, //资源类型
 		collegeId: null, //院校一级id
 		collegeTwoId: null, //院校二级id
 		collegeThreeId: null, //院校三级id
 		resourceDesc: null, //资源介绍
 		majorId: null, //专业id
-		courseTypeName: [], // 资源类型
+		// courseTypeName: [], // 资源类型
 		keywordValue: [], // 添加关键词
 		keyword: [], // 热门关键词
-		publicStatus: 'public', // 资源是否公开
+		publicStatus: '0', // 资源是否公开
 		isRecommend: 0, // 资源是否推荐
 		isHot: 0 // 资源是否热门
 	})
+	const formRef = ref() // 添加表单引用
 	const collegeMajorOptions = ref([]) //院系
 	const HotKeywordsOptions = ref([]) //热门关键词列表
 	const majorIdName = ref([]) //院系回显
@@ -205,11 +294,30 @@
 		emit('close')
 		fileList.value = []
 	}
+	// 自定义校验函数示例
+	const validateKeywords = (rule, value, callback) => {
+		if (value.length < 2) {
+			callback(new Error('至少需要添加2个关键词'))
+		} else if (value.length > 5) {
+			callback(new Error('最多只能添加5个关键词'))
+		} else {
+			callback()
+		}
+	}
 	const rules = {
 		courseTypeName: [{ required: true, message: '请选择资源类型', trigger: 'change' }],
-		keywordValue: [{ required: true, message: '请添加关键词', trigger: 'blur' }]
+		collegeId: [{ required: true, message: '请选择院系', trigger: 'blur' }],
+		keywordValue: [
+			{ required: true, message: '请选择关键词', trigger: 'blur' },
+			{ validator: validateKeywords, trigger: 'blur' }
+		],
+		majorId: [{ required: true, message: '请选择专业', trigger: 'change' }],
+		courseType: [{ required: true, message: '请选择资源类型', trigger: 'change' }],
+		resourceDesc: [
+			{ required: true, message: '请输入资源描述', trigger: 'blur' },
+			{ pattern: /^[\s\S]{10,500}$/, message: '描述长度应在10-500字符之间', trigger: 'blur' }
+		]
 	}
-
 	const newKeyword = ref('') //关键词
 	const handleAddKeyword = (e) => {
 		const newKeywords = newKeyword.value.trim()
@@ -286,6 +394,7 @@
 	}
 	const changeCollegeMajor = (value, selectedOptions) => {
 		console.log('Selected:', value, selectedOptions)
+		majorIdName.value = selectedOptions.map((it) => it.name).join('/')
 		formState.collegeId = value[0] || null
 		formState.collegeTwoId = value[1] || null
 		formState.collegeThreeId = value[2] || null
@@ -298,53 +407,66 @@
 			// 	fullPath: selectedOptions.map((opt) => opt.name).join(' / ')
 			// }
 			console.log(lastSelected, '最后一级id')
-			resourceAuditApi
-				.zyselect({ id: lastSelected.id })
-				.then((res) => {
-					console.log(res.data, '专业下拉数据')
-					majorOptions.value = res.data
-				})
-				.catch((err) => {
-					console.log(err)
-				})
+			getCollegeMajor(lastSelected.id)
 		}
 	}
-	// 确认上传
-	const handleUploadOk = () => {
-		if (!formState.userfileIds) {
-			Modal.error({ content: '请先上传文件!' })
-			return
-		}
-
-		const formData = {
-			userfileIds: formState.userfileIds,
-			courseTypeName: formState.courseTypeName,
-			keywordValue: formState.keywordValue
-				.split(',')
-				.map((keyword) => keyword.trim())
-				.filter((keyword) => keyword),
-			keyword: formState.keyword,
-			publicStatus: formState.publicStatus
-		}
-
+	const getCollegeMajor = (id) => {
 		resourceAuditApi
-			.add(formData)
+			.zyselect({ collegeId: id })
 			.then((res) => {
-				emit('getList')
-				Modal.success({ content: '资源上传成功' })
+				console.log(res.data, '专业下拉数据')
+				majorOptions.value = res.data
 			})
 			.catch((err) => {
-				Modal.error({ content: '资源上传失败' })
 				console.log(err)
 			})
-			.finally(() => {
-				fileList.value = []
-				formState.userfileIds = null
-				formState.courseTypeName = ''
-				formState.keywordValue = ''
-				formState.hotKeywords = []
-				formState.publicStatus = 'public'
-			})
+	}
+	// 确认上传
+	const handleUploadOk = async () => {
+		try {
+			await formRef.value.validate()
+
+			if (!formState.userfileIds) {
+				Modal.error({ content: '请先上传文件!' })
+				return
+			}
+
+			const formData = {
+				id: props.resourcesId,
+				userfileIds: formState.userfileIds,
+				courseType: formState.courseType,
+				collegeId: formState.collegeId,
+				collegeTwoId: formState.collegeTwoId,
+				collegeThreeId: formState.collegeThreeId,
+				keywordValue: formState.keywordValue.join(', '),
+				keyword: formState.keyword.join(', '),
+				resourceDesc: formState.resourceDesc,
+				majorId: formState.majorId,
+				isHot: formState.isHot,
+				isRecommend: formState.isRecommend,
+				coverImage: formState.coverImage,
+				publicStatus: formState.publicStatus
+			}
+			resourceAuditApi
+				.add(formData)
+				.then((res) => {
+					emit('getList')
+					Modal.success({ content: '资源上传成功' })
+				})
+				.catch((err) => {
+					Modal.error({ content: '资源上传失败' })
+					console.log(err)
+				})
+		} catch (error) {
+			if (error.errorFields) {
+				// 表单验证错误
+				Modal.error({ content: '请检查表单填写是否正确' })
+			} else {
+				// API错误
+				Modal.error({ content: '资源上传失败' })
+				console.error(error)
+			}
+		}
 	}
 	// 获取资源详情
 	const getDetail = () => {
@@ -354,7 +476,8 @@
 			formState.collegeId = res.data.collegeId
 			formState.collegeTwoId = res.data.collegeTwoId
 			formState.collegeThreeId = res.data.collegeThreeId
-			majorIdName.value = [res.data.collegeId, res.data.collegeTwoId, res.data.collegeThreeId]
+			majorIdName.value = res.data.collegeAllId.split(',')
+			getCollegeMajor(majorIdName.value[majorIdName.value.length - 1])
 			formState.resourceDesc = res.data.resourceDesc
 			formState.majorId = res.data.majorId
 		})
@@ -461,4 +584,15 @@
 		color: #fff;
 		border-color: #40a9ff;
 	}
+	.upload-area {
+		border: 2px dashed #3ca9f5;
+		padding: 40px;
+		text-align: center;
+		transition: border-color 0.3s; /* 平滑过渡效果 */
+	}
+
+	.upload-area.drag-over {
+		border-color: #1890ff;
+		background-color: rgba(24, 144, 255, 0.05);
+	}
 </style>