教学框架设计
This commit is contained in:
parent
19283456d4
commit
c803ecd796
|
@ -48,10 +48,10 @@ export default defineConfig({
|
|||
changeOrigin: true, // 改变请求的起源
|
||||
rewrite: (path) => path.replace(/^\/parth/, '') // 重写路径
|
||||
},
|
||||
'/v1': {
|
||||
'/api': {
|
||||
target: 'https://ai.ysaix.com:7864',
|
||||
changeOrigin: true,
|
||||
pathRewrite: { '^/v1': '' }
|
||||
pathRewrite: { '^/api': '' }
|
||||
}
|
||||
},
|
||||
},
|
||||
|
|
72
package.json
72
package.json
|
@ -33,14 +33,18 @@
|
|||
"@electron-toolkit/utils": "^3.0.0",
|
||||
"@electron/remote": "^2.1.2",
|
||||
"@element-plus/icons-vue": "^2.3.1",
|
||||
"@icon-park/vue-next": "^1.4.2",
|
||||
"@vitejs/plugin-vue-jsx": "^4.0.0",
|
||||
"@vue-office/docx": "^1.6.2",
|
||||
"@vue-office/excel": "^1.7.11",
|
||||
"@vue-office/pdf": "^2.0.2",
|
||||
"@vueuse/core": "^10.11.0",
|
||||
"animate.css": "^4.1.1",
|
||||
"circular-json": "^0.5.9",
|
||||
"clipboard": "^2.0.11",
|
||||
"cropperjs": "^1.6.2",
|
||||
"crypto-js": "^4.2.0",
|
||||
"dexie": "3.0.3",
|
||||
"echarts": "^5.5.1",
|
||||
"electron-dl-manager": "^3.0.0",
|
||||
"electron-log": "^5.1.7",
|
||||
|
@ -49,6 +53,9 @@
|
|||
"element-china-area-data": "^6.1.0",
|
||||
"element-plus": "^2.8.0",
|
||||
"fabric": "^5.3.0",
|
||||
"file-saver": "^2.0.5",
|
||||
"hfmath": "^0.0.2",
|
||||
"html-to-image": "^1.11.11",
|
||||
"im_electron_sdk": "^8.0.5904",
|
||||
"js-cookie": "^3.0.5",
|
||||
"jsencrypt": "^3.3.2",
|
||||
|
@ -56,28 +63,13 @@
|
|||
"less": "^4.2.0",
|
||||
"less-loader": "^7.3.0",
|
||||
"lodash": "^4.17.21",
|
||||
"mitt": "^3.0.1",
|
||||
"nanoid": "^5.0.7",
|
||||
"node-addon-api": "^8.1.0",
|
||||
"number-precision": "^1.6.0",
|
||||
"pdfjs-dist": "4.4.168",
|
||||
"pinia": "^2.1.7",
|
||||
"pinia-plugin-persistedstate": "^3.2.1",
|
||||
"spark-md5": "^3.0.2",
|
||||
"vite-plugin-electron": "^0.28.8",
|
||||
"vue-qr": "^4.0.9",
|
||||
"vue-router": "^4.4.0",
|
||||
"whiteboard_lyc": "^0.1.3",
|
||||
"xgplayer": "^3.0.19",
|
||||
"xlsx": "^0.18.5",
|
||||
|
||||
"@icon-park/vue-next": "^1.4.2",
|
||||
"animate.css": "^4.1.1",
|
||||
"clipboard": "^2.0.11",
|
||||
"dexie": "3.0.3",
|
||||
"file-saver": "^2.0.5",
|
||||
"hfmath": "^0.0.2",
|
||||
"html-to-image": "^1.11.11",
|
||||
"mitt": "^3.0.1",
|
||||
"nanoid": "^5.0.7",
|
||||
"number-precision": "^1.6.0",
|
||||
"pptxgenjs": "^3.12.0",
|
||||
"pptxtojson": "^1.0.3",
|
||||
"prosemirror-commands": "^1.6.0",
|
||||
|
@ -91,33 +83,25 @@
|
|||
"prosemirror-schema-list": "^1.4.1",
|
||||
"prosemirror-state": "^1.4.3",
|
||||
"prosemirror-view": "^1.33.9",
|
||||
"spark-md5": "^3.0.2",
|
||||
"svg-arc-to-cubic-bezier": "^3.2.0",
|
||||
"svg-pathdata": "^7.1.0",
|
||||
"tinycolor2": "^1.6.0",
|
||||
"tippy.js": "^6.3.7",
|
||||
"vite-plugin-electron": "^0.28.8",
|
||||
"vue": "^3.4.34",
|
||||
"vuedraggable": "^4.1.0"
|
||||
"vue-qr": "^4.0.9",
|
||||
"vue-router": "^4.4.0",
|
||||
"vuedraggable": "^4.1.0",
|
||||
"whiteboard_lyc": "^0.1.3",
|
||||
"xgplayer": "^3.0.19",
|
||||
"xlsx": "^0.18.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@electron-toolkit/eslint-config": "^1.0.2",
|
||||
"@rushstack/eslint-patch": "^1.10.3",
|
||||
"@vitejs/plugin-vue": "^5.0.5",
|
||||
"@vue/eslint-config-prettier": "^9.0.0",
|
||||
"axios": "^1.7.2",
|
||||
"electron": "^31.0.2",
|
||||
"electron-builder": "^24.13.3",
|
||||
"electron-vite": "^2.3.0",
|
||||
"eslint": "^8.57.0",
|
||||
"eslint-plugin-vue": "^9.26.0",
|
||||
"prettier": "^3.3.2",
|
||||
"sass": "^1.77.6",
|
||||
"vite": "^5.3.1",
|
||||
"vite-plugin-windicss": "^1.9.3",
|
||||
"vue": "^3.4.30",
|
||||
"windicss": "^3.5.6",
|
||||
|
||||
"@commitlint/cli": "^18.4.3",
|
||||
"@commitlint/config-conventional": "^18.4.3",
|
||||
"@electron-toolkit/eslint-config": "^1.0.2",
|
||||
"@rushstack/eslint-patch": "^1.10.3",
|
||||
"@tsconfig/node18": "^18.2.2",
|
||||
"@types/crypto-js": "^4.2.1",
|
||||
"@types/file-saver": "^2.0.7",
|
||||
|
@ -125,11 +109,25 @@
|
|||
"@types/node": "^18.19.3",
|
||||
"@types/svg-arc-to-cubic-bezier": "^3.2.2",
|
||||
"@types/tinycolor2": "^1.4.6",
|
||||
"@vitejs/plugin-vue": "^5.0.5",
|
||||
"@vue/eslint-config-prettier": "^9.0.0",
|
||||
"@vue/eslint-config-typescript": "^12.0.0",
|
||||
"@vue/tsconfig": "^0.5.0",
|
||||
"axios": "^1.7.2",
|
||||
"electron": "^31.0.2",
|
||||
"electron-builder": "^24.13.3",
|
||||
"electron-vite": "^2.3.0",
|
||||
"eslint": "^8.57.0",
|
||||
"eslint-plugin-vue": "^9.26.0",
|
||||
"husky": "^8.0.3",
|
||||
"npm-run-all2": "^6.1.1",
|
||||
"prettier": "^3.3.2",
|
||||
"sass": "^1.77.6",
|
||||
"typescript": "~5.3.0",
|
||||
"vue-tsc": "^1.8.25"
|
||||
"vite": "^5.3.1",
|
||||
"vite-plugin-windicss": "^1.9.3",
|
||||
"vue": "^3.4.30",
|
||||
"vue-tsc": "^1.8.25",
|
||||
"windicss": "^3.5.6"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,10 +26,10 @@ export function conversation(data) {
|
|||
// 进行课标研读对话
|
||||
export function completion(data) {
|
||||
return axios({
|
||||
url: rootPath + '/v1/api/completion',
|
||||
url: rootPath + '/api/v1/parse/docs',
|
||||
method: 'post',
|
||||
headers: {
|
||||
Authorization: 'Bearer ragflow-IwNzMxMTIyOGY0ZTExZWZiOGE2MDI0Mm',
|
||||
Authorization: 'Bearer ragflow-IwMDI1MGU2YTU3NjExZWZiNWEzMDI0Mm',
|
||||
'Content-Type': 'application/json',
|
||||
Accept: '*/*'
|
||||
},
|
||||
|
|
|
@ -44,6 +44,7 @@ import { ref, reactive, onMounted } from 'vue'
|
|||
import { conversation, completion } from '@/api/mode/index'
|
||||
import { sessionStore } from '@/utils/store'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import { dataSetJson } from '@/utils/comm.js'
|
||||
|
||||
const textarea = ref('')
|
||||
|
||||
|
@ -55,6 +56,10 @@ const props = defineProps({
|
|||
default: () => {
|
||||
return { name: '11' }
|
||||
}
|
||||
},
|
||||
modeType: {
|
||||
type: Number,
|
||||
default: 1
|
||||
}
|
||||
})
|
||||
|
||||
|
@ -77,31 +82,22 @@ const send = () =>{
|
|||
const curNode = reactive({})
|
||||
const params = reactive(
|
||||
{
|
||||
"conversation_id": "",
|
||||
"messages": [
|
||||
{
|
||||
"role": "user",
|
||||
"content": ""
|
||||
}
|
||||
],
|
||||
"quote": false,
|
||||
"stream": false
|
||||
prompt: '',
|
||||
dataset_id: ''
|
||||
}
|
||||
)
|
||||
// 获取会话ID
|
||||
const getConversation = async (val) => {
|
||||
const result = await conversation()
|
||||
params.conversation_id = result.data.data.id
|
||||
const getConversation = (val) => {
|
||||
|
||||
getCompletion(val)
|
||||
}
|
||||
// 大模型对话
|
||||
const getCompletion = async (val) => {
|
||||
try {
|
||||
|
||||
params.messages[0].content = `根据${curNode.edustage}语文课标${props.item.name},${val}`
|
||||
const res = await completion(params)
|
||||
console.log('对话结果===》', res)
|
||||
let answer = res.data.data.answer
|
||||
params.prompt = `根据${curNode.edustage}${curNode.edusubject}课标${props.item.name},${val}`
|
||||
const { data } = await completion(params)
|
||||
let answer = data.answer
|
||||
msgList.value.push({
|
||||
type: 'robot',
|
||||
msg: answer,
|
||||
|
@ -121,6 +117,10 @@ const saveAdjust = (item) =>{
|
|||
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]
|
||||
|
||||
})
|
||||
|
||||
|
|
|
@ -42,7 +42,7 @@ const props = defineProps({
|
|||
}
|
||||
})
|
||||
|
||||
watch(() => props.item.oldAnswer, (newVal) => {
|
||||
watch(() => props.item.answer, (newVal) => {
|
||||
if (newVal) {
|
||||
textarea.value = newVal
|
||||
}
|
||||
|
|
|
@ -55,7 +55,7 @@
|
|||
<!--AI 对话调整-->
|
||||
<AdjustDialog v-model="isAdjust" :item="editItem" @saveAdjust="saveAdjust" />
|
||||
<!--编辑提示词-->
|
||||
<keywordDialog v-model="isEditKeyWord" :isAdd="isAdd" :item="keywordItem"/>
|
||||
<keywordDialog v-model="isEditKeyWord" :isAdd="isEdit" :item="keywordItem"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
@ -68,7 +68,7 @@ import keywordDialog from './keyword-dialog.vue';
|
|||
import { sessionStore } from '@/utils/store'
|
||||
import useUserStore from '@/store/modules/user'
|
||||
import { conversation, completion, modelList, removeChildTemp } from '@/api/mode/index'
|
||||
|
||||
import { dataSetJson } from '@/utils/comm.js'
|
||||
|
||||
const userStore = useUserStore()
|
||||
|
||||
|
@ -107,24 +107,14 @@ watch(() => props.tempId, (newVal) => {
|
|||
// 获取会话ID
|
||||
const params = reactive(
|
||||
{
|
||||
"conversation_id": "",
|
||||
"messages": [
|
||||
{
|
||||
"role": "user",
|
||||
"content": ""
|
||||
}
|
||||
],
|
||||
"quote": false,
|
||||
"stream": false
|
||||
prompt: '',
|
||||
dataset_id: ''
|
||||
}
|
||||
)
|
||||
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()
|
||||
}
|
||||
// 大模型对话
|
||||
|
@ -132,10 +122,9 @@ const getCompletion = async () => {
|
|||
for (let item of childTempList.value) {
|
||||
try {
|
||||
item.loading = true
|
||||
params.messages[0].content = `根据${curNode.edustage}语文课标,提炼出${item.name}`
|
||||
const res = await completion(params)
|
||||
console.log('对话结果===》', res)
|
||||
let answer = res.data.data.answer
|
||||
params.prompt = `根据${curNode.edustage}语文课标,提炼出${item.name}`
|
||||
const { data } = await completion(params)
|
||||
let answer = data.answer
|
||||
item.oldAnswer = answer
|
||||
item.answer = getResult(answer);
|
||||
|
||||
|
@ -150,11 +139,11 @@ const getCompletion = async () => {
|
|||
const againResult = async (index, item) => {
|
||||
try {
|
||||
childTempList.value[index].loading = true
|
||||
params.messages[0].content = `根据${curNode.edustage}语文课标,提炼出${item.name}`
|
||||
const res = await completion(params)
|
||||
let answer = res.data.data.answer
|
||||
item.oldAnswer = answer
|
||||
item.answer = getResult(answer);
|
||||
params.prompt = `根据${curNode.edustage}语文课标,提炼出${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
|
||||
}
|
||||
|
@ -210,12 +199,17 @@ const editKeyWord = (item) =>{
|
|||
const removeItem = async(item) =>{
|
||||
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]
|
||||
|
||||
})
|
||||
|
||||
defineExpose({
|
||||
|
|
|
@ -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,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>
|
|
@ -5,7 +5,7 @@
|
|||
<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>选择模式</el-button>
|
||||
<el-button type="primary" link @click="onSelect(item)">选择模式</el-button>
|
||||
</div>
|
||||
<el-scrollbar>
|
||||
<div class="item-list flex">
|
||||
|
@ -26,6 +26,7 @@
|
|||
|
||||
<script setup>
|
||||
import { ref, onMounted } from 'vue';
|
||||
import emitter from '@/utils/mitt';
|
||||
import { modelList } from '@/api/mode/index'
|
||||
|
||||
// 获取模板
|
||||
|
@ -52,10 +53,17 @@ const getChildTemp = async () => {
|
|||
})
|
||||
} finally {
|
||||
loading.value = false
|
||||
emitter.emit('changeMode', tempList.value[0])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 选择模板
|
||||
const emit = defineEmits([''])
|
||||
const onSelect = (item) =>{
|
||||
emitter.emit('changeMode', item)
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
getTemplate()
|
||||
})
|
||||
|
|
|
@ -15,20 +15,120 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class="right-con flex">
|
||||
<div class="con-item 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>设置情景</span>
|
||||
<div>
|
||||
<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-bom"></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>
|
||||
|
||||
|
@ -36,6 +136,7 @@
|
|||
.container-right {
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
|
||||
.right-header {
|
||||
height: 45px;
|
||||
background: #fff;
|
||||
|
@ -49,14 +150,57 @@
|
|||
flex: 1;
|
||||
background: #F6F6F6;
|
||||
padding: 15px;
|
||||
.con-item{
|
||||
flex-direction: column;
|
||||
.item-top{
|
||||
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{
|
||||
|
||||
.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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
<template>
|
||||
<div class="page-design flex">
|
||||
<div class="page-left">
|
||||
<!--左侧-->
|
||||
<left />
|
||||
</div>
|
||||
<div class="page-right">
|
||||
<!--右侧-->
|
||||
<right />
|
||||
</div>
|
||||
</div>
|
||||
|
@ -12,7 +14,6 @@
|
|||
<script setup>
|
||||
import left from './container/left.vue';
|
||||
import right from './container/right.vue';
|
||||
import { ref } from 'vue'
|
||||
|
||||
|
||||
</script>
|
||||
|
|
Loading…
Reference in New Issue