持续开发习题管理模块,新增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