Compare commits
12 Commits
b24c3f1899
...
2641845ce0
Author | SHA1 | Date |
---|---|---|
小杨 | 2641845ce0 | |
朱浩 | e1a12ff0e0 | |
朱浩 | 4fbd77c40c | |
baigl | dfe1a23327 | |
白了个白 | 437bff2cdd | |
白了个白 | 6a6d932852 | |
朱浩 | d3b5493810 | |
白了个白 | 2fd17df429 | |
lyc | fbf906f390 | |
lyc | 663ecb962c | |
朱浩 | 398de60dcd | |
lyc | 2f99a00a47 |
|
@ -8,7 +8,7 @@
|
||||||
http-equiv="Content-Security-Policy"
|
http-equiv="Content-Security-Policy"
|
||||||
content="default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:"
|
content="default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:"
|
||||||
/> -->
|
/> -->
|
||||||
<meta http-equiv="Content-Security-Policy" content="connect-src * blob: data:; default-src 'self'; 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;" />
|
<meta http-equiv="Content-Security-Policy" content="connect-src * blob: data:; default-src 'self'; script-src 'self' 'unsafe-eval' http://www.wiris.net 'unsafe-inline'; style-src 'self' 'unsafe-inline' http://www.wiris.net; media-src * blob:;img-src * 'self' data: blob:;font-src 'self' http://www.wiris.net;" />
|
||||||
|
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
|
|
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 700 B After Width: | Height: | Size: 700 B |
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
|
@ -15,7 +15,7 @@ export function conversation(data) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 进行课标研读对话
|
// 进行课标研读对话 质点提取
|
||||||
export function completion(data) {
|
export function completion(data) {
|
||||||
return axios({
|
return axios({
|
||||||
url: rootPath + '/api/v1/parse/docs',
|
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-face {
|
||||||
font-family: "iconfont"; /* Project id 4723712 */
|
font-family: "iconfont"; /* Project id 4723712 */
|
||||||
src: url('iconfont.woff2?t=1732173266977') format('woff2'),
|
src: url('iconfont.woff2?t=1732240267757') format('woff2'),
|
||||||
url('iconfont.woff?t=1732173266977') format('woff'),
|
url('iconfont.woff?t=1732240267757') format('woff'),
|
||||||
url('iconfont.ttf?t=1732173266977') format('truetype');
|
url('iconfont.ttf?t=1732240267757') format('truetype');
|
||||||
}
|
}
|
||||||
|
|
||||||
.iconfont {
|
.iconfont {
|
||||||
|
@ -13,6 +13,10 @@
|
||||||
-moz-osx-font-smoothing: grayscale;
|
-moz-osx-font-smoothing: grayscale;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.icon-shangchuan:before {
|
||||||
|
content: "\e61b";
|
||||||
|
}
|
||||||
|
|
||||||
.icon-jiqiren_o:before {
|
.icon-jiqiren_o:before {
|
||||||
content: "\eb62";
|
content: "\eb62";
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,13 @@
|
||||||
"css_prefix_text": "icon-",
|
"css_prefix_text": "icon-",
|
||||||
"description": "",
|
"description": "",
|
||||||
"glyphs": [
|
"glyphs": [
|
||||||
|
{
|
||||||
|
"icon_id": "4942656",
|
||||||
|
"name": "上传",
|
||||||
|
"font_class": "shangchuan",
|
||||||
|
"unicode": "e61b",
|
||||||
|
"unicode_decimal": 58907
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"icon_id": "5387814",
|
"icon_id": "5387814",
|
||||||
"name": "机器人_o",
|
"name": "机器人_o",
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
<div class="container-header flex">
|
<div class="container-header flex">
|
||||||
<div class="header-left flex">
|
<div class="header-left flex">
|
||||||
<el-button link @click="showDialog = true">
|
<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>
|
</el-button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@
|
||||||
</el-icon>
|
</el-icon>
|
||||||
添加提示词
|
添加提示词
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button type="primary" link>保存模板</el-button>
|
<!-- <el-button type="primary" link>保存模板</el-button> -->
|
||||||
<el-button type="primary" @click="aiRead">一键研读</el-button>
|
<el-button type="primary" @click="aiRead">一键研读</el-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -37,14 +37,14 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<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 { Plus } from '@element-plus/icons-vue'
|
||||||
import { ElMessageBox } from 'element-plus'
|
import { ElMessageBox } from 'element-plus'
|
||||||
import { modelList } from '@/api/mode/index'
|
import { modelList } from '@/api/mode/index'
|
||||||
import Dialog from './dialog.vue'
|
import Dialog from './dialog.vue'
|
||||||
import keywordDialog from './keyword-dialog.vue'
|
import keywordDialog from './keyword-dialog.vue'
|
||||||
import emitter from '@/utils/mitt';
|
import emitter from '@/utils/mitt';
|
||||||
|
import { sessionStore } from '@/utils/store'
|
||||||
|
|
||||||
const wordDialog = ref(false)
|
const wordDialog = ref(false)
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
|
@ -107,10 +107,13 @@ const onAdd = () => {
|
||||||
onUnmounted(() => {
|
onUnmounted(() => {
|
||||||
emitter.off('onGetMain')
|
emitter.off('onGetMain')
|
||||||
})
|
})
|
||||||
|
const curNode = reactive({})
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
|
let data = sessionStore.get('subject.curNode')
|
||||||
|
Object.assign(curNode, data);
|
||||||
getTemplateList()
|
getTemplateList()
|
||||||
})
|
})
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
|
|
@ -187,10 +187,10 @@ const init = reactive({
|
||||||
min_height: props.minHeight,
|
min_height: props.minHeight,
|
||||||
draggable_modal: true,
|
draggable_modal: true,
|
||||||
extended_valid_elements: '*[.*]',
|
extended_valid_elements: '*[.*]',
|
||||||
external_plugins: {
|
// external_plugins: {
|
||||||
tiny_mce_wiris: `/tinymce/tool/@wiris/mathtype-tinymce6/plugin.min.js`,
|
// tiny_mce_wiris: getStaticUrl('/tinymce/tool/wiris/mathtype-tinymce6/plugin.min.js'),
|
||||||
//tiny_mce_wiris: `https://www.wiris.net/demo/plugins/tiny_mce/plugin.js`,
|
// //tiny_mce_wiris: `https://www.wiris.net/demo/plugins/tiny_mce/plugin.js`,
|
||||||
},
|
// },
|
||||||
|
|
||||||
// setup: function (editor) {
|
// setup: function (editor) {
|
||||||
// },
|
// },
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
:style="type == 'design' ? ['top: 10px', 'justify-content: space-between'] : ['bottom: 10px', 'justify-content: center']">
|
:style="type == 'design' ? ['top: 10px', 'justify-content: space-between'] : ['bottom: 10px', 'justify-content: center']">
|
||||||
<div class="left">
|
<div class="left">
|
||||||
<!-- 前进回退 -->
|
<!-- 前进回退 -->
|
||||||
<div class="blockBox" v-if="!readonly && width >= 1000">
|
<div class="blockBox" v-if="!readonly && (width >= 1000 || width==='100%')">
|
||||||
<el-tooltip effect="light" content="回退" placement="top">
|
<el-tooltip effect="light" content="回退" placement="top">
|
||||||
<el-button :icon="RefreshLeft" circle :disabled="!canUndo" @click="undo" />
|
<el-button :icon="RefreshLeft" circle :disabled="!canUndo" @click="undo" />
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
|
@ -180,7 +180,7 @@
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<!-- 滚动 -->
|
<!-- 滚动 -->
|
||||||
<div v-if="width >= 1000" class="blockBox">
|
<div v-if="width >= 1000 || width==='100%'" class="blockBox">
|
||||||
<template v-if="type == 'design'">
|
<template v-if="type == 'design'">
|
||||||
<el-tooltip effect="light" content="滚动至中心" placement="top">
|
<el-tooltip effect="light" content="滚动至中心" placement="top">
|
||||||
<el-button icon="Operation" @click="scrollToCenter" />
|
<el-button icon="Operation" @click="scrollToCenter" />
|
||||||
|
@ -202,7 +202,7 @@
|
||||||
</div> -->
|
</div> -->
|
||||||
|
|
||||||
<!-- 橡皮擦、显示网格、清空 -->
|
<!-- 橡皮擦、显示网格、清空 -->
|
||||||
<div v-if="width >= 1000" class="blockBox">
|
<div v-if="width >= 1000 || width==='100%'" class="blockBox">
|
||||||
<!-- 橡皮擦 -->
|
<!-- 橡皮擦 -->
|
||||||
<el-tooltip effect="light" :content="currentType === 'eraser' ? '关闭橡皮擦' : '橡皮擦'" placement="top">
|
<el-tooltip effect="light" :content="currentType === 'eraser' ? '关闭橡皮擦' : '橡皮擦'" placement="top">
|
||||||
<el-button v-if="!readonly" :icon="Remove" circle :type="currentType === 'eraser' ? 'primary' : null"
|
<el-button v-if="!readonly" :icon="Remove" circle :type="currentType === 'eraser' ? 'primary' : null"
|
||||||
|
|
|
@ -29,13 +29,14 @@ import { ElMessage } from 'element-plus'
|
||||||
|
|
||||||
const emit = defineEmits(['itemClick'])
|
const emit = defineEmits(['itemClick'])
|
||||||
const items = shallowRef([
|
const items = shallowRef([
|
||||||
{ title: '自主搜题', description: '1111111111111111111111111111111111111', icon: '#icon-soutibao-',type:'primary' },
|
{ title: '自主搜题', description: '上千万高质量习题资源,历届考试真题,每道题均有习题解析', icon: '#icon-soutibao-',type:'default' },
|
||||||
{ title: '校本题库', description: '222222', icon: '#icon-soutibao-',type:'success' },
|
{ title: '校本题库', description: '本校公共题库资源。', icon: '#icon-soutibao-',type:'default' },
|
||||||
{ title: '个人题库', description: '333333', icon: '#icon-soutibao-',type:'default' },
|
{ title: '个人题库', description: '老师上传维护自己的个人题库。', icon: '#icon-soutibao-',type:'default' },
|
||||||
{ title: '智能推荐', description: '444444', icon: '#icon-tubiao_wuxing-',type:'default' },
|
{ title: '智能推荐', description: '通过对学生的薄弱知识点分析,推送不同难度的习题进行强化训练。', icon: '#icon-tubiao_wuxing-',type:'default' },
|
||||||
{ title: '课堂展示', description: '555555', icon: '#icon-huaban',type:'primary' },
|
{ title: '课堂展示', description: '通过课堂白板绘制作业,提升学生的创作思维能力。', icon: '#icon-huaban',type:'primary' },
|
||||||
{ title: '常规作业', description: '555555', icon: '#icon-zhaoxiangji',type:'primary' },
|
{ title: '常规作业', description: '推送pdf、视频、音频、图片,学生可以拍照上传。', icon: '#icon-zhaoxiangji',type:'danger' },
|
||||||
{ title: 'AI设计作业', description: '555555', icon: '#icon-jiqiren_o',type:'danger' },
|
{ title: 'AI设计作业', description: '通过AI助手,根据课标、教材、考试等分析结果,智能创建作业。', icon: '#icon-jiqiren_o',type:'danger' },
|
||||||
|
{ title: '习题上传', description: '自己上传个人题库。', icon: '#icon-shangchuan',type:'danger' },
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const handleClick = (item) => {
|
const handleClick = (item) => {
|
||||||
|
@ -70,7 +71,7 @@ const handleClick = (item) => {
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
|
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
|
||||||
padding: 8px;
|
padding: 8px;
|
||||||
width: calc(25% - 16px);
|
width: calc(25% - 16px);
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: all 0.3s ease;
|
transition: all 0.3s ease;
|
||||||
}
|
}
|
||||||
|
@ -139,4 +140,4 @@ const handleClick = (item) => {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -155,6 +155,7 @@ import { useRouter, useRoute } from 'vue-router'
|
||||||
import useUserStore from '@/store/modules/user'
|
import useUserStore from '@/store/modules/user'
|
||||||
const userStore = useUserStore().user
|
const userStore = useUserStore().user
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
|
const router = useRouter()
|
||||||
const { proxy } = getCurrentInstance()
|
const { proxy } = getCurrentInstance()
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
})
|
})
|
||||||
|
@ -202,6 +203,11 @@ onMounted(() => {
|
||||||
//---------作业设计---
|
//---------作业设计---
|
||||||
const handleItemClick = (itemName) => {
|
const handleItemClick = (itemName) => {
|
||||||
console.log('itemName', itemName);
|
console.log('itemName', itemName);
|
||||||
|
if(itemName == '习题上传'){
|
||||||
|
router.push({ path: '/model/questionUpload', query: { courseObj: JSON.stringify(courseObj) } });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
currentRow.value = {id:1}; // 作业设计
|
currentRow.value = {id:1}; // 作业设计
|
||||||
/**
|
/**
|
||||||
* 智能推荐?AI设计作业?
|
* 智能推荐?AI设计作业?
|
||||||
|
|
|
@ -457,8 +457,6 @@ const handleDelete = async(item, index) => {
|
||||||
// ElMessage('试题已经存在')
|
// ElMessage('试题已经存在')
|
||||||
// }
|
// }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// 防抖
|
// 防抖
|
||||||
const debounceQueryData = debounce(() => {
|
const debounceQueryData = debounce(() => {
|
||||||
console.log("防抖 加载数据中...")
|
console.log("防抖 加载数据中...")
|
||||||
|
@ -477,17 +475,7 @@ watch(() => props.bookobj.levelSecondId, (newVal, oldVal) => {
|
||||||
})
|
})
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
<style>
|
<style src="@/assets/styles/JYStyle.css"></style>
|
||||||
.my-custom-dialog{
|
|
||||||
width: 60% !important;
|
|
||||||
height: 77vh !important;
|
|
||||||
overflow: hidden !important;
|
|
||||||
}
|
|
||||||
.my-custom-dialog .el-dialog__body {
|
|
||||||
height: 90% !important;
|
|
||||||
overflow: auto !important;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
.page-myquest {
|
.page-myquest {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
@ -522,4 +510,14 @@ watch(() => props.bookobj.levelSecondId, (newVal, oldVal) => {
|
||||||
// }
|
// }
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
<style src="@/assets/styles/JYStyle.css"></style>
|
<style>
|
||||||
|
.my-custom-dialog{
|
||||||
|
width: 60% !important;
|
||||||
|
height: 77vh !important;
|
||||||
|
overflow: hidden !important;
|
||||||
|
}
|
||||||
|
.my-custom-dialog .el-dialog__body {
|
||||||
|
height: 90% !important;
|
||||||
|
overflow: auto !important;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
|
@ -46,8 +46,8 @@
|
||||||
<p>orc 使用说明</p>
|
<p>orc 使用说明</p>
|
||||||
<p>1、本地浏览 </p>
|
<p>1、本地浏览 </p>
|
||||||
<p>2、获取剪贴板图片 </p>
|
<p>2、获取剪贴板图片 </p>
|
||||||
<p>3、整题识别 </p>
|
<p>3、整题识别:可识别整张图片,自动填充到对应内容。 </p>
|
||||||
<p> </p>
|
<p>4、右侧搜索按钮:点击后可识别图中内容到对应的富文本中。 </p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
|
|
|
@ -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" />
|
<PDF :url="pdfUrl" :showCatalog="false" v-if="pdfUrl" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
|
@ -11,7 +10,6 @@ import { ref, onMounted, nextTick } from 'vue';
|
||||||
import PDF from '@/components/PdfJs/index.vue'
|
import PDF from '@/components/PdfJs/index.vue'
|
||||||
import { sessionStore } from '@/utils/store'
|
import { sessionStore } from '@/utils/store'
|
||||||
|
|
||||||
|
|
||||||
const pdfUrl = ref('')
|
const pdfUrl = ref('')
|
||||||
|
|
||||||
onMounted(async () =>{
|
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>
|
|