Compare commits

...

16 Commits

Author SHA1 Message Date
“zouyf” 2511a6cc32 优化查找图标 2024-11-21 15:02:40 +08:00
白了个白 30b2b9b964 Merge branch 'main' of http://27.128.240.72:3000/zhuhao/AIx_Smarttalk_WS into baigl 2024-11-21 11:21:16 +08:00
白了个白 cadb8088a6 习题上传:习题内容识别迁移 2024-11-21 11:20:58 +08:00
lyc a9732218f4 Merge pull request 'lyc-dev' (#47) from lyc-dev into main 2024-11-21 10:58:19 +08:00
lyc 538e9190c7 Merge branch 'main' into lyc-dev 2024-11-21 10:57:31 +08:00
lyc 5567e94235 模板 2024-11-21 10:56:35 +08:00
baigl a118afbc64 Merge pull request 'baigl' (#46) from baigl into main
Reviewed-on: #46
2024-11-21 10:38:09 +08:00
白了个白 ab8fe885cb 1 2024-11-21 10:36:00 +08:00
白了个白 853fb871ef 1 2024-11-20 17:35:08 +08:00
白了个白 41db306f77 1 2024-11-20 17:31:14 +08:00
白了个白 0f9c2a7d53 Merge branch 'zouyf_dev' of http://27.128.240.72:3000/zhuhao/AIx_Smarttalk_WS into baigl 2024-11-20 17:13:31 +08:00
白了个白 bf51f5084f 1 2024-11-20 17:13:07 +08:00
白了个白 2f2350531a 1 2024-11-20 16:20:45 +08:00
白了个白 5cbe56d1bf 作业管理 2024-11-20 15:30:18 +08:00
白了个白 9534622067 Merge branch 'main' of http://27.128.240.72:3000/zhuhao/AIx_Smarttalk_WS into baigl 2024-11-20 14:33:08 +08:00
白了个白 761f19cf22 习题上传:待完善 2024-11-20 14:32:40 +08:00
16 changed files with 2187 additions and 158 deletions

View File

@ -0,0 +1,65 @@
import request from '@/utils/request'
// 查询知识点列表
export function listKnowlegepoint(query) {
return request({
url: '/point/list',
method: 'get',
params: query
})
}
// 查询一级知识点查下级所有层级
export function childKnowlegepoint(query) {
return request({
url: '/point/child/list',
method: 'get',
params: query
})
}
// 新增
export function addKnowlegepoint(data) {
return request({
url: '/point/add',
method: 'post',
data: data
})
}
// 更新
export function updateKnowlegepoint(data) {
return request({
url: '/point/update',
method: 'post',
data: data
})
}
// 绑定
export function bindKnowlegepoint(data) {
return request({
url: '/point/evalution/bind',
method: 'post',
data: data
})
}
// 查询章节知识点关系
export function getBindlist(query) {
return request({
url: '/point/bind/list',
method: 'get',
params: query
})
}
// 删除
export function delKnowlegepoint(data) {
return request({
url: '/point/bind/delete',
method: 'post',
data: data
})
}

View File

@ -0,0 +1,42 @@
import request from '@/utils/request'
// 新增图片存eos
export function saveUploadFile(data) {
return request({
url: '/education/uploadfile/saveUploadFile',
method: 'post',
headers: {
'Content-Type': 'multipart/form-data'
},
data: data
})
}
// 新增批量图片存eos
export function saveUploadFiles(data) {
return request({
url: '/education/uploadfile/saveUploadFiles',
method: 'post',
headers: {
'Content-Type': 'multipart/form-data'
},
data: data
})
}
// 修改basecomment
export function updateUploadFile(data) {
return request({
url: '/education/uploadfile',
method: 'put',
data: data
})
}
// 删除basecomment
export function delUploadFile(id) {
return request({
url: '/education/uploadfile/' + id,
method: 'delete'
})
}

View File

@ -59,7 +59,7 @@ export function editChildTemp(data) {
// 删除子模板
export function removeChildTemp(id) {
return request({
url: '/education/llmModel/' + id,
url: '/education/llmModel/home/' + id,
method: 'delete'
})
}
@ -100,10 +100,3 @@ export function tempResult(params) {
})
}
// 删除模板结果
export function tempResultRemove(id) {
return request({
url: `/education/result/${id}`,
method: 'get',
})
}

View File

@ -32,7 +32,7 @@
</div>
</div>
<!--添加提示词-->
<keywordDialog v-model="wordDialog" :modeType="type" :isAdd="wordDialog" :item="curTemplate"/>
<keywordDialog v-model="wordDialog" :modeType="type" :isAdd="wordDialog" :item="curTemplate" />
<Dialog v-model="showDialog" :modeType="type" />
</template>
@ -43,6 +43,8 @@ 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';
const wordDialog = ref(false)
const props = defineProps({
@ -53,7 +55,7 @@ const props = defineProps({
})
watch(() => props.type, (newValue) => {
console.log(newValue, 'newValue2');
}, { immediate: true });
}, { immediate: true });
const emit = defineEmits(['changeTemp', 'onRead'])
@ -70,7 +72,7 @@ const curTemplate = reactive({ name: '', id: '' })
const templateList = ref([])
//
const getTemplateList = () => {
modelList({ model: props.type, type: 1 }).then(res => {
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)
@ -94,11 +96,18 @@ const changeTemplate = (val) => {
})
}
const onAdd = () =>{
wordDialog.value = true
emitter.on('onGetMain', () =>{
getTemplateList()
})
const onAdd = () => {
wordDialog.value = true
}
onUnmounted(() => {
emitter.off('onGetMain')
})
onMounted(() => {
getTemplateList()
})
@ -129,5 +138,4 @@ onMounted(() => {
font-weight: bold;
}
}
</style>

View File

@ -2,18 +2,18 @@
<el-dialog v-model="mode" :show-close="false" width="600" destroy-on-close>
<template #header>
<div class="custom-header flex">
<span>{{ isAdd ? item && item.ex3 == '1' ? '请输入新的模板名称' : '添加提示词' : '编辑提示词' }}</span>
<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>
<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="isAdd ? !(item && item.ex3 == '1') : true">
<el-form-item label="提示词" v-if="item.ex3 == '1' ? false : true">
<el-input v-model="form.prompt" type="textarea" />
</el-form-item>
</el-form>
@ -33,10 +33,9 @@
<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: {
@ -48,20 +47,25 @@ const props = defineProps({
default: true
},
item: { //
type: Object
type: Object,
default: () => {
return { ex3: '' }
}
},
tempId: {
type: [String, Number],
default: ''
},
temp: { //
Object
}
})
const form = reactive({
name: '',
prompt: '',
})
watch(() => props.isAdd, (newVal) => {
console.log(newVal)
if (!newVal) {
form.name = props.item?.name
form.prompt = props.item?.prompt
@ -71,47 +75,66 @@ watch(() => props.isAdd, (newVal) => {
const loading = ref(false)
const saveAdd = async () => {
loading.value = true
if (props.isAdd) {
try {
var msg = null
//
if (props.item.ex3 == '1') {
var { msg } = await addKeyWords({ name: form.name, id: props.item.id })
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 {
//
let obj = {
name: form.name,
type: 2, // 2
sortNum: 1,
parentId: props.item.id,
lmType: 1,
model: props.modeType,
prompt: form.prompt,
ex1: props.item.ex1, //
ex2: props.item.ex2, //
ex3: '', //
}
var { msg } = await addChildTemp(obj)
}
ElMessage.success(msg)
mode.value = false
} finally {
loading.value = false
}
else{
onAddChildTemp(props.item.parentId)
}
} else {
//
try {
let data = JSON.parse(JSON.stringify(props.item))
data.name = form.name;
data.prompt = form.prompt
const { msg } = await editChildTemp(data)
ElMessage.success(msg)
mode.value = false
} finally {
loading.value = false
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
}
}
@ -128,7 +151,8 @@ const saveAdd = async () => {
font-weight: bold;
}
}
.small-tip{
.small-tip {
text-align: left;
font-size: 12px;
margin-bottom: 15px;

View File

@ -10,7 +10,7 @@
<div>
<span class="blue">#</span>{{ item.name }}
</div>
<el-popover placement="bottom-end" trigger="hover" popper-class="template-custom-popover" >
<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>
@ -55,13 +55,13 @@
<!--AI 对话调整-->
<AdjustDialog v-model="isAdjust" :modeType="modeType" :item="editItem" @saveAdjust="saveAdjust" />
<!--编辑提示词-->
<keywordDialog v-model="isEditKeyWord" :isAdd="!isEditKeyWord" :item="keywordItem"/>
<keywordDialog v-model="isEditKeyWord" :isAdd="isAdd" :item="keywordItem" :tempId="tempId" />
</div>
</template>
<script setup>
import { ref, reactive, onMounted, watch } from 'vue';
import { ElMessage } from 'element-plus'
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';
@ -69,6 +69,7 @@ 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()
@ -83,10 +84,15 @@ const props = defineProps({
}
})
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
@ -96,13 +102,12 @@ const getChildTemplate = () => {
})
}
//
const getTempResult = () =>{
tempResult({mainModelId: props.tempId}).then(res =>{
console.log(res,1000)
const getTempResult = () => {
tempResult({ mainModelId: props.tempId }).then(res => {
let rows = res.rows
childTempList.value.forEach(item =>{
rows.forEach(el =>{
if(item.id == el.modelId){
childTempList.value.forEach(item => {
rows.forEach(el => {
if (item.id == el.modelId) {
item.answer = el.content
item.reultId = el.id
}
@ -111,8 +116,6 @@ const getTempResult = () =>{
})
}
const isEdit = ref(false)
watch(() => props.tempId, (newVal) => {
if (newVal) {
@ -133,7 +136,6 @@ const params = reactive(
const curNode = reactive({})
const getConversation = () => {
getCompletion()
}
//
@ -154,14 +156,14 @@ const getCompletion = async () => {
}
//
const onSaveTemp = (item) =>{
const onSaveTemp = (item) => {
const data = {
mainModelId: props.tempId,
modelId: item.id,
examDocld: '',
content: item.oldAnswer
}
tempSave(data).then(res =>{
tempSave(data).then(res => {
console.log(res)
})
}
@ -224,30 +226,59 @@ const saveAdjust = (item) => {
//
const keywordItem = reactive({})
const isEditKeyWord = ref(false)
const editKeyWord = (item) =>{
const isAdd = ref(true)
const editKeyWord = (item) => {
console.log(item)
isAdd.value = false
isEditKeyWord.value = true
Object.assign(keywordItem, item)
}
//
const removeItem = async(item) =>{
const { msg } = await removeChildTemp(item.id)
ElMessage.success(msg)
getChildTemplate()
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 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
@ -451,18 +482,20 @@ defineExpose({
}
}
.icon-shenglvehao{
.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 {

View File

@ -46,7 +46,8 @@ import "tinymce/plugins/anchor"; //锚点
import { ref, reactive, defineProps, defineEmits, nextTick, onMounted, computed, watch } from 'vue'
import { getStaticUrl } from '@/utils/tool'
//import { listUploadfile, getUploadFile, delUploadFile, addUploadFile, saveUploadFile } from "@/api/comm/uploadfile";
import useUserStore from '@/store/modules/user'
import { saveUploadFile } from "@/api/file/img";
const emits = defineEmits(["update:modelValue", "setHtml"]);
//props便
@ -107,6 +108,8 @@ const props = defineProps({
default: () => ({ userId: 0, fileAlias: '单题上传' }),
},
});
const userStore = useUserStore().user;
const pasteImgName = ref('');
const uploadUrl = ref(import.meta.env.VITE_APP_BASE_API + "/common/upload"); //
@ -212,29 +215,31 @@ const init = reactive({
// /() - , [images_upload_handler]
file_picker_callback: function(callback, value, meta) {
return;
//
let filetype='.pdf, .txt, .zip, .rar, .7z, .doc, .docx, .xls, .xlsx, .ppt, .pptx, .mp3, .mp4';
let upURL = '/common/upload';
//
switch(meta.filetype){
case 'image':
filetype='.jpg, .jpeg, .png, .gif';
//upURL='upimg.php';
break;
case 'media':
filetype='.mp3, .mp4';
//upURL='upfile.php';
break;
case 'file':
default:
}
// let filetype='.pdf, .txt, .zip, .rar, .7z, .doc, .docx, .xls, .xlsx, .ppt, .pptx, .mp3, .mp4';
// let upURL = '/common/upload';
// //
// switch(meta.filetype){
// case 'image':
// filetype='.jpg, .jpeg, .png, .gif';
// //upURL='upimg.php';
// break;
// case 'media':
// filetype='.mp3, .mp4';
// //upURL='upfile.php';
// break;
// case 'file':
// default:
// }
// input
let input = document.createElement('input');
input.setAttribute('type', 'file');
input.setAttribute('accept', filetype);
// // input
// let input = document.createElement('input');
// input.setAttribute('type', 'file');
// input.setAttribute('accept', filetype);
//
// //
// input.onchange = function() {
// const file = this.files[0];
// const formData = new FormData();
@ -250,7 +255,7 @@ const init = reactive({
// });
// };
input.click();
// input.click();
},
// /()
@ -278,22 +283,25 @@ const init = reactive({
formData.append("entpcourseid", 0);
formData.append("filetype", "image");
formData.append("suffix", "image");
formData.append("status", '0');
if(props.upFileParams?.hasOwnProperty('deptId')){
formData.append("entpid", props.upFileParams.deptId);
formData.append("status", '1');
if(userStore.deptId && userStore.deptId != null){
formData.append("entpid", userStore.deptId);
}
if(props.upFileParams?.hasOwnProperty('userId')){
formData.append("userid", props.upFileParams.userId);
if(userStore.userId && userStore.userId != null){
formData.append("userid", userStore.userId);
}
if(props.upFileParams?.hasOwnProperty('edudegree')){
let edudegree = props.upFileParams.edudegree.toString();
if(userStore.edudegree && userStore.edudegree != null){
let edudegree = userStore.edudegree.toString();
if(edudegree != '' && edudegree.indexOf('年级') == -1){
edudegree += '年级';
}
formData.append("edudegree", edudegree);
}
if(props.upFileParams?.hasOwnProperty('edusubject')){
formData.append("edusubject", props.upFileParams.edusubject);
if(userStore.edusubject && userStore.edusubject != null){
formData.append("edusubject", userStore.edusubject);
}
if(userStore.edustage && userStore.edustage != null){
formData.append("edustage", userStore.edustage);
}
if(props.upFileParams?.hasOwnProperty('lessionId')){
formData.append("evalid", props.upFileParams.lessionId);
@ -301,19 +309,22 @@ const init = reactive({
if(props.upFileParams?.hasOwnProperty('fileAlias')){
formData.append("filegroup", props.upFileParams.fileAlias);
}
loading.value = true;
console.log('formData->', formData);
//
// saveUploadFile(formData)
// .then((res) => {
// loading.value = false;
// return resolve(res.fileurl);
// })
// .catch((err) => {
// loading.value = false;
// return reject('err:' + err);
// });
saveUploadFile(formData)
.then((res) => {
console.log('res->', res);
loading.value = false;
return resolve(res.fileurl);
})
.catch((err) => {
loading.value = false;
return reject('err:' + err);
});
}
),

View File

@ -73,6 +73,18 @@ export const constantRoutes = [
name: 'teaching-design',
meta: { title: '教学框架设计' },
},
{
path: 'newClassTaskAssign',
component: () => import('@/views/classTask/newClassTaskAssign/index.vue'),
name: 'newClassTaskAssign',
meta: { title: '作业管理' }
},
{
path: 'questionUpload',
component: () => import('@/views/classTask/newClassTaskAssign/questionUpload/index.vue'),
name: 'questionUpload',
meta: { title: '习题上传' }
},
]
},
@ -128,26 +140,12 @@ const dynamicRoutes = [
name: 'classTaskAssign',
meta: { title: '作业布置', showBread: true }
},
{
path: 'newClassTaskAssign',
component: () => import('@/views/classTask/newClassTaskAssign/index.vue'),
name: 'newClassTaskAssign',
meta: { title: '新作业管理', showBread: true }
},
{
path: 'questionUpload',
component: () => import('@/views/classTask/newClassTaskAssign/questionUpload/index.vue'),
name: 'questionUpload',
meta: { title: '新作业管理', showBread: true }
},
{
path: 'classTask',
component: () => import('@/views/classTask/classTask.vue'),
name: 'classCorrect',
meta: { title: '作业批改', showBread: true }
},
{
path: '/teach',
component: () => import('@/views/teach/index.vue'),

View File

@ -16,7 +16,6 @@
<!-- <i v-if="!isCollapse" class="iconfont icon-xiangzuo" style="color: blue;"></i> -->
<span>作业设计</span>
<!-- <i v-if="isCollapse" class="iconfont icon-xiangyou" style="color: blue;"></i> -->
<el-button type="primary" @click="goToNewClassTaskAssign">新版作业管理</el-button>
</div>
<div v-else class="unit-top-left">
<i class="iconfont icon-xiangzuo cursor-pointer" style="color: blue;" @click="goBack">返回上页</i>
@ -81,9 +80,6 @@ const courseObj = reactive({
})
// ---------------------------------------------------
const goToNewClassTaskAssign = () => {
router.push({ path: '/newClassTaskAssign', query: { courseObj: JSON.stringify(courseObj)} });
}
//
const getData = (data) => {

View File

@ -94,6 +94,7 @@
</div>
</template>
<script setup>
import { Search } from '@element-plus/icons-vue'
import { onMounted, ref,watch, reactive, getCurrentInstance,nextTick } from 'vue'
import { useRouter, useRoute } from 'vue-router'
@ -104,9 +105,8 @@ import { delEntpcoursework } from "@/api/education/entpCourseWork";
import examDetailsDrawer from '@/components/exam-question/examDetailsDrawer.vue'
import { useHandleData } from "@/hooks/useHandleData";
import { processList } from '@/hooks/useProcessList'
import { useGetHomework } from '@/hooks/useGetHomework'
import { sessionStore } from '@/utils/store'
import {throttle,debounce } from '@/utils/comm'
import { debounce } from '@/utils/comm'
import useUserStore from '@/store/modules/user'
const router = useRouter()
@ -196,7 +196,7 @@ onMounted(() => {
})
const goToQuestUpload = () => {
router.push({ path: '/questionUpload', query: { courseObj: JSON.stringify(props.bookobj) } });
router.push({ path: '/model/questionUpload', query: { courseObj: JSON.stringify(props.bookobj) } });
}
const initPageParams = () => {

View File

@ -55,7 +55,19 @@
</div>
<div class="page-right">
<QuesItem ref="refquesItem"
:bookobj="courseObj"
:activeVersion="activeParams.version"
:activeLession="activeParams.lession"
:evalidArr="activeParams.evalidArr"
:curLessionList="curLessionList"
:isCropper="true"
@submit-exam-single-callback="onSubmitExamSingleCallback"
@cancel-exam-single-callback="onCancelExamSingleCallback"
@cropper-exam-form-item="cropperExamFormItem"
:style="{'height':'100%', 'overflow': 'auto', 'padding-top': '10px'}"
>
</QuesItem>
</div>
</div>
</template>
@ -72,14 +84,29 @@ import { editListItem } from '@/hooks/useClassTask'
import { useGetHomework } from '@/hooks/useGetHomework'
import { sessionStore } from '@/utils/store'
import { useRouter, useRoute } from 'vue-router'
import useUserStore from '@/store/modules/user'
import { ocrImg2ExamByManualUpl, ocrImg2ItemByManualUpl } from "@/views/classTask/newClassTaskAssign/questionUpload/ocrImg2ExamQues";
import QuesItem from "@/views/classTask/newClassTaskAssign/questionUpload/quesItem/index.vue";
// const Remote = require('@electron/remote')
// const fs = require('fs');
// const path = require('path');
import useUserStore from '@/store/modules/user'
const userStore = useUserStore().user
const route = useRoute();
const router = useRouter()
const { proxy } = getCurrentInstance()
const props = defineProps({
})
const activeParams = reactive({
version: {},
lession: {},
tab: '国家体系',
evalidArr: [],//id
versionList: [],//list
lessionList: [],//list
});
const propsQueryCourseObj = route.query.courseObj;//
const courseObj = reactive({
@ -120,6 +147,7 @@ const cropOption = reactive({
})
onMounted(() => {
console.log('propsQueryCourseObj', JSON.parse(propsQueryCourseObj));
if(propsQueryCourseObj&&JSON.parse(propsQueryCourseObj)){
@ -146,7 +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);
};
});
}
/**
* @desc: 上传本地图片
* @return: {*}
@ -162,10 +205,35 @@ const handleImportImg = (uploadFile) => {
}
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]));
console.log(cropOption.img);
// cropOption.img = window.URL.createObjectURL(new Blob([uploadFile.raw]));
// cropOption.img = window.URL.createObjectURL(new Blob([uploadFile.raw]));
// console.log(cropOption.img);
ElMessage.success('上传成功');
};
/**
@ -178,6 +246,9 @@ 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);
@ -213,7 +284,50 @@ const identifyOverallImg =()=>{
})
});
};
/** 单题上传/纠错 抛上来的识别单项内容 */
const cropperExamFormItem=(examType, curItem)=>{
if (cropOption.img == null || cropOption.img == '') {
ElMessage({
message: '识别区域中无图片, 禁止识别',
type: 'error',
});
return;
}
let formValue = null;
proxy.$refs.cropper.getCropData(async (imgBase64) => {
formValue = await ocrImg2ItemByManualUpl(OCR_WORK_TEST, imgBase64, examType, curItem);
if (formValue == null) {
return;
}
nextTick( () => {
// []
let key = curItem;
if (examType === '复合题' && curItem=='workdesc') {
key = 'mulList';
}
else if (curItem=='workdesc') {
key = 'list';
}
proxy.$refs.refquesItem.cropperFormItemCallBack(key, formValue);
})
});
}
//
const onCancelExamSingleCallback=()=>{
//
//
// this.dlgImportSingle.open = false;
};
/** 单题上传/纠错 完成后的回调 */
const onSubmitExamSingleCallback =(callback) =>{
if (callback.submitType !== 1) {
console.log('999-999');
return;
}
//
router.back()
};
</script>

View File

@ -1,5 +1,6 @@
import { ElMessageBox, ElMessage } from "element-plus";
import qs from "qs";
import axios from 'axios'
import { pyOCRAPI } from "@/api/education/entpcoursework";

View File

@ -52,7 +52,7 @@
</el-form-item>
</el-col>
<el-col :span="5">
<el-button @click="handleQueryParamFromEntpCourseWork(1)"><el-icon><Search /></el-icon> </el-button>
<el-button @click="handleQueryParamFromEntpCourseWork(1)"><el-icon><Search /></el-icon></el-button>
</el-col>
</el-row>
<!-- 习题表格 -->
@ -102,6 +102,8 @@
</div>
</template>
<script setup>
import { Search } from '@element-plus/icons-vue'
import { onMounted, ref,watch, reactive, getCurrentInstance,nextTick } from 'vue'
import {listEntpcoursework, listEntpcourseworkNew, getEntpcoursework} from '@/api/education/entpCourseWork'

View File

@ -2,7 +2,13 @@
<div>
<div class="form-item-cover">
<el-form-item label="答案点评" prop="discuss">
<tinymce v-model="discuss"/>
<tinymce
v-model="discuss"
:upFileParams="{
lessionId: 123456,
fileAlias: '单题上传',
}"
/>
</el-form-item>
</div>
</div>

View File

@ -2,7 +2,8 @@
<div>
<div class="mb-4">
<el-button type="primary" @click="onchange('/model/curriculum')">课标研读</el-button>
<el-button type="primary" @click="onchange('/model/management')">作业管理</el-button>
<el-button type="primary" @click="onchange('/model/management')">作业管理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>
@ -13,18 +14,57 @@
</template>
<script setup>
import { onMounted, ref, watch, reactive } from 'vue'
import { useRouter } from 'vue-router'
import { createWindow } from '@/utils/tool' //
import ChooseTextbook from '@/components/choose-textbook/index.vue'
const router = useRouter()
const courseObj = reactive({
// : id,id,id,
textbookId: '',
levelFirstId: '',
levelSecondId: '',
coursetitle:'',
node: null, //
//
})
//
const getData = (data) => {
const { textBook, node } = data
let textbookId = textBook.curBookId
let levelSecondId = node.id
let levelFirstId
if (node.parentNode) {
levelFirstId = node.parentNode.id
} else {
levelFirstId = node.id
levelSecondId = ''
}
courseObj.textbookId = textbookId //
courseObj.levelFirstId = levelFirstId //
courseObj.levelSecondId = levelSecondId //
courseObj.coursetitle = node.itemtitle // (/)
courseObj.node = node; //
// ID
localStorage.setItem('unitId', JSON.stringify({ levelFirstId, levelSecondId}))
}
const openPPTist = () =>{
createWindow('open-win', {url: '/pptist'})
}
const onchange = (path) =>{
router.push(path)
if(path == '/model/newClassTaskAssign'){
//
router.push({path, query: { courseObj: JSON.stringify(courseObj)}})
}else{
router.push(path)
}
}
</script>