Compare commits
4 Commits
57fb6b9c75
...
b0d3876e05
Author | SHA1 | Date |
---|---|---|
lyc | b0d3876e05 | |
lyc | eb197db4fd | |
lyc | 5808798b95 | |
lyc | 393587848f |
|
@ -45,6 +45,7 @@ import { conversation, completion } from '@/api/mode/index'
|
||||||
import { sessionStore } from '@/utils/store'
|
import { sessionStore } from '@/utils/store'
|
||||||
import { ElMessage } from 'element-plus'
|
import { ElMessage } from 'element-plus'
|
||||||
import { dataSetJson } from '@/utils/comm.js'
|
import { dataSetJson } from '@/utils/comm.js'
|
||||||
|
import emitter from '@/utils/mitt';
|
||||||
|
|
||||||
const textarea = ref('')
|
const textarea = ref('')
|
||||||
|
|
||||||
|
@ -109,13 +110,16 @@ const getCompletion = async (val) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
const saveAdjust = (item) =>{
|
const saveAdjust = (item) =>{
|
||||||
emit('saveAdjust', item.msg)
|
|
||||||
isDialog.value = false
|
isDialog.value = false
|
||||||
ElMessage.success('操作成功')
|
ElMessage.success('操作成功')
|
||||||
|
emitter.on('saveAdjust', item.msg)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
let data = sessionStore.get('subject.curNode')
|
let data = sessionStore.get('subject.curNode')
|
||||||
|
|
||||||
Object.assign(curNode, data);
|
Object.assign(curNode, data);
|
||||||
let text = props.modeType == 1||props.modeType == 2 ? '课标' : '考试'
|
let text = props.modeType == 1||props.modeType == 2 ? '课标' : '考试'
|
||||||
let jsonKey = `${text}-${data.edustage}-${data.edusubject}`
|
let jsonKey = `${text}-${data.edustage}-${data.edusubject}`
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
import { ref, watch} from 'vue'
|
import { ref, watch} from 'vue'
|
||||||
import { ElMessage } from 'element-plus'
|
import { ElMessage } from 'element-plus'
|
||||||
import { editTempResult } from '@/api/mode/index.js'
|
import { editTempResult } from '@/api/mode/index.js'
|
||||||
|
import emitter from '@/utils/mitt';
|
||||||
|
|
||||||
const textarea = ref('')
|
const textarea = ref('')
|
||||||
|
|
||||||
|
@ -49,12 +50,12 @@ watch(() => props.item.answer, (newVal) => {
|
||||||
}
|
}
|
||||||
},{ deep: true })
|
},{ deep: true })
|
||||||
|
|
||||||
const emit = defineEmits(['saveEdit'])
|
|
||||||
const onSave = () =>{
|
const onSave = () =>{
|
||||||
editTempResult({id: props.item.reultId, content: textarea.value}).then( res =>{
|
editTempResult({id: props.item.reultId, content: textarea.value}).then( res =>{
|
||||||
isDialog.value = false
|
isDialog.value = false
|
||||||
ElMessage.success('操作成功')
|
ElMessage.success('操作成功')
|
||||||
emit('saveEdit', textarea.value)
|
emitter.emit('onGetChild', textarea.value)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,149 +0,0 @@
|
||||||
<template>
|
|
||||||
<div class="container-header flex">
|
|
||||||
<div class="header-left flex">
|
|
||||||
<el-button link @click="onClick">
|
|
||||||
{{ curNode.edustage}}{{ curNode.edusubject }}{{ type == 1 ? '课标研读': '教材分析'}}<i class="iconfont icon-xiangxia"></i>
|
|
||||||
</el-button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="header-right flex">
|
|
||||||
<el-dropdown @command="changeTemplate" :hide-on-click="false">
|
|
||||||
<span class="el-dropdown-link">
|
|
||||||
{{ curTemplate.name }}
|
|
||||||
<i class="iconfont icon-xiangxia"></i>
|
|
||||||
</span>
|
|
||||||
<template #dropdown>
|
|
||||||
<el-dropdown-menu>
|
|
||||||
<el-dropdown-item v-for="item in templateList" :command="item" :key="item.id">{{ item.name
|
|
||||||
}}</el-dropdown-item>
|
|
||||||
</el-dropdown-menu>
|
|
||||||
</template>
|
|
||||||
</el-dropdown>
|
|
||||||
<div>
|
|
||||||
|
|
||||||
<el-button type="primary" link @click="onAdd">
|
|
||||||
<el-icon>
|
|
||||||
<Plus />
|
|
||||||
</el-icon>
|
|
||||||
添加提示词
|
|
||||||
</el-button>
|
|
||||||
<!-- <el-button type="danger">删除</el-button> -->
|
|
||||||
<!-- <el-button type="primary" link>保存模板</el-button> -->
|
|
||||||
<el-button type="primary" @click="aiRead">一键研读</el-button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!--添加提示词-->
|
|
||||||
<keywordDialog v-model="wordDialog" :modeType="type" :isAdd="wordDialog" :item="curTemplate" />
|
|
||||||
<Dialog v-model="showDialog" :modeType="type" />
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup>
|
|
||||||
import { ref, reactive, onMounted, onUnmounted, watch } from 'vue'
|
|
||||||
import { Plus } from '@element-plus/icons-vue'
|
|
||||||
import { ElMessageBox } from 'element-plus'
|
|
||||||
import { modelList } from '@/api/mode/index'
|
|
||||||
import Dialog from './dialog.vue'
|
|
||||||
import keywordDialog from './keyword-dialog.vue'
|
|
||||||
import emitter from '@/utils/mitt';
|
|
||||||
import { sessionStore } from '@/utils/store'
|
|
||||||
|
|
||||||
const wordDialog = ref(false)
|
|
||||||
const props = defineProps({
|
|
||||||
type: {
|
|
||||||
type: Number,
|
|
||||||
default: 1
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
const emit = defineEmits(['changeTemp', 'onRead'])
|
|
||||||
|
|
||||||
const showDialog = ref(false)
|
|
||||||
|
|
||||||
const aiRead = () => {
|
|
||||||
emit('onRead')
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// 当前模板名称
|
|
||||||
const curTemplate = reactive({ name: '', id: '' })
|
|
||||||
// 模板列表
|
|
||||||
const templateList = ref([])
|
|
||||||
// 获取模板列表
|
|
||||||
const getTemplateList = () => {
|
|
||||||
modelList({ model: props.type, type: 1, pageNum: 1, pageSize: 10000 }).then(res => {
|
|
||||||
templateList.value = res.rows
|
|
||||||
Object.assign(curTemplate, res.rows[0]);
|
|
||||||
emit('changeTemp', res.rows[0].id)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
// 模板切换
|
|
||||||
const changeTemplate = (val) => {
|
|
||||||
|
|
||||||
ElMessageBox.confirm(
|
|
||||||
'切换模板将清除当前研读结果?',
|
|
||||||
'提示',
|
|
||||||
{
|
|
||||||
confirmButtonText: '确定',
|
|
||||||
cancelButtonText: '取消',
|
|
||||||
type: 'warning',
|
|
||||||
}
|
|
||||||
)
|
|
||||||
.then(() => {
|
|
||||||
Object.assign(curTemplate, val);
|
|
||||||
emit('changeTemp', curTemplate.id)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
emitter.on('onGetMain', () =>{
|
|
||||||
getTemplateList()
|
|
||||||
})
|
|
||||||
|
|
||||||
const onAdd = () => {
|
|
||||||
wordDialog.value = true
|
|
||||||
}
|
|
||||||
|
|
||||||
const onClick = () =>{
|
|
||||||
if(props.type == 1) return
|
|
||||||
showDialog.value = true
|
|
||||||
}
|
|
||||||
|
|
||||||
onUnmounted(() => {
|
|
||||||
emitter.off('onGetMain')
|
|
||||||
})
|
|
||||||
const curNode = reactive({})
|
|
||||||
onMounted(() => {
|
|
||||||
let data = sessionStore.get('subject.curNode')
|
|
||||||
Object.assign(curNode, data);
|
|
||||||
getTemplateList()
|
|
||||||
})
|
|
||||||
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.container-header {
|
|
||||||
height: 45px;
|
|
||||||
background: #fff;
|
|
||||||
border-radius: 5px 5px 0 0;
|
|
||||||
box-shadow: 0px 0px 20px 0px rgba(99, 99, 99, 0.06);
|
|
||||||
|
|
||||||
.header-left {
|
|
||||||
width: 50%;
|
|
||||||
align-items: center;
|
|
||||||
padding-left: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.header-right {
|
|
||||||
width: 50%;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
|
||||||
padding: 0 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.icon-xiangxia {
|
|
||||||
margin-left: 5px;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<el-dialog v-model="mode" :show-close="false" width="600" destroy-on-close>
|
<el-dialog v-model="mode" :show-close="false" width="600" append-to-body destroy-on-close>
|
||||||
<template #header>
|
<template #header>
|
||||||
<div class="custom-header flex">
|
<div class="custom-header flex">
|
||||||
<span>{{ item.ex3 == '1' ? '请输入新的模板名称' : isAdd ? '添加提示词' : '编辑提示词' }}</span>
|
<span>{{ item.ex3 == '1' ? '请输入新的模板名称' : isAdd ? '添加提示词' : '编辑提示词' }}</span>
|
||||||
|
@ -12,12 +12,10 @@
|
||||||
<el-form-item label="名称">
|
<el-form-item label="名称">
|
||||||
<el-input v-model="form.name" />
|
<el-input v-model="form.name" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item label="提示词" v-if="item.ex3 == '1' ? false : true">
|
<el-form-item label="提示词" v-if="item.ex3 == '1' ? false : true">
|
||||||
<el-input v-model="form.prompt" type="textarea" />
|
<el-input v-model="form.prompt" type="textarea" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<div class="dialog-footer">
|
<div class="dialog-footer">
|
||||||
|
@ -52,14 +50,9 @@ const props = defineProps({
|
||||||
return { ex3: '' }
|
return { ex3: '' }
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
tempId: {
|
|
||||||
type: [String, Number],
|
|
||||||
default: ''
|
|
||||||
},
|
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const form = reactive({
|
const form = reactive({
|
||||||
name: '',
|
name: '',
|
||||||
prompt: '',
|
prompt: '',
|
||||||
|
@ -73,16 +66,17 @@ watch(() => props.isAdd, (newVal) => {
|
||||||
|
|
||||||
}, { immediate: false })
|
}, { immediate: false })
|
||||||
|
|
||||||
|
|
||||||
const loading = ref(false)
|
const loading = ref(false)
|
||||||
const saveAdd = async () => {
|
const saveAdd = async () => {
|
||||||
|
|
||||||
loading.value = true
|
loading.value = true
|
||||||
if (props.item.ex3 == '1') {
|
if (props.item.ex3 == '1') {
|
||||||
|
|
||||||
if (props.isAdd) {
|
if (props.isAdd) {
|
||||||
try {
|
try {
|
||||||
// 系统预设模板 copy一份
|
// 系统预设模板 copy一份
|
||||||
const { msg } = await addKeyWords({ name: form.name, id: props.item.id })
|
const { msg } = await addKeyWords({ name: form.name, id: props.item.id })
|
||||||
emitter.emit('onGetChild')
|
emitter.emit('onGetMain')
|
||||||
ElMessage.success(msg)
|
ElMessage.success(msg)
|
||||||
mode.value = false
|
mode.value = false
|
||||||
} finally {
|
} finally {
|
||||||
|
@ -138,7 +132,6 @@ const onAddChildTemp = async (parentId) => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
|
|
@ -0,0 +1,60 @@
|
||||||
|
<template>
|
||||||
|
<div class="container-left-page flex">
|
||||||
|
<div class="container-left-header flex">
|
||||||
|
<el-button link @click="onClick">
|
||||||
|
{{ curNode.edustage }}{{ curNode.edusubject }}{{ type == 1 ? '课标研读' : '教材分析' }}<i
|
||||||
|
class="iconfont icon-xiangxia"></i>
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
<div class="container-left-pdf">
|
||||||
|
<PDF :url="pdfUrl" :showCatalog="false" v-if="pdfUrl" />
|
||||||
|
</div>
|
||||||
|
<!--弹窗-->
|
||||||
|
<LeftDialog v-model="showDialog" :modeType="type" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, onMounted, nextTick } from 'vue'
|
||||||
|
import PDF from '@/components/PdfJs/index.vue'
|
||||||
|
import LeftDialog from './left-dialog.vue'
|
||||||
|
|
||||||
|
const props = defineProps(['curNode', 'type'])
|
||||||
|
|
||||||
|
const showDialog = ref(false)
|
||||||
|
const onClick = () => {
|
||||||
|
if (props.type == 1) return
|
||||||
|
showDialog.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
// 加载PDF
|
||||||
|
const pdfUrl = ref('')
|
||||||
|
onMounted(async () => {
|
||||||
|
await nextTick()
|
||||||
|
const { fileurl } = props.curNode
|
||||||
|
pdfUrl.value = import.meta.env.VITE_APP_RES_FILE_PATH + fileurl.replace('.txt', '.pdf')
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.container-left-page {
|
||||||
|
height: 100%;
|
||||||
|
flex-direction: column;
|
||||||
|
.container-left-header {
|
||||||
|
height: 45px;
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 5px 0 0 0;
|
||||||
|
justify-content: flex-start;
|
||||||
|
padding-left: 10px;
|
||||||
|
|
||||||
|
.icon-xiangxia {
|
||||||
|
margin-left: 5px;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.container-left-pdf {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -1,28 +0,0 @@
|
||||||
<template>
|
|
||||||
<div class="container-pdf">
|
|
||||||
<PDF :url="pdfUrl" :showCatalog="false" v-if="pdfUrl" />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup>
|
|
||||||
import { ref, onMounted, nextTick } from 'vue';
|
|
||||||
import PDF from '@/components/PdfJs/index.vue'
|
|
||||||
import { sessionStore } from '@/utils/store'
|
|
||||||
|
|
||||||
const pdfUrl = ref('')
|
|
||||||
|
|
||||||
onMounted(async () =>{
|
|
||||||
await nextTick()
|
|
||||||
const { fileurl } = sessionStore.get('subject.curBook')
|
|
||||||
console.log(fileurl,'fileurl');
|
|
||||||
|
|
||||||
pdfUrl.value = import.meta.env.VITE_APP_RES_FILE_PATH + fileurl.replace('.txt','.pdf')
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.container-pdf{
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
</style>
|
|
|
@ -1,505 +0,0 @@
|
||||||
<template>
|
|
||||||
<div class="read-container">
|
|
||||||
|
|
||||||
<el-scrollbar height="100%">
|
|
||||||
<div class="template-list">
|
|
||||||
<el-row v-for="(item, index) in childTempList">
|
|
||||||
<el-col :span="24">
|
|
||||||
<div class="template-item" v-loading="item.loading">
|
|
||||||
<div class="item-header">
|
|
||||||
<div>
|
|
||||||
<span class="blue">#</span>{{ item.name }}
|
|
||||||
</div>
|
|
||||||
<el-popover placement="bottom-end" trigger="hover" popper-class="template-custom-popover">
|
|
||||||
<template #reference>
|
|
||||||
<el-button link type="primary">
|
|
||||||
<i class="iconfont icon-shenglvehao"></i></el-button>
|
|
||||||
</template>
|
|
||||||
<template #default>
|
|
||||||
<el-button type="primary" link @click="editKeyWord(item)">编辑</el-button>
|
|
||||||
<el-button type="primary" link @click="removeItem(item)">移除</el-button>
|
|
||||||
</template>
|
|
||||||
</el-popover>
|
|
||||||
</div>
|
|
||||||
<div class="item-text">
|
|
||||||
{{ item.prompt }}
|
|
||||||
</div>
|
|
||||||
<div class="item-text text-answer" v-if="item.answer">
|
|
||||||
<div class="item-icon">
|
|
||||||
<i class="iconfont icon-ai"></i>
|
|
||||||
</div>
|
|
||||||
<div class="item-answer" v-html="item.answer"></div>
|
|
||||||
</div>
|
|
||||||
<div class="ai-btn" v-if="item.answer">
|
|
||||||
<el-button type="primary" link @click="againResult(index, item)">
|
|
||||||
<i class="iconfont icon-ai1"></i>
|
|
||||||
重新研读
|
|
||||||
</el-button>
|
|
||||||
<el-button type="primary" link @click="onAdjust(index, item)">
|
|
||||||
<i class="iconfont icon-duihua"></i>
|
|
||||||
AI对话调整
|
|
||||||
</el-button>
|
|
||||||
<el-button type="primary" link @click="onEdit(index, item)">
|
|
||||||
<i class="iconfont icon-bianji1"></i>
|
|
||||||
手动编辑结果
|
|
||||||
</el-button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
<el-empty v-if="!childTempList.length" description="暂无模板数据" />
|
|
||||||
</div>
|
|
||||||
</el-scrollbar>
|
|
||||||
<!--编辑结果-->
|
|
||||||
<EditDialog v-model="isEdit" :item="editItem" @saveEdit="saveEdit" />
|
|
||||||
<!--AI 对话调整-->
|
|
||||||
<AdjustDialog v-model="isAdjust" :modeType="modeType" :item="editItem" @saveAdjust="saveAdjust" />
|
|
||||||
<!--编辑提示词-->
|
|
||||||
<keywordDialog v-model="isEditKeyWord" :isAdd="isAdd" :item="keywordItem" :tempId="tempId" />
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup>
|
|
||||||
import { ref, reactive, onMounted, watch, onUnmounted } from 'vue';
|
|
||||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
|
||||||
import EditDialog from './edit-dialog.vue'
|
|
||||||
import AdjustDialog from './adjust-dialog.vue'
|
|
||||||
import keywordDialog from './keyword-dialog.vue';
|
|
||||||
import { sessionStore } from '@/utils/store'
|
|
||||||
import useUserStore from '@/store/modules/user'
|
|
||||||
import { tempSave, completion, modelList, removeChildTemp, tempResult } from '@/api/mode/index'
|
|
||||||
import { dataSetJson } from '@/utils/comm.js'
|
|
||||||
import emitter from '@/utils/mitt';
|
|
||||||
|
|
||||||
const userStore = useUserStore()
|
|
||||||
|
|
||||||
const props = defineProps({
|
|
||||||
tempId: {
|
|
||||||
type: [String, Number],
|
|
||||||
default: ''
|
|
||||||
},
|
|
||||||
modeType: {
|
|
||||||
type: Number,
|
|
||||||
default: 1
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
emitter.on('onGetChild', () =>{
|
|
||||||
getChildTemplate()
|
|
||||||
})
|
|
||||||
|
|
||||||
// 获取子模板
|
|
||||||
const tempLoading = ref(false)
|
|
||||||
const childTempList = ref([])
|
|
||||||
const getChildTemplate = () => {
|
|
||||||
|
|
||||||
tempLoading.value = true
|
|
||||||
modelList({ model: props.modeType, type: 2, parentId: props.tempId }).then(res => {
|
|
||||||
childTempList.value = res.rows
|
|
||||||
getTempResult()
|
|
||||||
}).finally(() => {
|
|
||||||
tempLoading.value = false
|
|
||||||
})
|
|
||||||
}
|
|
||||||
// 查询模板结果
|
|
||||||
const getTempResult = () => {
|
|
||||||
tempResult({ mainModelId: props.tempId }).then(res => {
|
|
||||||
let rows = res.rows
|
|
||||||
childTempList.value.forEach(item => {
|
|
||||||
rows.forEach(el => {
|
|
||||||
if (item.id == el.modelId) {
|
|
||||||
item.answer = el.content
|
|
||||||
item.reultId = el.id
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
const isEdit = ref(false)
|
|
||||||
watch(() => props.tempId, (newVal) => {
|
|
||||||
if (newVal) {
|
|
||||||
// isEdit.value = true
|
|
||||||
getChildTemplate()
|
|
||||||
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
// 获取会话ID
|
|
||||||
const params = reactive(
|
|
||||||
{
|
|
||||||
prompt: '',
|
|
||||||
dataset_id: ''
|
|
||||||
}
|
|
||||||
)
|
|
||||||
const curNode = reactive({})
|
|
||||||
const getConversation = () => {
|
|
||||||
|
|
||||||
getCompletion()
|
|
||||||
}
|
|
||||||
// 大模型对话
|
|
||||||
const getCompletion = async () => {
|
|
||||||
for (let item of childTempList.value) {
|
|
||||||
try {
|
|
||||||
item.loading = true
|
|
||||||
params.prompt = `根据${curNode.edustage}${curNode.edusubject}课标,提炼出${item.name}`
|
|
||||||
const { data } = await completion(params)
|
|
||||||
let answer = data.answer
|
|
||||||
item.oldAnswer = answer
|
|
||||||
item.answer = getResult(answer);
|
|
||||||
onSaveTemp(item)
|
|
||||||
} finally {
|
|
||||||
item.loading = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 保存模板
|
|
||||||
const onSaveTemp = (item) => {
|
|
||||||
const data = {
|
|
||||||
mainModelId: props.tempId,
|
|
||||||
modelId: item.id,
|
|
||||||
examDocld: '',
|
|
||||||
content: item.oldAnswer
|
|
||||||
}
|
|
||||||
tempSave(data).then(res => {
|
|
||||||
console.log(res)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// 重新研读
|
|
||||||
const againResult = async (index, item) => {
|
|
||||||
try {
|
|
||||||
childTempList.value[index].loading = true
|
|
||||||
params.prompt = `根据${curNode.edustage}${curNode.edusubject}课标,提炼出${item.name}`
|
|
||||||
const { data } = await completion(params)
|
|
||||||
let answer = data.answer
|
|
||||||
childTempList.value[index].oldAnswer = answer
|
|
||||||
childTempList.value[index].answer = getResult(answer);
|
|
||||||
} finally {
|
|
||||||
childTempList.value[index].loading = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// 分析获取课标对话结果
|
|
||||||
let getResult = (text) => {
|
|
||||||
text = text.replace(/^\n\n(.*?)\n\n$/s, '<div>$1</div>');
|
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
// 编辑
|
|
||||||
const curIndex = ref(-1)
|
|
||||||
const editItem = reactive({})
|
|
||||||
const onEdit = (index, item) => {
|
|
||||||
curIndex.value = index
|
|
||||||
Object.assign(editItem, item)
|
|
||||||
isEdit.value = true
|
|
||||||
}
|
|
||||||
|
|
||||||
// 保存编辑
|
|
||||||
const saveEdit = (data) => {
|
|
||||||
// childTempList.value[curIndex.value].oldAnswer = data
|
|
||||||
// let answer = getResult(data);
|
|
||||||
// childTempList.value[curIndex.value].answer = answer
|
|
||||||
getChildTemplate()
|
|
||||||
}
|
|
||||||
|
|
||||||
const isAdjust = ref(false)
|
|
||||||
const onAdjust = (index, item) => {
|
|
||||||
curIndex.value = index
|
|
||||||
Object.assign(editItem, item)
|
|
||||||
isAdjust.value = true
|
|
||||||
}
|
|
||||||
const saveAdjust = (item) => {
|
|
||||||
childTempList.value[curIndex.value].oldAnswer = item
|
|
||||||
let answer = getResult(item);
|
|
||||||
childTempList.value[curIndex.value].answer = answer
|
|
||||||
}
|
|
||||||
|
|
||||||
// 编辑提示词
|
|
||||||
const keywordItem = reactive({})
|
|
||||||
const isEditKeyWord = ref(false)
|
|
||||||
const isAdd = ref(true)
|
|
||||||
const editKeyWord = (item) => {
|
|
||||||
console.log(item)
|
|
||||||
isAdd.value = false
|
|
||||||
isEditKeyWord.value = true
|
|
||||||
Object.assign(keywordItem, item)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 移除子模板
|
|
||||||
const removeItem = async (item) => {
|
|
||||||
if (item.ex3 != '1') {
|
|
||||||
ElMessageBox.confirm(
|
|
||||||
'确认是否移除?',
|
|
||||||
'提示',
|
|
||||||
{
|
|
||||||
confirmButtonText: '确定',
|
|
||||||
cancelButtonText: '取消',
|
|
||||||
type: 'warning',
|
|
||||||
}
|
|
||||||
).then(() => {
|
|
||||||
console.log(item)
|
|
||||||
removeChildTemp(item.id).then(res => {
|
|
||||||
ElMessage.success('操作成功')
|
|
||||||
getChildTemplate()
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
isAdd.value = false
|
|
||||||
Object.assign(keywordItem, item)
|
|
||||||
isEditKeyWord.value = true
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// const { msg } = await removeChildTemp(item.id)
|
|
||||||
// ElMessage.success(msg)
|
|
||||||
// getChildTemplate()
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
let data = sessionStore.get('subject.curNode')
|
|
||||||
Object.assign(curNode, data);
|
|
||||||
let text = props.modeType == 1 || props.modeType == 2 ? '课标' : '考试'
|
|
||||||
let jsonKey = `${text}-${data.edustage}-${data.edusubject}`
|
|
||||||
params.dataset_id = dataSetJson[jsonKey]
|
|
||||||
|
|
||||||
})
|
|
||||||
// 解绑
|
|
||||||
onUnmounted(() => {
|
|
||||||
emitter.off('onGetChild')
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
defineExpose({
|
|
||||||
getConversation
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.read-container {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
width: 100%;
|
|
||||||
padding: 15px 0;
|
|
||||||
height: 100%;
|
|
||||||
position: relative;
|
|
||||||
|
|
||||||
.el-scrollbar {
|
|
||||||
position: absolute;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
left: 0;
|
|
||||||
top: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.el-dropdown-link {
|
|
||||||
font-weight: bold;
|
|
||||||
|
|
||||||
.el-icon--right {
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.read-header {
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
.add-btn {
|
|
||||||
font-size: 13px;
|
|
||||||
|
|
||||||
.icon-jiahao {
|
|
||||||
margin-right: 3px;
|
|
||||||
font-size: 14px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
.right-con {
|
|
||||||
display: flex;
|
|
||||||
}
|
|
||||||
|
|
||||||
.template-list {
|
|
||||||
|
|
||||||
.template-item {
|
|
||||||
background: #fff;
|
|
||||||
padding: 10px;
|
|
||||||
margin-top: 10px;
|
|
||||||
border-radius: 5px;
|
|
||||||
|
|
||||||
.item-header {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
font-size: 16px;
|
|
||||||
font-weight: bold;
|
|
||||||
color: #000;
|
|
||||||
justify-content: space-between;
|
|
||||||
|
|
||||||
.blue {
|
|
||||||
font-size: 22px;
|
|
||||||
color: #409eff;
|
|
||||||
margin-right: 5px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.item-text {
|
|
||||||
display: flex;
|
|
||||||
margin-top: 10px;
|
|
||||||
font-size: 14px;
|
|
||||||
text-align: left;
|
|
||||||
color: #606266;
|
|
||||||
|
|
||||||
.item-icon {
|
|
||||||
width: 30px;
|
|
||||||
height: 30px;
|
|
||||||
line-height: 30px;
|
|
||||||
text-align: center;
|
|
||||||
background: #F6F6F6;
|
|
||||||
border-radius: 50%;
|
|
||||||
margin-right: 10px;
|
|
||||||
flex-shrink: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.item-answer {
|
|
||||||
flex-direction: column;
|
|
||||||
padding-top: 5px;
|
|
||||||
|
|
||||||
:deep(.text-tit) {
|
|
||||||
font-weight: bold;
|
|
||||||
margin: 10px 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
:deep(.text-num) {
|
|
||||||
padding-left: 2em;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
.text-answer {
|
|
||||||
color: #409eff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ai-btn {
|
|
||||||
margin-top: 10px;
|
|
||||||
display: flex;
|
|
||||||
justify-content: flex-end;
|
|
||||||
|
|
||||||
.iconfont {
|
|
||||||
margin-right: 3px;
|
|
||||||
}
|
|
||||||
|
|
||||||
:deep(.el-button) {
|
|
||||||
font-size: 13px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.icon-ai1 {
|
|
||||||
font-size: 18px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.template-item-result {
|
|
||||||
background: #DDEAFD !important;
|
|
||||||
|
|
||||||
.result-item-header {
|
|
||||||
display: flex;
|
|
||||||
align-items: flex-start;
|
|
||||||
text-align: left;
|
|
||||||
font-size: 16px;
|
|
||||||
font-weight: bold;
|
|
||||||
color: #3D3D3D;
|
|
||||||
|
|
||||||
.icon-xiaoxi {
|
|
||||||
color: #5881D5;
|
|
||||||
font-weight: bold;
|
|
||||||
font-size: 20px;
|
|
||||||
margin-right: 10px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.result-icon-btn {
|
|
||||||
justify-content: space-between;
|
|
||||||
font-size: 13px;
|
|
||||||
margin-top: 5px;
|
|
||||||
|
|
||||||
span {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
cursor: pointer;
|
|
||||||
margin-right: 10px;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
background: #cfe0fa
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.iconfont {
|
|
||||||
margin-right: 3px;
|
|
||||||
color: #3498fc;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.line {
|
|
||||||
height: 1px;
|
|
||||||
background: #D8D8D8;
|
|
||||||
margin: 10px 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.other-msg {
|
|
||||||
font-size: 13px;
|
|
||||||
|
|
||||||
.other-user {
|
|
||||||
align-items: center;
|
|
||||||
color: #BA4B0F;
|
|
||||||
font-size: 12px;
|
|
||||||
|
|
||||||
.icon-touxiang {
|
|
||||||
color: #BA4B0F;
|
|
||||||
font-weight: bold;
|
|
||||||
font-size: 16px;
|
|
||||||
margin-right: 5px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.other-text {
|
|
||||||
color: #191919;
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.icon-shenglvehao {
|
|
||||||
font-weight: bold;
|
|
||||||
font-size: 22px;
|
|
||||||
}
|
|
||||||
|
|
||||||
:deep(.el-popover) {
|
|
||||||
min-width: 50px;
|
|
||||||
width: 50px !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pl-25 {
|
|
||||||
padding-left: 25px;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
<style>
|
|
||||||
.template-custom-popover {
|
|
||||||
width: 110px !important;
|
|
||||||
min-width: 110px !important;
|
|
||||||
}
|
|
||||||
</style>
|
|
|
@ -0,0 +1,451 @@
|
||||||
|
<template>
|
||||||
|
<div class="container-right-page flex">
|
||||||
|
<!--头部-->
|
||||||
|
<div class="container-right-header flex">
|
||||||
|
<el-dropdown @command="changeTemplate" :hide-on-click="false">
|
||||||
|
<span class="el-dropdown-link">
|
||||||
|
{{ curTemplate.name }}
|
||||||
|
<i class="iconfont icon-xiangxia"></i>
|
||||||
|
</span>
|
||||||
|
<template #dropdown>
|
||||||
|
<el-dropdown-menu>
|
||||||
|
<el-dropdown-item v-for="item in templateList" :command="item" :key="item.id">{{ item.name
|
||||||
|
}}</el-dropdown-item>
|
||||||
|
</el-dropdown-menu>
|
||||||
|
</template>
|
||||||
|
</el-dropdown>
|
||||||
|
<div>
|
||||||
|
<el-button type="danger" link @click="removeItem(curTemplate, false)">
|
||||||
|
删除
|
||||||
|
</el-button>
|
||||||
|
<el-button type="primary" link @click="onAdd">
|
||||||
|
<i class="iconfont icon-jiahao"></i>
|
||||||
|
添加提示词
|
||||||
|
</el-button>
|
||||||
|
<el-button type="primary" :disabled="!(childTempList.length)" @click="getCompletion">一键研读</el-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!--List-->
|
||||||
|
<div class="container-right-list">
|
||||||
|
<template v-for="(item, index) in childTempList">
|
||||||
|
<div class="template-item" v-loading="item.loading">
|
||||||
|
<div class="item-header">
|
||||||
|
<div>
|
||||||
|
<span class="blue">#</span>{{ item.name }}
|
||||||
|
</div>
|
||||||
|
<el-popover placement="bottom-end" trigger="hover" popper-class="template-custom-popover">
|
||||||
|
<template #reference>
|
||||||
|
<el-button link type="primary">
|
||||||
|
<i class="iconfont icon-shenglvehao"></i></el-button>
|
||||||
|
</template>
|
||||||
|
<template #default>
|
||||||
|
<el-button type="primary" link @click="editKeyWord(item)">编辑</el-button>
|
||||||
|
<el-button type="primary" link @click="removeItem(item, true)">移除</el-button>
|
||||||
|
</template>
|
||||||
|
</el-popover>
|
||||||
|
</div>
|
||||||
|
<div class="item-text">
|
||||||
|
{{ item.prompt }}
|
||||||
|
</div>
|
||||||
|
<div class="item-text text-answer" v-if="item.answer">
|
||||||
|
<div class="item-icon">
|
||||||
|
<i class="iconfont icon-ai"></i>
|
||||||
|
</div>
|
||||||
|
<div class="item-answer" v-html="item.answer"></div>
|
||||||
|
</div>
|
||||||
|
<div class="ai-btn" v-if="item.answer">
|
||||||
|
<el-button type="primary" link @click="againResult(index, item)">
|
||||||
|
<i class="iconfont icon-ai1"></i>
|
||||||
|
重新研读
|
||||||
|
</el-button>
|
||||||
|
<el-button type="primary" link @click="onAdjust(index, item)">
|
||||||
|
<i class="iconfont icon-duihua"></i>
|
||||||
|
AI对话调整
|
||||||
|
</el-button>
|
||||||
|
<el-button type="primary" link @click="onEdit(index, item)">
|
||||||
|
<i class="iconfont icon-bianji1"></i>
|
||||||
|
手动编辑结果
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</template>
|
||||||
|
<el-empty v-if="!childTempList.length" description="暂无模板数据" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!--编辑结果-->
|
||||||
|
<EditDialog v-model="isEdit" :item="editItem" />
|
||||||
|
<!--AI 对话调整-->
|
||||||
|
<AdjustDialog v-model="isAdjust" :modeType="type" :item="editItem" />
|
||||||
|
<!--添加、编辑提示词-->
|
||||||
|
<keywordDialog v-model="isWordDialog" :isAdd="isAdd" :item="editItem" />
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, reactive, onMounted, computed, onUnmounted } from 'vue'
|
||||||
|
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||||
|
import { tempSave, completion, modelList, removeChildTemp, tempResult } from '@/api/mode/index'
|
||||||
|
import keywordDialog from './keyword-dialog.vue';
|
||||||
|
import AdjustDialog from './adjust-dialog.vue'
|
||||||
|
import EditDialog from './edit-dialog.vue'
|
||||||
|
import emitter from '@/utils/mitt';
|
||||||
|
import { dataSetJson } from '@/utils/comm.js'
|
||||||
|
|
||||||
|
const props = defineProps(['curNode', 'type'])
|
||||||
|
|
||||||
|
/*****************提示词相关****************/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* isWordDialog : 提示词弹窗
|
||||||
|
* isAdd : 是否添加 默认false
|
||||||
|
* editItem: 当前操作的item (添加的时候不需要这个)
|
||||||
|
*/
|
||||||
|
|
||||||
|
const isWordDialog = ref(false)
|
||||||
|
const isAdd = ref(false)
|
||||||
|
const editItem = reactive({})
|
||||||
|
const onAdd = () => {
|
||||||
|
isAdd.value = true
|
||||||
|
Object.assign(editItem, curTemplate)
|
||||||
|
isWordDialog.value = true
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
const editKeyWord = (item, val) => {
|
||||||
|
/**
|
||||||
|
* isAdd: 字模板中的移除 为编辑 头部删除 添加提示词为新增
|
||||||
|
*/
|
||||||
|
isAdd.value = val
|
||||||
|
Object.assign(editItem, item)
|
||||||
|
isWordDialog.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************模板相关**********************/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* curTemplate :当前模板
|
||||||
|
* templateList :主模板List
|
||||||
|
* childTempList : 子模板List
|
||||||
|
* getTemplateList() : 获取主模板
|
||||||
|
* getChildTemplate() :获取子模板
|
||||||
|
*/
|
||||||
|
const tempLoading = ref(false)
|
||||||
|
const curTemplate = reactive({ name: '', id: '' })
|
||||||
|
const templateList = ref([])
|
||||||
|
const childTempList = ref([])
|
||||||
|
const getTemplateList = () => {
|
||||||
|
modelList({ model: props.type, type: 1, pageNum: 1, pageSize: 10000 }).then(res => {
|
||||||
|
templateList.value = res.rows
|
||||||
|
Object.assign(curTemplate, res.rows[0]);
|
||||||
|
getChildTemplate()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
const getChildTemplate = () => {
|
||||||
|
tempLoading.value = true
|
||||||
|
modelList({ model: props.type, type: 2, parentId: curTemplate.id }).then(res => {
|
||||||
|
childTempList.value = res.rows
|
||||||
|
|
||||||
|
getTempResult()
|
||||||
|
}).finally(() => {
|
||||||
|
tempLoading.value = false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 查询模板结果
|
||||||
|
const getTempResult = () => {
|
||||||
|
tempResult({ mainModelId: curTemplate.id }).then(res => {
|
||||||
|
let rows = res.rows
|
||||||
|
childTempList.value.forEach(item => {
|
||||||
|
rows.forEach(el => {
|
||||||
|
if (item.id == el.modelId) {
|
||||||
|
item.answer = el.content
|
||||||
|
item.reultId = el.id
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 模板切换
|
||||||
|
const changeTemplate = (val) => {
|
||||||
|
ElMessageBox.confirm(
|
||||||
|
'切换模板将清除当前研读结果?',
|
||||||
|
'提示',
|
||||||
|
{
|
||||||
|
confirmButtonText: '确定',
|
||||||
|
cancelButtonText: '取消',
|
||||||
|
type: 'warning',
|
||||||
|
}
|
||||||
|
).then(() => {
|
||||||
|
Object.assign(curTemplate, val);
|
||||||
|
getChildTemplate()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 移除模板
|
||||||
|
const removeItem = async (item, isChild) => {
|
||||||
|
/**
|
||||||
|
* item: 当前操作的模板
|
||||||
|
* isChild: 子模板中的移除为 true 否则为false
|
||||||
|
*/
|
||||||
|
if (item.ex3 != '1') {
|
||||||
|
ElMessageBox.confirm(
|
||||||
|
'确认是否移除?',
|
||||||
|
'提示',
|
||||||
|
{
|
||||||
|
confirmButtonText: '确定',
|
||||||
|
cancelButtonText: '取消',
|
||||||
|
type: 'warning',
|
||||||
|
}
|
||||||
|
).then(() => {
|
||||||
|
removeChildTemp(item.id).then(res => {
|
||||||
|
ElMessage.success('操作成功')
|
||||||
|
if(isChild){
|
||||||
|
// 获取子模板
|
||||||
|
getChildTemplate()
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
// 获取主模板
|
||||||
|
getTemplateList()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
|
|
||||||
|
editKeyWord(item,!isChild)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Ai对话调整
|
||||||
|
const curIndex = ref(-1)
|
||||||
|
const isAdjust = ref(false)
|
||||||
|
const onAdjust = (index, item) => {
|
||||||
|
curIndex.value = index
|
||||||
|
Object.assign(editItem, item)
|
||||||
|
isAdjust.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
// 编辑结果
|
||||||
|
const isEdit = ref(false)
|
||||||
|
const onEdit = (index, item) => {
|
||||||
|
curIndex.value = index
|
||||||
|
Object.assign(editItem, item)
|
||||||
|
isEdit.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const modeType = computed(() => {
|
||||||
|
if (props.type == 1) return '课标';
|
||||||
|
if (props.type == 2) return '教材';
|
||||||
|
if (props.type == 3) return '考试';
|
||||||
|
})
|
||||||
|
// 重新研读
|
||||||
|
const params = reactive(
|
||||||
|
{
|
||||||
|
prompt: '',
|
||||||
|
dataset_id: ''
|
||||||
|
}
|
||||||
|
)
|
||||||
|
// 重新研读
|
||||||
|
const againResult = async (index, item) => {
|
||||||
|
try {
|
||||||
|
childTempList.value[index].loading = true
|
||||||
|
params.prompt = `按照${item.name}的要求,针对${props.curNode.edustage}${props.curNode.edusubject}${modeType} 对${props.curNode.itemtitle}进行教学分析`
|
||||||
|
const { data } = await completion(params)
|
||||||
|
let answer = data.answer
|
||||||
|
childTempList.value[index].oldAnswer = answer
|
||||||
|
childTempList.value[index].answer = getResult(answer);
|
||||||
|
onSaveTemp(item)
|
||||||
|
} finally {
|
||||||
|
childTempList.value[index].loading = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 一键研读
|
||||||
|
const getCompletion = async () => {
|
||||||
|
for (let item of childTempList.value) {
|
||||||
|
try {
|
||||||
|
item.loading = true
|
||||||
|
params.prompt = `按照${item.name}的要求,针对${props.curNode.edustage}${props.curNode.edusubject}${modeType} 对${props.curNode.itemtitle}进行教学分析`
|
||||||
|
const { data } = await completion(params)
|
||||||
|
let answer = data.answer
|
||||||
|
item.oldAnswer = answer
|
||||||
|
item.answer = getResult(answer);
|
||||||
|
onSaveTemp(item)
|
||||||
|
} finally {
|
||||||
|
item.loading = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 保存模板
|
||||||
|
const onSaveTemp = (item) => {
|
||||||
|
const data = {
|
||||||
|
mainModelId: props.tempId,
|
||||||
|
modelId: item.id,
|
||||||
|
examDocld: '',
|
||||||
|
content: item.oldAnswer
|
||||||
|
}
|
||||||
|
tempSave(data).then(res => {
|
||||||
|
console.log(res)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// 替换分析结果
|
||||||
|
emitter.on('saveAdjust', (item) => {
|
||||||
|
childTempList.value[curIndex.value].oldAnswer = item
|
||||||
|
let answer = getResult(item);
|
||||||
|
childTempList.value[curIndex.value].answer = answer
|
||||||
|
})
|
||||||
|
|
||||||
|
// 分析获取课标对话结果
|
||||||
|
let getResult = (text) => {
|
||||||
|
text = text.replace(/^\n\n(.*?)\n\n$/s, '<div>$1</div>');
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
// 操作之后获取字模板
|
||||||
|
emitter.on('onGetChild', () => {
|
||||||
|
getChildTemplate()
|
||||||
|
})
|
||||||
|
// 操作之后获取主模板
|
||||||
|
emitter.on('onGetMain', () => {
|
||||||
|
getTemplateList()
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
getTemplateList()
|
||||||
|
let jsonKey = `${modeType}-${props.curNode.edustage}-${props.curNode.edusubject}`
|
||||||
|
params.dataset_id = dataSetJson[jsonKey]
|
||||||
|
})
|
||||||
|
|
||||||
|
// 解绑
|
||||||
|
onUnmounted(() => {
|
||||||
|
emitter.off('onGetChild');
|
||||||
|
emitter.off('saveAdjust');
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.container-right-page {
|
||||||
|
height: 100%;
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
|
.container-right-header {
|
||||||
|
height: 45px;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
background: #fff;
|
||||||
|
border-left: solid #EBF0F4 1px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding: 0 15px;
|
||||||
|
border-radius: 0 5px 0 0
|
||||||
|
}
|
||||||
|
|
||||||
|
.container-right-list {
|
||||||
|
flex: 1;
|
||||||
|
overflow-y: auto;
|
||||||
|
padding: 5px 15px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.template-item {
|
||||||
|
background: #fff;
|
||||||
|
padding: 10px;
|
||||||
|
margin-top: 10px;
|
||||||
|
border-radius: 5px;
|
||||||
|
|
||||||
|
.item-header {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #000;
|
||||||
|
justify-content: space-between;
|
||||||
|
|
||||||
|
.blue {
|
||||||
|
font-size: 22px;
|
||||||
|
color: #409eff;
|
||||||
|
margin-right: 5px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.item-text {
|
||||||
|
display: flex;
|
||||||
|
margin-top: 10px;
|
||||||
|
font-size: 14px;
|
||||||
|
text-align: left;
|
||||||
|
color: #606266;
|
||||||
|
|
||||||
|
.item-icon {
|
||||||
|
width: 30px;
|
||||||
|
height: 30px;
|
||||||
|
line-height: 30px;
|
||||||
|
text-align: center;
|
||||||
|
background: #F6F6F6;
|
||||||
|
border-radius: 50%;
|
||||||
|
margin-right: 10px;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.item-answer {
|
||||||
|
flex-direction: column;
|
||||||
|
padding-top: 5px;
|
||||||
|
|
||||||
|
:deep(.text-tit) {
|
||||||
|
font-weight: bold;
|
||||||
|
margin: 10px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.text-num) {
|
||||||
|
padding-left: 2em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-answer {
|
||||||
|
color: #409eff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ai-btn {
|
||||||
|
margin-top: 10px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
|
||||||
|
.iconfont {
|
||||||
|
margin-right: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.el-button) {
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-ai1 {
|
||||||
|
font-size: 18px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<style>
|
||||||
|
.template-custom-popover {
|
||||||
|
width: 110px !important;
|
||||||
|
min-width: 110px !important;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -1,26 +1,21 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="page-template flex">
|
<div class="page-template flex">
|
||||||
<!--头部-->
|
<el-row>
|
||||||
<Header :type="type" @changeTemp="changeTemp" @onRead="onRead"/>
|
|
||||||
<el-row :gutter="20" class="tempalte-main">
|
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<!--左侧pdf-->
|
<Left :curNode="curNode" :type="type" />
|
||||||
<Pdf />
|
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<!--右侧模板研读-->
|
<Right :curNode="curNode" :type="type" />
|
||||||
<Result ref="resultRef" :modeType="type" :tempId="tempId"/>
|
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref } from 'vue'
|
import { reactive, onMounted } from 'vue'
|
||||||
import Header from './container/header.vue'
|
import { sessionStore } from '@/utils/store'
|
||||||
import Pdf from './container/pdf.vue'
|
import Left from './container/left.vue'
|
||||||
import Result from './container/result.vue'
|
import Right from './container/right.vue'
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
type: {
|
type: {
|
||||||
|
@ -29,22 +24,24 @@ const props = defineProps({
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const curNode = reactive({})
|
||||||
|
onMounted(() =>{
|
||||||
|
let data = sessionStore.get('subject.curNode')
|
||||||
|
Object.assign(curNode, data);
|
||||||
|
})
|
||||||
|
|
||||||
const resultRef = ref()
|
|
||||||
const tempId = ref('')
|
|
||||||
const changeTemp = (id) =>{
|
|
||||||
tempId.value = id
|
|
||||||
}
|
|
||||||
|
|
||||||
const onRead = () =>{
|
|
||||||
resultRef.value.getConversation()
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.page-template {
|
.page-template {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
.el-row{
|
||||||
|
height: 100%;
|
||||||
|
.el-col{
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
.tempalte-main {
|
.tempalte-main {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,18 +7,22 @@
|
||||||
<span>{{ item.name }}</span>
|
<span>{{ item.name }}</span>
|
||||||
<el-button type="primary" link @click="onSelect(item)">选择模式</el-button>
|
<el-button type="primary" link @click="onSelect(item)">选择模式</el-button>
|
||||||
</div>
|
</div>
|
||||||
<el-scrollbar>
|
<div class="content-list">
|
||||||
<div class="item-list flex">
|
<div class="item-list flex">
|
||||||
<el-card class="item-card" shadow="never" v-for="el in item.child" :key="el.id">
|
<el-card class="item-card" shadow="never" v-for="el in item.child" :key="el.id">
|
||||||
<p class="card-name">{{ el.name }}</p>
|
<p class="card-name">
|
||||||
<div class="card-text">
|
<el-text line-clamp="1" :title="el.name">
|
||||||
<el-text line-clamp="2">
|
{{ el.name }}
|
||||||
{{ el.prompt }}
|
</el-text>
|
||||||
</el-text>
|
</p>
|
||||||
</div>
|
<div class="card-text">
|
||||||
</el-card>
|
<el-text line-clamp="4" :title="el.prompt">
|
||||||
</div>
|
{{ el.prompt }}
|
||||||
</el-scrollbar>
|
</el-text>
|
||||||
|
</div>
|
||||||
|
</el-card>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -97,30 +101,44 @@ onMounted(() => {
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
margin-bottom: 5px;
|
margin-bottom: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.con-item {
|
.con-item {
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column
|
||||||
|
}
|
||||||
|
.item-list{
|
||||||
|
margin-bottom: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.item-card {
|
.item-card {
|
||||||
width: 130px;
|
width: 130px;
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
margin-right: 20px;
|
margin-right: 20px;
|
||||||
|
flex-shrink: 0;
|
||||||
|
border-radius: 10px;
|
||||||
:deep(.el-card__body) {
|
:deep(.el-card__body) {
|
||||||
padding: 0 !important;
|
padding: 0 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.card-name {
|
.card-name {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
font-size: 14px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.card-text {
|
.card-text {
|
||||||
text-align: left;
|
text-align: left;
|
||||||
font-size: 12px;
|
|
||||||
|
.el-text{
|
||||||
|
font-size: 12px !important;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.content-list{
|
||||||
|
overflow-x: auto
|
||||||
|
}
|
||||||
|
.content-list::-webkit-scrollbar {
|
||||||
|
height: 8px;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
|
@ -52,26 +52,55 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, onUnmounted, reactive } from 'vue'
|
import { ref, onMounted, onUnmounted, reactive } from 'vue'
|
||||||
|
import { sessionStore } from '@/utils/store'
|
||||||
import emitter from '@/utils/mitt'
|
import emitter from '@/utils/mitt'
|
||||||
import EditDialog from './edit-dialog.vue'
|
import EditDialog from './edit-dialog.vue'
|
||||||
import AdjustDialog from './adjust-dialog.vue'
|
import AdjustDialog from './adjust-dialog.vue'
|
||||||
import { completion } from '@/api/mode/index.js'
|
import { completion, tempResult } from '@/api/mode/index.js'
|
||||||
|
import { dataSetJson } from '@/utils/comm.js'
|
||||||
|
|
||||||
|
|
||||||
const resultList = ref([])
|
const resultList = ref([])
|
||||||
emitter.on('changeMode', (item) => {
|
emitter.on('changeMode', (item) => {
|
||||||
|
console.log(item, 'item')
|
||||||
resultList.value = item.child
|
resultList.value = item.child
|
||||||
conversation()
|
// conversation()
|
||||||
|
getTempResult(item.id)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
// 查询模板结果
|
||||||
|
const getTempResult = (id) => {
|
||||||
|
tempResult({ mainModelId: id }).then(res => {
|
||||||
|
console.log(res, 2000)
|
||||||
|
let rows = res.rows
|
||||||
|
if (rows.length > 0) {
|
||||||
|
resultList.value.forEach(item => {
|
||||||
|
rows.forEach(el => {
|
||||||
|
if (item.id == el.modelId) {
|
||||||
|
item.answer = el.content
|
||||||
|
item.reultId = el.id
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const params = reactive(
|
||||||
|
{
|
||||||
|
prompt: '',
|
||||||
|
dataset_id: ''
|
||||||
|
}
|
||||||
|
)
|
||||||
const conversation = async () => {
|
const conversation = async () => {
|
||||||
for (let item of resultList.value) {
|
for (let item of resultList.value) {
|
||||||
item.loading = true
|
item.loading = true
|
||||||
try {
|
try {
|
||||||
const { data } = await completion({
|
params.prompt = `按照${item.prompt}的要求,针对${curNode.edustage}${curNode.edusubject}课标对${curNode.itemtitle}进行教学分析`
|
||||||
dataset_id: 'cee3062a9fcf11efa6910242ac140006',
|
const { data } = await completion(params)
|
||||||
prompt: item.prompt
|
|
||||||
})
|
|
||||||
item.answer = data.answer
|
item.answer = data.answer
|
||||||
} finally {
|
} finally {
|
||||||
item.loading = false
|
item.loading = false
|
||||||
|
@ -89,10 +118,8 @@ const curItem = reactive({})
|
||||||
const againResult = async (index, item) => {
|
const againResult = async (index, item) => {
|
||||||
try {
|
try {
|
||||||
resultList.value[index].loading = true
|
resultList.value[index].loading = true
|
||||||
const { data } = await completion({
|
params.prompt = `按照${item.prompt}的要求,针对${curNode.edustage}${curNode.edusubject}课标对${curNode.itemtitle}进行教学分析`
|
||||||
dataset_id: 'cee3062a9fcf11efa6910242ac140006',
|
const { data } = await completion(params)
|
||||||
prompt: item.prompt
|
|
||||||
})
|
|
||||||
resultList.value[index].answer = data.answer
|
resultList.value[index].answer = data.answer
|
||||||
} finally {
|
} finally {
|
||||||
resultList.value[index].loading = false
|
resultList.value[index].loading = false
|
||||||
|
@ -101,12 +128,12 @@ const againResult = async (index, item) => {
|
||||||
|
|
||||||
// 对话调整
|
// 对话调整
|
||||||
const isAdjust = ref(false)
|
const isAdjust = ref(false)
|
||||||
const onAdjust = (index, item) => {
|
const onAdjust = (index, item) => {
|
||||||
curIndex.value = index
|
curIndex.value = index
|
||||||
Object.assign(curItem, item)
|
Object.assign(curItem, item)
|
||||||
isAdjust.value = true
|
isAdjust.value = true
|
||||||
}
|
}
|
||||||
emitter.on('changeAdjust', (item) =>{
|
emitter.on('changeAdjust', (item) => {
|
||||||
resultList.value[curIndex.value].answer = item
|
resultList.value[curIndex.value].answer = item
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -122,6 +149,17 @@ emitter.on('changeResult', (item) => {
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const curNode = reactive({})
|
||||||
|
onMounted(() => {
|
||||||
|
let data = sessionStore.get('subject.curNode')
|
||||||
|
Object.assign(curNode, data);
|
||||||
|
|
||||||
|
let jsonKey = `课标-${data.edustage}-${data.edusubject}`
|
||||||
|
params.dataset_id = dataSetJson[jsonKey]
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
// 解绑
|
// 解绑
|
||||||
onUnmounted(() => {
|
onUnmounted(() => {
|
||||||
emitter.off('changeMode')
|
emitter.off('changeMode')
|
||||||
|
|
Loading…
Reference in New Issue