edit 框架设计
This commit is contained in:
parent
586ce134f8
commit
49facdffa9
|
@ -20,23 +20,31 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="center-con" v-loading="loading">
|
<div class="center-con" v-loading="loading">
|
||||||
<!-- <TypingEffect v-if="answer" :text="answer" :delay="10" :aiShow="aiShow"/> -->
|
<template v-if="answer.title">
|
||||||
<div style="font-size: 18px;color: #409eff;">封面页</div>
|
<div class="flex justify-between">
|
||||||
|
<span style="font-size: 18px;color: #409eff;">封面页</span>
|
||||||
|
<el-button type="primary" link @click="onEdit(item, -1)">编辑</el-button>
|
||||||
|
</div>
|
||||||
<div class="con-item mb-5">
|
<div class="con-item mb-5">
|
||||||
<div class="item-name">标题:{{ answer.title }}</div>
|
<div class="item-name">标题:{{ answer.title }}</div>
|
||||||
<div class="item-name">副标题:{{answer.subTitle }}</div>
|
<div class="item-name">副标题:{{ answer.subTitle }}</div>
|
||||||
</div>
|
</div>
|
||||||
<div style="font-size: 18px;color: #409eff;">目录页</div>
|
<div style="font-size: 18px;color: #409eff;">目录页</div>
|
||||||
<div class="con-item" v-for="(item,index) in answer.chapters">
|
<div class="con-item" v-for="(item, index) in answer.chapters">
|
||||||
<div class="item-name">{{index + 1}}:{{ item.chapterTitle }}</div>
|
<div class="item-name">
|
||||||
|
<span>{{ index + 1 }}:{{ item.chapterTitle }}</span>
|
||||||
|
<el-button type="primary" link @click="onEdit(item, index)">编辑</el-button>
|
||||||
|
</div>
|
||||||
<div class="item-text">
|
<div class="item-text">
|
||||||
<p v-for="(el,i) in item.chapterContents">{{ index + 1 }} - {{ i + 1}} : {{ el.chapterTitle }}</p>
|
<p v-for="(el, i) in item.chapterContents">{{ index + 1 }} - {{ i + 1 }} : {{ el.chapterTitle }}</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<el-empty v-else description="请选择符合您需要的教学模式,生成教学大纲" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<el-empty v-if="!answer.title" description="请选择符合您需要的教学模式,生成教学大纲" />
|
<EditDialog v-model="isEdit" :item="editItem" :index="editIndex" />
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<EditDialog v-model="isEdit" :item="curItem" />
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
|
@ -47,9 +55,10 @@ import EditDialog from './edit-dialog.vue'
|
||||||
import emitter from '@/utils/mitt'
|
import emitter from '@/utils/mitt'
|
||||||
import * as commUtils from '@/utils/comm.js'
|
import * as commUtils from '@/utils/comm.js'
|
||||||
import { createChart, sendChart } from '@/api/ai/index'
|
import { createChart, sendChart } from '@/api/ai/index'
|
||||||
import { completion, addSyllabus, syllabuss, removeSyllabus } from '@/api/mode/index.js'
|
import { completion, addSyllabus, syllabuss, removeSyllabus, editSyllabus } from '@/api/mode/index.js'
|
||||||
import { createOutlineV2 } from '@/utils/ppt-request.js'
|
import { createOutlineV2 } from '@/utils/ppt-request.js'
|
||||||
import useUserStore from '@/store/modules/user'
|
import useUserStore from '@/store/modules/user'
|
||||||
|
import { cloneDeep } from 'lodash'
|
||||||
|
|
||||||
const curMode = ref(2)
|
const curMode = ref(2)
|
||||||
const isEdit = ref(false)
|
const isEdit = ref(false)
|
||||||
|
@ -70,26 +79,22 @@ const modeOptions = ref([
|
||||||
|
|
||||||
// 选中的环节
|
// 选中的环节
|
||||||
const selectedData = ref([])
|
const selectedData = ref([])
|
||||||
emitter.on('selected', (data)=>{
|
emitter.on('selected', (data) => {
|
||||||
selectedData.value = data
|
selectedData.value = data
|
||||||
})
|
})
|
||||||
// 回显大纲
|
// 回显大纲
|
||||||
const curItem = reactive({})
|
const curItem = reactive({})
|
||||||
emitter.on('onShow', (data)=>{
|
emitter.on('onShow', (data) => {
|
||||||
console.log(data)
|
console.log(data)
|
||||||
aiShow.value = false
|
aiShow.value = false
|
||||||
Object.assign(answer, JSON.parse(data.outline))
|
Object.assign(answer, JSON.parse(data.outline))
|
||||||
|
|
||||||
|
|
||||||
Object.assign(curItem, data)
|
Object.assign(curItem, data)
|
||||||
curItem.answer = curItem.outline
|
emitter.emit('onResult',data)
|
||||||
getDetails(data.id)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
const getDetails = (id) =>{
|
|
||||||
syllabuss(id).then( res =>{
|
|
||||||
Object.assign(curItem, res.data)
|
|
||||||
emitter.emit('onResult', res.data)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
const params = reactive(
|
const params = reactive(
|
||||||
{
|
{
|
||||||
|
@ -103,13 +108,13 @@ const params = reactive(
|
||||||
const loading = ref(false)
|
const loading = ref(false)
|
||||||
const answer = reactive({})
|
const answer = reactive({})
|
||||||
|
|
||||||
const createAi = async ()=>{
|
const createAi = async () => {
|
||||||
if(selectedData.value.length == 0){
|
if (selectedData.value.length == 0) {
|
||||||
ElMessage.warning('请先选择教学环节后再生成教学大纲')
|
ElMessage.warning('请先选择教学环节后再生成教学大纲')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
let str = selectedData.value.map( item => item.name).join('、')
|
let str = selectedData.value.map(item => item.name).join('、')
|
||||||
let bookV = curNode.roottitle.split('-')[1] + '版'
|
let bookV = curNode.roottitle.split('-')[1] + '版'
|
||||||
loading.value = true
|
loading.value = true
|
||||||
aiShow.value = true
|
aiShow.value = true
|
||||||
|
@ -134,7 +139,7 @@ const createAi = async ()=>{
|
||||||
|
|
||||||
data = res.data
|
data = res.data
|
||||||
}
|
}
|
||||||
const res = await createOutlineV2({query: data.answer})
|
const res = await createOutlineV2({ query: data.answer })
|
||||||
console.log(res)
|
console.log(res)
|
||||||
emitter.emit('onResult', res)
|
emitter.emit('onResult', res)
|
||||||
Object.assign(answer, res.outline)
|
Object.assign(answer, res.outline)
|
||||||
|
@ -144,11 +149,49 @@ const createAi = async ()=>{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 编辑大纲
|
||||||
|
const editItem = reactive({})
|
||||||
|
const editIndex = ref(0)
|
||||||
|
const onEdit = (item, index)=>{
|
||||||
|
|
||||||
|
let obj = null
|
||||||
|
if(index == -1){
|
||||||
|
obj = {
|
||||||
|
title: answer.title,
|
||||||
|
subTitle: answer.subTitle
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
obj = cloneDeep(item)
|
||||||
|
}
|
||||||
|
editIndex.value = index
|
||||||
|
isEdit.value = true
|
||||||
|
Object.assign(editItem, obj)
|
||||||
|
}
|
||||||
|
|
||||||
|
emitter.on('editItem', (item) =>{
|
||||||
|
if(editIndex.value == -1){
|
||||||
|
answer.title = item.title
|
||||||
|
answer.subTitle = item.subTitle
|
||||||
|
}else{
|
||||||
|
answer.chapters[editIndex.value] = item
|
||||||
|
}
|
||||||
|
let data = cloneDeep(curItem)
|
||||||
|
|
||||||
|
data.outline = JSON.stringify(cloneDeep(answer))
|
||||||
|
loading.value = true
|
||||||
|
|
||||||
|
editSyllabus(data).then( res =>{
|
||||||
|
ElMessage.success('操作成功')
|
||||||
|
}).finally( ()=>{
|
||||||
|
loading.value = false
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
// 保存模板
|
// 保存模板
|
||||||
const onSaveTemp = async (answer) => {
|
const onSaveTemp = async (answer) => {
|
||||||
if (answer == '') return
|
if (answer == '') return
|
||||||
let modelIds = selectedData.value.map( item => item.id).join(',')
|
let modelIds = selectedData.value.map(item => item.id).join(',')
|
||||||
const data = {
|
const data = {
|
||||||
eduId: curNode.id,
|
eduId: curNode.id,
|
||||||
outline: answer,
|
outline: answer,
|
||||||
|
@ -162,7 +205,7 @@ const onSaveTemp = async (answer) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
// 删除大纲
|
// 删除大纲
|
||||||
const delAnswer = () =>{
|
const delAnswer = () => {
|
||||||
ElMessageBox.confirm(
|
ElMessageBox.confirm(
|
||||||
'确定要删除大纲吗?',
|
'确定要删除大纲吗?',
|
||||||
'温馨提示',
|
'温馨提示',
|
||||||
|
@ -178,7 +221,7 @@ const delAnswer = () =>{
|
||||||
answer.value = ''
|
answer.value = ''
|
||||||
emitter.emit('resetSelect')
|
emitter.emit('resetSelect')
|
||||||
})
|
})
|
||||||
.catch(() => {})
|
.catch(() => { })
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -192,9 +235,11 @@ const getChartId = () => {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
onUnmounted(()=>{
|
onUnmounted(() => {
|
||||||
emitter.off('selected')
|
emitter.off('selected')
|
||||||
emitter.off('onShow')
|
emitter.off('onShow')
|
||||||
|
emitter.off('editItem')
|
||||||
|
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -216,18 +261,21 @@ onMounted(() => {
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.container-center{
|
.container-center {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
font-size: 15px;
|
font-size: 15px;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
.center-header{
|
|
||||||
|
.center-header {
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
.icon-jiahao{
|
|
||||||
|
.icon-jiahao {
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.center-con{
|
|
||||||
|
.center-con {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
margin-top: 5px;
|
margin-top: 5px;
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
|
@ -235,11 +283,16 @@ onMounted(() => {
|
||||||
text-align: left;
|
text-align: left;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
padding: 15px;
|
padding: 15px;
|
||||||
.con-item{
|
|
||||||
|
.con-item {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
margin-top: 15px;
|
margin-top: 15px;
|
||||||
.item-text{
|
.item-name{
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
.item-text {
|
||||||
background: #F2F2F2;
|
background: #F2F2F2;
|
||||||
padding: 15px;
|
padding: 15px;
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
|
@ -248,5 +301,4 @@ onMounted(() => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
|
@ -7,11 +7,28 @@
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<div class="dialog-content" v-loading="loading">
|
<div class="dialog-content" v-loading="loading">
|
||||||
<el-row>
|
<template v-if="props.index == -1">
|
||||||
<el-col :span="24">
|
<div class="flex mb-5">
|
||||||
<el-input v-model="textarea" :autosize="{ minRows: 5, maxRows: 15 }" type="textarea" />
|
<span class="name">标题:</span>
|
||||||
</el-col>
|
<el-input v-model="editItem.title" />
|
||||||
</el-row>
|
</div>
|
||||||
|
<div class="flex mb-5">
|
||||||
|
<span class="name">副标题</span>
|
||||||
|
<el-input v-model="editItem.subTitle" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<template v-else>
|
||||||
|
<div class="flex mb-5">
|
||||||
|
<span class="name">标题:</span>
|
||||||
|
<el-input v-model="editItem.chapterTitle" />
|
||||||
|
</div>
|
||||||
|
<div class="flex">
|
||||||
|
<span class="name">内容:</span>
|
||||||
|
<div class="flex edit-con">
|
||||||
|
<el-input class="mb-3" v-model="item.chapterTitle" v-for="item in editItem.chapterContents" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<template #footer>
|
<template #footer>
|
||||||
|
@ -26,13 +43,13 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, watch} from 'vue'
|
import { reactive, ref, watch} from 'vue'
|
||||||
import { ElMessage } from 'element-plus'
|
import { ElMessage } from 'element-plus'
|
||||||
import { editSyllabus } from '@/api/mode/index.js'
|
import { editSyllabus } from '@/api/mode/index.js'
|
||||||
import { cloneDeep } from 'lodash';
|
import { cloneDeep } from 'lodash';
|
||||||
import emitter from '@/utils/mitt';
|
import emitter from '@/utils/mitt';
|
||||||
|
|
||||||
const textarea = ref('')
|
|
||||||
|
|
||||||
const isDialog = defineModel()
|
const isDialog = defineModel()
|
||||||
const loading = ref(false)
|
const loading = ref(false)
|
||||||
|
@ -40,20 +57,28 @@ const loading = ref(false)
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
item: {
|
item: {
|
||||||
type: Object,
|
type: Object,
|
||||||
default: () => {
|
|
||||||
return { name: '11' }
|
},
|
||||||
}
|
index: {
|
||||||
|
type: [Number, String]
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
watch(() => props.item.answer, (newVal) => {
|
const editItem = reactive({})
|
||||||
if (newVal) {
|
|
||||||
textarea.value = newVal
|
watch(() => isDialog.value, (newVal) => {
|
||||||
|
if(newVal){
|
||||||
|
let data = cloneDeep(props.item)
|
||||||
|
Object.assign(editItem, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
},{ deep: true })
|
},{ deep: true })
|
||||||
|
|
||||||
const emit = defineEmits(['saveEdit'])
|
const emit = defineEmits(['saveEdit'])
|
||||||
const onSave = () =>{
|
const onSave = () =>{
|
||||||
|
emitter.emit('editItem', editItem)
|
||||||
|
isDialog.value = false
|
||||||
|
return
|
||||||
loading.value = true
|
loading.value = true
|
||||||
let data = cloneDeep(props.item)
|
let data = cloneDeep(props.item)
|
||||||
data.outline = textarea.value
|
data.outline = textarea.value
|
||||||
|
@ -83,6 +108,12 @@ const onSave = () =>{
|
||||||
|
|
||||||
.dialog-content {
|
.dialog-content {
|
||||||
padding-top: 10px;
|
padding-top: 10px;
|
||||||
|
.name{
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
.edit-con{
|
||||||
|
width: 100%;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
Loading…
Reference in New Issue