|
|
@@ -1,71 +1,363 @@
|
|
|
<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
|
|
|
+ v-model:visible="uploadModalVisible"
|
|
|
+ :title="isState == 0 ? '上传资源' : '编辑'"
|
|
|
+ @ok="handleUploadOk"
|
|
|
+ @cancel="handleUploadCancel"
|
|
|
+ width="600px"
|
|
|
+ >
|
|
|
+ <a-form :model="formState">
|
|
|
+ <a-form-item label="院系" :label-col="{ span: 6 }" :wrapper-col="{ span: 18 }">
|
|
|
+ <a-cascader
|
|
|
+ v-model:value="formState.majorIdName"
|
|
|
+ :options="collegeMajorOptions"
|
|
|
+ :fieldNames="{ label: 'name', value: 'id', children: 'children' }"
|
|
|
+ placeholder="请选择院系"
|
|
|
+ style="width: 300px"
|
|
|
+ changeOnSelect
|
|
|
+ @change="changeCollegeMajor"
|
|
|
+ />
|
|
|
+ </a-form-item>
|
|
|
+ <a-form-item label="专业" :label-col="{ span: 6 }" :wrapper-col="{ span: 18 }">
|
|
|
+ <a-select
|
|
|
+ v-model:value="formState.majorId"
|
|
|
+ style="width: 200px"
|
|
|
+ :fieldNames="{ label: 'createUserName', value: 'popular' }"
|
|
|
+ :options="majorOptions"
|
|
|
+ placeholder="请选择专业"
|
|
|
+ />
|
|
|
+ </a-form-item>
|
|
|
+ <!-- <a-form-item label="课程" :label-col="{ span: 6 }" :wrapper-col="{ span: 18 }">
|
|
|
+ <a-select
|
|
|
+ v-model:value="formState.courseId"
|
|
|
+ style="width: 200px"
|
|
|
+ :fieldNames="{ label: 'courseName', value: 'courseId' }"
|
|
|
+ :options="courseOptions"
|
|
|
+ placeholder="请选择课程"
|
|
|
+ />
|
|
|
+ </a-form-item> -->
|
|
|
+ <a-form-item label="资源类型" :label-col="{ span: 6 }" :wrapper-col="{ span: 18 }">
|
|
|
+ <a-select
|
|
|
+ v-model:value="formState.courseType"
|
|
|
+ style="width: 200px"
|
|
|
+ :options="courseTypeOptions"
|
|
|
+ placeholder="请选择资源类型"
|
|
|
+ />
|
|
|
+ </a-form-item>
|
|
|
+ <a-form-item label="关键词(需添加2-5个关键词)" :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
|
|
|
+ v-for="(keyword, index) in formState.keywordValue"
|
|
|
+ :key="index"
|
|
|
+ closable
|
|
|
+ @close="handleRemoveKeyword(index)"
|
|
|
+ >
|
|
|
+ {{ keyword }}
|
|
|
+ </a-tag>
|
|
|
+ </div>
|
|
|
+ </a-form-item>
|
|
|
+ <a-form-item label="热门关键词" :label-col="{ span: 6 }" :wrapper-col="{ span: 18 }">
|
|
|
+ <a-checkbox-group
|
|
|
+ v-model:value="formState.keyword"
|
|
|
+ :options="HotKeywordsOptions"
|
|
|
+ @change="handleChangeKeyword"
|
|
|
+ />
|
|
|
+ </a-form-item>
|
|
|
+ <a-row>
|
|
|
+ <a-col :span="5"></a-col>
|
|
|
+ <a-col :span="8">
|
|
|
+ <a-input v-model:value="newKeyword" placeholder="请输入关键词" @pressEnter="handleAddKeyword" />
|
|
|
+ </a-col>
|
|
|
+ <a-col :span="9" style="line-height: 30px"> 按回车Enter创建新关键词 </a-col>
|
|
|
+ </a-row>
|
|
|
+ <a-form-item label="资源是否公开" style="margin-top: 10px" :label-col="{ span: 6 }" :wrapper-col="{ span: 18 }">
|
|
|
+ <div class="public-status-buttons">
|
|
|
+ <button :class="['status-button', { active: formState.publicStatus === '0' }]" @click="setPublicStatus('0')">
|
|
|
+ 公开
|
|
|
+ </button>
|
|
|
+ <button :class="['status-button', { active: formState.publicStatus === '1' }]" @click="setPublicStatus('1')">
|
|
|
+ 部分人可见
|
|
|
+ </button>
|
|
|
+ </div>
|
|
|
+ </a-form-item>
|
|
|
+ <a-form-item label="是否热门" :label-col="{ span: 6 }" :wrapper-col="{ span: 18 }">
|
|
|
+ <a-radio-group v-model:value="formState.isHot">
|
|
|
+ <a-radio :value="0">否</a-radio>
|
|
|
+ <a-radio :value="1">是</a-radio>
|
|
|
+ </a-radio-group>
|
|
|
+ </a-form-item>
|
|
|
+ <a-form-item label="是否推荐" :label-col="{ span: 6 }" :wrapper-col="{ span: 18 }">
|
|
|
+ <a-radio-group v-model:value="formState.isRecommend">
|
|
|
+ <a-radio :value="0">否</a-radio>
|
|
|
+ <a-radio :value="1">是</a-radio>
|
|
|
+ </a-radio-group>
|
|
|
+ </a-form-item>
|
|
|
+ <a-form-item v-if="isState == 1" label="资源描述" name="courseDesc">
|
|
|
+ <a-textarea v-model:value="formState.resourceDesc" placeholder="请输入课程介绍" :rows="4" />
|
|
|
+ </a-form-item>
|
|
|
+ <a-form-item v-if="isState == 1" label="上传封面" name="coverImage">
|
|
|
+ <coverUpload
|
|
|
+ :isedit="true"
|
|
|
+ :coverImageId="formState.coverImage"
|
|
|
+ @handleChangeCover="handleChangeCover"
|
|
|
+ @handleRemoveCover="handleRemoveCover"
|
|
|
+ ></coverUpload>
|
|
|
+ </a-form-item>
|
|
|
+ <!-- 选择成员 -->
|
|
|
+ <userSelection
|
|
|
+ v-if="userReleaseVisible"
|
|
|
+ @close="userReleaseVisible = false"
|
|
|
+ @confirm="confirmUser"
|
|
|
+ ></userSelection>
|
|
|
+ </a-form>
|
|
|
+ <template v-if="isState == 0">
|
|
|
+ <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>
|
|
|
+ </template>
|
|
|
</a-modal>
|
|
|
</template>
|
|
|
|
|
|
<script setup>
|
|
|
- import { ref, reactive } from 'vue'
|
|
|
- import { Modal, Upload } from 'ant-design-vue'
|
|
|
+ import { ref, reactive, onMounted } from 'vue'
|
|
|
+ import { Modal, Upload, Form } from 'ant-design-vue'
|
|
|
import resourceAuditApi from '@/api/resourceAudit.js'
|
|
|
+ import userSelection from './userSelection.vue'
|
|
|
+ import coverUpload from './coverUpload/index.vue'
|
|
|
+ const props = defineProps({
|
|
|
+ isState: {
|
|
|
+ type: Number,
|
|
|
+ required: true,
|
|
|
+ default: 0
|
|
|
+ },
|
|
|
+ resourcesId: {
|
|
|
+ type: Number,
|
|
|
+ required: true,
|
|
|
+ default: null
|
|
|
+ }
|
|
|
+ })
|
|
|
const emit = defineEmits(['close', 'getList'])
|
|
|
+ import tool from '@/utils/tool'
|
|
|
+ const headers = ref({
|
|
|
+ token: tool.data.get('TOKEN')
|
|
|
+ })
|
|
|
+ //课程类型
|
|
|
+ const courseTypeOptions = tool.dictList('COURSE_TYPE')
|
|
|
+ const action = ref('http://192.168.31.80:9003/api/webapp/dev/file/uploadMinioReturnId')
|
|
|
const formState = reactive({
|
|
|
- resourcesId: null
|
|
|
+ userfileIds: null, //资源文件id
|
|
|
+ coverImage: null, //封面id
|
|
|
+ // courseId: null, //课程
|
|
|
+ majorType: null, //专业
|
|
|
+ courseType: null, //课程类型
|
|
|
+ collegeId: null, //院校一级id
|
|
|
+ collegeTwoId: null, //院校二级id
|
|
|
+ collegeThreeId: null, //院校三级id
|
|
|
+ resourceDesc: null, //资源介绍
|
|
|
+ majorId: null, //专业id
|
|
|
+ courseTypeName: [], // 资源类型
|
|
|
+ keywordValue: [], // 添加关键词
|
|
|
+ keyword: [], // 热门关键词
|
|
|
+ publicStatus: 'public', // 资源是否公开
|
|
|
+ isRecommend: 0, // 资源是否推荐
|
|
|
+ isHot: 0 // 资源是否热门
|
|
|
})
|
|
|
+ const collegeMajorOptions = ref([]) //院系
|
|
|
+ const HotKeywordsOptions = ref([]) //热门关键词列表
|
|
|
+ const majorIdName = ref([]) //院系回显
|
|
|
+ const majorOptions = ref([]) //专业
|
|
|
+ const courseOptions = ref([]) //课程
|
|
|
// 上传资源模态框
|
|
|
const uploadModalVisible = ref(true)
|
|
|
+ // 用户选择模态框
|
|
|
+ const userReleaseVisible = ref(false)
|
|
|
|
|
|
// 文件列表
|
|
|
const fileList = ref([])
|
|
|
|
|
|
// 关闭模态框
|
|
|
const handleUploadCancel = () => {
|
|
|
- // uploadModalVisible.value = false
|
|
|
emit('close')
|
|
|
fileList.value = []
|
|
|
}
|
|
|
+ const rules = {
|
|
|
+ courseTypeName: [{ required: true, message: '请选择资源类型', trigger: 'change' }],
|
|
|
+ keywordValue: [{ required: true, message: '请添加关键词', trigger: 'blur' }]
|
|
|
+ }
|
|
|
|
|
|
+ const newKeyword = ref('') //关键词
|
|
|
+ const handleAddKeyword = (e) => {
|
|
|
+ const newKeywords = newKeyword.value.trim()
|
|
|
+ resourceAuditApi
|
|
|
+ .addHotKeywords({
|
|
|
+ wordName: newKeywords,
|
|
|
+ popular: 0
|
|
|
+ })
|
|
|
+ .then((res) => {
|
|
|
+ console.log(res.data, '添加热门关键词')
|
|
|
+ getHotKeywords()
|
|
|
+ newKeyword.value = ''
|
|
|
+ })
|
|
|
+ .catch((err) => {
|
|
|
+ console.log(err)
|
|
|
+ })
|
|
|
+ // if (newKeywords && !formState.keywordValue.includes(newKeywords)) {
|
|
|
+ // formState.keywordValue.push(newKeywords)
|
|
|
+ // }
|
|
|
+ }
|
|
|
+
|
|
|
+ const handleRemoveKeyword = (index) => {
|
|
|
+ formState.keywordValue.splice(index, 1)
|
|
|
+ }
|
|
|
+ const getHotKeywords = () => {
|
|
|
+ resourceAuditApi
|
|
|
+ .HotKeywords()
|
|
|
+ .then((res) => {
|
|
|
+ console.log(res.data, '获取热门关键词')
|
|
|
+ HotKeywordsOptions.value = res.data.map((it) => {
|
|
|
+ return {
|
|
|
+ value: it.wordName,
|
|
|
+ label: it.wordName
|
|
|
+ }
|
|
|
+ })
|
|
|
+ })
|
|
|
+ .catch((err) => {
|
|
|
+ console.log(err)
|
|
|
+ })
|
|
|
+ }
|
|
|
+ const handleChangeKeyword = (e) => {
|
|
|
+ console.log(e)
|
|
|
+ formState.keywordValue = e
|
|
|
+ }
|
|
|
+ const setPublicStatus = (status) => {
|
|
|
+ formState.publicStatus = status
|
|
|
+ if (status === '1') {
|
|
|
+ userReleaseVisible.value = true
|
|
|
+ }
|
|
|
+ }
|
|
|
+ //院系组织查询
|
|
|
+ const getOrgTreeSelector = () => {
|
|
|
+ resourceAuditApi
|
|
|
+ .orgTreeSelector()
|
|
|
+ .then((res) => {
|
|
|
+ console.log(res.data, '获取组织树选择器')
|
|
|
+ collegeMajorOptions.value = res.data
|
|
|
+ })
|
|
|
+ .catch((err) => {
|
|
|
+ console.log(err)
|
|
|
+ })
|
|
|
+ }
|
|
|
+ //院系组织查询
|
|
|
+ const getCourseAllList = () => {
|
|
|
+ resourceAuditApi
|
|
|
+ .courseAllList()
|
|
|
+ .then((res) => {
|
|
|
+ console.log(res.data, '获取全部课程')
|
|
|
+ courseOptions.value = res.data
|
|
|
+ })
|
|
|
+ .catch((err) => {
|
|
|
+ console.log(err)
|
|
|
+ })
|
|
|
+ }
|
|
|
+ const changeCollegeMajor = (value, selectedOptions) => {
|
|
|
+ console.log('Selected:', value, selectedOptions)
|
|
|
+ formState.collegeId = value[0] || null
|
|
|
+ formState.collegeTwoId = value[1] || null
|
|
|
+ formState.collegeThreeId = value[2] || null
|
|
|
+ if (selectedOptions.length) {
|
|
|
+ // 获取选中的最后一级
|
|
|
+ const lastSelected = selectedOptions[selectedOptions.length - 1]
|
|
|
+ // formState.selectedCollegeMajor = {
|
|
|
+ // id: lastSelected.id,
|
|
|
+ // name: lastSelected.name,
|
|
|
+ // 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)
|
|
|
+ })
|
|
|
+ }
|
|
|
+ }
|
|
|
// 确认上传
|
|
|
const handleUploadOk = () => {
|
|
|
- // 这里可以添加实际的上传逻辑
|
|
|
- console.log('Upload confirmed:', fileList.value)
|
|
|
- // uploadModalVisible.value = false
|
|
|
- emit('close')
|
|
|
- fileList.value = []
|
|
|
+ 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
|
|
|
+ }
|
|
|
+
|
|
|
resourceAuditApi
|
|
|
- .add({ fileId: formState.resourcesId })
|
|
|
+ .add(formData)
|
|
|
.then((res) => {
|
|
|
emit('getList')
|
|
|
+ Modal.success({ content: '资源上传成功' })
|
|
|
})
|
|
|
.catch((err) => {
|
|
|
+ Modal.error({ content: '资源上传失败' })
|
|
|
console.log(err)
|
|
|
})
|
|
|
+ .finally(() => {
|
|
|
+ fileList.value = []
|
|
|
+ formState.userfileIds = null
|
|
|
+ formState.courseTypeName = ''
|
|
|
+ formState.keywordValue = ''
|
|
|
+ formState.hotKeywords = []
|
|
|
+ formState.publicStatus = 'public'
|
|
|
+ })
|
|
|
+ }
|
|
|
+ // 获取资源详情
|
|
|
+ const getDetail = () => {
|
|
|
+ resourceAuditApi.detail({ id: props.resourcesId }).then((res) => {
|
|
|
+ console.log(res.data, '资源详情')
|
|
|
+ formState.courseType = res.data.courseType
|
|
|
+ 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]
|
|
|
+ formState.resourceDesc = res.data.resourceDesc
|
|
|
+ formState.majorId = res.data.majorId
|
|
|
+ })
|
|
|
}
|
|
|
// 上传前的钩子函数
|
|
|
const beforeUpload = (file) => {
|
|
|
@@ -83,8 +375,8 @@
|
|
|
newFileList.splice(index, 1)
|
|
|
fileList.value = newFileList
|
|
|
// 如果移除的是当前封面文件,则清空coverImageId
|
|
|
- if (formState.resourcesId === file.id) {
|
|
|
- formState.resourcesId = null
|
|
|
+ if (formState.userfileIds === file.id) {
|
|
|
+ formState.userfileIds = null
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -101,7 +393,7 @@
|
|
|
const fileId = file.response?.data || file.id
|
|
|
console.log('上传成功,获取文件ID', fileId)
|
|
|
if (fileId) {
|
|
|
- formState.resourcesId = fileId
|
|
|
+ formState.userfileIds = fileId
|
|
|
}
|
|
|
}
|
|
|
fileList.value = newFileList
|
|
|
@@ -116,8 +408,15 @@
|
|
|
file.percent = 0
|
|
|
}
|
|
|
}
|
|
|
+ onMounted(() => {
|
|
|
+ getOrgTreeSelector()
|
|
|
+ getCourseAllList()
|
|
|
+ getHotKeywords()
|
|
|
+ if (props.isState == 1) {
|
|
|
+ getDetail()
|
|
|
+ }
|
|
|
+ })
|
|
|
</script>
|
|
|
-
|
|
|
<style scoped>
|
|
|
.upload-area {
|
|
|
border: 2px dashed #3ca9f5;
|
|
|
@@ -139,4 +438,27 @@
|
|
|
flex: 1;
|
|
|
margin: 0 10px;
|
|
|
}
|
|
|
+
|
|
|
+ /* 新增表单样式 */
|
|
|
+ .ant-form-item {
|
|
|
+ margin-bottom: 16px;
|
|
|
+ }
|
|
|
+ .public-status-buttons {
|
|
|
+ display: flex;
|
|
|
+ }
|
|
|
+
|
|
|
+ .status-button {
|
|
|
+ padding: 5px 10px;
|
|
|
+ /* margin-right: 10px; */
|
|
|
+ border: 1px solid #ccc;
|
|
|
+ /* border-radius: 3px; */
|
|
|
+ cursor: pointer;
|
|
|
+ background-color: #fff;
|
|
|
+ }
|
|
|
+
|
|
|
+ .status-button.active {
|
|
|
+ background-color: #40a9ff;
|
|
|
+ color: #fff;
|
|
|
+ border-color: #40a9ff;
|
|
|
+ }
|
|
|
</style>
|