Compare commits
No commits in common. "5fe9359d6455ec80cbe84737ac97d57f767b2805" and "be9d33fcd37f72551593d69143124144f79ae7cf" have entirely different histories.
5fe9359d64
...
be9d33fcd3
|
@ -34,7 +34,7 @@ export default defineConfig({
|
||||||
'/dev-api': {
|
'/dev-api': {
|
||||||
target: 'http://27.128.240.72:7865',
|
target: 'http://27.128.240.72:7865',
|
||||||
// target: 'http://36.134.181.164:7863',
|
// target: 'http://36.134.181.164:7863',
|
||||||
// target: 'http://192.168.0.102:7865',
|
// target: 'http://192.168.2.52:7863',
|
||||||
changeOrigin: true,
|
changeOrigin: true,
|
||||||
rewrite: (p) => p.replace(/^\/dev-api/, '')
|
rewrite: (p) => p.replace(/^\/dev-api/, '')
|
||||||
},
|
},
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
http-equiv="Content-Security-Policy"
|
http-equiv="Content-Security-Policy"
|
||||||
content="default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:"
|
content="default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:"
|
||||||
/> -->
|
/> -->
|
||||||
<meta http-equiv="Content-Security-Policy" content="connect-src * blob: data:; default-src 'self' https://wzyzoss.eos-chongqing-3.cmecloud.cn/; script-src 'self' 'unsafe-eval' http://www.wiris.net 'unsafe-inline'; style-src 'self' 'unsafe-inline' http://www.wiris.net; media-src * blob:;img-src * 'self' data: blob:;font-src 'self' http://www.wiris.net;" />
|
<meta http-equiv="Content-Security-Policy" content="connect-src * blob: data:; default-src 'self'; script-src 'self' 'unsafe-eval' http://www.wiris.net 'unsafe-inline'; style-src 'self' 'unsafe-inline' http://www.wiris.net; media-src * blob:;img-src * 'self' data: blob:;font-src 'self' http://www.wiris.net;" />
|
||||||
|
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
|
|
|
@ -142,19 +142,13 @@ const handleNodeClick = (data) => {
|
||||||
|
|
||||||
//增加一个label 之前取的label
|
//增加一个label 之前取的label
|
||||||
nodeData.label = nodeData.itemtitle
|
nodeData.label = nodeData.itemtitle
|
||||||
let parentNode
|
// 父级节点 如果当前是一级节点 父级则为null
|
||||||
// 存在children 则为一级节点
|
let parent = {
|
||||||
if(nodeData.children){
|
|
||||||
// 为一级节点
|
|
||||||
parentNode = null
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
parentNode = {
|
|
||||||
id: nodeData.parentid,
|
id: nodeData.parentid,
|
||||||
label: nodeData.parenttitle,
|
label: nodeData.parenttitle,
|
||||||
itemtitle: nodeData.parenttitle
|
itemtitle: nodeData.parenttitle
|
||||||
}
|
}
|
||||||
}
|
const parentNode = nodeData.parentid ? parent : null
|
||||||
nodeData.parentNode = parentNode
|
nodeData.parentNode = parentNode
|
||||||
let curData = {
|
let curData = {
|
||||||
textBook: {
|
textBook: {
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!--List-->
|
<!--List-->
|
||||||
<div class="container-right-list" ref="listRef">
|
<div class="container-right-list">
|
||||||
<template v-for="(item, index) in childTempList">
|
<template v-for="(item, index) in childTempList">
|
||||||
<div class="template-item" v-loading="item.loading">
|
<div class="template-item" v-loading="item.loading">
|
||||||
<div class="item-header">
|
<div class="item-header">
|
||||||
|
@ -52,7 +52,7 @@
|
||||||
<i class="iconfont icon-ai"></i>
|
<i class="iconfont icon-ai"></i>
|
||||||
</div>
|
</div>
|
||||||
<div class="item-answer">
|
<div class="item-answer">
|
||||||
<TypingEffect v-if="isStarted[index]" :text="item.answer" :delay="10" :aiShow="item.aiShow" @complete="handleCompleteText($event,index)" @updateScroll="scrollToBottom($event,index)" />
|
<TypingEffect :text="item.oldAnswer" :delay="10" :aiShow="item.aiShow" @complete="onSaveTemp(item)" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="ai-btn" v-if="item.answer">
|
<div class="ai-btn" v-if="item.answer">
|
||||||
|
@ -83,7 +83,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, reactive, onMounted, watch, onUnmounted, nextTick } from 'vue'
|
import { ref, reactive, onMounted, watch, onUnmounted } from 'vue'
|
||||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||||
import { tempSave, completion, modelList, removeChildTemp, tempResult, editTempResult } from '@/api/mode/index'
|
import { tempSave, completion, modelList, removeChildTemp, tempResult, editTempResult } from '@/api/mode/index'
|
||||||
import { sessionStore } from '@/utils/store'
|
import { sessionStore } from '@/utils/store'
|
||||||
|
@ -146,16 +146,14 @@ const getChildTemplate = () => {
|
||||||
tempLoading.value = true
|
tempLoading.value = true
|
||||||
modelList({ model: props.type, type: 2, parentId: curTemplate.id }).then(res => {
|
modelList({ model: props.type, type: 2, parentId: curTemplate.id }).then(res => {
|
||||||
childTempList.value = res.rows
|
childTempList.value = res.rows
|
||||||
if(childTempList.value.length){
|
|
||||||
childTempList.value.forEach(item => item.answer = '')
|
|
||||||
}
|
|
||||||
getTempResult()
|
getTempResult()
|
||||||
}).finally(() => {
|
}).finally(() => {
|
||||||
tempLoading.value = false
|
tempLoading.value = false
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
const isStarted = ref([]);
|
|
||||||
const listRef = ref()
|
|
||||||
// 查询模板结果
|
// 查询模板结果
|
||||||
const getTempResult = () => {
|
const getTempResult = () => {
|
||||||
tempResult({ mainModelId: curTemplate.id, pageNum: 1, pageSize: 10000 }).then(res => {
|
tempResult({ mainModelId: curTemplate.id, pageNum: 1, pageSize: 10000 }).then(res => {
|
||||||
|
@ -163,40 +161,14 @@ const getTempResult = () => {
|
||||||
childTempList.value.forEach(item => {
|
childTempList.value.forEach(item => {
|
||||||
rows.forEach(el => {
|
rows.forEach(el => {
|
||||||
if (item.id == el.modelId) {
|
if (item.id == el.modelId) {
|
||||||
item.answer = getResult(el.content)
|
item.answer = el.content
|
||||||
item.resultId = el.id
|
item.resultId = el.id
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
if(rows.length > 0){
|
|
||||||
isStarted.value = new Array(rows.length).fill(true)
|
|
||||||
}
|
|
||||||
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const scrollToBottom = (height,index) =>{
|
|
||||||
|
|
||||||
if (listRef.value) {
|
|
||||||
let sum = 0
|
|
||||||
let listDom = listRef.value.children
|
|
||||||
|
|
||||||
if(index == 0){
|
|
||||||
// 220 去掉头部
|
|
||||||
let screenHeight = window.innerHeight - 220
|
|
||||||
if(height > screenHeight){
|
|
||||||
listRef.value.scrollTop = (height - screenHeight + 50)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
for(let i = 0; i < index; i++){
|
|
||||||
sum += listDom[i].clientHeight
|
|
||||||
}
|
|
||||||
listRef.value.scrollTop = sum + height
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 模板切换
|
// 模板切换
|
||||||
const changeTemplate = (val) => {
|
const changeTemplate = (val) => {
|
||||||
ElMessageBox.confirm(
|
ElMessageBox.confirm(
|
||||||
|
@ -231,11 +203,11 @@ const removeItem = async (item, isChild) => {
|
||||||
).then(() => {
|
).then(() => {
|
||||||
removeChildTemp(item.id).then(res => {
|
removeChildTemp(item.id).then(res => {
|
||||||
ElMessage.success('操作成功')
|
ElMessage.success('操作成功')
|
||||||
if (isChild) {
|
if(isChild){
|
||||||
// 获取子模板
|
// 获取子模板
|
||||||
getChildTemplate()
|
getChildTemplate()
|
||||||
}
|
}
|
||||||
else {
|
else{
|
||||||
// 获取主模板
|
// 获取主模板
|
||||||
getTemplateList()
|
getTemplateList()
|
||||||
}
|
}
|
||||||
|
@ -243,7 +215,7 @@ const removeItem = async (item, isChild) => {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
editKeyWord(item, !isChild)
|
editKeyWord(item,!isChild)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -268,18 +240,19 @@ const onEdit = (index, item) => {
|
||||||
|
|
||||||
const modeType = ref('课标')
|
const modeType = ref('课标')
|
||||||
watch(() => props.type, (newVal) => {
|
watch(() => props.type, (newVal) => {
|
||||||
if (newVal == 1) {
|
if (newVal == 1){
|
||||||
modeType.value = '课标'
|
modeType.value = '课标'
|
||||||
}
|
}
|
||||||
if (newVal == 2) {
|
if (newVal == 2){
|
||||||
modeType.value = '教材'
|
modeType.value = '教材'
|
||||||
}
|
}
|
||||||
if (newVal == 3) {
|
if (newVal == 2){
|
||||||
modeType.value = '考试'
|
modeType.value = '考试'
|
||||||
}
|
}
|
||||||
|
|
||||||
}, { immediate: false })
|
}, { immediate: false })
|
||||||
|
|
||||||
|
|
||||||
// 重新研读
|
// 重新研读
|
||||||
const params = reactive(
|
const params = reactive(
|
||||||
{
|
{
|
||||||
|
@ -287,102 +260,76 @@ const params = reactive(
|
||||||
dataset_id: ''
|
dataset_id: ''
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
// 重新研读
|
// 重新研读
|
||||||
const isAgain = ref(false)
|
|
||||||
const againResult = async (index, item) => {
|
const againResult = async (index, item) => {
|
||||||
isAgain.value = true
|
|
||||||
isStarted.value[index] = false
|
|
||||||
childTempList.value[index].answer = ''
|
|
||||||
|
|
||||||
if(index == 0){
|
|
||||||
listRef.value.scrollTop = 0
|
|
||||||
|
|
||||||
}else{
|
|
||||||
scrollToBottom(50, index)
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await nextTick()
|
|
||||||
childTempList.value[index].loading = true
|
childTempList.value[index].loading = true
|
||||||
item.aiShow = true
|
item.aiShow = true
|
||||||
|
childTempList.value[index].oldAnswer = ''
|
||||||
params.prompt = `按照${item.name}的要求,针对${curNode.edustage}${curNode.edusubject}${modeType.value} 对${curNode.itemtitle}进行教学分析`
|
params.prompt = `按照${item.name}的要求,针对${curNode.edustage}${curNode.edusubject}${modeType.value} 对${curNode.itemtitle}进行教学分析`
|
||||||
const { data } = await completion(params)
|
const { data } = await completion(params)
|
||||||
childTempList.value[index].answer = getResult(data.answer);
|
let answer = data.answer
|
||||||
isStarted.value[index] = true
|
childTempList.value[index].oldAnswer = answer
|
||||||
|
childTempList.value[index].answer = getResult(answer);
|
||||||
|
// onEditSave(item)
|
||||||
} finally {
|
} finally {
|
||||||
childTempList.value[index].loading = false
|
childTempList.value[index].loading = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 一键研读
|
// 一键研读
|
||||||
const getCompletion = async () => {
|
const getCompletion = async () => {
|
||||||
isStarted.value = new Array(childTempList.length).fill(false)
|
|
||||||
isStarted.value[0] = true
|
|
||||||
|
|
||||||
childTempList.value.forEach(item =>{
|
|
||||||
if(item.answer){
|
|
||||||
item.answer = ''
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
for (let item of childTempList.value) {
|
for (let item of childTempList.value) {
|
||||||
try {
|
try {
|
||||||
item.loading = true
|
item.loading = true
|
||||||
item.aiShow = true
|
item.aiShow = true
|
||||||
params.prompt = `按照${item.name}的要求,针对${curNode.edustage}${curNode.edusubject}${modeType.value} 对${curNode.itemtitle}进行教学分析`
|
params.prompt = `按照${item.name}的要求,针对${curNode.edustage}${curNode.edusubject}${modeType.value} 对${curNode.itemtitle}进行教学分析`
|
||||||
const { data } = await completion(params)
|
const { data } = await completion(params)
|
||||||
item.answer = getResult(data.answer)
|
let answer = data.answer
|
||||||
onSaveTemp(item)
|
item.oldAnswer = answer
|
||||||
|
item.answer = getResult(answer);
|
||||||
|
|
||||||
} finally {
|
} finally {
|
||||||
item.loading = false
|
item.loading = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleCompleteText = async (answer, index) =>{
|
|
||||||
if (index < childTempList.value.length - 1) {
|
|
||||||
isStarted.value[index + 1] = true; // 开始显示下一个文本
|
|
||||||
}
|
|
||||||
if(isAgain.value){
|
|
||||||
try{
|
|
||||||
await editTempResult({ id: childTempList.value[index].resultId, content: answer })
|
|
||||||
}finally{
|
|
||||||
isAgain.value = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 替换分析结果
|
// 替换分析结果
|
||||||
emitter.on('onSaveAdjust', (item) => {
|
emitter.on('onSaveAdjust', (item) => {
|
||||||
childTempList.value[curIndex.value].answer = item
|
childTempList.value[curIndex.value].oldAnswer = item
|
||||||
|
let answer = getResult(item);
|
||||||
|
childTempList.value[curIndex.value].oldAnswer = item
|
||||||
|
childTempList.value[curIndex.value].answer = answer
|
||||||
onEditSave(childTempList.value[curIndex.value])
|
onEditSave(childTempList.value[curIndex.value])
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
// 保存 重新研读后的结果
|
// 保存 重新研读后的结果
|
||||||
const onEditSave = async (item) => {
|
const onEditSave = async (item) =>{
|
||||||
const { res } = await editTempResult({ id: item.resultId, content: item.answer })
|
const { res } = await editTempResult({id: item.resultId, content: item.oldAnswer})
|
||||||
ElMessage.success(res)
|
ElMessage.success(res)
|
||||||
getChildTemplate()
|
getChildTemplate()
|
||||||
}
|
}
|
||||||
|
|
||||||
// 保存模板
|
// 保存模板
|
||||||
const onSaveTemp = (item) => {
|
const onSaveTemp = (item) => {
|
||||||
if (item.answer == '') return
|
if(item.oldAnswer == '') return
|
||||||
|
|
||||||
const data = {
|
const data = {
|
||||||
mainModelId: curTemplate.id,
|
mainModelId: curTemplate.id,
|
||||||
modelId: item.id,
|
modelId: item.id,
|
||||||
examDocld: '',
|
examDocld: '',
|
||||||
content: item.answer
|
content: item.oldAnswer
|
||||||
}
|
}
|
||||||
tempSave(data).then(res => { })
|
tempSave(data).then(res => {})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 去掉字符串中的 ### **
|
// 分析获取课标对话结果
|
||||||
let getResult = (str) => {
|
let getResult = (text) => {
|
||||||
let newStr = str.replace(/#+|(\*\*)/g, '');
|
text = text.replace(/^\n\n(.*?)\n\n$/s, '<div>$1</div>');
|
||||||
return newStr
|
text = text.replace(/^\n(.*?)\n$/s, '<p>$1</p>');
|
||||||
|
text = text.replace(/\*\*(.*?)\*\*/g, "<div class='text-tit'>$1</div>");
|
||||||
|
text = text.replace(/(\d+\..*?)\n/g, "<div class='text-num'>$1</div>\n");
|
||||||
|
return text
|
||||||
}
|
}
|
||||||
|
|
||||||
// 操作之后获取字模板
|
// 操作之后获取字模板
|
||||||
|
@ -434,6 +381,8 @@ onUnmounted(() => {
|
||||||
padding: 5px 15px;
|
padding: 5px 15px;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
.template-item {
|
.template-item {
|
||||||
background: #fff;
|
background: #fff;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="typing-effect" ref="typingEffectRef">
|
<div class="typing-effect">
|
||||||
<!-- <span v-html="displayedText"></span> -->
|
<!-- <span v-html="displayedText"></span> -->
|
||||||
<el-input
|
<el-input
|
||||||
v-model="displayedText"
|
v-model="displayedText"
|
||||||
|
@ -14,11 +14,11 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, onMounted, watch, nextTick } from 'vue';
|
import { ref, onMounted, watch } from 'vue';
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
text: {
|
text: {
|
||||||
type: [String, Object],
|
type: String,
|
||||||
required: true
|
required: true
|
||||||
},
|
},
|
||||||
delay: {
|
delay: {
|
||||||
|
@ -26,48 +26,35 @@ const props = defineProps({
|
||||||
default: 100 // 默认每个字符出现的延迟时间,单位是毫秒
|
default: 100 // 默认每个字符出现的延迟时间,单位是毫秒
|
||||||
},
|
},
|
||||||
aiShow: {
|
aiShow: {
|
||||||
type: [Boolean] // 为true 只展示
|
type: [Boolean]
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
const typingEffectRef = ref(null);
|
const emit = defineEmits(['complete']);
|
||||||
const emit = defineEmits(['complete', 'updateScroll']);
|
|
||||||
const displayedText = ref('');
|
const displayedText = ref('');
|
||||||
const index = ref(0);
|
const index = ref(0);
|
||||||
|
|
||||||
const type = async () => {
|
const type = () => {
|
||||||
await nextTick()
|
if(!props.aiShow) return
|
||||||
if(!props.aiShow) {
|
|
||||||
displayedText.value = props.text
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if (index.value <= props.text.length) {
|
if (index.value <= props.text.length) {
|
||||||
displayedText.value += props.text.charAt(index.value);
|
displayedText.value += props.text.charAt(index.value);
|
||||||
index.value++;
|
index.value++;
|
||||||
setTimeout(() => {
|
setTimeout(() => type(), props.delay);
|
||||||
type();
|
|
||||||
emit('updateScroll', typingEffectRef.value.clientHeight); // 每次添加新字符后滚动到底部
|
|
||||||
}, props.delay);
|
|
||||||
} else {
|
} else {
|
||||||
// 当所有字符都显示完毕时,触发 complete 事件
|
// 当所有字符都显示完毕时,触发 complete 事件
|
||||||
emit('complete',displayedText.value);
|
emit('complete');
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
resetAndType();
|
type();
|
||||||
});
|
});
|
||||||
|
|
||||||
const resetAndType = () =>{
|
// 监听 props 的变化,以便当传入的 text 或 delay 发生改变时重新开始打字机效果
|
||||||
|
watch([() => props.text, () => props.delay], () => {
|
||||||
displayedText.value = '';
|
displayedText.value = '';
|
||||||
index.value = 0;
|
index.value = 0;
|
||||||
type();
|
type();
|
||||||
}
|
});
|
||||||
|
|
||||||
// 监听 props 的变化,以便当传入的 text 或 delay 发生改变时重新开始打字机效果
|
|
||||||
watch([() => props.text, () => props.delay], resetAndType);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<el-dialog v-model="isDialog" :show-close="false" width="900" append-to-body destroy-on-close>
|
<el-dialog v-model="isDialog" :show-close="false" width="900" destroy-on-close>
|
||||||
<template #header>
|
<template #header>
|
||||||
<div class="custom-header flex">
|
<div class="custom-header flex">
|
||||||
<span>选择{{ title }}</span>
|
<span>选择{{ title }}</span>
|
||||||
|
@ -15,10 +15,8 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="content-list">
|
<div class="content-list">
|
||||||
<ul>
|
<ul>
|
||||||
<li v-for="(item, index) in fileList" :class="activeIndex == index ? 'li-active' : ''"
|
<li v-for="(item, index) in fileList" :class="activeIndex == index ? 'li-active' : ''" @click="clickItem(index, item)">
|
||||||
@click="clickItem(index, item)">
|
|
||||||
<el-image class="img" :src="url" />
|
<el-image class="img" :src="url" />
|
||||||
<el-button type="primary" class="prev-btn" @click.stop="onPrevItem(item)">预览</el-button>
|
|
||||||
<el-text truncated>{{ item.fileName }}</el-text>
|
<el-text truncated>{{ item.fileName }}</el-text>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
@ -26,8 +24,8 @@
|
||||||
</div>
|
</div>
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<div class="dialog-footer">
|
<div class="dialog-footer">
|
||||||
<el-upload class="upload-demo" :action="uploadFileUrl" :limit="1" :show-file-list="false" :headers="headers"
|
<el-upload class="upload-demo" :action="uploadFileUrl" :limit="1" :show-file-list="false"
|
||||||
:on-success="onSuccess">
|
:headers="headers" :on-success="onSuccess">
|
||||||
<el-button type="primary">上传</el-button>
|
<el-button type="primary">上传</el-button>
|
||||||
</el-upload>
|
</el-upload>
|
||||||
<div>
|
<div>
|
||||||
|
@ -39,31 +37,6 @@
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
<el-dialog v-model="prevVisible" fullscreen :show-close="false" class="prev-dialog">
|
|
||||||
<template #header>
|
|
||||||
<div class="custom-header flex">
|
|
||||||
<span>预览</span>
|
|
||||||
<i class="iconfont icon-guanbi" @click="prevVisible = false"></i>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<div style="height: calc(100vh - 120px);">
|
|
||||||
<template v-if="getFileSuffix(prevItem.fileUrl) == 'pdf'">
|
|
||||||
<iframe :src="prevItem.fileUrl"
|
|
||||||
frameborder="0" width="100%" height="100%"></iframe>
|
|
||||||
</template>
|
|
||||||
<template v-else>
|
|
||||||
<el-image :src="prevItem.fileUrl" style="height:100%"/>
|
|
||||||
</template>
|
|
||||||
</div>
|
|
||||||
<template #footer>
|
|
||||||
<div class="dialog-footer">
|
|
||||||
<div></div>
|
|
||||||
<el-button type="primary" @click="prevVisible = false">
|
|
||||||
关闭
|
|
||||||
</el-button>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</el-dialog>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
|
@ -74,7 +47,6 @@ import { sessionStore } from '@/utils/store'
|
||||||
import { dataSetJson } from '@/utils/comm.js'
|
import { dataSetJson } from '@/utils/comm.js'
|
||||||
import { ElMessage } from 'element-plus'
|
import { ElMessage } from 'element-plus'
|
||||||
import useUserStore from '@/store/modules/user'
|
import useUserStore from '@/store/modules/user'
|
||||||
import { getFileSuffix } from '@/utils/ruoyi.js'
|
|
||||||
import emitter from '@/utils/mitt';
|
import emitter from '@/utils/mitt';
|
||||||
|
|
||||||
const userInfo = useUserStore().user
|
const userInfo = useUserStore().user
|
||||||
|
@ -84,7 +56,6 @@ const headers = ref({ Authorization: "Bearer " + getToken() });
|
||||||
const url = 'https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fsafe-img.xhscdn.com%2Fbw1%2F11044b08-04c1-41a0-a453-1fd20b58a614%3FimageView2%2F2%2Fw%2F1080%2Fformat%2Fjpg&refer=http%3A%2F%2Fsafe-img.xhscdn.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1732953359&t=7ab1d1b3a903db85b1149914407aea35'
|
const url = 'https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fsafe-img.xhscdn.com%2Fbw1%2F11044b08-04c1-41a0-a453-1fd20b58a614%3FimageView2%2F2%2Fw%2F1080%2Fformat%2Fjpg&refer=http%3A%2F%2Fsafe-img.xhscdn.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1732953359&t=7ab1d1b3a903db85b1149914407aea35'
|
||||||
|
|
||||||
const isDialog = defineModel()
|
const isDialog = defineModel()
|
||||||
const prevVisible = ref(false)
|
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
modeType: {
|
modeType: {
|
||||||
|
@ -128,15 +99,15 @@ const activeIndex = ref(0)
|
||||||
const dataset_id = ref('')
|
const dataset_id = ref('')
|
||||||
|
|
||||||
// 上传成功
|
// 上传成功
|
||||||
const onSuccess = async (response) => {
|
const onSuccess = async (response) =>{
|
||||||
console.log(response, 'response')
|
console.log(response,'response')
|
||||||
let data = {
|
let data = {
|
||||||
url: response.url,
|
url: response.url,
|
||||||
dataset_id: dataset_id.value
|
dataset_id: dataset_id.value
|
||||||
}
|
}
|
||||||
const res = await completion(data)
|
const res = await completion(data)
|
||||||
|
|
||||||
if (res.data.code != 200) return
|
if(res.data.code != 200) return
|
||||||
let docData = {
|
let docData = {
|
||||||
fileUrl: response.url,
|
fileUrl: response.url,
|
||||||
fileId: response.file.id,
|
fileId: response.file.id,
|
||||||
|
@ -156,11 +127,11 @@ const curNode = reactive({})
|
||||||
|
|
||||||
const fileList = ref([])
|
const fileList = ref([])
|
||||||
const curFile = reactive({})
|
const curFile = reactive({})
|
||||||
const getList = () => {
|
const getList = () =>{
|
||||||
docList({
|
docList({
|
||||||
userId: userInfo.userId,
|
userId: userInfo.userId,
|
||||||
dataset_id: dataset_id.value
|
dataset_id: dataset_id.value
|
||||||
}).then(res => {
|
}).then( res =>{
|
||||||
fileList.value = [...res.rows]
|
fileList.value = [...res.rows]
|
||||||
Object.assign(curFile, fileList.value[0])
|
Object.assign(curFile, fileList.value[0])
|
||||||
})
|
})
|
||||||
|
@ -169,19 +140,12 @@ const getList = () => {
|
||||||
const clickItem = (index, item) => {
|
const clickItem = (index, item) => {
|
||||||
activeIndex.value = index
|
activeIndex.value = index
|
||||||
Object.assign(curFile, item)
|
Object.assign(curFile, item)
|
||||||
emitter.emit('curFile', item)
|
emitter.emit('curFile',item)
|
||||||
}
|
|
||||||
|
|
||||||
const prevItem = reactive({})
|
|
||||||
const onPrevItem = (item) => {
|
|
||||||
console.log(item)
|
|
||||||
Object.assign(prevItem, item)
|
|
||||||
prevVisible.value = true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() =>{
|
||||||
let data = sessionStore.get('subject.curNode')
|
let data = sessionStore.get('subject.curNode')
|
||||||
Object.assign(curNode, data);
|
Object.assign(curNode, data);
|
||||||
|
|
||||||
|
@ -191,6 +155,7 @@ onMounted(() => {
|
||||||
})
|
})
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.custom-header {
|
.custom-header {
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
|
@ -227,11 +192,9 @@ onMounted(() => {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
margin-right: 20px;
|
margin-right: 20px;
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
position: relative;
|
|
||||||
overflow: hidden;
|
|
||||||
|
|
||||||
.img {
|
.img {
|
||||||
width: 100%;
|
width: 100px;
|
||||||
height: 130px;
|
height: 130px;
|
||||||
border: solid #ccc 1px;
|
border: solid #ccc 1px;
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
|
@ -240,10 +203,6 @@ onMounted(() => {
|
||||||
&:hover {
|
&:hover {
|
||||||
background: #E0EAFF;
|
background: #E0EAFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
&:hover .prev-btn {
|
|
||||||
transform: translate(-50%, -50%)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.li-active {
|
.li-active {
|
||||||
|
@ -253,20 +212,9 @@ onMounted(() => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.dialog-footer{
|
||||||
.dialog-footer {
|
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
}
|
}
|
||||||
|
|
||||||
.prev-btn {
|
|
||||||
position: absolute;
|
|
||||||
top: 50%;
|
|
||||||
left: 50%;
|
|
||||||
transform: translate(-50%, -50%) translateY(-110px);
|
|
||||||
/* 按钮初始位置在容器外 */
|
|
||||||
transition: transform 0.3s ease-in-out;
|
|
||||||
/* 设置过渡效果 */
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
|
@ -14,14 +14,8 @@ const pdfUrl = ref('')
|
||||||
|
|
||||||
onMounted(async () =>{
|
onMounted(async () =>{
|
||||||
await nextTick()
|
await nextTick()
|
||||||
|
const { fileurl } = sessionStore.get('subject.curBook')
|
||||||
let data = sessionStore.get('subject.curBook')
|
pdfUrl.value = import.meta.env.VITE_APP_RES_FILE_PATH + fileurl.replace('.txt','.pdf')
|
||||||
let fileurl = data.fileurl
|
|
||||||
|
|
||||||
if(fileurl == ''){
|
|
||||||
fileurl = `${data.edustage}-${data.edusubject}-课标.txt`
|
|
||||||
}
|
|
||||||
pdfUrl.value = import.meta.env.VITE_APP_RES_FILE_PATH + fileurl.replace('.txt', '.pdf')
|
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
@ -57,11 +57,11 @@
|
||||||
</el-row>
|
</el-row>
|
||||||
<div>
|
<div>
|
||||||
<el-button style="margin-bottom: 5px;" type="primary" @click="activeStep = 0">上一步</el-button>
|
<el-button style="margin-bottom: 5px;" type="primary" @click="activeStep = 0">上一步</el-button>
|
||||||
<el-button style="margin-bottom: 5px;" type="primary" v-loading="createPPTLoading" @click="outlineCreatePPT()">生成PPT</el-button>
|
<el-button style="margin-bottom: 5px;" type="primary" @click="outlineCreatePPT()">生成PPT</el-button>
|
||||||
</div>
|
</div>
|
||||||
</el-card>
|
</el-card>
|
||||||
<el-card v-if="activeStep === 2">
|
<el-card v-if="activeStep === 2">
|
||||||
<el-progress :percentage="percentage" type="circle"></el-progress>
|
<el-progress :percentage="30" type="circle" v-if="percentage === 30"></el-progress>
|
||||||
</el-card>
|
</el-card>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -79,7 +79,6 @@ import {
|
||||||
import CryptoJS from "crypto-js"
|
import CryptoJS from "crypto-js"
|
||||||
|
|
||||||
import { getSignature } from "@/utils/index.js";
|
import { getSignature } from "@/utils/index.js";
|
||||||
import {sessionStore} from "@/utils/store";
|
|
||||||
|
|
||||||
let appId = "01ec9aa3";
|
let appId = "01ec9aa3";
|
||||||
let secret = "M2QxMDAxMjYyYTEzODMwMGRkZTQ4NmUy";
|
let secret = "M2QxMDAxMjYyYTEzODMwMGRkZTQ4NmUy";
|
||||||
|
@ -99,8 +98,8 @@ let secondArray = ref([]); //大纲的文字部分
|
||||||
|
|
||||||
|
|
||||||
const backGroundList = ref([]);
|
const backGroundList = ref([]);
|
||||||
let subjectdata = sessionStore.get('subject.curNode')
|
|
||||||
const inputTheme = ref(subjectdata.edustage + subjectdata.edusubject + "《" + subjectdata.itemtitle + "》的授课课件"); // 输入的主题
|
const inputTheme = ref("高中语文《沁园春雪》的授课课件"); // 输入的主题
|
||||||
const inputRequire = ref("") // 输入的需求
|
const inputRequire = ref("") // 输入的需求
|
||||||
const activeStep = ref(0); // 上方进度条
|
const activeStep = ref(0); // 上方进度条
|
||||||
const combined = ref('') // 修改完毕的大纲数据,准备传入ppt生成模型
|
const combined = ref('') // 修改完毕的大纲数据,准备传入ppt生成模型
|
||||||
|
@ -110,8 +109,6 @@ const status = ref("init");
|
||||||
|
|
||||||
const percentage = ref(0);
|
const percentage = ref(0);
|
||||||
|
|
||||||
const createPPTLoading = ref(false);
|
|
||||||
|
|
||||||
const getBackgrounds = () => {
|
const getBackgrounds = () => {
|
||||||
treeData.value = [];
|
treeData.value = [];
|
||||||
getBackGroundV2().then((res) => {
|
getBackGroundV2().then((res) => {
|
||||||
|
@ -129,8 +126,6 @@ const outlineData = ref({
|
||||||
// templateId: 'auto', // ppt生成主题
|
// templateId: 'auto', // ppt生成主题
|
||||||
author: 'AIX平台',
|
author: 'AIX平台',
|
||||||
isFigure: false, // 是否自动配图
|
isFigure: false, // 是否自动配图
|
||||||
search: true,
|
|
||||||
language: "cn"
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -150,17 +145,20 @@ function updateStagingData(role, newData) {
|
||||||
const outlineCreatePPT = () => {
|
const outlineCreatePPT = () => {
|
||||||
const newOutlineData = { ...outlineData.value, };
|
const newOutlineData = { ...outlineData.value, };
|
||||||
newOutlineData.query = outputText.value;
|
newOutlineData.query = outputText.value;
|
||||||
createPPTLoading.value = true;
|
|
||||||
createPPTV2(newOutlineData).then((res) => {
|
createPPTV2(newOutlineData).then((res) => {
|
||||||
console.log(res, "正在生成中");
|
console.log(res, "正在生成中");
|
||||||
createPPTLoading.value = false;
|
|
||||||
activeStep.value = 2
|
activeStep.value = 2
|
||||||
|
|
||||||
const checkProgress = () => {
|
const checkProgress = () => {
|
||||||
getProgressV2(res.sid).then(response => {
|
getProgressV2(res.sid).then((response) => {
|
||||||
percentage.value = Math.round(response?.donePages/response?.totalPages)*100;
|
percentage.value = response.process;
|
||||||
if (response.pptStatus === "done") {
|
if (response && response.pptUrl && response.pptUrl.length > 4) {
|
||||||
emit('addSuccess',{...res,url:response.pptUrl})
|
console.log('PPT',response)
|
||||||
|
// window.location.href = response.data.pptUrl;
|
||||||
|
//发消息到主进程,携带名称和URL,将URL下载下来后复制到文件列表并上传到服务
|
||||||
|
// let url = "https://bjcdn.openstorage.cn/xinghuo-privatedata/%2Ftmp/apiTempFiledf28bf990a4c40ffb7477ed4b65392c27232357022409613439/%E3%80%8A%E9%9D%99%E5%A5%B3%E3%80%8B%E6%B7%B1%E5%BA%A6%E8%A7%A3%E8%AF%BB%E4%B8%8E%E7%A0%94%E7%A9%B6.pptx"
|
||||||
|
emit('addSuccess',res)
|
||||||
ElMessage.success("生成成功");
|
ElMessage.success("生成成功");
|
||||||
} else {
|
} else {
|
||||||
const sleepTime = 2000;
|
const sleepTime = 2000;
|
||||||
|
|
|
@ -332,6 +332,10 @@ export default {
|
||||||
const { id, rootid } = sessionStore.get('subject.curNode')
|
const { id, rootid } = sessionStore.get('subject.curNode')
|
||||||
const path="/teaching/aptindex?id="+items.fileId + "&unitId=" + id + "&bookId=" + rootid;
|
const path="/teaching/aptindex?id="+items.fileId + "&unitId=" + id + "&bookId=" + rootid;
|
||||||
let configObj = outLink().getBaseData()
|
let configObj = outLink().getBaseData()
|
||||||
|
configObj.fullPath = 'https://localhost:7860/'
|
||||||
|
configObj.data.url = 'https://localhost:7860/'
|
||||||
|
configObj.data.domain = 'localhost'
|
||||||
|
console.log(configObj)
|
||||||
let fullPath = configObj.fullPath + path
|
let fullPath = configObj.fullPath + path
|
||||||
fullPath = fullPath.replaceAll('//', '/')
|
fullPath = fullPath.replaceAll('//', '/')
|
||||||
// 通知主进程
|
// 通知主进程
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import AiPptist from './ai-pptistV2.vue';
|
import AiPptist from './ai-pptist.vue';
|
||||||
const model = defineModel()
|
const model = defineModel()
|
||||||
const emit = defineEmits(['addSuccess'])
|
const emit = defineEmits(['addSuccess'])
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<div class="info">
|
<div class="info">
|
||||||
<div class="info-name">{{ state.user.nickName }}</div>
|
<div class="info-name">{{ state.user.nickName }}</div>
|
||||||
<div class="infomation">
|
<div class="infomation">
|
||||||
<selectClass v-if="!isSubject"/>
|
<selectClass/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -46,10 +46,8 @@ const state = reactive({
|
||||||
postGroup: {}
|
postGroup: {}
|
||||||
})
|
})
|
||||||
|
|
||||||
const isSubject = ref(false)
|
|
||||||
async function getUser() {
|
async function getUser() {
|
||||||
getUserProfile().then((response) => {
|
getUserProfile().then((response) => {
|
||||||
isSubject.value = response.roleGroup.indexOf('场馆管理员') != -1
|
|
||||||
// response.data.avatar = import.meta.env.VITE_APP_BASE_API + response.data.avatar
|
// response.data.avatar = import.meta.env.VITE_APP_BASE_API + response.data.avatar
|
||||||
Object.assign(state.user,response.data)
|
Object.assign(state.user,response.data)
|
||||||
state.roleGroup = response.roleGroup
|
state.roleGroup = response.roleGroup
|
||||||
|
|
|
@ -68,7 +68,6 @@ import {PPTXFileToJson} from '@/AixPPTist/src/hooks/useImport' // ppt转json
|
||||||
import * as API_entpcourse from '@/api/education/entpcourse' // 相关api
|
import * as API_entpcourse from '@/api/education/entpcourse' // 相关api
|
||||||
import * as API_entpcoursefile from '@/api/education/entpcoursefile' // 相关api
|
import * as API_entpcoursefile from '@/api/education/entpcoursefile' // 相关api
|
||||||
import * as Api_server from '@/api/apiService' // 相关api
|
import * as Api_server from '@/api/apiService' // 相关api
|
||||||
import * as API_smarttalk from '@/api/file' // 文件相关api
|
|
||||||
import msgUtils from '@/plugins/modal' // 消息工具
|
import msgUtils from '@/plugins/modal' // 消息工具
|
||||||
|
|
||||||
const userStore = useUserStore()
|
const userStore = useUserStore()
|
||||||
|
@ -137,8 +136,6 @@ const addAiPPT = async(res) => {
|
||||||
const p_params = {parentContent: JSON.stringify(content)}
|
const p_params = {parentContent: JSON.stringify(content)}
|
||||||
const parentid = await HTTP_SERVER_API('addEntpcoursefile', p_params)
|
const parentid = await HTTP_SERVER_API('addEntpcoursefile', p_params)
|
||||||
if (!!parentid??null) { // 生成内容幻灯片
|
if (!!parentid??null) { // 生成内容幻灯片
|
||||||
// 生成备课资源-Smarttalk
|
|
||||||
HTTP_SERVER_API('addSmarttalk',{fileId: parentid})
|
|
||||||
if (slides.length > 0) {
|
if (slides.length > 0) {
|
||||||
const resSlides = slides.map(({id, ...slide}) => JSON.stringify(slide))
|
const resSlides = slides.map(({id, ...slide}) => JSON.stringify(slide))
|
||||||
const params = {parentid, filetype: 'slide', title: '', slides: resSlides }
|
const params = {parentid, filetype: 'slide', title: '', slides: resSlides }
|
||||||
|
@ -209,20 +206,6 @@ emitter.on('changeResult', (item) => {
|
||||||
// 统一HTTP处理
|
// 统一HTTP处理
|
||||||
const HTTP_SERVER_API = (type, params = {}) => {
|
const HTTP_SERVER_API = (type, params = {}) => {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case 'addSmarttalk': { // 获取课程
|
|
||||||
const node = courseObj.node || {}
|
|
||||||
const def = {
|
|
||||||
fileId: '', // 文件id - Entpcoursefile 对应id
|
|
||||||
fileFlag: 'aptist',
|
|
||||||
fileShowName: node.itemtitle + '.aptist',
|
|
||||||
textbookId: node.rootid,
|
|
||||||
levelFirstId: node.parentid||node.id,
|
|
||||||
levelSecondId: node.parentid && node.id,
|
|
||||||
fileSource: '个人',
|
|
||||||
fileRoot: '备课'
|
|
||||||
}
|
|
||||||
return API_smarttalk.creatAPT({...def, ...params})
|
|
||||||
}
|
|
||||||
case 'addEntpcourse': { // 添加课程
|
case 'addEntpcourse': { // 添加课程
|
||||||
const node = courseObj.node || {}
|
const node = courseObj.node || {}
|
||||||
if (!node) return msgUtils.msgWarning('请选择章节?')
|
if (!node) return msgUtils.msgWarning('请选择章节?')
|
||||||
|
@ -315,7 +298,6 @@ const toRousrceUrl = async(o) => {
|
||||||
const curNode = reactive({})
|
const curNode = reactive({})
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
let data = sessionStore.get('subject.curNode')
|
let data = sessionStore.get('subject.curNode')
|
||||||
console.log('data', sessionStore)
|
|
||||||
Object.assign(curNode, data);
|
Object.assign(curNode, data);
|
||||||
courseObj.node = data
|
courseObj.node = data
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue