Compare commits

...

12 Commits

Author SHA1 Message Date
小杨 2641845ce0 fix:新增图标; 2024-11-22 09:52:21 +08:00
朱浩 e1a12ff0e0 个别文字说明修改 2024-11-22 09:48:43 +08:00
朱浩 4fbd77c40c Merge remote-tracking branch 'origin/main' 2024-11-22 09:34:38 +08:00
baigl dfe1a23327 Merge pull request 'baigl' (#56) from baigl into main
Reviewed-on: #56
2024-11-22 09:34:23 +08:00
白了个白 437bff2cdd Merge branch 'main' of http://27.128.240.72:3000/zhuhao/AIx_Smarttalk_WS into baigl 2024-11-22 09:33:32 +08:00
白了个白 6a6d932852 作业管理 2024-11-22 09:33:04 +08:00
朱浩 d3b5493810 Merge remote-tracking branch 'origin/main' 2024-11-22 09:18:02 +08:00
白了个白 2fd17df429 1 2024-11-21 17:35:52 +08:00
lyc fbf906f390 Merge pull request 'lyc-dev' (#55) from lyc-dev into main 2024-11-21 17:34:05 +08:00
lyc 663ecb962c model/index.vue 冲突 解决 2024-11-21 17:33:36 +08:00
朱浩 398de60dcd 关闭自动同步文件,超过150M文件不允许加入课程 2024-11-21 17:32:47 +08:00
lyc 2f99a00a47 模板-考试分析 2024-11-21 17:31:26 +08:00
110 changed files with 1528 additions and 652 deletions

View File

@ -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>

View File

@ -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
})
}

View File

@ -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";
} }

File diff suppressed because one or more lines are too long

View File

@ -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",

View File

@ -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>

View File

@ -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) {
// }, // },

View File

@ -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"

View File

@ -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>

View File

@ -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设计作业

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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 () =>{

View File

@ -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>

Some files were not shown because too many files have changed in this diff Show More