|
@@ -199,39 +199,71 @@
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
</template>
|
|
|
|
+ <template v-if="lessonSokrates.url">
|
|
|
|
+ <div class="file-show">
|
|
|
|
+ 作品:
|
|
|
|
+ <span @click="lookSokrates()" style="color: #0c66c3; cursor: pointer;">{{ lessonSokrates.uploadName }}</span>
|
|
|
|
+ </div>
|
|
|
|
+ </template>
|
|
<template v-if="contest?.upload && contest.upload.actState === 'going' && !contest?.upload.captainUpload || contest?.upload.captainUpload && isLeader">
|
|
<template v-if="contest?.upload && contest.upload.actState === 'going' && !contest?.upload.captainUpload || contest?.upload.captainUpload && isLeader">
|
|
- <el-upload class="upload-demo" ref="refUpload" :file-list="fileList" :accept="accept" drag multiple :on-change="handleChange" :auto-upload="false" action="">
|
|
|
|
- <el-icon class="el-icon--upload"><UploadFilled /></el-icon>
|
|
|
|
- <div class="el-upload__text">
|
|
|
|
- 上传作品
|
|
|
|
- </div>
|
|
|
|
- <template #tip>
|
|
|
|
- <div class="tag-box">
|
|
|
|
- <el-tag :type="contest?.upload.captainUpload ? 'warning' : 'success'" disable-transitions effect="dark">
|
|
|
|
- {{ contest?.upload.captainUpload ? '队长统一上传' : '个人上传' }}
|
|
|
|
- </el-tag>
|
|
|
|
- <template v-if="contest?.upload.type === 'file'">
|
|
|
|
- <el-tag type="success" disable-transitions v-for="(item, index) in contest?.upload.fileType" :key="index">
|
|
|
|
- {{ item }}
|
|
|
|
- </el-tag>
|
|
|
|
- </template>
|
|
|
|
- <template v-else-if="contest?.upload.type === 'lesson'">
|
|
|
|
- <el-tag type="success" disable-transitions>
|
|
|
|
- 必须上传视频
|
|
|
|
- </el-tag>
|
|
|
|
- </template>
|
|
|
|
|
|
+ <template v-if="contest.upload.uploadType.length">
|
|
|
|
+ <el-radio-group v-model="radioFileType">
|
|
|
|
+ <el-radio v-for="(item, index) in contest.upload.uploadType" :key="index" :label="item" size="large">
|
|
|
|
+ {{ item === 'file' ? '文件' : item === 'sokrates' ? '苏格拉底影片' : '课例' }}
|
|
|
|
+ </el-radio>
|
|
|
|
+ </el-radio-group>
|
|
|
|
+ </template>
|
|
|
|
+ <template v-if="radioFileType === 'file' || contest.upload.type === 'file'">
|
|
|
|
+ <el-upload class="upload-demo" ref="refUpload" :file-list="fileList" :accept="accept" drag multiple :on-change="handleChange" :auto-upload="false" action="">
|
|
|
|
+ <el-icon class="el-icon--upload"><UploadFilled /></el-icon>
|
|
|
|
+ <div class="el-upload__text">
|
|
|
|
+ 上传作品
|
|
</div>
|
|
</div>
|
|
- </template>
|
|
|
|
- <template #file="UploadFile">
|
|
|
|
- <p class="file-list-box">
|
|
|
|
- <span>{{ UploadFile.file.name }}</span>
|
|
|
|
- <el-icon v-show="!isUpload" size="20" @click="handleRemove(UploadFile.file)"><Close /></el-icon>
|
|
|
|
- </p>
|
|
|
|
- <p class="file-list-progress">
|
|
|
|
- <el-progress :percentage="UploadFile.file.progress" :status="UploadFile.file.progress === 100 ? 'success' : ''" />
|
|
|
|
- </p>
|
|
|
|
- </template>
|
|
|
|
- </el-upload>
|
|
|
|
|
|
+ <template #tip>
|
|
|
|
+ <div class="tag-box">
|
|
|
|
+ <el-tag :type="contest?.upload.captainUpload ? 'warning' : 'success'" disable-transitions effect="dark">
|
|
|
|
+ {{ contest?.upload.captainUpload ? '队长统一上传' : '个人上传' }}
|
|
|
|
+ </el-tag>
|
|
|
|
+ <template v-if="radioFileType === 'file' || contest?.upload.type === 'file'">
|
|
|
|
+ <el-tag type="success" disable-transitions v-for="(item, index) in contest?.upload.fileType" :key="index">
|
|
|
|
+ {{ item }}
|
|
|
|
+ </el-tag>
|
|
|
|
+ </template>
|
|
|
|
+ <!-- <template v-else>
|
|
|
|
+ <el-tag type="success" disable-transitions>
|
|
|
|
+ 必须上传视频
|
|
|
|
+ </el-tag>
|
|
|
|
+ </template> -->
|
|
|
|
+ </div>
|
|
|
|
+ </template>
|
|
|
|
+ <template #file="UploadFile">
|
|
|
|
+ <p class="file-list-box">
|
|
|
|
+ <span>{{ UploadFile.file.name }}</span>
|
|
|
|
+ <el-icon v-show="!isUpload" size="20" @click="handleRemove(UploadFile.file)"><Close /></el-icon>
|
|
|
|
+ </p>
|
|
|
|
+ <p class="file-list-progress">
|
|
|
|
+ <el-progress :percentage="UploadFile.file.progress" :status="UploadFile.file.progress === 100 ? 'success' : ''" />
|
|
|
|
+ </p>
|
|
|
|
+ </template>
|
|
|
|
+ </el-upload>
|
|
|
|
+ </template>
|
|
|
|
+ <template v-else>
|
|
|
|
+ <el-form :model="sokratesForm" label-width="auto" style="margin-top: 20px;">
|
|
|
|
+ <el-form-item label="作品名称">
|
|
|
|
+ <el-input v-model="sokratesForm.name" />
|
|
|
|
+ </el-form-item>
|
|
|
|
+ <el-form-item label="作品链接" v-show="radioFileType === 'sokrates'">
|
|
|
|
+ <el-input v-model="sokratesForm.link" />
|
|
|
|
+ <span>
|
|
|
|
+ <el-icon color="#ba6b26"><Warning /></el-icon>
|
|
|
|
+ 请确保作品已在苏格拉底平台公开
|
|
|
|
+ </span>
|
|
|
|
+ </el-form-item>
|
|
|
|
+ <el-form-item label="课例ID" v-show="radioFileType === 'lesson'">
|
|
|
|
+ <el-input v-model="sokratesForm.course" />
|
|
|
|
+ </el-form-item>
|
|
|
|
+ </el-form>
|
|
|
|
+ </template>
|
|
<el-button type="success" @click="uploadFile()" v-show="!isUpload">
|
|
<el-button type="success" @click="uploadFile()" v-show="!isUpload">
|
|
上传
|
|
上传
|
|
</el-button>
|
|
</el-button>
|
|
@@ -343,6 +375,7 @@ let nowYear = ref('')
|
|
let scopeVal = ref('')
|
|
let scopeVal = ref('')
|
|
let publishVal = ref('')
|
|
let publishVal = ref('')
|
|
let uploadName = ref('')
|
|
let uploadName = ref('')
|
|
|
|
+let radioFileType = ref('')
|
|
let searShow = ref(false)
|
|
let searShow = ref(false)
|
|
let skModule = ref(true)
|
|
let skModule = ref(true)
|
|
let isLeader = ref(false)
|
|
let isLeader = ref(false)
|
|
@@ -364,7 +397,9 @@ let contest = ref({})
|
|
let research = ref({}) //教研
|
|
let research = ref({}) //教研
|
|
let training = ref({}) //研修
|
|
let training = ref({}) //研修
|
|
let previewFile = ref({})
|
|
let previewFile = ref({})
|
|
|
|
+let lessonSokrates = ref({url: ''})
|
|
let scoreData = ref({detailScore: []})
|
|
let scoreData = ref({detailScore: []})
|
|
|
|
+let sokratesForm = ref({name: '', link: '', course: ''})
|
|
|
|
|
|
const refUpload = ref(HTMLElement)
|
|
const refUpload = ref(HTMLElement)
|
|
const cipher = ref({})
|
|
const cipher = ref({})
|
|
@@ -411,6 +446,8 @@ function getListInfo(info, index) {
|
|
actIndex.value = index
|
|
actIndex.value = index
|
|
actInfo.value = {attachment: []}
|
|
actInfo.value = {attachment: []}
|
|
uploadList.value = []
|
|
uploadList.value = []
|
|
|
|
+ lessonSokrates.value = {url: ''}
|
|
|
|
+ sokratesForm.value = {name: '', link: '', course: ''}
|
|
fileList.value = []
|
|
fileList.value = []
|
|
accept.value = ''
|
|
accept.value = ''
|
|
uploadName.value = ''
|
|
uploadName.value = ''
|
|
@@ -430,7 +467,7 @@ function getListInfo(info, index) {
|
|
})
|
|
})
|
|
actInfo.value = res.activity
|
|
actInfo.value = res.activity
|
|
ruleTree.value = res.reviewRule?.trees || []
|
|
ruleTree.value = res.reviewRule?.trees || []
|
|
- if(res.contest?.upload.type === 'file') accept.value = res.contest?.upload.fileType.map(item => '.' + item).join()
|
|
|
|
|
|
+ if(res.contest?.upload.type === 'file' || res.contest?.upload.uploadType.includes('file')) accept.value = res.contest?.upload.fileType.map(item => '.' + item).join()
|
|
let nowDate = new Date().getTime()
|
|
let nowDate = new Date().getTime()
|
|
res.contest.modules.forEach((item, index) => {
|
|
res.contest.modules.forEach((item, index) => {
|
|
res.contest[item].actState = nowDate < res.contest[item].stime ? 'notStart' : (nowDate > res.contest[item].etime ? 'finish' : 'going')
|
|
res.contest[item].actState = nowDate < res.contest[item].stime ? 'notStart' : (nowDate > res.contest[item].etime ? 'finish' : 'going')
|
|
@@ -440,6 +477,7 @@ function getListInfo(info, index) {
|
|
})
|
|
})
|
|
contestStep.value = index === -1 ? 4 : (!index && res.contest.upload.actState === 'going' ? 1 : index)
|
|
contestStep.value = index === -1 ? 4 : (!index && res.contest.upload.actState === 'going' ? 1 : index)
|
|
contest.value = res.contest
|
|
contest.value = res.contest
|
|
|
|
+ radioFileType.value = res.contest?.upload.uploadType.length ? res.contest?.upload.uploadType[0] : ''
|
|
contestScores.value = res.contestScores || []
|
|
contestScores.value = res.contestScores || []
|
|
research.value = res.research
|
|
research.value = res.research
|
|
training.value = res.training
|
|
training.value = res.training
|
|
@@ -468,10 +506,13 @@ function getEnroll() {
|
|
})
|
|
})
|
|
let sasUrl = await proxy.$api.blobSasRCW({name: actInfo.value.owner, role: 'teacher' })
|
|
let sasUrl = await proxy.$api.blobSasRCW({name: actInfo.value.owner, role: 'teacher' })
|
|
if(res.enroll.upload) {
|
|
if(res.enroll.upload) {
|
|
- uploadList.value = res.enroll.upload.files.map(item => {
|
|
|
|
|
|
+ let arr = res.enroll.upload.uploadType.includes('file') ? res.enroll.upload.complexes.map(item => item.uploadFile) : res.enroll.upload.files
|
|
|
|
+ uploadList.value = arr.map(item => {
|
|
item.urlShow = sasUrl.url + '/' + actInfo.value.owner + item.blob + '?' + sasUrl.sas
|
|
item.urlShow = sasUrl.url + '/' + actInfo.value.owner + item.blob + '?' + sasUrl.sas
|
|
return item
|
|
return item
|
|
})
|
|
})
|
|
|
|
+ lessonSokrates.value = (res.enroll.upload.uploadType.length && !res.enroll.upload.uploadType.includes('file')) ? res.enroll.upload.complexes[0]?.lessonSokrates : {url: ''}
|
|
|
|
+ lessonSokrates.value.uploadName = res.enroll.upload.name
|
|
}
|
|
}
|
|
/* memberData.value.push(Object.fromEntries(field))
|
|
/* memberData.value.push(Object.fromEntries(field))
|
|
memberData.value[0].identity = res.enroll.contest.leader
|
|
memberData.value[0].identity = res.enroll.contest.leader
|
|
@@ -646,7 +687,15 @@ function handleChange(file, files) {
|
|
files.splice(fileList.value.length, 1)
|
|
files.splice(fileList.value.length, 1)
|
|
return
|
|
return
|
|
}
|
|
}
|
|
- if(file.size > 100 * 1024 * 1024) {
|
|
|
|
|
|
+ if(file.raw.type.includes('video') && file.size > 2 * 1024 * 1024 * 1024) {
|
|
|
|
+ ElMessage({
|
|
|
|
+ type: 'warning',
|
|
|
|
+ message: '视频大小不能超过2GB!'
|
|
|
|
+ })
|
|
|
|
+ files.splice(fileList.value.length, 1)
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+ if(!file.raw.type.includes('video') && file.size > 100 * 1024 * 1024) {
|
|
ElMessage({
|
|
ElMessage({
|
|
type: 'warning',
|
|
type: 'warning',
|
|
message: '文件大小不能超过100MB!'
|
|
message: '文件大小不能超过100MB!'
|
|
@@ -727,25 +776,36 @@ function deleteBlobPrefix(code, path) {
|
|
}
|
|
}
|
|
|
|
|
|
async function uploadFile() {
|
|
async function uploadFile() {
|
|
- if(!fileList.value.length) {
|
|
|
|
|
|
+ if(radioFileType.value != 'file' && (!sokratesForm.value.name || (radioFileType.value === 'sokrates' && !sokratesForm.value.link) || (radioFileType.value === 'lesson' && !sokratesForm.value.course))) {
|
|
|
|
+ ElMessage({
|
|
|
|
+ type: 'warning',
|
|
|
|
+ message: '请完善信息'
|
|
|
|
+ })
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+ if(radioFileType.value === 'file' && !fileList.value.length) {
|
|
ElMessage({
|
|
ElMessage({
|
|
type: 'warning',
|
|
type: 'warning',
|
|
message: '请先选择文件!'
|
|
message: '请先选择文件!'
|
|
})
|
|
})
|
|
return
|
|
return
|
|
}
|
|
}
|
|
- if(contest.value.upload.type === 'lesson' && !fileList.value.find(item => item.raw.type === 'video/mp4')) {
|
|
|
|
|
|
+ /* if((contest.value.upload.type === 'lesson' || radioFileType.value === 'lesson') && !fileList.value.find(item => item.raw.type === 'video/mp4')) {
|
|
ElMessage({
|
|
ElMessage({
|
|
type: 'warning',
|
|
type: 'warning',
|
|
message: '必须上传视频!'
|
|
message: '必须上传视频!'
|
|
})
|
|
})
|
|
return
|
|
return
|
|
|
|
+ } */
|
|
|
|
+ if(radioFileType.value === 'file') {
|
|
|
|
+ uploadDia.value = true
|
|
|
|
+ } else {
|
|
|
|
+ startUpload()
|
|
}
|
|
}
|
|
- uploadDia.value = true
|
|
|
|
}
|
|
}
|
|
|
|
|
|
async function startUpload() {
|
|
async function startUpload() {
|
|
- if(!uploadName.value) {
|
|
|
|
|
|
+ if(radioFileType.value === 'file' && !uploadName.value) {
|
|
ElMessage({
|
|
ElMessage({
|
|
type: 'warning',
|
|
type: 'warning',
|
|
message: '请输入作品集名称'
|
|
message: '请输入作品集名称'
|
|
@@ -754,36 +814,49 @@ async function startUpload() {
|
|
}
|
|
}
|
|
isUpload.value = true
|
|
isUpload.value = true
|
|
uploadDia.value = false
|
|
uploadDia.value = false
|
|
- let blobList = await uploadBlob()
|
|
|
|
- if(!blobList) {
|
|
|
|
- ElMessage({
|
|
|
|
- type: 'warning',
|
|
|
|
- message: '上传失败'
|
|
|
|
- })
|
|
|
|
- isUpload.value = false
|
|
|
|
- return
|
|
|
|
|
|
+ let blobList = undefined
|
|
|
|
+ if(radioFileType.value === 'file') {
|
|
|
|
+ blobList = await uploadBlob()
|
|
|
|
+ if(!blobList) {
|
|
|
|
+ ElMessage({
|
|
|
|
+ type: 'warning',
|
|
|
|
+ message: '上传失败'
|
|
|
|
+ })
|
|
|
|
+ isUpload.value = false
|
|
|
|
+ return
|
|
|
|
+ }
|
|
}
|
|
}
|
|
let params = {
|
|
let params = {
|
|
grant_type: 'upload-contest',
|
|
grant_type: 'upload-contest',
|
|
activityId: actInfo.value.id,
|
|
activityId: actInfo.value.id,
|
|
uploadData: {
|
|
uploadData: {
|
|
- type: contest.value.upload.type,
|
|
|
|
- name: uploadName.value,
|
|
|
|
|
|
+ // type: contest.value.upload.type,
|
|
|
|
+ name: radioFileType.value === 'file' ? uploadName.value : sokratesForm.value.name,
|
|
|
|
+ complexes: []
|
|
},
|
|
},
|
|
}
|
|
}
|
|
// 暂不考虑这种情况,因为创建活动时必须填写报名模块
|
|
// 暂不考虑这种情况,因为创建活动时必须填写报名模块
|
|
- /* if(!contest.value.modules.incldes('sign')) {
|
|
|
|
|
|
+ /* if(!contest.value.modules.includes('sign')) {
|
|
// 活动没有报名模块,直接上传作品
|
|
// 活动没有报名模块,直接上传作品
|
|
params.uploadData.schoolId
|
|
params.uploadData.schoolId
|
|
params.uploadData.schoolName
|
|
params.uploadData.schoolName
|
|
params.uploadData.schoolPicture
|
|
params.uploadData.schoolPicture
|
|
} */
|
|
} */
|
|
- if(contest.value.upload.type === 'file') {
|
|
|
|
|
|
+ // 统一改为 complexes:[{type: 'file'/'sokrates'/'lesson', ('sokrates'/'lesson'使用)lessonSokrates: {url: ''}, ('file'使用)uploadFile: {}}]
|
|
|
|
+ /* if(contest.value.upload.type === 'file') {
|
|
params.uploadData.files = blobList
|
|
params.uploadData.files = blobList
|
|
} else if(contest.value.upload.type === 'lesson') {
|
|
} else if(contest.value.upload.type === 'lesson') {
|
|
params.uploadData.lessons = blobList
|
|
params.uploadData.lessons = blobList
|
|
} else {
|
|
} else {
|
|
params.uploadData.sokrates = []
|
|
params.uploadData.sokrates = []
|
|
|
|
+ } */
|
|
|
|
+ if(radioFileType.value === 'file' || contest.value.upload.type === 'file') {
|
|
|
|
+ params.uploadData.complexes = blobList.map(item => {
|
|
|
|
+ return {type: 'file', uploadFile: item}
|
|
|
|
+ })
|
|
|
|
+ } else {
|
|
|
|
+ // 课例需再处理
|
|
|
|
+ params.uploadData.complexes = [{type: radioFileType.value, lessonSokrates: {url: sokratesForm.value.link}}]
|
|
}
|
|
}
|
|
proxy.$api.teaContest(params).then(async res => {
|
|
proxy.$api.teaContest(params).then(async res => {
|
|
if(res.code === 200) {
|
|
if(res.code === 200) {
|
|
@@ -791,11 +864,19 @@ async function startUpload() {
|
|
type: 'success',
|
|
type: 'success',
|
|
message: '上传成功'
|
|
message: '上传成功'
|
|
})
|
|
})
|
|
- let sasUrl = await proxy.$api.blobSasRCW({name: actInfo.value.owner, role: 'teacher' })
|
|
|
|
- uploadList.value = blobList.map(item => {
|
|
|
|
- item.urlShow = sasUrl.url + '/' + actInfo.value.owner + item.blob + '?' + sasUrl.sas
|
|
|
|
- return item
|
|
|
|
- })
|
|
|
|
|
|
+ if(radioFileType.value === 'file') {
|
|
|
|
+ let sasUrl = await proxy.$api.blobSasRCW({name: actInfo.value.owner, role: 'teacher' })
|
|
|
|
+ uploadList.value = blobList.map(item => {
|
|
|
|
+ item.urlShow = sasUrl.url + '/' + actInfo.value.owner + item.blob + '?' + sasUrl.sas
|
|
|
|
+ return item
|
|
|
|
+ })
|
|
|
|
+ lessonSokrates.value = {url: ''}
|
|
|
|
+ } else {
|
|
|
|
+ lessonSokrates.value = params.uploadData.complexes[0].lessonSokrates
|
|
|
|
+ lessonSokrates.value.uploadName = params.uploadData.name
|
|
|
|
+ uploadList.value = []
|
|
|
|
+ }
|
|
|
|
+ sokratesForm.value = {name: '', link: '', course: ''}
|
|
fileList.value = []
|
|
fileList.value = []
|
|
} else {
|
|
} else {
|
|
ElMessage({
|
|
ElMessage({
|
|
@@ -892,6 +973,13 @@ function onFilterClear() {
|
|
getListInfo(actListShow.value[0], 0)
|
|
getListInfo(actListShow.value[0], 0)
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+function lookSokrates() {
|
|
|
|
+ // 查看苏格拉底单点登录页面所需字段,在此处重新拼接
|
|
|
|
+ // https://account.teammodel.cn/?callback=https%3A%2F%2Fsokrates.teammodel.cn%2Fauth%2Flogin%2Fcallback-habook%3Fto%3DaHR0cHM6Ly9zb2tyYXRlcy50ZWFtbW9kZWwuY24vZXhoaWJpdGlvbi90YmF2aWRlbyMvY29udGVudC81MDk1Mz9ncm91cElkcz0xNDImY2hhbm5lbElkPTEzMQ%3D%3D
|
|
|
|
+ let url = "https://account.teammodel.cn/?callback=" + 'https://sokrates.teammodel.cn/auth/login/callback-habook' + '?to=' + btoa(lessonSokrates.value.url)
|
|
|
|
+ window.open(url, '_blank')
|
|
|
|
+}
|
|
|
|
+
|
|
watch(nowYear, (newValue, oldValue) => {
|
|
watch(nowYear, (newValue, oldValue) => {
|
|
getActList()
|
|
getActList()
|
|
})
|
|
})
|