Merge branch 'main' into zouyf_dev
# Conflicts: # package.json
This commit is contained in:
commit
d5a8da438a
|
@ -49,14 +49,21 @@ export default defineConfig({
|
||||||
changeOrigin: true, // 改变请求的起源
|
changeOrigin: true, // 改变请求的起源
|
||||||
rewrite: (path) => path.replace(/^\/parth/, '') // 重写路径
|
rewrite: (path) => path.replace(/^\/parth/, '') // 重写路径
|
||||||
},
|
},
|
||||||
'/v1': {
|
'/api': {
|
||||||
target: 'https://ai.ysaix.com:7864',
|
target: 'https://ai.ysaix.com:7864',
|
||||||
changeOrigin: true,
|
changeOrigin: true,
|
||||||
pathRewrite: { '^/v1': '' }
|
pathRewrite: { '^/api': '' }
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
plugins: [vue(), WindiCSS(),vitePpt()],
|
plugins: [vue(), WindiCSS(),vitePpt()],
|
||||||
assetsInclude:('**/*.woff', '**/*.woff2', '**/*.ttf'),
|
assetsInclude:('**/*.woff', '**/*.woff2', '**/*.ttf'),
|
||||||
|
css: {
|
||||||
|
preprocessorOptions: {
|
||||||
|
scss: {
|
||||||
|
silenceDeprecations: ['legacy-js-api']
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,7 +1,69 @@
|
||||||
import request from '@/utils/request'
|
import request from '@/utils/request'
|
||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
|
|
||||||
let rootPath = import.meta.env.VITE_APP_ENV === 'production' ? "https://ai.ysaix.com:7864" : '';
|
let rootPath = import.meta.env.VITE_APP_ENV === 'production' ? 'https://ai.ysaix.com:7864' : ''
|
||||||
|
|
||||||
|
export function conversation(data) {
|
||||||
|
return axios({
|
||||||
|
url: rootPath + '/v1/api/new_conversation',
|
||||||
|
method: 'get',
|
||||||
|
headers: {
|
||||||
|
Authorization: 'Bearer ragflow-IwNzMxMTIyOGY0ZTExZWZiOGE2MDI0Mm',
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
},
|
||||||
|
data: data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 进行课标研读对话
|
||||||
|
export function completion(data) {
|
||||||
|
return axios({
|
||||||
|
url: rootPath + '/api/v1/parse/docs',
|
||||||
|
method: 'post',
|
||||||
|
headers: {
|
||||||
|
Authorization: 'Bearer ragflow-IwMDI1MGU2YTU3NjExZWZiNWEzMDI0Mm',
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
Accept: '*/*'
|
||||||
|
},
|
||||||
|
data: data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加提示词 (系统预设)
|
||||||
|
export function addKeyWords(data) {
|
||||||
|
return request({
|
||||||
|
url: '/education/llmModel/copy',
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加子模板
|
||||||
|
export function addChildTemp(data) {
|
||||||
|
return request({
|
||||||
|
url: '/education/llmModel',
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 编辑子模板
|
||||||
|
export function editChildTemp(data) {
|
||||||
|
return request({
|
||||||
|
url: '/education/llmModel',
|
||||||
|
method: 'put',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除子模板
|
||||||
|
export function removeChildTemp(id) {
|
||||||
|
return request({
|
||||||
|
url: '/education/llmModel/' + id,
|
||||||
|
method: 'delete'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// 查询模板列表
|
// 查询模板列表
|
||||||
export function modelList(params) {
|
export function modelList(params) {
|
||||||
return request({
|
return request({
|
||||||
|
@ -11,28 +73,37 @@ export function modelList(params) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export function conversation(data) {
|
// 保存模板 结果
|
||||||
return axios({
|
export function tempSave(data) {
|
||||||
url: rootPath + '/v1/api/new_conversation',
|
return request({
|
||||||
method: 'get',
|
url: '/education/result',
|
||||||
headers: {
|
method: 'post',
|
||||||
'Authorization':'Bearer ragflow-IwNzMxMTIyOGY0ZTExZWZiOGE2MDI0Mm',
|
data
|
||||||
'Content-Type': 'application/json',
|
|
||||||
},
|
|
||||||
data: data
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 进行课标研读对话
|
// 修改模板结果
|
||||||
export function completion(data) {
|
export function editTempResult(data) {
|
||||||
return axios({
|
return request({
|
||||||
url: rootPath + '/v1/api/completion',
|
url: '/education/result',
|
||||||
method: 'post',
|
method: 'put',
|
||||||
headers: {
|
data
|
||||||
'Authorization':'Bearer ragflow-IwNzMxMTIyOGY0ZTExZWZiOGE2MDI0Mm',
|
})
|
||||||
'Content-Type': 'application/json',
|
}
|
||||||
'Accept': '*/*'
|
|
||||||
},
|
// 查询模板结果
|
||||||
data: data
|
export function tempResult(params) {
|
||||||
|
return request({
|
||||||
|
url: '/education/result/list',
|
||||||
|
method: 'get',
|
||||||
|
params
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除模板结果
|
||||||
|
export function tempResultRemove(id) {
|
||||||
|
return request({
|
||||||
|
url: `/education/result/${id}`,
|
||||||
|
method: 'get',
|
||||||
})
|
})
|
||||||
}
|
}
|
|
@ -1,8 +1,8 @@
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: "iconfont"; /* Project id 4723712 */
|
font-family: "iconfont"; /* Project id 4723712 */
|
||||||
src: url('iconfont.woff2?t=1731393731097') format('woff2'),
|
src: url('iconfont.woff2?t=1731913617367') format('woff2'),
|
||||||
url('iconfont.woff?t=1731393731097') format('woff'),
|
url('iconfont.woff?t=1731913617367') format('woff'),
|
||||||
url('iconfont.ttf?t=1731393731097') format('truetype');
|
url('iconfont.ttf?t=1731913617367') format('truetype');
|
||||||
}
|
}
|
||||||
|
|
||||||
.iconfont {
|
.iconfont {
|
||||||
|
@ -13,6 +13,10 @@
|
||||||
-moz-osx-font-smoothing: grayscale;
|
-moz-osx-font-smoothing: grayscale;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.icon-baocun:before {
|
||||||
|
content: "\e60e";
|
||||||
|
}
|
||||||
|
|
||||||
.icon-tihuan:before {
|
.icon-tihuan:before {
|
||||||
content: "\e7ab";
|
content: "\e7ab";
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -5,6 +5,13 @@
|
||||||
"css_prefix_text": "icon-",
|
"css_prefix_text": "icon-",
|
||||||
"description": "",
|
"description": "",
|
||||||
"glyphs": [
|
"glyphs": [
|
||||||
|
{
|
||||||
|
"icon_id": "11467388",
|
||||||
|
"name": "保存",
|
||||||
|
"font_class": "baocun",
|
||||||
|
"unicode": "e60e",
|
||||||
|
"unicode_decimal": 58894
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"icon_id": "12730938",
|
"icon_id": "12730938",
|
||||||
"name": "替换",
|
"name": "替换",
|
||||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -44,6 +44,7 @@ import { ref, reactive, onMounted } from 'vue'
|
||||||
import { conversation, completion } from '@/api/mode/index'
|
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'
|
||||||
|
|
||||||
const textarea = ref('')
|
const textarea = ref('')
|
||||||
|
|
||||||
|
@ -55,6 +56,10 @@ const props = defineProps({
|
||||||
default: () => {
|
default: () => {
|
||||||
return { name: '11' }
|
return { name: '11' }
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
modeType: {
|
||||||
|
type: Number,
|
||||||
|
default: 1
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -77,31 +82,22 @@ const send = () =>{
|
||||||
const curNode = reactive({})
|
const curNode = reactive({})
|
||||||
const params = reactive(
|
const params = reactive(
|
||||||
{
|
{
|
||||||
"conversation_id": "",
|
prompt: '',
|
||||||
"messages": [
|
dataset_id: ''
|
||||||
{
|
|
||||||
"role": "user",
|
|
||||||
"content": ""
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"quote": false,
|
|
||||||
"stream": false
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
// 获取会话ID
|
// 获取会话ID
|
||||||
const getConversation = async (val) => {
|
const getConversation = (val) => {
|
||||||
const result = await conversation()
|
|
||||||
params.conversation_id = result.data.data.id
|
|
||||||
getCompletion(val)
|
getCompletion(val)
|
||||||
}
|
}
|
||||||
// 大模型对话
|
// 大模型对话
|
||||||
const getCompletion = async (val) => {
|
const getCompletion = async (val) => {
|
||||||
try {
|
try {
|
||||||
|
|
||||||
params.messages[0].content = `根据${curNode.edustage}语文课标${props.item.name},${val}`
|
params.prompt = `根据${curNode.edustage}${curNode.edusubject}课标${props.item.name},${val}`
|
||||||
const res = await completion(params)
|
const { data } = await completion(params)
|
||||||
console.log('对话结果===》', res)
|
let answer = data.answer
|
||||||
let answer = res.data.data.answer
|
|
||||||
msgList.value.push({
|
msgList.value.push({
|
||||||
type: 'robot',
|
type: 'robot',
|
||||||
msg: answer,
|
msg: answer,
|
||||||
|
@ -121,6 +117,10 @@ const saveAdjust = (item) =>{
|
||||||
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 jsonKey = `${text}-${data.edustage}-${data.edusubject}`
|
||||||
|
params.dataset_id = dataSetJson[jsonKey]
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
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'
|
||||||
|
|
||||||
const textarea = ref('')
|
const textarea = ref('')
|
||||||
|
|
||||||
|
@ -42,7 +43,7 @@ const props = defineProps({
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
watch(() => props.item.oldAnswer, (newVal) => {
|
watch(() => props.item.answer, (newVal) => {
|
||||||
if (newVal) {
|
if (newVal) {
|
||||||
textarea.value = newVal
|
textarea.value = newVal
|
||||||
}
|
}
|
||||||
|
@ -50,9 +51,11 @@ watch(() => props.item.oldAnswer, (newVal) => {
|
||||||
|
|
||||||
const emit = defineEmits(['saveEdit'])
|
const emit = defineEmits(['saveEdit'])
|
||||||
const onSave = () =>{
|
const onSave = () =>{
|
||||||
emit('saveEdit', textarea.value)
|
editTempResult({id: props.item.reultId, content: textarea.value}).then( res =>{
|
||||||
isDialog.value = false
|
isDialog.value = false
|
||||||
ElMessage.success('操作成功')
|
ElMessage.success('操作成功')
|
||||||
|
emit('saveEdit', textarea.value)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
<el-dropdown @command="changeTemplate" :hide-on-click="false">
|
<el-dropdown @command="changeTemplate" :hide-on-click="false">
|
||||||
<span class="el-dropdown-link">
|
<span class="el-dropdown-link">
|
||||||
{{ curTemplate.name }}
|
{{ curTemplate.name }}
|
||||||
<i class="iconfont icon-xiangxia" </i>
|
<i class="iconfont icon-xiangxia"></i>
|
||||||
</span>
|
</span>
|
||||||
<template #dropdown>
|
<template #dropdown>
|
||||||
<el-dropdown-menu>
|
<el-dropdown-menu>
|
||||||
|
@ -20,7 +20,7 @@
|
||||||
</template>
|
</template>
|
||||||
</el-dropdown>
|
</el-dropdown>
|
||||||
<div>
|
<div>
|
||||||
<el-button type="primary" link @click="wordDialog = true">
|
<el-button type="primary" link @click="onAdd">
|
||||||
<el-icon>
|
<el-icon>
|
||||||
<Plus />
|
<Plus />
|
||||||
</el-icon>
|
</el-icon>
|
||||||
|
@ -31,7 +31,8 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<keywordDialog v-model="wordDialog"/>
|
<!--添加提示词-->
|
||||||
|
<keywordDialog v-model="wordDialog" :modeType="type" :isAdd="wordDialog" :item="curTemplate"/>
|
||||||
<Dialog v-model="showDialog" :modeType="type" />
|
<Dialog v-model="showDialog" :modeType="type" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -93,6 +94,11 @@ const changeTemplate = (val) => {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const onAdd = () =>{
|
||||||
|
wordDialog.value = true
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
getTemplateList()
|
getTemplateList()
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,28 +1,28 @@
|
||||||
<template>
|
<template>
|
||||||
<el-dialog v-model="mode" :show-close="false" width="600">
|
<el-dialog v-model="mode" :show-close="false" width="600" destroy-on-close>
|
||||||
<template #header>
|
<template #header>
|
||||||
<div class="custom-header flex">
|
<div class="custom-header flex">
|
||||||
<span>{{ isAdd ? '添加' : '编辑' }}提示词</span>
|
<span>{{ isAdd ? item && item.ex3 == '1' ? '请输入新的模板名称' : '添加提示词' : '编辑提示词' }}</span>
|
||||||
<i class="iconfont icon-guanbi" @click="mode = false"></i>
|
<i class="iconfont icon-guanbi" @click="mode = false"></i>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<div class="dialog-content">
|
<div class="dialog-content" v-loading="loading">
|
||||||
|
<p class="small-tip" v-if="item && item.ex3 == '1'">*当前模板为系统预设,不支持直接操作。会复制一份为自己的然后再操作</p>
|
||||||
<el-form :model="form" label-width="auto">
|
<el-form :model="form" label-width="auto">
|
||||||
<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="提示词">
|
<el-form-item label="提示词" v-if="isAdd ? !(item && item.ex3 == '1') : 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">
|
||||||
<el-button @click="mode = false">取消</el-button>
|
<el-button @click="mode = false">取消</el-button>
|
||||||
<el-button type="primary" @click="mode = false">
|
<el-button type="primary" @click="saveAdd">
|
||||||
确定
|
确定
|
||||||
</el-button>
|
</el-button>
|
||||||
</div>
|
</div>
|
||||||
|
@ -31,16 +31,27 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { reactive, watch } from 'vue'
|
import { ref, reactive, watch } from 'vue'
|
||||||
const mode = defineModel()
|
import { ElMessage } from 'element-plus'
|
||||||
|
import { addKeyWords, addChildTemp, editChildTemp } from '@/api/mode/index'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const mode = defineModel()
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
|
modeType: {
|
||||||
|
type: Number,
|
||||||
|
default: 1
|
||||||
|
},
|
||||||
isAdd: {
|
isAdd: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: true
|
default: true
|
||||||
},
|
},
|
||||||
item: {
|
item: { // 子模板
|
||||||
type: Object
|
type: Object
|
||||||
|
},
|
||||||
|
temp: { // 当前主模板
|
||||||
|
Object
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -50,12 +61,60 @@ const form = reactive({
|
||||||
})
|
})
|
||||||
|
|
||||||
watch(() => props.isAdd, (newVal) => {
|
watch(() => props.isAdd, (newVal) => {
|
||||||
|
console.log(newVal)
|
||||||
if (!newVal) {
|
if (!newVal) {
|
||||||
console.log(props.item)
|
form.name = props.item?.name
|
||||||
form.name = props.item.name
|
form.prompt = props.item?.prompt
|
||||||
form.prompt = props.item.prompt
|
|
||||||
}
|
}
|
||||||
}, { immediate: true })
|
|
||||||
|
}, { immediate: false })
|
||||||
|
|
||||||
|
const loading = ref(false)
|
||||||
|
const saveAdd = async () => {
|
||||||
|
loading.value = true
|
||||||
|
if (props.isAdd) {
|
||||||
|
try {
|
||||||
|
var msg = null
|
||||||
|
// 为主模板预设
|
||||||
|
if (props.item.ex3 == '1') {
|
||||||
|
var { msg } = await addKeyWords({ name: form.name, id: props.item.id })
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// 添加子模板
|
||||||
|
let obj = {
|
||||||
|
name: form.name,
|
||||||
|
type: 2, // 子模板 固定值为2
|
||||||
|
sortNum: 1,
|
||||||
|
parentId: props.item.id,
|
||||||
|
lmType: 1,
|
||||||
|
model: props.modeType,
|
||||||
|
prompt: form.prompt,
|
||||||
|
ex1: props.item.ex1, //学段
|
||||||
|
ex2: props.item.ex2, // 学科
|
||||||
|
ex3: '', //是否系统预设 这里默认空
|
||||||
|
}
|
||||||
|
var { msg } = await addChildTemp(obj)
|
||||||
|
}
|
||||||
|
ElMessage.success(msg)
|
||||||
|
mode.value = false
|
||||||
|
} finally {
|
||||||
|
loading.value = false
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 编辑
|
||||||
|
try {
|
||||||
|
let data = JSON.parse(JSON.stringify(props.item))
|
||||||
|
data.name = form.name;
|
||||||
|
data.prompt = form.prompt
|
||||||
|
const { msg } = await editChildTemp(data)
|
||||||
|
ElMessage.success(msg)
|
||||||
|
mode.value = false
|
||||||
|
} finally {
|
||||||
|
loading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -69,4 +128,10 @@ watch(() => props.isAdd, (newVal) => {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.small-tip{
|
||||||
|
text-align: left;
|
||||||
|
font-size: 12px;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
color: #F56C6C;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
|
@ -17,7 +17,7 @@
|
||||||
</template>
|
</template>
|
||||||
<template #default>
|
<template #default>
|
||||||
<el-button type="primary" link @click="editKeyWord(item)">编辑</el-button>
|
<el-button type="primary" link @click="editKeyWord(item)">编辑</el-button>
|
||||||
<el-button type="primary" link>移除</el-button>
|
<el-button type="primary" link @click="removeItem(item)">移除</el-button>
|
||||||
</template>
|
</template>
|
||||||
</el-popover>
|
</el-popover>
|
||||||
</div>
|
</div>
|
||||||
|
@ -53,21 +53,22 @@
|
||||||
<!--编辑结果-->
|
<!--编辑结果-->
|
||||||
<EditDialog v-model="isEdit" :item="editItem" @saveEdit="saveEdit" />
|
<EditDialog v-model="isEdit" :item="editItem" @saveEdit="saveEdit" />
|
||||||
<!--AI 对话调整-->
|
<!--AI 对话调整-->
|
||||||
<AdjustDialog v-model="isAdjust" :item="editItem" @saveAdjust="saveAdjust" />
|
<AdjustDialog v-model="isAdjust" :modeType="modeType" :item="editItem" @saveAdjust="saveAdjust" />
|
||||||
<!--编辑提示词-->
|
<!--编辑提示词-->
|
||||||
<keywordDialog v-model="isEditKeyWord" :isAdd="false" :item="keywordItem"/>
|
<keywordDialog v-model="isEditKeyWord" :isAdd="!isEditKeyWord" :item="keywordItem"/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, reactive, onMounted, watch } from 'vue';
|
import { ref, reactive, onMounted, watch } from 'vue';
|
||||||
|
import { ElMessage } from 'element-plus'
|
||||||
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 keywordDialog from './keyword-dialog.vue';
|
import keywordDialog from './keyword-dialog.vue';
|
||||||
import { sessionStore } from '@/utils/store'
|
import { sessionStore } from '@/utils/store'
|
||||||
import useUserStore from '@/store/modules/user'
|
import useUserStore from '@/store/modules/user'
|
||||||
import { conversation, completion, modelList } from '@/api/mode/index'
|
import { tempSave, completion, modelList, removeChildTemp, tempResult } from '@/api/mode/index'
|
||||||
|
import { dataSetJson } from '@/utils/comm.js'
|
||||||
|
|
||||||
const userStore = useUserStore()
|
const userStore = useUserStore()
|
||||||
|
|
||||||
|
@ -89,16 +90,35 @@ const getChildTemplate = () => {
|
||||||
tempLoading.value = true
|
tempLoading.value = true
|
||||||
modelList({ model: props.modeType, type: 2, parentId: props.tempId }).then(res => {
|
modelList({ model: props.modeType, type: 2, parentId: props.tempId }).then(res => {
|
||||||
childTempList.value = res.rows
|
childTempList.value = res.rows
|
||||||
|
getTempResult()
|
||||||
}).finally(() => {
|
}).finally(() => {
|
||||||
tempLoading.value = false
|
tempLoading.value = false
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
// 查询模板结果
|
||||||
|
const getTempResult = () =>{
|
||||||
|
tempResult({mainModelId: props.tempId}).then(res =>{
|
||||||
|
console.log(res,1000)
|
||||||
|
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)
|
const isEdit = ref(false)
|
||||||
watch(() => props.tempId, (newVal) => {
|
watch(() => props.tempId, (newVal) => {
|
||||||
if (newVal) {
|
if (newVal) {
|
||||||
// isEdit.value = true
|
// isEdit.value = true
|
||||||
getChildTemplate()
|
getChildTemplate()
|
||||||
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -106,24 +126,14 @@ watch(() => props.tempId, (newVal) => {
|
||||||
// 获取会话ID
|
// 获取会话ID
|
||||||
const params = reactive(
|
const params = reactive(
|
||||||
{
|
{
|
||||||
"conversation_id": "",
|
prompt: '',
|
||||||
"messages": [
|
dataset_id: ''
|
||||||
{
|
|
||||||
"role": "user",
|
|
||||||
"content": ""
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"quote": false,
|
|
||||||
"stream": false
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
const curNode = reactive({})
|
const curNode = reactive({})
|
||||||
const getConversation = async () => {
|
const getConversation = () => {
|
||||||
|
|
||||||
|
|
||||||
const { user: { userId } } = userStore
|
|
||||||
const result = await conversation({ user_id: String(userId) })
|
|
||||||
console.log('result', result)
|
|
||||||
params.conversation_id = result.data.data.id
|
|
||||||
getCompletion()
|
getCompletion()
|
||||||
}
|
}
|
||||||
// 大模型对话
|
// 大模型对话
|
||||||
|
@ -131,29 +141,42 @@ const getCompletion = async () => {
|
||||||
for (let item of childTempList.value) {
|
for (let item of childTempList.value) {
|
||||||
try {
|
try {
|
||||||
item.loading = true
|
item.loading = true
|
||||||
params.messages[0].content = `根据${curNode.edustage}语文课标,提炼出${item.name}`
|
params.prompt = `根据${curNode.edustage}${curNode.edusubject}课标,提炼出${item.name}`
|
||||||
const res = await completion(params)
|
const { data } = await completion(params)
|
||||||
console.log('对话结果===》', res)
|
let answer = data.answer
|
||||||
let answer = res.data.data.answer
|
|
||||||
item.oldAnswer = answer
|
item.oldAnswer = answer
|
||||||
item.answer = getResult(answer);
|
item.answer = getResult(answer);
|
||||||
|
onSaveTemp(item)
|
||||||
} finally {
|
} finally {
|
||||||
item.loading = false
|
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) => {
|
const againResult = async (index, item) => {
|
||||||
try {
|
try {
|
||||||
childTempList.value[index].loading = true
|
childTempList.value[index].loading = true
|
||||||
params.messages[0].content = `根据${curNode.edustage}语文课标,提炼出${item.name}`
|
params.prompt = `根据${curNode.edustage}${curNode.edusubject}课标,提炼出${item.name}`
|
||||||
const res = await completion(params)
|
const { data } = await completion(params)
|
||||||
let answer = res.data.data.answer
|
let answer = data.answer
|
||||||
item.oldAnswer = answer
|
childTempList.value[index].oldAnswer = answer
|
||||||
item.answer = getResult(answer);
|
childTempList.value[index].answer = getResult(answer);
|
||||||
} finally {
|
} finally {
|
||||||
childTempList.value[index].loading = false
|
childTempList.value[index].loading = false
|
||||||
}
|
}
|
||||||
|
@ -180,9 +203,10 @@ const onEdit = (index, item) => {
|
||||||
|
|
||||||
// 保存编辑
|
// 保存编辑
|
||||||
const saveEdit = (data) => {
|
const saveEdit = (data) => {
|
||||||
childTempList.value[curIndex.value].oldAnswer = data
|
// childTempList.value[curIndex.value].oldAnswer = data
|
||||||
let answer = getResult(data);
|
// let answer = getResult(data);
|
||||||
childTempList.value[curIndex.value].answer = answer
|
// childTempList.value[curIndex.value].answer = answer
|
||||||
|
getChildTemplate()
|
||||||
}
|
}
|
||||||
|
|
||||||
const isAdjust = ref(false)
|
const isAdjust = ref(false)
|
||||||
|
@ -201,15 +225,28 @@ const saveAdjust = (item) => {
|
||||||
const keywordItem = reactive({})
|
const keywordItem = reactive({})
|
||||||
const isEditKeyWord = ref(false)
|
const isEditKeyWord = ref(false)
|
||||||
const editKeyWord = (item) =>{
|
const editKeyWord = (item) =>{
|
||||||
|
console.log(item)
|
||||||
|
|
||||||
isEditKeyWord.value = true
|
isEditKeyWord.value = true
|
||||||
Object.assign(keywordItem, item)
|
Object.assign(keywordItem, item)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 移除子模板
|
||||||
|
const removeItem = async(item) =>{
|
||||||
|
const { msg } = await removeChildTemp(item.id)
|
||||||
|
ElMessage.success(msg)
|
||||||
|
getChildTemplate()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
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 jsonKey = `${text}-${data.edustage}-${data.edusubject}`
|
||||||
|
params.dataset_id = dataSetJson[jsonKey]
|
||||||
|
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
defineExpose({
|
defineExpose({
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="whiteboart-container" :style="{ height: height + 'px' }">
|
<div class="whiteboart-container">
|
||||||
<div class="canvasBox" ref="box"></div>
|
<div class="canvasBox" ref="box"></div>
|
||||||
|
|
||||||
<div class="footerLeft" @click.stop
|
<div class="footerLeft" @click.stop
|
||||||
|
|
|
@ -66,20 +66,12 @@ export const constantRoutes = [
|
||||||
component: () => import('@/views/job-management/index.vue'),
|
component: () => import('@/views/job-management/index.vue'),
|
||||||
name: 'job-management',
|
name: 'job-management',
|
||||||
meta: { title: '作业管理' },
|
meta: { title: '作业管理' },
|
||||||
// children: [
|
},
|
||||||
// {
|
{
|
||||||
// path: 'details',
|
path: 'design',
|
||||||
// component: () => import('@/views/job-management/Details/index.vue'),
|
component: () => import('@/views/teachingDesign/index.vue'),
|
||||||
// name: 'details',
|
name: 'teaching-design',
|
||||||
// meta: { title: '详情' }
|
meta: { title: '教学框架设计' },
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// path: 'right',
|
|
||||||
// component: () => import('@/views/job-management/Right/index.vue'),
|
|
||||||
// name: 'right',
|
|
||||||
// meta: { title: '主页' }
|
|
||||||
// },
|
|
||||||
// ]
|
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|
|
@ -351,3 +351,26 @@ export function throttle(func, wait) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* 大模型对话dataset_id
|
||||||
|
*/
|
||||||
|
export const dataSetJson = {
|
||||||
|
"考试-高中-地理": "e790f68aa19811efbe0b0242ac140006",
|
||||||
|
"考试-高中-数学": "9cc3084ea19811ef97f00242ac140006",
|
||||||
|
"考试-高中-物理": "b19749c4a19811ef89a80242ac140006",
|
||||||
|
"考试-高中-化学": "bb7dcd40a19811efb6090242ac140006",
|
||||||
|
"考试-高中-生物": "c31f8df8a19811efbd6d0242ac140006",
|
||||||
|
"考试-高中-英语": "a84527afa19811ef8bf00242ac140006",
|
||||||
|
"考试-高中-语文": "928e6da0a19811efb6e50242ac140006",
|
||||||
|
"考试-高中-历史": "df2c09e6a19811ef84d00242ac140006",
|
||||||
|
"考试-高中-政治": "ce43ea58a19811efb41c0242ac140006",
|
||||||
|
"课标-高中-语文": "cee3062a9fcf11efa6910242ac140006",
|
||||||
|
"课标-高中-生物": "fb5d01d59fd011ef9bb90242ac140006",
|
||||||
|
"课标-高中-历史": "f2f6c1fb9fd011ef98740242ac140006",
|
||||||
|
"课标-高中-英语": "e889fcac9fd011efb22a0242ac140006",
|
||||||
|
"课标-高中-数学": "e03aa4fe9fd011ef91270242ac140006",
|
||||||
|
"课标-高中-地理": "270516829fd111efb13c0242ac140006",
|
||||||
|
"鉴权": "ragflow-IwMDI1MGU2YTU3NjExZWZiNWEzMDI0Mm"
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
import mitt from 'mitt'
|
||||||
|
// 创建mitt实例
|
||||||
|
const emitter = mitt()
|
||||||
|
// 导出
|
||||||
|
export default emitter
|
|
@ -0,0 +1,12 @@
|
||||||
|
<template>
|
||||||
|
<!-- <whiteboard/> -->
|
||||||
|
<div> 1</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import whiteboard from '@/components/whiteboard/whiteboard.vue';
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
|
||||||
|
</style>
|
|
@ -40,6 +40,7 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref,defineProps ,defineEmits,nextTick , onMounted,shallowRef } from 'vue'
|
import { ref,defineProps ,defineEmits,nextTick , onMounted,shallowRef } from 'vue'
|
||||||
import ClassroomPresentation from './classroomPresentation/index.vue'
|
import ClassroomPresentation from './classroomPresentation/index.vue'
|
||||||
|
import ClassPresentation from './classPresentation/index.vue'
|
||||||
import selfSearchQuestions from './selfSearchQuestions/index.vue'
|
import selfSearchQuestions from './selfSearchQuestions/index.vue'
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
parameter: Object
|
parameter: Object
|
||||||
|
@ -65,6 +66,8 @@ const rightComponets = (str) => {
|
||||||
return ClassroomPresentation
|
return ClassroomPresentation
|
||||||
case 'selfSearchQuestions':
|
case 'selfSearchQuestions':
|
||||||
return selfSearchQuestions
|
return selfSearchQuestions
|
||||||
|
case 'classPresentation':
|
||||||
|
return ClassPresentation
|
||||||
default:
|
default:
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
|
@ -76,7 +76,7 @@ const items = ref([
|
||||||
label:'智能推荐',
|
label:'智能推荐',
|
||||||
},
|
},
|
||||||
] },
|
] },
|
||||||
{ title: '课堂展示', description: '555555', icon: markRaw(Document), type: 'primary', text: '课堂展示',components:'selfSearchQuestions',titleList:[
|
{ title: '课堂展示', description: '555555', icon: markRaw(Document), type: 'primary', text: '课堂展示',components:'classPresentation',titleList:[
|
||||||
{
|
{
|
||||||
id:1,
|
id:1,
|
||||||
label:'课堂展示',
|
label:'课堂展示',
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
<el-button type="primary" @click="onchange('/model/curriculum')">课标研读</el-button>
|
<el-button type="primary" @click="onchange('/model/curriculum')">课标研读</el-button>
|
||||||
<el-button type="primary" @click="onchange('/model/management')">作业管理</el-button>
|
<el-button type="primary" @click="onchange('/model/management')">作业管理</el-button>
|
||||||
<el-button type="success" @click="onchange('/model/teaching')">教材研读</el-button>
|
<el-button type="success" @click="onchange('/model/teaching')">教材研读</el-button>
|
||||||
|
<el-button type="info" @click="onchange('/model/design')">教学框架设计</el-button>
|
||||||
<el-button type="success" @click="openPPTist">打开PPTist</el-button>
|
<el-button type="success" @click="openPPTist">打开PPTist</el-button>
|
||||||
<!-- <el-button type="info" @click="onchange('/model/examination')">考试分析</el-button> -->
|
<!-- <el-button type="info" @click="onchange('/model/examination')">考试分析</el-button> -->
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -0,0 +1,249 @@
|
||||||
|
<template>
|
||||||
|
<el-dialog v-model="isDialog" :show-close="false" width="800" destroy-on-close>
|
||||||
|
<template #header>
|
||||||
|
<div class="custom-header flex">
|
||||||
|
<span>{{ item.name }}</span>
|
||||||
|
<i class="iconfont icon-guanbi" @click="isDialog = false"></i>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<div class="dialog-content">
|
||||||
|
<el-scrollbar height="400px">
|
||||||
|
<div class="chart-con flex">
|
||||||
|
<template v-for="item in msgList">
|
||||||
|
<div class="flex-end flex" v-if="item.type == 'user'">
|
||||||
|
<div class="chart-item user">{{ item.msg }}</div>
|
||||||
|
</div>
|
||||||
|
<div class="flex-start flex" v-else>
|
||||||
|
<div class="flex" v-loading="!item.msg">
|
||||||
|
<div class="chart-item robot">{{ item.msg }}</div>
|
||||||
|
</div>
|
||||||
|
<div class="flex flex-end replace-item">
|
||||||
|
<span @click="saveAdjust(item)"><i class="iconfont icon-tihuan"></i>替换分析结果</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div v-if="loaded" class="chart-loading">
|
||||||
|
<div></div>
|
||||||
|
<div></div>
|
||||||
|
<div></div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
</el-scrollbar>
|
||||||
|
<div class="input-box flex">
|
||||||
|
<el-input v-model="textarea" @keyup.enter="send" :disabled="loaded" />
|
||||||
|
<div class="ipt-icon" @click="send">
|
||||||
|
<i class="iconfont icon-fasong"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</el-dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, reactive, onMounted } from 'vue'
|
||||||
|
import { completion } from '@/api/mode/index'
|
||||||
|
import emitter from '@/utils/mitt';
|
||||||
|
import { sessionStore } from '@/utils/store'
|
||||||
|
import { ElMessage } from 'element-plus'
|
||||||
|
|
||||||
|
const textarea = ref('')
|
||||||
|
|
||||||
|
const isDialog = defineModel()
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
item: {
|
||||||
|
type: Object,
|
||||||
|
default: () => {
|
||||||
|
return { name: '11' }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const emit = defineEmits(['saveEdit'])
|
||||||
|
|
||||||
|
const loaded = ref(false)
|
||||||
|
|
||||||
|
const msgList = ref([])
|
||||||
|
|
||||||
|
const send = () => {
|
||||||
|
if (loaded.value) return
|
||||||
|
msgList.value.push({
|
||||||
|
type: 'user',
|
||||||
|
msg: textarea.value
|
||||||
|
})
|
||||||
|
loaded.value = true
|
||||||
|
getConversation(textarea.value)
|
||||||
|
textarea.value = ''
|
||||||
|
}
|
||||||
|
const curNode = reactive({})
|
||||||
|
|
||||||
|
// 获取会话ID
|
||||||
|
const getConversation = async (val) => {
|
||||||
|
try {
|
||||||
|
const { data } = await completion({
|
||||||
|
dataset_id: 'cee3062a9fcf11efa6910242ac140006',
|
||||||
|
prompt: val
|
||||||
|
})
|
||||||
|
msgList.value.push({
|
||||||
|
type: 'robot',
|
||||||
|
msg: data.answer,
|
||||||
|
})
|
||||||
|
} finally {
|
||||||
|
loaded.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const saveAdjust = (item) => {
|
||||||
|
// emit('saveAdjust', item.msg)
|
||||||
|
emitter.emit('changeAdjust', item.msg)
|
||||||
|
isDialog.value = false
|
||||||
|
ElMessage.success('操作成功')
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
let data = sessionStore.get('subject.curNode')
|
||||||
|
Object.assign(curNode, data);
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.custom-header {
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
.icon-guanbi {
|
||||||
|
cursor: pointer;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.dialog-content {
|
||||||
|
padding-top: 10px;
|
||||||
|
padding-bottom: 20px;
|
||||||
|
|
||||||
|
.chart-con {
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: flex-start;
|
||||||
|
|
||||||
|
.flex-end {
|
||||||
|
width: 100%;
|
||||||
|
justify-content: flex-end;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flex-start {
|
||||||
|
width: 100%;
|
||||||
|
justify-content: flex-start;
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.chart-item {
|
||||||
|
border-radius: 5px;
|
||||||
|
padding: 5px;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user {
|
||||||
|
background: #F2F2F2;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.robot {
|
||||||
|
background: #409EFF;
|
||||||
|
color: #FFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
.replace-item {
|
||||||
|
font-size: 12px;
|
||||||
|
color: #409EFF;
|
||||||
|
align-items: center;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-box {
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
.ipt-icon {
|
||||||
|
cursor: pointer;
|
||||||
|
padding: 0 5px;
|
||||||
|
|
||||||
|
.icon-fasong {
|
||||||
|
font-size: 26px;
|
||||||
|
color: #409EFF;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.chart-loading,
|
||||||
|
.chart-loading>div {
|
||||||
|
position: relative;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chart-loading {
|
||||||
|
display: block;
|
||||||
|
font-size: 0;
|
||||||
|
color: #66b1ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chart-loading.la-dark {
|
||||||
|
color: #66b1ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chart-loading>div {
|
||||||
|
display: inline-block;
|
||||||
|
float: none;
|
||||||
|
background-color: currentColor;
|
||||||
|
border: 0 solid currentColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chart-loading {
|
||||||
|
width: 54px;
|
||||||
|
height: 18px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chart-loading>div:nth-child(1) {
|
||||||
|
animation-delay: -200ms;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chart-loading>div:nth-child(2) {
|
||||||
|
animation-delay: -100ms;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chart-loading>div:nth-child(3) {
|
||||||
|
animation-delay: 0ms;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chart-loading>div {
|
||||||
|
width: 8px;
|
||||||
|
height: 8px;
|
||||||
|
border-radius: 100%;
|
||||||
|
margin-right: 4px;
|
||||||
|
animation: ball-pulse 1s ease infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes ball-pulse {
|
||||||
|
|
||||||
|
0%,
|
||||||
|
60%,
|
||||||
|
100% {
|
||||||
|
opacity: 1;
|
||||||
|
transform: scale(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
30% {
|
||||||
|
opacity: 0.1;
|
||||||
|
transform: scale(0.01);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -0,0 +1,77 @@
|
||||||
|
<template>
|
||||||
|
<el-dialog v-model="isDialog" :show-close="false" width="900" destroy-on-close>
|
||||||
|
<template #header>
|
||||||
|
<div class="custom-header flex">
|
||||||
|
<span>{{ item.name }}</span>
|
||||||
|
<i class="iconfont icon-guanbi" @click="isDialog = false"></i>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<div class="dialog-content">
|
||||||
|
<el-row>
|
||||||
|
<el-col :span="24">
|
||||||
|
<el-input v-model="textarea" :autosize="{ minRows: 5, maxRows: 15 }" type="textarea" />
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<template #footer>
|
||||||
|
<div class="dialog-footer">
|
||||||
|
<el-button @click="isDialog = false">取消</el-button>
|
||||||
|
<el-button type="primary" @click="onSave">
|
||||||
|
确定
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, watch} from 'vue'
|
||||||
|
import { ElMessage } from 'element-plus'
|
||||||
|
import emitter from '@/utils/mitt';
|
||||||
|
|
||||||
|
const textarea = ref('')
|
||||||
|
|
||||||
|
const isDialog = defineModel()
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
item: {
|
||||||
|
type: Object,
|
||||||
|
default: () => {
|
||||||
|
return { name: '11' }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
watch(() => props.item.answer, (newVal) => {
|
||||||
|
if (newVal) {
|
||||||
|
textarea.value = newVal
|
||||||
|
}
|
||||||
|
},{ deep: true })
|
||||||
|
|
||||||
|
const emit = defineEmits(['saveEdit'])
|
||||||
|
const onSave = () =>{
|
||||||
|
emitter.emit('changeResult', textarea.value)
|
||||||
|
isDialog.value = false
|
||||||
|
ElMessage.success('操作成功')
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.custom-header {
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
.icon-guanbi {
|
||||||
|
cursor: pointer;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.dialog-content {
|
||||||
|
padding-top: 10px;
|
||||||
|
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -0,0 +1,126 @@
|
||||||
|
<template>
|
||||||
|
<div class="container-left flex">
|
||||||
|
<div class="left-header flex">教学模式</div>
|
||||||
|
<div class="left-con" v-loading="loading">
|
||||||
|
<div class="con-item" v-for="item in tempList" :key="item.id">
|
||||||
|
<div class="item-header flex">
|
||||||
|
<span>{{ item.name }}</span>
|
||||||
|
<el-button type="primary" link @click="onSelect(item)">选择模式</el-button>
|
||||||
|
</div>
|
||||||
|
<el-scrollbar>
|
||||||
|
<div class="item-list flex">
|
||||||
|
<el-card class="item-card" shadow="never" v-for="el in item.child" :key="el.id">
|
||||||
|
<p class="card-name">{{ el.name }}</p>
|
||||||
|
<div class="card-text">
|
||||||
|
<el-text line-clamp="2">
|
||||||
|
{{ el.prompt }}
|
||||||
|
</el-text>
|
||||||
|
</div>
|
||||||
|
</el-card>
|
||||||
|
</div>
|
||||||
|
</el-scrollbar>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, onMounted } from 'vue';
|
||||||
|
import emitter from '@/utils/mitt';
|
||||||
|
import { modelList } from '@/api/mode/index'
|
||||||
|
|
||||||
|
// 获取模板
|
||||||
|
let list = []
|
||||||
|
const getTemplate = () => {
|
||||||
|
modelList({ model: 1, type: 1, ex3: 1 }).then(res => {
|
||||||
|
list = res.rows
|
||||||
|
getChildTemp()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取子模板
|
||||||
|
const loading = ref(false)
|
||||||
|
const tempList = ref([])
|
||||||
|
const getChildTemp = async () => {
|
||||||
|
loading.value = true
|
||||||
|
for (let item of list) {
|
||||||
|
try {
|
||||||
|
const { rows } = await modelList({ model: 1, type: 2, parentId: item.id })
|
||||||
|
tempList.value.push({
|
||||||
|
id: item.id,
|
||||||
|
name: item.name,
|
||||||
|
child: rows
|
||||||
|
})
|
||||||
|
} finally {
|
||||||
|
loading.value = false
|
||||||
|
emitter.emit('changeMode', tempList.value[0])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 选择模板
|
||||||
|
const emit = defineEmits([''])
|
||||||
|
const onSelect = (item) =>{
|
||||||
|
emitter.emit('changeMode', item)
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
getTemplate()
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.container-left {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
|
.left-header {
|
||||||
|
height: 45px;
|
||||||
|
background: #F6F6F6;
|
||||||
|
border-radius: 5px 0 0 0;
|
||||||
|
align-items: center;
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: bold;
|
||||||
|
text-indent: 2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.left-con {
|
||||||
|
flex: 1;
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 0 0 0 5px;
|
||||||
|
padding: 15px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
font-size: 14px;
|
||||||
|
|
||||||
|
.item-header {
|
||||||
|
justify-content: space-between;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.con-item {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.item-card {
|
||||||
|
width: 130px;
|
||||||
|
font-size: 13px;
|
||||||
|
padding: 10px;
|
||||||
|
margin-right: 20px;
|
||||||
|
|
||||||
|
:deep(.el-card__body) {
|
||||||
|
padding: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-name {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-text {
|
||||||
|
text-align: left;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -0,0 +1,208 @@
|
||||||
|
<template>
|
||||||
|
<div class="container-right flex">
|
||||||
|
<div class="right-header flex">
|
||||||
|
<div class="header-left">
|
||||||
|
<el-button type="primary" link>
|
||||||
|
<i class="iconfont icon-jiahao"></i>新活动
|
||||||
|
</el-button>
|
||||||
|
<el-button type="primary" link>
|
||||||
|
<i class="iconfont icon-baocun"></i>保存为教学模式
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
<div class="header-right">
|
||||||
|
<el-button type="primary">生成大纲</el-button>
|
||||||
|
<el-button type="danger">生成PPT</el-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="right-con flex">
|
||||||
|
<div class="con-item flex" v-for="(item, index) in resultList" :key="item.id" v-loading="item.loading">
|
||||||
|
<div class="item-top flex">
|
||||||
|
<span>{{ item.name }}</span>
|
||||||
|
<el-button type="info" link>
|
||||||
|
<i class="iconfont icon-xiazai9"></i>
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
<div class="item-bom">
|
||||||
|
<div class="item-prompt">{{ item.prompt }}</div>
|
||||||
|
<div class="item-answer" v-if="item.answer">
|
||||||
|
<div class="answer-text" v-html="item.answer">
|
||||||
|
</div>
|
||||||
|
<div class="item-btn flex">
|
||||||
|
<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>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<EditDialog v-model="isEdit" :item="curItem" />
|
||||||
|
<AdjustDialog v-model="isAdjust" :item="curItem" />
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, onUnmounted, reactive } from 'vue'
|
||||||
|
import emitter from '@/utils/mitt'
|
||||||
|
import EditDialog from './edit-dialog.vue'
|
||||||
|
import AdjustDialog from './adjust-dialog.vue'
|
||||||
|
import { completion } from '@/api/mode/index.js'
|
||||||
|
|
||||||
|
|
||||||
|
const resultList = ref([])
|
||||||
|
emitter.on('changeMode', (item) => {
|
||||||
|
console.log(item, 3000)
|
||||||
|
resultList.value = item.child
|
||||||
|
conversation()
|
||||||
|
})
|
||||||
|
const conversation = async () => {
|
||||||
|
for (let item of resultList.value) {
|
||||||
|
item.loading = true
|
||||||
|
try {
|
||||||
|
const { data } = await completion({
|
||||||
|
dataset_id: 'cee3062a9fcf11efa6910242ac140006',
|
||||||
|
prompt: item.prompt
|
||||||
|
})
|
||||||
|
item.answer = data.answer
|
||||||
|
} finally {
|
||||||
|
item.loading = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const isEdit = ref(false)
|
||||||
|
// 当前操作的索引
|
||||||
|
const curIndex = ref(-1)
|
||||||
|
// 当前操作的item
|
||||||
|
const curItem = reactive({})
|
||||||
|
|
||||||
|
// 重新生成
|
||||||
|
const againResult = async (index, item) => {
|
||||||
|
try {
|
||||||
|
resultList.value[index].loading = true
|
||||||
|
const { data } = await completion({
|
||||||
|
dataset_id: 'cee3062a9fcf11efa6910242ac140006',
|
||||||
|
prompt: item.prompt
|
||||||
|
})
|
||||||
|
resultList.value[index].answer = data.answer
|
||||||
|
} finally {
|
||||||
|
resultList.value[index].loading = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 对话调整
|
||||||
|
const isAdjust = ref(false)
|
||||||
|
const onAdjust = (index, item) => {
|
||||||
|
curIndex.value = index
|
||||||
|
Object.assign(curItem, item)
|
||||||
|
isAdjust.value = true
|
||||||
|
}
|
||||||
|
emitter.on('changeAdjust', (item) =>{
|
||||||
|
resultList.value[curIndex.value].answer = item
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
// 编辑
|
||||||
|
const onEdit = (index, item) => {
|
||||||
|
curIndex.value = index
|
||||||
|
Object.assign(curItem, item)
|
||||||
|
isEdit.value = true
|
||||||
|
}
|
||||||
|
emitter.on('changeResult', (item) => {
|
||||||
|
resultList.value[curIndex.value].answer = item
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
// 解绑
|
||||||
|
onUnmounted(() => {
|
||||||
|
emitter.off('changeMode')
|
||||||
|
emitter.off('changeResult')
|
||||||
|
emitter.off('changeAdjust')
|
||||||
|
})
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.container-right {
|
||||||
|
flex-direction: column;
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
.right-header {
|
||||||
|
height: 45px;
|
||||||
|
background: #fff;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
padding: 0 20px;
|
||||||
|
border-radius: 0 5px 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.right-con {
|
||||||
|
flex: 1;
|
||||||
|
background: #F6F6F6;
|
||||||
|
padding: 15px;
|
||||||
|
flex-direction: column;
|
||||||
|
overflow-y: scroll;
|
||||||
|
|
||||||
|
.con-item {
|
||||||
|
width: 100%;
|
||||||
|
flex-direction: column;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
|
||||||
|
.item-top {
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.item-bom {
|
||||||
|
background: #fff;
|
||||||
|
padding: 15px;
|
||||||
|
border-radius: 5px;
|
||||||
|
|
||||||
|
.item-prompt {
|
||||||
|
text-align: left;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.item-answer {
|
||||||
|
padding: 10px;
|
||||||
|
background: #F2F2F2;
|
||||||
|
border-radius: 5px;
|
||||||
|
|
||||||
|
.answer-text {
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 5px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
text-align: left;
|
||||||
|
font-size: 13px;
|
||||||
|
padding: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.item-btn {
|
||||||
|
justify-content: flex-end;
|
||||||
|
|
||||||
|
.iconfont {
|
||||||
|
margin-right: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-ai1 {
|
||||||
|
font-size: 18px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -0,0 +1,31 @@
|
||||||
|
<template>
|
||||||
|
<div class="page-design flex">
|
||||||
|
<div class="page-left">
|
||||||
|
<!--左侧-->
|
||||||
|
<left />
|
||||||
|
</div>
|
||||||
|
<div class="page-right">
|
||||||
|
<!--右侧-->
|
||||||
|
<right />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import left from './container/left.vue';
|
||||||
|
import right from './container/right.vue';
|
||||||
|
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.page-design {
|
||||||
|
height: 100%;
|
||||||
|
.page-left{
|
||||||
|
width: 50%;
|
||||||
|
}
|
||||||
|
.page-right{
|
||||||
|
width: 50%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
Loading…
Reference in New Issue