持续开发习题管理模块,新增ckeditor5富文本组件
parent
cbe10214f5
commit
40f5e10da7
@ -0,0 +1,12 @@
|
|||||||
|
import service from '@/utils/request'
|
||||||
|
const api = {
|
||||||
|
// 课程api
|
||||||
|
getExercisesList : data => {
|
||||||
|
return service({
|
||||||
|
url: '/question',
|
||||||
|
method: 'get',
|
||||||
|
params:data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export default api
|
@ -0,0 +1,180 @@
|
|||||||
|
<template>
|
||||||
|
<div id="app-ckeditor">
|
||||||
|
<ckeditor
|
||||||
|
v-model="editorData2"
|
||||||
|
:config="editorConfig"
|
||||||
|
@ready="logEvent('ready', $event)"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<!--<script src="/node_modules/ckeditor4/ckeditor.js"></script>-->
|
||||||
|
<!--<script src="/node_modules/ckeditor4-vue/dist/ckeditor.js"></script>-->
|
||||||
|
<!--<script src="https://cdn.ckeditor.com/4.19.1/standard-all/ckeditor.js"></script>-->
|
||||||
|
<script>
|
||||||
|
// import { MyCustomUploadAdapterPlugin } from "@/components/richText/customUploadAdapter";
|
||||||
|
import { getToken } from '@/utils/auth'
|
||||||
|
export default {
|
||||||
|
name: 'ckEditor4',
|
||||||
|
model: {
|
||||||
|
prop: 'content',
|
||||||
|
event: 'change'
|
||||||
|
},
|
||||||
|
props: ['modelValue', 'content'],
|
||||||
|
emits: ['update:modelValue'],
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
img_url:'',
|
||||||
|
events: [],
|
||||||
|
// editorUrl: "https://xxx/ckeditor/ckeditor.js",
|
||||||
|
editorConfig: {
|
||||||
|
extraPlugins: 'uploadimage,image2',
|
||||||
|
uploadUrl: 'https://apiwx.twzxjy.com/api/v1/public/uploadFile?command=QuickUpload&type=Files&responseType=json',
|
||||||
|
filebrowserBrowseUrl: 'https://apiwx.twzxjy.com/api/v1/public/uploadFile',
|
||||||
|
filebrowserImageBrowseUrl: 'https://apiwx.twzxjy.com/api/v1/public/uploadFile?type=Images',
|
||||||
|
filebrowserUploadUrl: 'https://apiwx.twzxjy.com/api/v1/public/uploadFile?command=QuickUpload&type=Files',
|
||||||
|
filebrowserImageUploadUrl: 'https://apiwx.twzxjy.com/api/v1/public/uploadFile',
|
||||||
|
imageUploadUrl: 'https://apiwx.twzxjy.com/api/v1/public/uploadFile',
|
||||||
|
|
||||||
|
fileTools_requestHeaders: {
|
||||||
|
'Authorization': 'Bearer ' + getToken()
|
||||||
|
},
|
||||||
|
image2_alignClasses: ['image-align-left', 'image-align-center', 'image-align-right'],
|
||||||
|
image2_disableResizer: true,
|
||||||
|
removeButtons: 'PasteFromWord'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
editorData: {
|
||||||
|
get() {
|
||||||
|
return this.modelValue
|
||||||
|
},
|
||||||
|
set(value) {
|
||||||
|
console.log(value)
|
||||||
|
this.$emit('update:modelValue', value)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
editorData2: {
|
||||||
|
get() {
|
||||||
|
return this.content
|
||||||
|
|
||||||
|
},
|
||||||
|
set(value) {
|
||||||
|
this.$emit('change', value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
// editorData(val1) {
|
||||||
|
// console.log(val1)
|
||||||
|
// }
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.getScript()
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
getScript() {
|
||||||
|
const script = document.createElement('script')
|
||||||
|
script.type = 'text/javascript'
|
||||||
|
script.src = '/node_modules/ckeditor4/ckeditor.js'
|
||||||
|
document.getElementsByTagName('head')[0].appendChild(script)
|
||||||
|
},
|
||||||
|
logEvent: function(eventName, event) {
|
||||||
|
const _this = this
|
||||||
|
// console.log(event)
|
||||||
|
// 上传请求
|
||||||
|
event.on( 'fileUploadRequest', async evt => {
|
||||||
|
console.log(evt)
|
||||||
|
var fileLoader = evt.data.fileLoader;
|
||||||
|
// let formData = new FormData();
|
||||||
|
// let xhr = fileLoader.xhr;
|
||||||
|
// xhr.setRequestHeader( 'Authorization', 'Bearer ' + getToken() );
|
||||||
|
// xhr.open( 'POST', fileLoader.uploadUrl, true );
|
||||||
|
// formData.append( 'multipartFile', fileLoader.file);
|
||||||
|
// fileLoader.xhr.send( formData );
|
||||||
|
|
||||||
|
|
||||||
|
// 测试
|
||||||
|
const xhr_ = new XMLHttpRequest()
|
||||||
|
xhr_.onreadystatechange=function()
|
||||||
|
{
|
||||||
|
if (xhr_.readyState==4 && xhr_.status==200)
|
||||||
|
{
|
||||||
|
// console.log(xhr_)
|
||||||
|
_this.img_url = xhr_.response.data.full_path
|
||||||
|
// var data = evt.data;
|
||||||
|
// data.url = res_url
|
||||||
|
// 用官方的方法进行访问
|
||||||
|
let xhr = fileLoader.xhr;
|
||||||
|
xhr.open( 'POST', fileLoader.uploadUrl, true );
|
||||||
|
xhr.setRequestHeader('Authorization', 'Bearer ' + getToken())
|
||||||
|
let formData = new FormData();
|
||||||
|
formData.append( 'multipartFile', fileLoader.file);
|
||||||
|
fileLoader.xhr.send( formData );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
xhr_.open('POST', fileLoader.uploadUrl, true)
|
||||||
|
xhr_.setRequestHeader('Authorization', 'Bearer ' + getToken())
|
||||||
|
xhr_.responseType = 'json'
|
||||||
|
|
||||||
|
const data = new FormData();
|
||||||
|
// 上传参数就根据后端的处理而设置了
|
||||||
|
data.append( 'file', fileLoader.file );
|
||||||
|
xhr_.send(data);
|
||||||
|
|
||||||
|
// 测试结束
|
||||||
|
|
||||||
|
// Prevented the default behavior.
|
||||||
|
evt.stop()
|
||||||
|
})
|
||||||
|
// 回调
|
||||||
|
event.on( 'fileUploadResponse', async evt => {
|
||||||
|
console.log(evt)
|
||||||
|
evt.stop();
|
||||||
|
evt.data.url = _this.img_url
|
||||||
|
// var data = evt.data;
|
||||||
|
// let xhr = data.fileLoader.xhr;
|
||||||
|
// let response = xhr.responseText;
|
||||||
|
// let imgUrl = JSON.parse(response).data;
|
||||||
|
// if(!imgUrl){
|
||||||
|
// data.message = imgUrl // 这是失败alert提示信息
|
||||||
|
// evt.cancel();
|
||||||
|
// }else{
|
||||||
|
// data.url = imgUrl // 返回到“图像信息”那里的URL框里面
|
||||||
|
// }
|
||||||
|
})
|
||||||
|
// if (this.events.length > 19) {
|
||||||
|
// this.events.pop()
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// const eventData = {
|
||||||
|
// name: eventName,
|
||||||
|
// timestamp: this.getCurrentTimestamp()
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// this.events.unshift(eventData)
|
||||||
|
|
||||||
|
// console.log(eventData.timestamp, eventData.name, event)
|
||||||
|
},
|
||||||
|
|
||||||
|
getCurrentTimestamp: function() {
|
||||||
|
return new Intl.DateTimeFormat('en', {
|
||||||
|
hour12: false,
|
||||||
|
hour: '2-digit',
|
||||||
|
minute: '2-digit',
|
||||||
|
second: '2-digit'
|
||||||
|
}).format(new Date())
|
||||||
|
},
|
||||||
|
|
||||||
|
clearEventsLog: function() {
|
||||||
|
this.events = []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style>
|
||||||
|
.ck-editor__main{
|
||||||
|
max-height: 350px;
|
||||||
|
overflow: scroll;
|
||||||
|
}
|
||||||
|
</style>
|
@ -0,0 +1,53 @@
|
|||||||
|
<template>
|
||||||
|
<div id="editor-box">
|
||||||
|
<ckeditor :editor="editor" v-model="value" :config="editorConfig" @ready="logEvent('ready', $event)"></ckeditor>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script >
|
||||||
|
// import ClassicEditor from '@ckeditor/ckeditor5-build-classic';
|
||||||
|
import ClassicEditor from 'axl-editor';
|
||||||
|
import { MyCustomUploadAdapterPlugin } from '@/components/richText/customUploadAdapter'
|
||||||
|
// import {ref,onMounted } from 'vue'
|
||||||
|
export default {
|
||||||
|
name: 'editor-box',
|
||||||
|
props: ['modelValue','content'],
|
||||||
|
emits: ['update:modelValue'],
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
editor: ClassicEditor,
|
||||||
|
editorData: '<p>Content of the editor.</p>',
|
||||||
|
editorConfig: {
|
||||||
|
// The configuration of the editor.
|
||||||
|
// uploadUrl: 'https://apiwx.twzxjy.com/api/v1/public/uploadFile?command=QuickUpload&type=Files&responseType=json',
|
||||||
|
// simpleUpload:{
|
||||||
|
// uploadUrl: 'https://apiwx.twzxjy.com/api/v1/public/uploadFile?command=QuickUpload&type=Files&responseType=json',
|
||||||
|
// }
|
||||||
|
extraPlugins:[MyCustomUploadAdapterPlugin]
|
||||||
|
}
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
value: {
|
||||||
|
get() {
|
||||||
|
return this.modelValue
|
||||||
|
},
|
||||||
|
set(value) {
|
||||||
|
this.$emit('update:modelValue', value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods:{
|
||||||
|
logEvent(eventName, event){
|
||||||
|
const _this = this
|
||||||
|
console.log(eventName)
|
||||||
|
// event.on( 'fileUploadRequest', async evt => {
|
||||||
|
// console.log(evt)
|
||||||
|
// })
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// const name = ref(ClassicEditor)
|
||||||
|
// const editorData = ref('<p>Content of the editor.</p>')
|
||||||
|
// const editorConfig = ref({})
|
||||||
|
</script>
|
@ -0,0 +1,103 @@
|
|||||||
|
<script setup>
|
||||||
|
// 引入依赖
|
||||||
|
// import api from '@/api/course'
|
||||||
|
// import com_api from '@/api/common'
|
||||||
|
// import custom from '@/utils/custom'
|
||||||
|
// import WarningBar from '@/components/warningBar/warningBar.vue'
|
||||||
|
import {ref,onMounted,watch,inject } from 'vue'
|
||||||
|
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||||
|
import { useRouter, useRoute } from 'vue-router'
|
||||||
|
const router = useRouter()
|
||||||
|
const route = useRoute()
|
||||||
|
import { useUserStore } from '@/pinia/modules/user'
|
||||||
|
const userStore = useUserStore()
|
||||||
|
// import chapterCom from '../components/chapter.vue'
|
||||||
|
const props = defineProps(['url_name'])
|
||||||
|
const emit = defineEmits(['on-success'])
|
||||||
|
import { clients, getNowDate } from '@/utils'
|
||||||
|
import custom from '@/utils/custom'
|
||||||
|
// import { getToken } from '@/utils/auth'
|
||||||
|
// 变量
|
||||||
|
// const headers = ref({ Authorization: 'Bearer ' + getToken() })
|
||||||
|
const drawer = ref(false)
|
||||||
|
const queryParams =ref({
|
||||||
|
pageIndex:1,
|
||||||
|
pageSize:10,
|
||||||
|
content:'',
|
||||||
|
subject:'',
|
||||||
|
subject_type:''
|
||||||
|
})
|
||||||
|
const typeList = custom.getExercisesTypeList()
|
||||||
|
// 生命周期
|
||||||
|
const subjectList = inject('subjectList')
|
||||||
|
const current_subject = inject('current_subject')
|
||||||
|
onMounted(() => {
|
||||||
|
// console.log(headers.value)
|
||||||
|
})
|
||||||
|
|
||||||
|
// 方法
|
||||||
|
function chooseChapterChildExercises() {
|
||||||
|
drawer.value = true
|
||||||
|
}
|
||||||
|
function onSubmit() {
|
||||||
|
|
||||||
|
}
|
||||||
|
function onReset() {
|
||||||
|
queryParams.value = {
|
||||||
|
pageIndex:1,
|
||||||
|
pageSize:10,
|
||||||
|
name:''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<el-button size="small" @click="chooseChapterChildExercises">添加习题</el-button>
|
||||||
|
<div v-if="url_name">{{url_name}}</div>
|
||||||
|
<el-drawer v-model="drawer" title="媒体库" size="60%">
|
||||||
|
<div class="drawer-section">
|
||||||
|
<!-- 搜索框-->
|
||||||
|
<div class="search-box">
|
||||||
|
<el-form ref="searchForm" :inline="true" :model="queryParams">
|
||||||
|
<el-form-item label="题目">
|
||||||
|
<el-input v-model="queryParams.content" placeholder="请输入" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="课程分类">
|
||||||
|
<el-select v-model="queryParams.subject" clearable placeholder="请选择">
|
||||||
|
<el-option
|
||||||
|
v-for="item in subjectList"
|
||||||
|
:key="item.id"
|
||||||
|
:label="item.name"
|
||||||
|
:value="item.id"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="题目类型">
|
||||||
|
<el-select v-model="queryParams.subject_type" clearable placeholder="请选择">
|
||||||
|
<el-option
|
||||||
|
v-for="item in typeList"
|
||||||
|
:key="item.value"
|
||||||
|
:label="item.label"
|
||||||
|
:value="item.value"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button size="small" type="primary" icon="search" @click="onSubmit">查询</el-button>
|
||||||
|
<el-button size="small" icon="refresh" @click="onReset">重置</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</div>
|
||||||
|
<!-- 数据列表-->
|
||||||
|
<div class="list-box">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</el-drawer>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<style scoped>
|
||||||
|
.drawer-section{
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
</style>
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue