|
@@ -50,11 +50,22 @@
|
|
|
:class="['volume-item',activeVolumeIndex === volumeIndex ? 'volume-active' : '']"
|
|
|
@click="onVolumeClick(volume,volumeIndex)">
|
|
|
<p class="volume-item-name">{{ volume.name }} <span class="status-idDel"
|
|
|
- v-if="volume.isDel">{{ $t('syllabus.isDel') }}</span> </p>
|
|
|
+ v-if="volume.isDel">{{ $t('syllabus.isDel') }}</span><span class="status-idDel status-coedit"
|
|
|
+ v-if="hasVolumeAuth(volume.auth) && isSchool">{{ $t('syllabus.canEdit') }}</span> </p>
|
|
|
<p class="volume-item-info" v-if="isSchool">
|
|
|
<span>{{ getGradeName(volume.gradeId) }}</span>
|
|
|
<span>|</span>
|
|
|
<span>{{ getSemesterName(volume.semesterId) }}</span>
|
|
|
+ <span style="margin: 0 8px;">|</span>
|
|
|
+ <Tooltip placement="bottom">
|
|
|
+ <span>{{ $t('syllabus.authorsTitle') }} {{ volume.auth.length }} </span>
|
|
|
+ <!-- <Icon type="md-information-circle" color="#9e9e9e" /> -->
|
|
|
+ <div slot="content">
|
|
|
+ <p v-if="!volume.auth.length">{{ $t('syllabus.noAuth') }}</p>
|
|
|
+ <p v-else v-for="(item,index) in volume.auth" :key="item.tmdid">
|
|
|
+ {{ item.tmdname }}</p>
|
|
|
+ </div>
|
|
|
+ </Tooltip>
|
|
|
</p>
|
|
|
<p class="volume-item-info" v-if="inShareView && volume.isDel">
|
|
|
<span style="display: flex;align-items: center;"
|
|
@@ -82,7 +93,7 @@
|
|
|
<span>{{ $t('syllabus.syllabusMenu') }}</span>
|
|
|
<span class="syllabus-content-header-tools"
|
|
|
v-if="volumeList.length && curVolume.id && !inShareView">
|
|
|
- <Icon type="md-add" @click="isAddTreeModal = true" v-if="hasSyllabusAuth" />
|
|
|
+ <Icon type="md-add" @click="isAddTreeModal = true" v-if="hasSyllabusAuth || hasVolumeAuth" />
|
|
|
</span>
|
|
|
</div>
|
|
|
<div class="syllabus-tree-box">
|
|
@@ -134,7 +145,8 @@
|
|
|
<img src="../../assets/source/zip.png" v-else-if="item.type === 'res'" />
|
|
|
<img src="../../assets/source/image.png" v-else-if="item.type === 'thum'" />
|
|
|
<img src="../../assets/source/unknow.png" v-else="item.type === 'other'" />
|
|
|
- <span v-html="item.title" style="max-width: 70%;cursor: pointer;" @click="onPreview(item)"></span>
|
|
|
+ <span v-html="item.title" style="max-width: 70%;cursor: pointer;"
|
|
|
+ @click="onPreview(item)"></span>
|
|
|
<div class="node-resource-tools">
|
|
|
<!-- <div class="node-resource-tool" >
|
|
|
<Icon type="md-eye" />
|
|
@@ -184,6 +196,12 @@
|
|
|
:placeholder="$t('syllabus.place2')"></Input>
|
|
|
<Input v-else v-model="addVolumeForm.name" :placeholder="$t('syllabus.place3')"></Input>
|
|
|
</FormItem>
|
|
|
+ <FormItem :label="$t('syllabus.authors')">
|
|
|
+ <Select v-model="addVolumeForm.auth" multiple filterable>
|
|
|
+ <Option v-for="(item,index) in teacherList" :value="item.id" :key="index">{{item.name}}
|
|
|
+ </Option>
|
|
|
+ </Select>
|
|
|
+ </FormItem>
|
|
|
<FormItem>
|
|
|
<Button @click="handleSubmit" :loading="isAddLoading">{{ $t('syllabus.confirm') }}</Button>
|
|
|
</FormItem>
|
|
@@ -319,6 +337,7 @@
|
|
|
myVolumeList: [],
|
|
|
questionList: [],
|
|
|
allChapterIds: [],
|
|
|
+ teacherList: [],
|
|
|
schoolInfo: null,
|
|
|
previewFile: {},
|
|
|
previewPaper: null,
|
|
@@ -344,7 +363,8 @@
|
|
|
addVolumeForm: {
|
|
|
grade: 0,
|
|
|
semester: 0,
|
|
|
- name: ''
|
|
|
+ name: '',
|
|
|
+ auth: []
|
|
|
},
|
|
|
nodeInfo: {
|
|
|
"id": "",
|
|
@@ -357,6 +377,7 @@
|
|
|
},
|
|
|
modifyIdArr: [],
|
|
|
flatArr: [],
|
|
|
+ myCreateChapters:[],
|
|
|
isSaveSyllabus: false,
|
|
|
}
|
|
|
},
|
|
@@ -364,6 +385,7 @@
|
|
|
this.isSchool = this.$route.name === 'syllabus'
|
|
|
this.getSchoolInfo()
|
|
|
this.initBlobTool()
|
|
|
+ this.getAllTeacher()
|
|
|
},
|
|
|
methods: {
|
|
|
/* 初始化BLOB对象 */
|
|
@@ -388,6 +410,21 @@
|
|
|
}
|
|
|
});
|
|
|
},
|
|
|
+ /* 获取学校所有教师列表 */
|
|
|
+ getAllTeacher() {
|
|
|
+ this.$store.dispatch('user/getSchoolTeacher').then(
|
|
|
+ res => {
|
|
|
+ if (res.code == 0) {
|
|
|
+ this.$Message.error('無法取得使用者資料')
|
|
|
+ } else {
|
|
|
+ this.teacherList = this.$store.state.user.schoolUserList.filter(i => i.status === 'join')
|
|
|
+ }
|
|
|
+ },
|
|
|
+ err => {
|
|
|
+ this.$Message.error('user/setSchoolTeacher API error!')
|
|
|
+ }
|
|
|
+ )
|
|
|
+ },
|
|
|
/* 提取富文本内容中的文本 */
|
|
|
async getItemSimpleText(item) {
|
|
|
try {
|
|
@@ -550,7 +587,8 @@
|
|
|
this.addVolumeForm = {
|
|
|
grade: 0,
|
|
|
semester: 0,
|
|
|
- name: ''
|
|
|
+ name: '',
|
|
|
+ auth:[]
|
|
|
}
|
|
|
this.isEditVolume = false
|
|
|
this.isAddVolumeModal = true
|
|
@@ -576,7 +614,8 @@
|
|
|
this.addVolumeForm = {
|
|
|
grade: this.curVolume.gradeId,
|
|
|
semester: this.semesterList.map(i => i.id).indexOf(this.curVolume.semesterId),
|
|
|
- name: this.curVolume.name
|
|
|
+ name: this.curVolume.name,
|
|
|
+ auth:this.curVolume.auth.length ? this.curVolume.auth.map(i => i.tmdid) : []
|
|
|
}
|
|
|
this.isEditVolume = true
|
|
|
this.isAddVolumeModal = true
|
|
@@ -744,12 +783,22 @@
|
|
|
this.nodeInfo.creatorId = this.$store.state.userInfo.TEAMModelId
|
|
|
// 统一传给树形组件的数据结构
|
|
|
this.treeOrigin.push({
|
|
|
- auth: null,
|
|
|
+ auth: this.isSchool ? [{
|
|
|
+ agree:0,
|
|
|
+ tmdid:this.$store.state.userInfo.TEAMModelId,
|
|
|
+ tmdname:this.$store.state.userInfo.name,
|
|
|
+ type:'coedit'
|
|
|
+ }] : [],
|
|
|
id: this.nodeInfo.id,
|
|
|
+ creatorId:this.$store.state.userInfo.TEAMModelId,
|
|
|
scope: this.curVolume.scope,
|
|
|
trees: [this.nodeInfo],
|
|
|
volumeId: this.curVolume.id,
|
|
|
- rnodes:[]
|
|
|
+ rnodes: []
|
|
|
+ })
|
|
|
+ this.myCreateChapters.push({
|
|
|
+ name:this.nodeInfo.title,
|
|
|
+ id:this.nodeInfo.id
|
|
|
})
|
|
|
// 只要本地新增的章节 都要记录到修改数据里
|
|
|
this.$nextTick(() => {
|
|
@@ -760,8 +809,9 @@
|
|
|
"pid": "",
|
|
|
"title": "",
|
|
|
"type": 1,
|
|
|
+ "creatorId":this.$store.state.userInfo.TEAMModelId,
|
|
|
"children": [],
|
|
|
- "rnodes":[]
|
|
|
+ "rnodes": []
|
|
|
}
|
|
|
})
|
|
|
this.hasModify = true;
|
|
@@ -786,23 +836,69 @@
|
|
|
codeval: this.curCode,
|
|
|
volumeId: this.curVolume.id,
|
|
|
scope: this.curVolume.scope,
|
|
|
+ creatorId:this.$store.state.userInfo.TEAMModelId,
|
|
|
trees: allChapter.find(i => i.id === id) ? [allChapter.find(i => i.id === id)] : []
|
|
|
}
|
|
|
}) : [];
|
|
|
this.allChapterIds = allChapter.map(i => i.id)
|
|
|
+ // 先保存树结构数据
|
|
|
this.$api.syllabus.UpsertTree(modifyChapters).then((res) => {
|
|
|
if (!res.error && res) {
|
|
|
+ // 然后保存册别的章节ID集合
|
|
|
this.handleSubmit().then(result => {
|
|
|
- this.treeOrigin = res;
|
|
|
- this.hasModify = false;
|
|
|
- this.$refs.treeRef && (this.$refs.treeRef.modifyIdArr = [])
|
|
|
- // this.isEditVolume = false
|
|
|
+ let promiseArr = []
|
|
|
+ if(this.myCreateChapters.length){
|
|
|
+ // 然后如果是自己新增的章节 则需要把自己加入到共编权限内
|
|
|
+ this.myCreateChapters.forEach(i => {
|
|
|
+ if(modifyIdArr.includes(i.id)){
|
|
|
+ promiseArr.push(this.doShareMyself(i.id,i.name))
|
|
|
+ }
|
|
|
+ })
|
|
|
+ Promise.all(promiseArr).then(shareResult => {
|
|
|
+ this.treeOrigin = res;
|
|
|
+ this.hasModify = false;
|
|
|
+ this.$refs.treeRef && (this.$refs.treeRef.modifyIdArr = [])
|
|
|
+ }).catch(err => {
|
|
|
+ this.$Message.error(err)
|
|
|
+ })
|
|
|
+ }
|
|
|
})
|
|
|
} else {
|
|
|
this.$Message.warning(this.$t('syllabus.saveFailTip'));
|
|
|
}
|
|
|
});
|
|
|
},
|
|
|
+ /* 新增的章节 需要把创建者加入到共编数据内 */
|
|
|
+ doShareMyself(id,name){
|
|
|
+ return new Promise((r,j) => {
|
|
|
+ let curVolume = this.curVolume
|
|
|
+ this.$api.syllabus.ShareTree({
|
|
|
+ "school": curVolume.school,
|
|
|
+ "scope": curVolume.scope,
|
|
|
+ "tmdInfo": [
|
|
|
+ {
|
|
|
+ "tmdid": this.$store.state.userInfo.TEAMModelId,
|
|
|
+ "tmdname": this.$store.state.userInfo.name
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ "type": 'coedit',
|
|
|
+ "issuer": this.$store.state.userInfo.TEAMModelId,
|
|
|
+ "opt": 'add',
|
|
|
+ "syllabusId": id,
|
|
|
+ "syllabusName":name,
|
|
|
+ "volumeId": curVolume.id,
|
|
|
+ "volumeName": curVolume.name
|
|
|
+ }).then(res => {
|
|
|
+ if(res.code === 200){
|
|
|
+ r(200)
|
|
|
+ }
|
|
|
+ }).catch(err => {
|
|
|
+ this.$Message.error(err)
|
|
|
+ j(err)
|
|
|
+ })
|
|
|
+ })
|
|
|
+
|
|
|
+ },
|
|
|
/* 点击某个节点 */
|
|
|
onNodeClick(data) {
|
|
|
this.curChapter = this.getChapterByNode(data.node)
|
|
@@ -846,7 +942,7 @@
|
|
|
if (!/^(http:|https:)/i.test(curLink)) {
|
|
|
curLink = "http://" + curLink;
|
|
|
}
|
|
|
- if(!this.isURL(curLink)){
|
|
|
+ if (!this.isURL(curLink)) {
|
|
|
this.$Message.warning(this.$t('evaluation.repairResourse.formatErrorTip'))
|
|
|
return
|
|
|
}
|
|
@@ -859,28 +955,39 @@
|
|
|
type: 'link',
|
|
|
ctnr: ''
|
|
|
})
|
|
|
+ this.$refs.treeRef.curData.creatorId = this.$store.state.userInfo.TEAMModelId
|
|
|
this.modifyIdArr.push(this.curChapter.data.id)
|
|
|
this.hasModify = true
|
|
|
this.isShowLinkModal = false
|
|
|
},
|
|
|
/* 判断是否为正确的链接地址 */
|
|
|
isURL(url) {
|
|
|
- const strRegex = '^((https|http|ftp)://)?'//(https或http或ftp):// 可有可无
|
|
|
- + '(([\\w_!~*\'()\\.&=+$%-]+: )?[\\w_!~*\'()\\.&=+$%-]+@)?' //ftp的user@ 可有可无
|
|
|
- + '(([0-9]{1,3}\\.){3}[0-9]{1,3}' // IP形式的URL- 3位数字.3位数字.3位数字.3位数字
|
|
|
- + '|' // 允许IP和DOMAIN(域名)
|
|
|
- + '(localhost)|' //匹配localhost
|
|
|
- + '([\\w_!~*\'()-]+\\.)*' // 域名- 至少一个[英文或数字_!~*\'()-]加上.
|
|
|
- + '\\w+\\.' // 一级域名 -英文或数字 加上.
|
|
|
- + '[a-zA-Z]{1,6})' // 顶级域名- 1-6位英文
|
|
|
- + '(:[0-9]{1,5})?' // 端口- :80 ,1-5位数字
|
|
|
- + '((/?)|' // url无参数结尾 - 斜杆或这没有
|
|
|
- + '(/[\\w_!~*\'()\\.;?:@&=+$,%#-]+)+/?)$';//请求参数结尾- 英文或数字和[]内的各种字符
|
|
|
- const re = new RegExp(strRegex, 'i'); // 大小写不敏感
|
|
|
- if (re.test(encodeURI(url))) {
|
|
|
- return true;
|
|
|
- }
|
|
|
- return false;
|
|
|
+ const strRegex = '^((https|http|ftp)://)?' //(https或http或ftp):// 可有可无
|
|
|
+ +
|
|
|
+ '(([\\w_!~*\'()\\.&=+$%-]+: )?[\\w_!~*\'()\\.&=+$%-]+@)?' //ftp的user@ 可有可无
|
|
|
+ +
|
|
|
+ '(([0-9]{1,3}\\.){3}[0-9]{1,3}' // IP形式的URL- 3位数字.3位数字.3位数字.3位数字
|
|
|
+ +
|
|
|
+ '|' // 允许IP和DOMAIN(域名)
|
|
|
+ +
|
|
|
+ '(localhost)|' //匹配localhost
|
|
|
+ +
|
|
|
+ '([\\w_!~*\'()-]+\\.)*' // 域名- 至少一个[英文或数字_!~*\'()-]加上.
|
|
|
+ +
|
|
|
+ '\\w+\\.' // 一级域名 -英文或数字 加上.
|
|
|
+ +
|
|
|
+ '[a-zA-Z]{1,6})' // 顶级域名- 1-6位英文
|
|
|
+ +
|
|
|
+ '(:[0-9]{1,5})?' // 端口- :80 ,1-5位数字
|
|
|
+ +
|
|
|
+ '((/?)|' // url无参数结尾 - 斜杆或这没有
|
|
|
+ +
|
|
|
+ '(/[\\w_!~*\'()\\.;?:@&=+$,%#-]+)+/?)$'; //请求参数结尾- 英文或数字和[]内的各种字符
|
|
|
+ const re = new RegExp(strRegex, 'i'); // 大小写不敏感
|
|
|
+ if (re.test(encodeURI(url))) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ return false;
|
|
|
},
|
|
|
/* 点击添加关联内容 */
|
|
|
async onAddResource(type) {
|
|
@@ -994,7 +1101,7 @@
|
|
|
'private')
|
|
|
let schoolSas = await this.$tools.getSchoolSas()
|
|
|
let schoolBlobTool = new BlobTool(schoolSas.url, schoolSas.name, schoolSas.sas,
|
|
|
- 'school')
|
|
|
+ 'school')
|
|
|
let toClient = privateToSchool ? schoolBlobTool : privateBlobTool
|
|
|
let fromClient = privateToSchool ? privateBlobTool : schoolBlobTool
|
|
|
const itemJsonFile = await this.$evTools.createBlobItem(pItem);
|
|
@@ -1023,7 +1130,7 @@
|
|
|
onSelectQuestion(val) {
|
|
|
return new Promise((r, j) => {
|
|
|
let exRef = this.$refs.chooseContentRef.$refs.exListRef
|
|
|
- let list = exRef ? exRef.selectItems : []
|
|
|
+ let list = exRef ? exRef.selectItems : []
|
|
|
console.log('xxxxx', list)
|
|
|
if (!list.length) {
|
|
|
r(200)
|
|
@@ -1198,7 +1305,7 @@
|
|
|
onSelectPaper() {
|
|
|
return new Promise(async (r, j) => {
|
|
|
let paperRef = this.$refs.chooseContentRef.$refs.paperListRef
|
|
|
- let list = paperRef ? paperRef.checkedPaperList : []
|
|
|
+ let list = paperRef ? paperRef.checkedPaperList : []
|
|
|
if (!list.length) {
|
|
|
r(200)
|
|
|
} else {
|
|
@@ -1215,7 +1322,8 @@
|
|
|
if (schoolPaperList.map(i => i.name).includes(paper.name)) {
|
|
|
this.$Modal.confirm({
|
|
|
title: '提示',
|
|
|
- content: this.$t('syllabus.copyTip1') + paper.name +
|
|
|
+ content: this.$t('syllabus.copyTip1') + paper
|
|
|
+ .name +
|
|
|
this.$t('syllabus.copyTip2'),
|
|
|
onOk: async () => {
|
|
|
// 继续进行操作完成试卷覆盖
|
|
@@ -1257,7 +1365,7 @@
|
|
|
// 拿到试卷的index.json 先完善学段科目年级信息后 去进行上传覆盖操作
|
|
|
let indexJsonFile = await this.$tools.getFile(this.$evTools
|
|
|
.getBlobHost() + '/' + paper.code.replace('Paper-',
|
|
|
- '') + paper.blob + '/index.json' + privateSas.sas)
|
|
|
+ '') + paper.blob + '/index.json' + privateSas.sas)
|
|
|
let paperIndexJson = JSON.parse(indexJsonFile)
|
|
|
paperIndexJson.periodId = this.periodList[this
|
|
|
.currentPeriodIndex].id
|
|
@@ -1330,6 +1438,7 @@
|
|
|
this.isRelateContentModal = false
|
|
|
this.hasModify = true
|
|
|
this.modifyIdArr.push(this.curChapter.data.id)
|
|
|
+ this.$refs.treeRef.curData.creatorId = this.$store.state.userInfo.TEAMModelId
|
|
|
}).catch(err => {
|
|
|
console.log(err)
|
|
|
this.isRelateLoading = false
|
|
@@ -1394,7 +1503,7 @@
|
|
|
break;
|
|
|
case 'other':
|
|
|
this.$Message.warning(this.$t('syllabus.noPreview'))
|
|
|
- break;
|
|
|
+ break;
|
|
|
case 'doc':
|
|
|
let copyLink = JSON.parse(JSON.stringify(item.link))
|
|
|
let docSas = ''
|
|
@@ -1452,6 +1561,7 @@
|
|
|
this.$refs.treeRef.curData.rnodes.splice(index, 1)
|
|
|
this.hasModify = true
|
|
|
this.modifyIdArr.push(this.curChapter.data.id)
|
|
|
+ this.$refs.treeRef.curData.creatorId = this.$store.state.userInfo.TEAMModelId
|
|
|
}).catch(err => {
|
|
|
this.$Message.error(err)
|
|
|
}).finally(() => {
|
|
@@ -1489,9 +1599,13 @@
|
|
|
handleSubmit() {
|
|
|
return new Promise((r, j) => {
|
|
|
this.isAddLoading = true
|
|
|
- console.log(this.addVolumeForm)
|
|
|
- console.log(this.curVolume)
|
|
|
let addVolumeParams = {
|
|
|
+ "auth": this.addVolumeForm.auth.map(i => {
|
|
|
+ return {
|
|
|
+ tmdid: i,
|
|
|
+ tmdname: this.teacherList.find(j => j.id === i).name
|
|
|
+ }
|
|
|
+ }),
|
|
|
"code": this.curCode,
|
|
|
"periodId": this.isSchool ? this.periodList[this.currentPeriodIndex].id : null,
|
|
|
"subjectId": this.isSchool ? this.subjectList[this.activeSubjectIndex].id : null,
|
|
@@ -1523,7 +1637,8 @@
|
|
|
this.getVolumeList(true)
|
|
|
r(200)
|
|
|
} else {
|
|
|
- this.$Message.warning(res.error === 4 ? this.$t('syllabus.isExistVolume') : res.error);
|
|
|
+ this.$Message.warning(res.error === 4 ? this.$t('syllabus.isExistVolume') : res
|
|
|
+ .error);
|
|
|
}
|
|
|
}).catch(err => {
|
|
|
// this.$Message.error(err);
|
|
@@ -1602,6 +1717,11 @@
|
|
|
return item.type !== 'item' && item.type !== 'paper' && item.type !== 'link'
|
|
|
}
|
|
|
},
|
|
|
+ hasVolumeAuth(){
|
|
|
+ return auth => {
|
|
|
+ return this.$access.can('admin.*|Syllabus_Edit') || auth.map(i => i.tmdid).includes(this.$store.state.userInfo.TEAMModelId)
|
|
|
+ }
|
|
|
+ },
|
|
|
hasEditAuth() {
|
|
|
return nodeData => {
|
|
|
if (!nodeData.id) return false
|
|
@@ -1610,7 +1730,7 @@
|
|
|
let chapterId = nodeData.pid === this.curVolume.id ? nodeData.id : this.getChapterIdById(nodeData
|
|
|
.id)
|
|
|
let chapterNode = this.treeOrigin.find(i => i.id === chapterId)
|
|
|
- return this.curVolume.creatorId === userId || (chapterNode.auth && chapterNode.auth.length &&
|
|
|
+ return this.$access.can('admin.*|Syllabus_Edit') || this.curVolume.auth.map(i => i.tmdid).includes(userId) || (chapterNode.auth && chapterNode.auth.length &&
|
|
|
chapterNode.auth.map(i => i.tmdid).includes(userId))
|
|
|
}
|
|
|
},
|
|
@@ -1775,14 +1895,14 @@
|
|
|
color: #808080;
|
|
|
}
|
|
|
|
|
|
- .form-container .ivu-select-single .ivu-select-selection {
|
|
|
+ .form-container .ivu-select-selection {
|
|
|
background: #575757;
|
|
|
color: #fbfbfb;
|
|
|
border-color: transparent;
|
|
|
height: 35px;
|
|
|
}
|
|
|
|
|
|
- .form-container .ivu-select-single .ivu-select-arrow {
|
|
|
+ .form-container .ivu-select-arrow {
|
|
|
color: #fbfbfb;
|
|
|
}
|
|
|
|