|
|
@@ -140,6 +140,7 @@
|
|
|
@editNote="handEditNote"
|
|
|
@saveCollect="saveCollect"
|
|
|
@getTranslate="getTranslate"
|
|
|
+ @editFeedback="handEditFeedback"
|
|
|
@selectedComponent="$emit('selectedComponent', $event)"
|
|
|
/>
|
|
|
<!-- <div
|
|
|
@@ -379,6 +380,26 @@
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
+ <div v-if="curToolbarIcon === 'feedback'" class="resource_box">
|
|
|
+ <h5>{{ drawerTitle }}</h5>
|
|
|
+ <div style="height: 40px"></div>
|
|
|
+ <ul v-if="allFeedbackList.length > 0" class="card-box">
|
|
|
+ <li v-for="item in allFeedbackList" :key="item.id">
|
|
|
+ <span class="el-icon-notebook-2"> 原文</span>
|
|
|
+ <span>{{ item.text }}</span>
|
|
|
+ <el-divider class="mt10" />
|
|
|
+ <span v-html="item.feedBack"></span>
|
|
|
+ <div>
|
|
|
+ <el-button type="text" class="el-icon-edit" @click="handEditFeedback(item)"> 编辑</el-button>
|
|
|
+ <el-divider direction="vertical" />
|
|
|
+ <el-button type="text" class="el-icon-delete" @click="handDelFeedback(item.id)"> 删除</el-button>
|
|
|
+ <el-divider direction="vertical" />
|
|
|
+ <el-button type="text" class="el-icon-place" @click="handleLocation(item, 13)"> 定位</el-button>
|
|
|
+ </div>
|
|
|
+ </li>
|
|
|
+ </ul>
|
|
|
+ </div>
|
|
|
+
|
|
|
<template v-if="curToolbarIcon === 'audit'">
|
|
|
<AuditRemark
|
|
|
:remark-list="remark_list"
|
|
|
@@ -410,7 +431,7 @@
|
|
|
|
|
|
<el-dialog
|
|
|
title="添加课件审核批注"
|
|
|
- :visible="visible"
|
|
|
+ :visible="visibleRemark"
|
|
|
width="680px"
|
|
|
:close-on-click-modal="false"
|
|
|
class="remark-dialog"
|
|
|
@@ -450,9 +471,9 @@
|
|
|
ref="explanatoryNote"
|
|
|
:open.sync="editDialogOpen"
|
|
|
:init-data="oldRichData"
|
|
|
- title-text="笔记"
|
|
|
- @confirm="saveNote"
|
|
|
- @cancel="delNote"
|
|
|
+ :title-text="dialogTitleText"
|
|
|
+ @confirm="dialogSave"
|
|
|
+ @cancel="dialogCancel"
|
|
|
/>
|
|
|
|
|
|
<TranslateDialog :open.sync="showTranslate" :init-text="translateText" :book-id="projectId" title-text="翻译" />
|
|
|
@@ -501,6 +522,9 @@ import {
|
|
|
SearchBookContentText,
|
|
|
SetBookResourceHide,
|
|
|
SubmitChapterAllCoursewareToAuditFlow,
|
|
|
+ AddCoursewareFeedback,
|
|
|
+ GetCoursewareFeedbackList,
|
|
|
+ DeleteCoursewareFeedback,
|
|
|
} from '@/api/book';
|
|
|
import { toggleFullScreen } from '@/utils/common';
|
|
|
import * as OpenCC from 'opencc-js';
|
|
|
@@ -582,6 +606,7 @@ export default {
|
|
|
{ icon: 'note', title: '笔记', handle: 'getNote', param: { type: '12' } },
|
|
|
{ icon: 'translate', title: '多语言', handle: 'openTranslate', param: { type: '21' } },
|
|
|
{ icon: 'setting', title: '设置', handle: 'openSetting', param: { type: 6 } },
|
|
|
+ { icon: 'feedback', title: '用户反馈', handle: 'getFeedback', param: { type: 22 } },
|
|
|
];
|
|
|
|
|
|
if (this.isShowAudit) {
|
|
|
@@ -619,7 +644,7 @@ export default {
|
|
|
remark_list_obj: {}, // 存放以组件为对象的批注数组
|
|
|
searchList: [],
|
|
|
searchContent: '',
|
|
|
- visible: false,
|
|
|
+ visibleRemark: false,
|
|
|
remark: {
|
|
|
remark_content: '',
|
|
|
file_id_list: [],
|
|
|
@@ -656,6 +681,7 @@ export default {
|
|
|
12: '笔记列表',
|
|
|
13: '搜索结果',
|
|
|
21: '多语言',
|
|
|
+ 22: '用户反馈',
|
|
|
},
|
|
|
page_capacity: 10,
|
|
|
cur_page: 1,
|
|
|
@@ -686,9 +712,11 @@ export default {
|
|
|
showTranslate: false,
|
|
|
translateText: '',
|
|
|
oldRichData: {},
|
|
|
+ dialogType: 1,
|
|
|
newSelectedInfo: null,
|
|
|
allCottectList: [],
|
|
|
bookChapterList: [],
|
|
|
+ allFeedbackList: [],
|
|
|
book_id: '',
|
|
|
activeBookChapterId: '',
|
|
|
multimediaLoadingStates: true,
|
|
|
@@ -724,6 +752,10 @@ export default {
|
|
|
return this.activeBookChapterId === chapter.id && item && item.file_id;
|
|
|
};
|
|
|
},
|
|
|
+ dialogTitleText() {
|
|
|
+ if (this.dialogType === 2) return '反馈';
|
|
|
+ return '笔记';
|
|
|
+ },
|
|
|
},
|
|
|
watch: {
|
|
|
isJudgeCorrect(newVal) {
|
|
|
@@ -740,6 +772,8 @@ export default {
|
|
|
this.getNote();
|
|
|
} else if (this.curToolbarIcon === 'collect') {
|
|
|
this.getCollect();
|
|
|
+ } else if (this.curToolbarIcon === 'feedback') {
|
|
|
+ this.getFeedback();
|
|
|
}
|
|
|
},
|
|
|
multimediaIsAllShow() {
|
|
|
@@ -940,7 +974,7 @@ export default {
|
|
|
remark_content: '',
|
|
|
file_id_list: [],
|
|
|
};
|
|
|
- this.visible = true;
|
|
|
+ this.visibleRemark = true;
|
|
|
if (selectNode) {
|
|
|
this.menuPosition = {
|
|
|
x,
|
|
|
@@ -974,7 +1008,7 @@ export default {
|
|
|
})
|
|
|
.then(() => {
|
|
|
this.submit_loading = false;
|
|
|
- this.visible = false;
|
|
|
+ this.visibleRemark = false;
|
|
|
this.getCoursewareAuditRemarkList(id || this.id);
|
|
|
})
|
|
|
.catch(() => {
|
|
|
@@ -1341,7 +1375,7 @@ export default {
|
|
|
/**
|
|
|
* 定位到对应位置
|
|
|
* @param {Object} item - 位置对象
|
|
|
- * @param {number} type - 定位类型(11: 笔记定位, 12: 收藏定位, 0: 资源定位)
|
|
|
+ * @param {number} type - 定位类型(11: 笔记定位, 12: 收藏定位, 13:反馈定位 0: 资源定位)
|
|
|
*/
|
|
|
handleLocation(item, type) {
|
|
|
if (type === 0) {
|
|
|
@@ -1363,6 +1397,14 @@ export default {
|
|
|
}
|
|
|
},
|
|
|
|
|
|
+ dialogSave(obj) {
|
|
|
+ if (this.dialogType === 1) return this.saveNote(obj);
|
|
|
+ if (this.dialogType === 2) return this.saveFeedback(obj);
|
|
|
+ },
|
|
|
+ dialogCancel(id) {
|
|
|
+ if (this.dialogType === 1) return this.delNote(id);
|
|
|
+ if (this.dialogType === 2) return this.delFeedback(id);
|
|
|
+ },
|
|
|
/**
|
|
|
* 获取笔记列表
|
|
|
* @param {Object} params - 参数对象
|
|
|
@@ -1404,16 +1446,18 @@ export default {
|
|
|
);
|
|
|
if (old) {
|
|
|
this.oldRichData = old;
|
|
|
+ this.oldRichData.dataStr = old.note;
|
|
|
}
|
|
|
this.newSelectedInfo = note;
|
|
|
this.editDialogOpen = true;
|
|
|
+ this.dialogType = 1;
|
|
|
},
|
|
|
saveNote(note) {
|
|
|
let noteInfo = {
|
|
|
blockId: this.newSelectedInfo.blockId,
|
|
|
startIndex: this.newSelectedInfo.startIndex,
|
|
|
endIndex: this.newSelectedInfo.endIndex,
|
|
|
- note: note.note,
|
|
|
+ note: note.dataStr,
|
|
|
text: this.newSelectedInfo.text,
|
|
|
};
|
|
|
|
|
|
@@ -1544,6 +1588,100 @@ export default {
|
|
|
this.showTranslate = true;
|
|
|
this.translateText = info.text;
|
|
|
},
|
|
|
+
|
|
|
+ async getFeedback(params) {
|
|
|
+ if (params && params.type) this.drawerType = Number(params.type);
|
|
|
+ this.allFeedbackList = [];
|
|
|
+ await GetCoursewareFeedbackList({ courseware_id: this.curSelectId }).then((res) => {
|
|
|
+ if (res.status === 1 && res.feedback_list) {
|
|
|
+ res.feedback_list.forEach((x) => {
|
|
|
+ if (x.content) {
|
|
|
+ let n = JSON.parse(x.content);
|
|
|
+ let obj = {
|
|
|
+ coursewareId: x.courseware_id,
|
|
|
+ id: x.id,
|
|
|
+ blockId: n.blockId,
|
|
|
+ startIndex: n.startIndex,
|
|
|
+ endIndex: n.endIndex,
|
|
|
+ text: n.text,
|
|
|
+ feedBack: n.feedBack,
|
|
|
+ };
|
|
|
+ this.allFeedbackList.push(obj);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+ });
|
|
|
+ },
|
|
|
+ async handEditFeedback(feedBack) {
|
|
|
+ this.oldRichData = {};
|
|
|
+ if (this.allFeedbackList.length === 0) {
|
|
|
+ await this.getFeedback();
|
|
|
+ }
|
|
|
+ let old = this.allFeedbackList.find(
|
|
|
+ (x) =>
|
|
|
+ x.coursewareId === feedBack.coursewareId &&
|
|
|
+ x.blockId === feedBack.blockId &&
|
|
|
+ x.startIndex === feedBack.startIndex &&
|
|
|
+ x.endIndex === feedBack.endIndex,
|
|
|
+ );
|
|
|
+ if (old) {
|
|
|
+ this.oldRichData = old;
|
|
|
+ this.oldRichData.dataStr = old.feedBack;
|
|
|
+ }
|
|
|
+ this.newSelectedInfo = feedBack;
|
|
|
+ this.editDialogOpen = true;
|
|
|
+ this.dialogType = 2;
|
|
|
+ },
|
|
|
+ saveFeedback(feedBack) {
|
|
|
+ if (feedBack.id) {
|
|
|
+ this.delFeedback(feedBack.id);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (feedBack.dataStr) {
|
|
|
+ let feedBackInfo = {
|
|
|
+ blockId: this.newSelectedInfo.blockId,
|
|
|
+ startIndex: this.newSelectedInfo.startIndex,
|
|
|
+ endIndex: this.newSelectedInfo.endIndex,
|
|
|
+ feedBack: feedBack.dataStr,
|
|
|
+ text: this.newSelectedInfo.text,
|
|
|
+ };
|
|
|
+
|
|
|
+ let reqData = {
|
|
|
+ courseware_id: this.newSelectedInfo.coursewareId, // 课件 ID
|
|
|
+ component_id: 'WHOLE',
|
|
|
+ content: JSON.stringify(feedBackInfo),
|
|
|
+ content_select: this.newSelectedInfo.text,
|
|
|
+ };
|
|
|
+
|
|
|
+ AddCoursewareFeedback(reqData).then(() => {
|
|
|
+ this.getFeedback();
|
|
|
+ });
|
|
|
+ }
|
|
|
+ this.editDialogOpen = false;
|
|
|
+ this.newSelectedInfo = null;
|
|
|
+ this.selectedInfo = null;
|
|
|
+ },
|
|
|
+ handDelFeedback(id) {
|
|
|
+ this.$confirm('确定要删除此条反馈吗?', '提示', {
|
|
|
+ confirmButtonText: '确定',
|
|
|
+ cancelButtonText: '取消',
|
|
|
+ type: 'warning',
|
|
|
+ })
|
|
|
+ .then(() => {
|
|
|
+ this.delFeedback(id);
|
|
|
+ })
|
|
|
+ .catch(() => {});
|
|
|
+ },
|
|
|
+ delFeedback(id) {
|
|
|
+ const feedBackId = id || (this.oldRichData && this.oldRichData.id);
|
|
|
+ if (!feedBackId) return;
|
|
|
+ DeleteCoursewareFeedback({ id: feedBackId })
|
|
|
+ .then(() => {
|
|
|
+ this.allFeedbackList = this.allFeedbackList.filter((x) => x.id !== feedBackId);
|
|
|
+ })
|
|
|
+ .catch((err) => {});
|
|
|
+ },
|
|
|
+
|
|
|
getSearch(params) {
|
|
|
if (params && params.type) this.drawerType = Number(params.type);
|
|
|
},
|