Merge remote-tracking branch 'origin/main'
This commit is contained in:
commit
d3b5493810
|
@ -8,7 +8,7 @@
|
|||
http-equiv="Content-Security-Policy"
|
||||
content="default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:"
|
||||
/> -->
|
||||
<meta http-equiv="Content-Security-Policy" content="connect-src *; default-src 'self'; script-src 'self' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; media-src * blob:;img-src * 'self' data: blob:" />
|
||||
<meta http-equiv="Content-Security-Policy" content="connect-src * blob: data:; default-src 'self'; script-src 'self' 'unsafe-eval' http://www.wiris.net; style-src 'self' 'unsafe-inline' http://www.wiris.net; media-src * blob:;img-src * 'self' data: blob:;font-src 'self' http://www.wiris.net;" />
|
||||
|
||||
</head>
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ export function conversation(data) {
|
|||
})
|
||||
}
|
||||
|
||||
// 进行课标研读对话
|
||||
// 进行课标研读对话 质点提取
|
||||
export function completion(data) {
|
||||
return axios({
|
||||
url: rootPath + '/api/v1/parse/docs',
|
||||
|
@ -100,3 +100,22 @@ export function tempResult(params) {
|
|||
})
|
||||
}
|
||||
|
||||
// 新增 doc
|
||||
export function addDoc(data) {
|
||||
return request({
|
||||
url: '/education/doc',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// 查询 doc
|
||||
export function docList(params) {
|
||||
return request({
|
||||
url: '/education/doc/list',
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
@font-face {
|
||||
font-family: "iconfont"; /* Project id 4723712 */
|
||||
src: url('iconfont.woff2?t=1731913617367') format('woff2'),
|
||||
url('iconfont.woff?t=1731913617367') format('woff'),
|
||||
url('iconfont.ttf?t=1731913617367') format('truetype');
|
||||
src: url('iconfont.woff2?t=1732173266977') format('woff2'),
|
||||
url('iconfont.woff?t=1732173266977') format('woff'),
|
||||
url('iconfont.ttf?t=1732173266977') format('truetype');
|
||||
}
|
||||
|
||||
.iconfont {
|
||||
|
@ -13,6 +13,26 @@
|
|||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
.icon-jiqiren_o:before {
|
||||
content: "\eb62";
|
||||
}
|
||||
|
||||
.icon-zhaoxiangji:before {
|
||||
content: "\e679";
|
||||
}
|
||||
|
||||
.icon-huaban:before {
|
||||
content: "\e6e2";
|
||||
}
|
||||
|
||||
.icon-tubiao_wuxing-:before {
|
||||
content: "\e612";
|
||||
}
|
||||
|
||||
.icon-soutibao-:before {
|
||||
content: "\e605";
|
||||
}
|
||||
|
||||
.icon-baocun:before {
|
||||
content: "\e60e";
|
||||
}
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -5,6 +5,41 @@
|
|||
"css_prefix_text": "icon-",
|
||||
"description": "",
|
||||
"glyphs": [
|
||||
{
|
||||
"icon_id": "5387814",
|
||||
"name": "机器人_o",
|
||||
"font_class": "jiqiren_o",
|
||||
"unicode": "eb62",
|
||||
"unicode_decimal": 60258
|
||||
},
|
||||
{
|
||||
"icon_id": "630128",
|
||||
"name": "照相机",
|
||||
"font_class": "zhaoxiangji",
|
||||
"unicode": "e679",
|
||||
"unicode_decimal": 59001
|
||||
},
|
||||
{
|
||||
"icon_id": "12592146",
|
||||
"name": "画板",
|
||||
"font_class": "huaban",
|
||||
"unicode": "e6e2",
|
||||
"unicode_decimal": 59106
|
||||
},
|
||||
{
|
||||
"icon_id": "6025688",
|
||||
"name": "图标_五星-2",
|
||||
"font_class": "tubiao_wuxing-",
|
||||
"unicode": "e612",
|
||||
"unicode_decimal": 58898
|
||||
},
|
||||
{
|
||||
"icon_id": "11756625",
|
||||
"name": "搜题宝-37",
|
||||
"font_class": "soutibao-",
|
||||
"unicode": "e605",
|
||||
"unicode_decimal": 58885
|
||||
},
|
||||
{
|
||||
"icon_id": "11467388",
|
||||
"name": "保存",
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -2,7 +2,7 @@
|
|||
<div class="container-header flex">
|
||||
<div class="header-left flex">
|
||||
<el-button link @click="showDialog = true">
|
||||
高中语文课程标准<i class="iconfont icon-xiangxia"></i>
|
||||
{{ curNode.edustage}}{{ curNode.edusubject }}{{ type == 1 ? '课标研读': '教材分析'}}<i class="iconfont icon-xiangxia"></i>
|
||||
</el-button>
|
||||
</div>
|
||||
|
||||
|
@ -26,7 +26,7 @@
|
|||
</el-icon>
|
||||
添加提示词
|
||||
</el-button>
|
||||
<el-button type="primary" link>保存模板</el-button>
|
||||
<!-- <el-button type="primary" link>保存模板</el-button> -->
|
||||
<el-button type="primary" @click="aiRead">一键研读</el-button>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -37,14 +37,14 @@
|
|||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive, onMounted, watch } from 'vue'
|
||||
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({
|
||||
|
@ -107,10 +107,13 @@ const onAdd = () => {
|
|||
onUnmounted(() => {
|
||||
emitter.off('onGetMain')
|
||||
})
|
||||
|
||||
const curNode = reactive({})
|
||||
onMounted(() => {
|
||||
let data = sessionStore.get('subject.curNode')
|
||||
Object.assign(curNode, data);
|
||||
getTemplateList()
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
|
|
@ -187,10 +187,10 @@ const init = reactive({
|
|||
min_height: props.minHeight,
|
||||
draggable_modal: true,
|
||||
extended_valid_elements: '*[.*]',
|
||||
// external_plugins: {
|
||||
// tiny_mce_wiris: `/tinymce/tool/@wiris/mathtype-tinymce6/plugin.min.js`,
|
||||
// //tiny_mce_wiris: `https://www.wiris.net/demo/plugins/tiny_mce/plugin.js`,
|
||||
// },
|
||||
external_plugins: {
|
||||
tiny_mce_wiris: `/tinymce/tool/@wiris/mathtype-tinymce6/plugin.min.js`,
|
||||
//tiny_mce_wiris: `https://www.wiris.net/demo/plugins/tiny_mce/plugin.js`,
|
||||
},
|
||||
|
||||
// setup: function (editor) {
|
||||
// },
|
||||
|
|
|
@ -1,12 +1,23 @@
|
|||
<template>
|
||||
<div class="list-content">
|
||||
<div class="list-container">
|
||||
<div class="content-list" v-for="(item, index) in items" :key="index" @click="handleClick(item)">
|
||||
<div class="item-content">
|
||||
<div class="item-text">
|
||||
<div class="title-header">
|
||||
<div class="item-title">{{ item.title }}</div>
|
||||
<div class="item-description">{{ item.description }}</div>
|
||||
<div class="icon-box">
|
||||
<svg class="icon iconfont" aria-hidden="true" style="font-size: 35px;">
|
||||
<use :xlink:href="item.icon"></use>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
<div class="item-description">{{ item.description }}</div>
|
||||
<div class="item-bottom">
|
||||
<el-tag :type="item.type" size="default">{{ item.title }}</el-tag>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<el-icon class="item-icon"><component :is="item.icon" /></el-icon>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -15,17 +26,16 @@
|
|||
<script setup>
|
||||
import { shallowRef } from 'vue';
|
||||
import { ElMessage } from 'element-plus'
|
||||
import { Plus, ArrowDown, Document, User, Setting } from '@element-plus/icons-vue';
|
||||
|
||||
const emit = defineEmits(['itemClick'])
|
||||
const items = shallowRef([
|
||||
{ title: '自主搜题', description: '1111111', icon: Document },
|
||||
{ title: '校本题库', description: '222222', icon: User },
|
||||
{ title: '个人题库', description: '333333', icon: Setting },
|
||||
{ title: '智能推荐', description: '444444', icon: Plus },
|
||||
{ title: '课堂展示', description: '555555', icon: ArrowDown },
|
||||
{ title: '常规作业', description: '555555', icon: ArrowDown },
|
||||
{ title: 'AI设计作业', description: '555555', icon: ArrowDown },
|
||||
{ title: '自主搜题', description: '1111111111111111111111111111111111111', icon: '#icon-soutibao-',type:'primary' },
|
||||
{ title: '校本题库', description: '222222', icon: '#icon-soutibao-',type:'success' },
|
||||
{ title: '个人题库', description: '333333', icon: '#icon-soutibao-',type:'default' },
|
||||
{ title: '智能推荐', description: '444444', icon: '#icon-tubiao_wuxing-',type:'default' },
|
||||
{ title: '课堂展示', description: '555555', icon: '#icon-huaban',type:'primary' },
|
||||
{ title: '常规作业', description: '555555', icon: '#icon-zhaoxiangji',type:'primary' },
|
||||
{ title: 'AI设计作业', description: '555555', icon: '#icon-jiqiren_o',type:'danger' },
|
||||
]);
|
||||
|
||||
const handleClick = (item) => {
|
||||
|
@ -42,20 +52,25 @@ const handleClick = (item) => {
|
|||
</script>
|
||||
|
||||
<style scoped>
|
||||
.list-content{
|
||||
padding: 8px;
|
||||
background-color: #f5f5f5;
|
||||
border-radius: 8px;
|
||||
height: 100%;
|
||||
margin-left: 10px
|
||||
}
|
||||
.list-container {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 16px;
|
||||
padding: 16px;
|
||||
/* background-color: #f5f5f5; */
|
||||
}
|
||||
|
||||
.content-list {
|
||||
background-color: #fff;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
|
||||
padding: 16px;
|
||||
width: calc(33.333% - 32px); /* 3列布局,每列减去gap */
|
||||
padding: 8px;
|
||||
width: calc(25% - 16px);
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
@ -68,6 +83,7 @@ const handleClick = (item) => {
|
|||
.item-content {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.item-icon {
|
||||
|
@ -78,6 +94,10 @@ const handleClick = (item) => {
|
|||
|
||||
.item-text {
|
||||
flex: 1;
|
||||
justify-content: space-between;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.item-title {
|
||||
|
@ -85,10 +105,38 @@ const handleClick = (item) => {
|
|||
font-weight: 500;
|
||||
color: #303133;
|
||||
margin-bottom: 4px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.item-description {
|
||||
font-size: 14px;
|
||||
color: #909399;
|
||||
text-align: left;
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 2; /* 设置最大行数 */
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
.title-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.item-bottom {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
/* 过渡动画 */
|
||||
.fade-enter-active, .fade-leave-active {
|
||||
transition: opacity 0.3s;
|
||||
}
|
||||
|
||||
.fade-enter, .fade-leave-to {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
</style>
|
|
@ -6,7 +6,7 @@
|
|||
<el-button type="success" @click="handleTaskAssignToAllClass()">批量推送</el-button>
|
||||
</div>
|
||||
<div v-if="currentRow.id > 0" class="page-top-right">
|
||||
<el-button type="primary" @click="handleNewAllClass">设计新作业</el-button>
|
||||
<el-button type="primary" @click="handleNewAllClass" :icon="Plus">设计新作业</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="page-resource">
|
||||
|
@ -22,18 +22,25 @@
|
|||
@current-change="handleCurrentChange"
|
||||
>
|
||||
<el-table-column type="selection" min-width="2%" align="center" :selectable="selectable"/>
|
||||
<el-table-column label="作业布置" min-width="18%" align="center">
|
||||
<el-table-column label="作业布置" min-width="15%" align="center">
|
||||
<template #default="scope">
|
||||
<div style="height: 100px;">
|
||||
<div style="height: 100px;cursor: pointer">
|
||||
<div style="display: flex;align-items: center;justify-content: space-between;">
|
||||
<div style="width: 90%;">
|
||||
<div class="pageleft-table-top">
|
||||
<span>{{ scope.row.uniquekey }}</span>
|
||||
</div>
|
||||
<div class="pageleft-table-top">
|
||||
<el-tag :type="scope.row.workclass" size="default">{{ scope.row.worktype }}</el-tag>
|
||||
<span>{{ scope.row.timestamp }}</span>
|
||||
<div class="pageleft-table-top" style="display: flex;justify-content: space-between">
|
||||
<el-tag style="padding:0 2px" :type="scope.row.workclass" size="default">{{ scope.row.worktype }}</el-tag>
|
||||
<el-text size="small" style="color:#ccc;white-space:nowrap">{{ scope.row.timestamp }}</el-text>
|
||||
</div>
|
||||
<div class="pageleft-table-cont">
|
||||
<p class="ellipsis "> {{ scope.row.worktype == "课堂展示" ? scope.row.worktag : scope.row.title }}</p>
|
||||
<div :title="scope.row.worktag || scope.row.title" class="ellipsis "> {{ scope.row.worktype == "课堂展示" ? scope.row.worktag : scope.row.title }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<svg class="icon iconfont" aria-hidden="true">
|
||||
<use xlink:href="#icon-xiangyou"></use>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
@ -122,6 +129,7 @@
|
|||
import { onMounted, ref,watch, reactive, getCurrentInstance,nextTick } from 'vue'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import { cloneDeep } from 'lodash'
|
||||
import { Plus } from '@element-plus/icons-vue'
|
||||
import { delClasswork } from '@/api/teaching/classwork'
|
||||
import {listEntpcoursework, listEntpcourseworkNew, getEntpcoursework} from '@/api/education/entpCourseWork'
|
||||
import { addClassworkReturnId } from '@/api/teaching/classwork'
|
||||
|
@ -716,7 +724,7 @@ const editWork = async (cform) =>{
|
|||
}
|
||||
}
|
||||
.page-left {
|
||||
width: 300px;
|
||||
width: 240px;
|
||||
background-color: white;
|
||||
border-radius: 10px;
|
||||
box-shadow: 0px 0px 20px 0px rgba(99, 99, 99, 0.06);
|
||||
|
@ -735,13 +743,16 @@ const editWork = async (cform) =>{
|
|||
// overflow: hidden;
|
||||
// flex-direction: row;
|
||||
// text-overflow: ellipsis;
|
||||
width: 230px; /* 设置容器的宽度 */
|
||||
width: 100%; /* 设置容器的宽度 */
|
||||
overflow: hidden; /* 隐藏超出容器的部分 */
|
||||
white-space: nowrap; /* 防止文本换行 */
|
||||
text-overflow: ellipsis; /* 超出部分显示省略号 */
|
||||
.ellipsis {
|
||||
width: 100%;
|
||||
text-align: left;
|
||||
overflow: hidden; /* 隐藏超出容器的部分 */
|
||||
white-space: nowrap; /* 防止文本换行 */
|
||||
text-overflow: ellipsis; /* 超出部分显示省略号 */
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -174,22 +174,22 @@ const initHomeWork = async()=> {
|
|||
// taskList.value = res;
|
||||
// tasklist_loading.value = false;
|
||||
}
|
||||
const getBase64 = (file) =>{
|
||||
return new Promise(function (resolve, reject) {
|
||||
let reader = new FileReader();
|
||||
let imgResult = "";
|
||||
reader.readAsDataURL(file);
|
||||
reader.onload = function () {
|
||||
imgResult = reader.result;
|
||||
};
|
||||
reader.onerror = function (error) {
|
||||
reject(error);
|
||||
};
|
||||
reader.onloadend = function () {
|
||||
resolve(imgResult);
|
||||
};
|
||||
});
|
||||
}
|
||||
// const getBase64 = (file) =>{
|
||||
// return new Promise(function (resolve, reject) {
|
||||
// let reader = new FileReader();
|
||||
// let imgResult = "";
|
||||
// reader.readAsDataURL(file);
|
||||
// reader.onload = function () {
|
||||
// imgResult = reader.result;
|
||||
// };
|
||||
// reader.onerror = function (error) {
|
||||
// reject(error);
|
||||
// };
|
||||
// reader.onloadend = function () {
|
||||
// resolve(imgResult);
|
||||
// };
|
||||
// });
|
||||
// }
|
||||
/**
|
||||
* @desc: 上传本地图片
|
||||
* @return: {*}
|
||||
|
@ -203,37 +203,7 @@ const handleImportImg = (uploadFile) => {
|
|||
});
|
||||
return;
|
||||
}
|
||||
console.log('uploadFile', uploadFile);
|
||||
// 假设你在渲染进程中
|
||||
getBase64(uploadFile.raw).then(res => {
|
||||
// console.log('res-------', res);
|
||||
|
||||
|
||||
// 在 Electron 主进程中使用 URL.createObjectURL
|
||||
// const base64Data = 'data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAYABgAAD/...'; // Base64 编码的图片数据
|
||||
// const base64Data = res; // Base64 编码的图片数据
|
||||
// const buffer = Buffer.from(base64Data.split(',')[1], 'base64');
|
||||
// const filePath = path.join(Remote.app.getPath('userData'), 'image.jpg');
|
||||
// console.log(filePath,'???????????????????');
|
||||
// fs.writeFileSync(filePath, buffer);
|
||||
// const buf = fs.readFileSync(filePath)
|
||||
// console.log(buf);
|
||||
// const uint8Buffer = Uint8Array.from(buf)
|
||||
// cropOption.img = window.URL.createObjectURL(new Blob([uint8Buffer]));
|
||||
// cropOption.img = URL.createObjectURL(new Blob([fs.readFileSync(filePath)]));
|
||||
// cropOption.img = URL.createObjectURL(new Blob([buffer]));
|
||||
cropOption.img = res;
|
||||
// console.log(cropOption.img);
|
||||
|
||||
|
||||
|
||||
// cropOption.img = window.URL.createObjectURL(new Blob([res]));
|
||||
// console.log(cropOption.img);
|
||||
})
|
||||
// cropOption.img = window.URL.createObjectURL(uploadFile.raw);
|
||||
// cropOption.img = window.URL.createObjectURL(new Blob([uploadFile.raw]));
|
||||
// cropOption.img = window.URL.createObjectURL(new Blob([uploadFile.raw]));
|
||||
// console.log(cropOption.img);
|
||||
cropOption.img = window.URL.createObjectURL(uploadFile.raw);
|
||||
ElMessage.success('上传成功');
|
||||
};
|
||||
/**
|
||||
|
@ -246,9 +216,6 @@ const getClipboardImg = async() => {
|
|||
for (const item of clipboardItems) {
|
||||
for (const type of item.types) {
|
||||
if (type.includes('image/')) {
|
||||
console.log('剪贴板图片type', type);
|
||||
console.log('剪贴板图片item', item);
|
||||
console.log('剪贴板图片clipboardItems', clipboardItems);
|
||||
const blob = await item.getType(type);
|
||||
// blob 是图片的 Blob 对象
|
||||
cropOption.img = URL.createObjectURL(blob);
|
||||
|
|
|
@ -0,0 +1,303 @@
|
|||
<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="file-list">
|
||||
<el-dropdown @command="changeFile">
|
||||
<span class="el-dropdown-link">
|
||||
{{ curFile.fileName }}
|
||||
<i class="iconfont icon-xiangxia"></i>
|
||||
</span>
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu>
|
||||
<el-dropdown-item v-for="item in fileList" :command="item" :key="item.id">{{ item.fileName
|
||||
}}</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</template>
|
||||
</el-dropdown>
|
||||
</div>
|
||||
<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 { conversation, completion, docList } from '@/api/mode/index'
|
||||
import { sessionStore } from '@/utils/store'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import { dataSetJson } from '@/utils/comm.js'
|
||||
import useUserStore from '@/store/modules/user'
|
||||
|
||||
const userInfo = useUserStore().user
|
||||
const textarea = ref('')
|
||||
|
||||
const isDialog = defineModel()
|
||||
|
||||
const props = defineProps({
|
||||
item: {
|
||||
type: Object,
|
||||
default: () => {
|
||||
return { name: '11' }
|
||||
}
|
||||
},
|
||||
modeType: {
|
||||
type: Number,
|
||||
default: 1
|
||||
}
|
||||
})
|
||||
|
||||
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({})
|
||||
const params = reactive(
|
||||
{
|
||||
prompt: '',
|
||||
dataset_id: '',
|
||||
document_ids: '',
|
||||
}
|
||||
)
|
||||
// 获取会话ID
|
||||
const getConversation = (val) => {
|
||||
|
||||
getCompletion(val)
|
||||
}
|
||||
// 大模型对话
|
||||
const getCompletion = async (val) => {
|
||||
try {
|
||||
|
||||
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,
|
||||
})
|
||||
|
||||
} finally {
|
||||
loaded.value = false
|
||||
}
|
||||
}
|
||||
|
||||
const saveAdjust = (item) =>{
|
||||
emit('saveAdjust', item.msg)
|
||||
isDialog.value = false
|
||||
ElMessage.success('操作成功')
|
||||
}
|
||||
|
||||
|
||||
const curFile = reactive({})
|
||||
const dataset_id = ref('')
|
||||
const fileList = ref([])
|
||||
const getList = () =>{
|
||||
docList({
|
||||
userId: userInfo.userId,
|
||||
dataset_id: dataset_id.value
|
||||
}).then( res =>{
|
||||
fileList.value = [{fileId: '',fileName: '选择文件', id:-1},...res.rows]
|
||||
Object.assign(curFile, fileList.value[0])
|
||||
})
|
||||
}
|
||||
|
||||
const changeFile = (val) =>{
|
||||
|
||||
Object.assign(curFile, val);
|
||||
params.document_ids = val.docId
|
||||
}
|
||||
|
||||
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]
|
||||
dataset_id.value = dataSetJson[jsonKey]
|
||||
getList()
|
||||
})
|
||||
|
||||
</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);
|
||||
}
|
||||
}
|
||||
|
||||
.file-list{
|
||||
display: flex;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,211 @@
|
|||
<template>
|
||||
<el-dialog v-model="isDialog" :show-close="false" width="900" destroy-on-close>
|
||||
<template #header>
|
||||
<div class="custom-header flex">
|
||||
<span>选择{{ title }}</span>
|
||||
<i class="iconfont icon-guanbi" @click="isDialog = false"></i>
|
||||
</div>
|
||||
</template>
|
||||
<div class="dialog-content">
|
||||
<div class="flex dialog-top">
|
||||
<el-radio-group v-model="radio" @change="changeRadio">
|
||||
<el-radio :value="item.value" v-for="item in radioList">{{ item.label }}</el-radio>
|
||||
</el-radio-group>
|
||||
|
||||
</div>
|
||||
<div class="content-list">
|
||||
<ul>
|
||||
<li v-for="(item, index) in list" :class="activeIndex == index ? 'li-active' : ''" @click="clickItem(index)">
|
||||
<el-image class="img" :src="item.url" />
|
||||
<span>{{ item.name }}</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-upload class="upload-demo" :action="uploadFileUrl" :limit="1" :show-file-list="false"
|
||||
:headers="headers" :on-success="onSuccess">
|
||||
<el-button type="primary">上传</el-button>
|
||||
</el-upload>
|
||||
<div>
|
||||
<el-button @click="isDialog = false">取消</el-button>
|
||||
<el-button type="primary" @click="isDialog = false">
|
||||
确定
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, computed, onMounted, reactive } from 'vue'
|
||||
import { completion, addDoc, docList } from '@/api/mode/index.js'
|
||||
import { getToken } from "@/utils/auth";
|
||||
import { sessionStore } from '@/utils/store'
|
||||
import { dataSetJson } from '@/utils/comm.js'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import useUserStore from '@/store/modules/user'
|
||||
|
||||
const userInfo = useUserStore().user
|
||||
const uploadFileUrl = ref(import.meta.env.VITE_APP_BASE_API + "/common/upload");
|
||||
const headers = ref({ Authorization: "Bearer " + getToken() });
|
||||
|
||||
const url = 'https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fsafe-img.xhscdn.com%2Fbw1%2F11044b08-04c1-41a0-a453-1fd20b58a614%3FimageView2%2F2%2Fw%2F1080%2Fformat%2Fjpg&refer=http%3A%2F%2Fsafe-img.xhscdn.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1732953359&t=7ab1d1b3a903db85b1149914407aea35'
|
||||
|
||||
const isDialog = defineModel()
|
||||
|
||||
const props = defineProps({
|
||||
modeType: {
|
||||
type: Number,
|
||||
default: 1
|
||||
}
|
||||
})
|
||||
|
||||
const title = computed(() => {
|
||||
if (props.modeType == 1) return '课标';
|
||||
if (props.modeType == 2) return '教材';
|
||||
if (props.modeType == 3) return '考试';
|
||||
})
|
||||
|
||||
|
||||
const radio = ref(1)
|
||||
const radioList = ref([
|
||||
{ label: '浏览研读', value: 1 },
|
||||
{ label: '跨学科研读', value: 2 },
|
||||
{ label: '跨学段研读', value: 3 },
|
||||
{ label: '课标修订研读', value: 4 },
|
||||
{ label: '自由研读', value: 5 },
|
||||
])
|
||||
const list = ref([
|
||||
{
|
||||
name: '高中语文课程标准',
|
||||
url
|
||||
}
|
||||
])
|
||||
const changeRadio = () => {
|
||||
list.value = []
|
||||
for (let i = 0; i < Math.floor(Math.random() * 5) + 1; i++) {
|
||||
list.value.push({
|
||||
name: '高中语文课程标准',
|
||||
url
|
||||
})
|
||||
}
|
||||
}
|
||||
const activeIndex = ref(-1)
|
||||
|
||||
const clickItem = (index) => {
|
||||
activeIndex.value = index
|
||||
}
|
||||
|
||||
const dataset_id = ref('')
|
||||
|
||||
// 上传成功
|
||||
const onSuccess = async (response) =>{
|
||||
console.log(response,'response')
|
||||
let data = {
|
||||
url: response.url,
|
||||
dataset_id: dataset_id.value
|
||||
}
|
||||
const res = await completion(data)
|
||||
console.log(res)
|
||||
if(res.data.code != 200) return
|
||||
let docData = {
|
||||
fileUrl: response.url,
|
||||
fileId: response.file.id,
|
||||
fileName: response.file.fileName,
|
||||
filesize: response.file.fileSize,
|
||||
datasetId: dataset_id.value,
|
||||
docId: res.data.document_id,
|
||||
edustage: curNode.edustage,
|
||||
edusubject: curNode.edusubject
|
||||
}
|
||||
const { msg } = await addDoc(docData)
|
||||
ElMessage.success(msg)
|
||||
|
||||
}
|
||||
const curNode = reactive({})
|
||||
|
||||
const getList = () =>{
|
||||
docList({
|
||||
userId: userInfo.userId,
|
||||
dataset_id: dataset_id.value
|
||||
}).then( res =>{
|
||||
console.log(res)
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
onMounted(() =>{
|
||||
let data = sessionStore.get('subject.curNode')
|
||||
Object.assign(curNode, data);
|
||||
|
||||
let jsonKey = `考试-${curNode.edustage}-${curNode.edusubject}`
|
||||
dataset_id.value = dataSetJson[jsonKey]
|
||||
getList()
|
||||
})
|
||||
|
||||
</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;
|
||||
|
||||
.dialog-top {
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.content-list {
|
||||
padding-top: 10px;
|
||||
|
||||
ul {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
|
||||
li {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
font-size: 13px;
|
||||
padding: 10px;
|
||||
cursor: pointer;
|
||||
border-radius: 5px;
|
||||
overflow: hidden;
|
||||
margin-right: 20px;
|
||||
margin-bottom: 10px;
|
||||
|
||||
.img {
|
||||
width: 100px;
|
||||
height: 130px;
|
||||
border: solid #ccc 1px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background: #E0EAFF;
|
||||
}
|
||||
}
|
||||
|
||||
.li-active {
|
||||
background: #E0EAFF;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
.dialog-footer{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,78 @@
|
|||
<template>
|
||||
<el-dialog v-model="isDialog" :show-close="false" width="900">
|
||||
<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 { editTempResult } from '@/api/mode/index.js'
|
||||
|
||||
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 = () =>{
|
||||
editTempResult({id: props.item.reultId, content: textarea.value}).then( res =>{
|
||||
isDialog.value = false
|
||||
ElMessage.success('操作成功')
|
||||
emit('saveEdit', textarea.value)
|
||||
})
|
||||
}
|
||||
|
||||
</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,143 @@
|
|||
<template>
|
||||
<div class="container-header flex">
|
||||
<div class="header-left flex">
|
||||
<el-button link @click="showDialog = true">
|
||||
{{ curNode.edustage}}{{ curNode.edusubject }}考试分析<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="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
|
||||
}
|
||||
|
||||
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>
|
|
@ -0,0 +1,161 @@
|
|||
<template>
|
||||
<el-dialog v-model="mode" :show-close="false" width="600" destroy-on-close>
|
||||
<template #header>
|
||||
<div class="custom-header flex">
|
||||
<span>{{ item.ex3 == '1' ? '请输入新的模板名称' : isAdd ? '添加提示词' : '编辑提示词' }}</span>
|
||||
<i class="iconfont icon-guanbi" @click="mode = false"></i>
|
||||
</div>
|
||||
</template>
|
||||
<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-item label="名称">
|
||||
<el-input v-model="form.name" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="提示词" v-if="item.ex3 == '1' ? false : true">
|
||||
<el-input v-model="form.prompt" type="textarea" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
</div>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="mode = false">取消</el-button>
|
||||
<el-button type="primary" @click="saveAdd">
|
||||
确定
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive, watch } from 'vue'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import emitter from '@/utils/mitt';
|
||||
import { addKeyWords, addChildTemp, editChildTemp } from '@/api/mode/index'
|
||||
|
||||
const mode = defineModel()
|
||||
const props = defineProps({
|
||||
modeType: {
|
||||
type: Number,
|
||||
default: 1
|
||||
},
|
||||
isAdd: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
item: { // 子模板
|
||||
type: Object,
|
||||
default: () => {
|
||||
return { ex3: '' }
|
||||
}
|
||||
},
|
||||
tempId: {
|
||||
type: [String, Number],
|
||||
default: ''
|
||||
},
|
||||
})
|
||||
|
||||
|
||||
|
||||
const form = reactive({
|
||||
name: '',
|
||||
prompt: '',
|
||||
})
|
||||
|
||||
watch(() => props.isAdd, (newVal) => {
|
||||
if (!newVal) {
|
||||
form.name = props.item?.name
|
||||
form.prompt = props.item?.prompt
|
||||
}
|
||||
|
||||
}, { immediate: false })
|
||||
|
||||
const loading = ref(false)
|
||||
const saveAdd = async () => {
|
||||
|
||||
loading.value = true
|
||||
if (props.item.ex3 == '1') {
|
||||
if (props.isAdd) {
|
||||
try {
|
||||
// 系统预设模板 copy一份
|
||||
const { msg } = await addKeyWords({ name: form.name, id: props.item.id })
|
||||
emitter.emit('onGetChild')
|
||||
ElMessage.success(msg)
|
||||
mode.value = false
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
else{
|
||||
onAddChildTemp(props.item.parentId)
|
||||
}
|
||||
} else {
|
||||
|
||||
if (props.isAdd) {
|
||||
onAddChildTemp(props.item.id)
|
||||
}
|
||||
else {
|
||||
try {
|
||||
let data = JSON.parse(JSON.stringify(props.item))
|
||||
data.name = form.name;
|
||||
data.prompt = form.prompt
|
||||
const { msg } = await editChildTemp(data)
|
||||
emitter.emit('onGetChild')
|
||||
ElMessage.success(msg)
|
||||
mode.value = false
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 添加子模板
|
||||
const onAddChildTemp = async (parentId) => {
|
||||
// 添加子模板
|
||||
let obj = {
|
||||
name: form.name,
|
||||
type: 2, // 子模板 固定值为2
|
||||
sortNum: 1,
|
||||
parentId,
|
||||
lmType: 1,
|
||||
model: props.modeType,
|
||||
prompt: form.prompt,
|
||||
ex1: props.item.ex1, //学段
|
||||
ex2: props.item.ex2, // 学科
|
||||
ex3: '', //是否系统预设 这里默认空
|
||||
}
|
||||
try {
|
||||
var { msg } = await addChildTemp(obj)
|
||||
emitter.emit('onGetChild')
|
||||
ElMessage.success(msg)
|
||||
mode.value = false
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.custom-header {
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
|
||||
.icon-guanbi {
|
||||
cursor: pointer;
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
|
||||
.small-tip {
|
||||
text-align: left;
|
||||
font-size: 12px;
|
||||
margin-bottom: 15px;
|
||||
color: #F56C6C;
|
||||
}
|
||||
</style>
|
|
@ -3,7 +3,6 @@
|
|||
<PDF :url="pdfUrl" :showCatalog="false" v-if="pdfUrl" />
|
||||
</div>
|
||||
|
||||
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
|
@ -11,7 +10,6 @@ import { ref, onMounted, nextTick } from 'vue';
|
|||
import PDF from '@/components/PdfJs/index.vue'
|
||||
import { sessionStore } from '@/utils/store'
|
||||
|
||||
|
||||
const pdfUrl = ref('')
|
||||
|
||||
onMounted(async () =>{
|
|
@ -1,153 +0,0 @@
|
|||
<template>
|
||||
<div class="question-container">
|
||||
<div class="question-main">
|
||||
<div class="question-item">
|
||||
<div class="item-con">
|
||||
<div class="item-q flex">
|
||||
<div class="q-user">
|
||||
<i class="iconfont icon-touxiang"></i>
|
||||
</div>
|
||||
<div class="q-text">研读课程标准,提取出与本课相关的核心素养与课程目标</div>
|
||||
</div>
|
||||
<div class="item-a flex">
|
||||
<div class="a-user">
|
||||
语
|
||||
</div>
|
||||
<div class="a-text">
|
||||
<p> 语言的建构与运用:学生在丰富的语言实践中,通过主动的积累、梳理和整合,逐步掌握祖国语言文字特点及其规律,形成个体言语经验,发展在具体语言情境中正确有效地运用祖国语言文字进行交流沟通的能力。</p>
|
||||
<a class="" href="">来自《高中语文课程标准2020》,点击查看原文:第4页</a>
|
||||
<p>语言建构有两方面的内涵:第一是指出于表达思想的目的,按照语言内部系统来建构话语-用词汇组构句子,用句子组构段落和篇章。第二是指每个人在个人言语经验的基础上,逐步建构起自己的言语表达体系,包括每个人的言语心理词典、句典和表达习惯。</p>
|
||||
<a href="">来自《高中语文课程标准解读》,点击查看原文:第58页</a>
|
||||
<p>高中语文课程标准2003版本中没有核心素养相关表达。 </p>
|
||||
<a href="">来自《高中语文课程标准2003》 </a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="item-icon flex">
|
||||
<div class="flex">
|
||||
<span>
|
||||
<i class="iconfont icon-fuzhi"></i>
|
||||
复制
|
||||
</span>
|
||||
<span>
|
||||
<i class="iconfont icon-bianji-gangbi"></i>
|
||||
写评价
|
||||
</span>
|
||||
<span>
|
||||
<i class="iconfont icon-rss-line"></i>
|
||||
添加到微教研
|
||||
</span>
|
||||
</div>
|
||||
<div>
|
||||
<span>
|
||||
<i class="iconfont icon-tianjia"></i>
|
||||
保存
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<el-input v-model="textarea" class="question-textarea" resize="none" :rows="2" type="textarea" placeholder="在这里输入发消息,输入@或/选择" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from 'vue'
|
||||
const textarea = ref('')
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.question-container {
|
||||
padding: 10px 15px;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
.question-item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.item-con {
|
||||
background: #fff;
|
||||
border-radius: 5px;
|
||||
padding: 10px;
|
||||
|
||||
.item-q {
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
margin-bottom: 10px;
|
||||
|
||||
.q-user {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
background: #F6F6F6;
|
||||
border-radius: 50%;
|
||||
margin-right: 10px;
|
||||
|
||||
.icon-touxiang {
|
||||
font-size: 18px;
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
|
||||
.q-text {
|
||||
color: #409eff;
|
||||
font-size: 13px;
|
||||
}
|
||||
}
|
||||
|
||||
.item-a {
|
||||
color: #3D3D3D;
|
||||
font-size: 13px;
|
||||
|
||||
.a-user {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
line-height: 30px;
|
||||
text-align: center;
|
||||
background: #F6F6F6;
|
||||
border-radius: 50%;
|
||||
margin-right: 10px;
|
||||
flex-shrink: 0;
|
||||
|
||||
}
|
||||
|
||||
.a-text {
|
||||
text-align: left;
|
||||
a{
|
||||
color: #409eff;
|
||||
text-decoration: underline;
|
||||
margin-bottom: 15px;
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.item-icon{
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
color: #3D3D3D;
|
||||
margin-top: 10px;
|
||||
font-size: 13px;
|
||||
span{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
margin-right: 10px;
|
||||
|
||||
&:hover{
|
||||
background: #F5F7FA
|
||||
}
|
||||
}
|
||||
.iconfont{
|
||||
margin-right: 3px;
|
||||
color: #3498fc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.question-textarea {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -1,174 +0,0 @@
|
|||
<template>
|
||||
<div class="read-container">
|
||||
|
||||
<div class="template-list">
|
||||
<el-row>
|
||||
<el-col :span="24">
|
||||
<div class="template-item">
|
||||
<div class="item-header"><span class="blue">#</span>历年高考真题分析</div>
|
||||
<div class="item-text">研读课程标准,提取出与本课相关的核心素养与课程目标</div>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-col :span="24">
|
||||
<div class="template-item">
|
||||
<div class="item-header"><span class="blue">#</span>新课标与新高考改革分析</div>
|
||||
<div class="item-text">研读课程标准,提取出与本课相关的核心素养与课程目标
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-col :span="24">
|
||||
<div class="template-item">
|
||||
<div class="item-header"><span class="blue">#</span>模拟命题</div>
|
||||
<div class="item-text">研读课程标准,提取出与本课相关的核心素养与课程目标
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.read-container {
|
||||
padding: 15px;
|
||||
|
||||
.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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.template-list {
|
||||
|
||||
.template-item {
|
||||
background: #fff;
|
||||
padding: 10px;
|
||||
margin-bottom: 10px;
|
||||
border-radius: 5px;
|
||||
|
||||
.item-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
color: #000;
|
||||
|
||||
.blue {
|
||||
font-size: 22px;
|
||||
color: #409eff;
|
||||
margin-right: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
.item-text {
|
||||
display: flex;
|
||||
color: #409eff;
|
||||
font-size: 13px;
|
||||
padding-left: 20px;
|
||||
text-align: left;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
.pl-25 {
|
||||
padding-left: 25px;
|
||||
}
|
||||
</style>
|
|
@ -1,116 +0,0 @@
|
|||
<template>
|
||||
<div class="read-container">
|
||||
<div class="read-header flex">
|
||||
<el-dropdown>
|
||||
<span class="el-dropdown-link">
|
||||
课标研读模板
|
||||
<i class="iconfont icon-xiangxia" </i>
|
||||
</span>
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu>
|
||||
<el-dropdown-item>考试分析模板一</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</template>
|
||||
</el-dropdown>
|
||||
<el-button text class="add-btn">
|
||||
<i class="iconfont icon-jiahao"></i>
|
||||
添加
|
||||
</el-button>
|
||||
</div>
|
||||
<div class="template-list">
|
||||
<el-row>
|
||||
<el-col :span="24">
|
||||
<div class="template-item">
|
||||
<div class="item-header"><span class="blue">#</span>历年高考真题分析</div>
|
||||
<div class="item-text">研读课程标准,提取出与本课相关的核心素养与课程目标</div>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-col :span="24">
|
||||
<div class="template-item">
|
||||
<div class="item-header"><span class="blue">#</span>新课标与新高考改革分析</div>
|
||||
<div class="item-text">研读课程标准,提取出与本课相关的核心素养与课程目标
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-col :span="24">
|
||||
<div class="template-item">
|
||||
<div class="item-header"><span class="blue">#</span>模拟命题</div>
|
||||
<div class="item-text">研读课程标准,提取出与本课相关的核心素养与课程目标
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.read-container {
|
||||
padding: 15px;
|
||||
|
||||
.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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.template-list {
|
||||
margin-top: 15px;
|
||||
|
||||
.template-item {
|
||||
background: #fff;
|
||||
padding: 10px;
|
||||
margin-bottom: 10px;
|
||||
border-radius: 5px;
|
||||
|
||||
.item-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
color: #3D3D3D;
|
||||
|
||||
.blue {
|
||||
font-size: 22px;
|
||||
color: #409eff;
|
||||
margin-right: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
.item-text {
|
||||
display: flex;
|
||||
color: #409eff;
|
||||
font-size: 13px;
|
||||
padding-left: 20px;
|
||||
text-align: left;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,505 @@
|
|||
<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.prompt}`
|
||||
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>
|
|
@ -1,177 +1,52 @@
|
|||
<template>
|
||||
<div class="page-curriculum flex">
|
||||
<el-row>
|
||||
<el-col :span="12" class="flex">
|
||||
<div class="page-left">
|
||||
<template v-if="activeMenu == 1">
|
||||
<div class="page-title">考试分析</div>
|
||||
<el-radio-group v-model="radio" @change="changeRadio">
|
||||
<el-radio :value="item.value" v-for="item in radioList">{{ item.label }}</el-radio>
|
||||
</el-radio-group>
|
||||
<div class="list">
|
||||
<ul>
|
||||
<li v-for="(item, index) in list" :class="activeIndex == index ? 'li-active' : ''"
|
||||
@click="clickItem(index)">
|
||||
<el-image class="img" :src="item.url" />
|
||||
<span>{{ item.name }}</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</template>
|
||||
<template v-if="activeMenu != 1">
|
||||
<PdfTemplate/>
|
||||
</template>
|
||||
</div>
|
||||
<div class="page-template flex">
|
||||
<!--头部-->
|
||||
<Header :type="type" @changeTemp="changeTemp" @onRead="onRead"/>
|
||||
<el-row :gutter="20" class="tempalte-main">
|
||||
<el-col :span="12">
|
||||
<!--左侧pdf-->
|
||||
<Pdf />
|
||||
</el-col>
|
||||
<el-col :span="12" class="flex">
|
||||
<div class="page-right">
|
||||
<div class="right-header">
|
||||
<el-button text :type="activeMenu == item.value ? 'primary' : ''" v-for="item in contentMenu"
|
||||
@click="onClickMenu(item)">{{ item.label
|
||||
}}</el-button>
|
||||
</div>
|
||||
<div class="right-con">
|
||||
<ReadTemplate v-if="activeMenu == 1" />
|
||||
<QuestionAnswer v-if="activeMenu == 2" />
|
||||
<ReadResult v-if="activeMenu == 3" />
|
||||
</div>
|
||||
</div>
|
||||
<el-col :span="12">
|
||||
<!--右侧模板研读-->
|
||||
<Result ref="resultRef" :modeType="type" :tempId="tempId"/>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from 'vue'
|
||||
import ReadTemplate from './container/read-template.vue';
|
||||
import QuestionAnswer from './container/question-answer.vue'
|
||||
import ReadResult from './container/read-result.vue'
|
||||
import PdfTemplate from './container/pdf-template.vue'
|
||||
import Header from './container/header.vue'
|
||||
import Pdf from './container/pdf.vue'
|
||||
import Result from './container/result.vue'
|
||||
|
||||
const url = 'http://t13.baidu.com/it/u=3055765737,2452458153&fm=224&app=112&f=JPEG?w=500&h=500'
|
||||
const props = defineProps({
|
||||
type: {
|
||||
type: Number,
|
||||
default: 3
|
||||
},
|
||||
})
|
||||
|
||||
/************************左侧************* */
|
||||
const radio = ref(1)
|
||||
const radioList = ref([
|
||||
{ label: '浏览研读', value: 1 },
|
||||
{ label: '跨学科研读', value: 2 },
|
||||
{ label: '文献研读', value: 3 },
|
||||
{ label: '模拟命题', value: 4 },
|
||||
])
|
||||
const list = ref([
|
||||
{
|
||||
name: '2021年高考真题',
|
||||
url
|
||||
}
|
||||
])
|
||||
const changeRadio = () => {
|
||||
list.value = []
|
||||
for (let i = 0; i < Math.floor(Math.random() * 5) + 1; i++) {
|
||||
list.value.push({
|
||||
name: '2021年高考真题',
|
||||
url
|
||||
})
|
||||
}
|
||||
}
|
||||
const activeIndex = ref(-1)
|
||||
|
||||
const clickItem = (index) => {
|
||||
activeIndex.value = index
|
||||
const resultRef = ref()
|
||||
const tempId = ref('')
|
||||
const changeTemp = (id) =>{
|
||||
tempId.value = id
|
||||
}
|
||||
|
||||
|
||||
/************************右侧************* */
|
||||
|
||||
const contentMenu = [
|
||||
{ label: '分析模板', value: 1 },
|
||||
{ label: '问答分析', value: 2 },
|
||||
{ label: '分析结果', value: 3 }
|
||||
]
|
||||
const activeMenu = ref(1)
|
||||
const onClickMenu = (item) => {
|
||||
activeMenu.value = item.value
|
||||
const onRead = () =>{
|
||||
resultRef.value.getConversation()
|
||||
}
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.page-curriculum {
|
||||
.page-template {
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
background: #fff;
|
||||
border-radius: 5px;
|
||||
overflow: hidden;
|
||||
|
||||
.el-row {
|
||||
width: 100%;
|
||||
|
||||
.page-left {
|
||||
width: 100%;
|
||||
padding: 0 20px;
|
||||
box-sizing: border-box;
|
||||
|
||||
.page-title {
|
||||
font-size: 20px;
|
||||
padding: 20px 0;
|
||||
}
|
||||
|
||||
.list {
|
||||
ul {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
|
||||
li {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
font-size: 13px;
|
||||
padding: 10px;
|
||||
cursor: pointer;
|
||||
border-radius: 5px;
|
||||
overflow: hidden;
|
||||
margin-right: 20px;
|
||||
margin-bottom: 10px;
|
||||
|
||||
.img {
|
||||
width: 100px;
|
||||
height: 130px;
|
||||
border: solid #ccc 1px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background: #E0EAFF;
|
||||
}
|
||||
}
|
||||
|
||||
.li-active {
|
||||
background: #E0EAFF;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.page-right {
|
||||
width: 100%;
|
||||
background: #F6F6F6;
|
||||
border-left: solid #ececec 1px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.right-header {
|
||||
padding-left: 30px;
|
||||
height: 45px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
background: #fff;
|
||||
border-bottom: solid #ececec 1px;
|
||||
}
|
||||
|
||||
.right-con {
|
||||
.tempalte-main {
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
</style>
|
|
@ -127,7 +127,6 @@ onMounted(() => {
|
|||
.title-header{
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,15 +1,21 @@
|
|||
<template>
|
||||
<div>
|
||||
<div class="mb-4">
|
||||
<el-button type="primary" @click="onchange('/model/curriculum')">课标研读</el-button>
|
||||
<div class="page-resource flex">
|
||||
<!-- 左侧 教材 目录 -->
|
||||
<ChooseTextbook @change-book="getData" @node-click="getData" />
|
||||
|
||||
<div class="page-right">
|
||||
<div class="button-container">
|
||||
<el-button style="margin-left: 12px;" type="primary" @click="onchange('/model/curriculum')">课标研读</el-button>
|
||||
<el-button type="primary" @click="onchange('/model/management')">作业管理1</el-button>
|
||||
<el-button type="primary" @click="onchange('/model/newClassTaskAssign')">作业管理2</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="info" @click="onchange('/model/examination')">考试分析</el-button> -->
|
||||
<el-button type="info" @click="onchange('/model/examination')">考试分析</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<ChooseTextbook @change-book="getData" @node-click="getData" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
@ -26,10 +32,10 @@ const courseObj = reactive({
|
|||
textbookId: '',
|
||||
levelFirstId: '',
|
||||
levelSecondId: '',
|
||||
coursetitle:'',
|
||||
coursetitle: '',
|
||||
node: null, // 选择的课程节点
|
||||
//
|
||||
})
|
||||
|
||||
// 查询
|
||||
const getData = (data) => {
|
||||
const { textBook, node } = data
|
||||
|
@ -50,22 +56,53 @@ const getData = (data) => {
|
|||
courseObj.node = node; // 保存当前节点
|
||||
|
||||
// 头部 教材分析打开外部链接需要当前章节ID
|
||||
localStorage.setItem('unitId', JSON.stringify({ levelFirstId, levelSecondId}))
|
||||
localStorage.setItem('unitId', JSON.stringify({ levelFirstId, levelSecondId }))
|
||||
}
|
||||
|
||||
|
||||
const openPPTist = () =>{
|
||||
createWindow('open-win', {url: '/pptist'})
|
||||
const openPPTist = () => {
|
||||
createWindow('open-win', { url: '/pptist' })
|
||||
}
|
||||
|
||||
const onchange = (path) =>{
|
||||
if(path == '/model/newClassTaskAssign'){
|
||||
const onchange = (path) => {
|
||||
if (path == '/model/newClassTaskAssign') {
|
||||
// 作业管理
|
||||
router.push({path, query: { courseObj: JSON.stringify(courseObj)}})
|
||||
}else{
|
||||
router.push({ path, query: { courseObj: JSON.stringify(courseObj) } })
|
||||
} else {
|
||||
router.push(path)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
||||
<style lang="scss" scoped>
|
||||
.page-resource {
|
||||
height: 100%;
|
||||
padding: 10px 15px 0;
|
||||
|
||||
.page-right {
|
||||
min-width: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex: 1;
|
||||
margin-left: 20px;
|
||||
height: 100%;
|
||||
background: #ffffff;
|
||||
border-radius: 10px;
|
||||
box-shadow: 0px 0px 20px 0px rgba(99, 99, 99, 0.06);
|
||||
}
|
||||
|
||||
.button-container {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 10px;
|
||||
margin: 1rem 0;
|
||||
justify-content: flex-start;
|
||||
|
||||
.el-button {
|
||||
flex: 1 1 15%;
|
||||
max-width: 15%;
|
||||
min-width: 15%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -62,10 +62,18 @@ const handleUserEduStage = (item) => {
|
|||
// 默认语文
|
||||
userStore.edusubject = '语文'
|
||||
}
|
||||
else if(item === '高中' && userStore.edusubject === "道德与法治"){
|
||||
// 默认语文
|
||||
userStore.edusubject = '政治'
|
||||
}
|
||||
else if(item != '高中' && userStore.edusubject === "政治"){
|
||||
// 默认语文
|
||||
userStore.edusubject = '道德与法治'
|
||||
}
|
||||
}
|
||||
// 选择学科
|
||||
const handleUserEduSubject = (item) => {
|
||||
userStore.edusubject = item
|
||||
userStore.edusubject = item;
|
||||
}
|
||||
onMounted(() => {
|
||||
getSubject()
|
||||
|
|
|
@ -61,7 +61,6 @@ import { completion } from '@/api/mode/index.js'
|
|||
|
||||
const resultList = ref([])
|
||||
emitter.on('changeMode', (item) => {
|
||||
console.log(item, 3000)
|
||||
resultList.value = item.child
|
||||
conversation()
|
||||
})
|
||||
|
|
Loading…
Reference in New Issue