Compare commits

..

9 Commits

15 changed files with 2084 additions and 112 deletions

View File

@ -20,7 +20,7 @@
</template>
</el-dropdown>
<div>
<el-button type="primary" link @click="keywordDialog = true">
<el-button type="primary" link @click="wordDialog = true">
<el-icon>
<Plus />
</el-icon>
@ -31,35 +31,7 @@
</div>
</div>
</div>
<el-dialog v-model="keywordDialog" :show-close="false" width="600">
<template #header>
<div class="custom-header flex">
<span>添加提示词</span>
<i class="iconfont icon-guanbi" @click="isDialog = false"></i>
</div>
</template>
<div class="dialog-content">
<el-form :model="form" label-width="auto">
<el-form-item label="名称">
<el-input v-model="form.name" />
</el-form-item>
<el-form-item label="提示词">
<el-input v-model="form.desc" type="textarea" />
</el-form-item>
</el-form>
</div>
<template #footer>
<div class="dialog-footer">
<el-button @click="keywordDialog = false">取消</el-button>
<el-button type="primary" @click="keywordDialog = false">
确定
</el-button>
</div>
</template>
</el-dialog>
<keywordDialog v-model="wordDialog"/>
<Dialog v-model="showDialog" :modeType="type" />
</template>
@ -69,8 +41,9 @@ 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'
const keywordDialog = ref(false)
const wordDialog = ref(false)
const props = defineProps({
type: {
type: Number,
@ -120,13 +93,6 @@ const changeTemplate = (val) => {
})
}
const form = reactive({
name: '',
desc: '',
})
onMounted(() => {
getTemplateList()
})
@ -143,8 +109,6 @@ onMounted(() => {
width: 50%;
align-items: center;
padding-left: 20px;
}
.header-right {
@ -160,13 +124,4 @@ onMounted(() => {
}
}
.custom-header {
justify-content: space-between;
align-items: center;
.icon-guanbi {
cursor: pointer;
font-weight: bold;
}
}
</style>

View File

@ -0,0 +1,72 @@
<template>
<el-dialog v-model="mode" :show-close="false" width="600">
<template #header>
<div class="custom-header flex">
<span>{{ isAdd ? '添加' : '编辑' }}提示词</span>
<i class="iconfont icon-guanbi" @click="mode = false"></i>
</div>
</template>
<div class="dialog-content">
<el-form :model="form" label-width="auto">
<el-form-item label="名称">
<el-input v-model="form.name" />
</el-form-item>
<el-form-item label="提示词">
<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="mode = false">
确定
</el-button>
</div>
</template>
</el-dialog>
</template>
<script setup>
import { reactive, watch } from 'vue'
const mode = defineModel()
const props = defineProps({
isAdd: {
type: Boolean,
default: true
},
item: {
type: Object
}
})
const form = reactive({
name: '',
prompt: '',
})
watch(() => props.isAdd, (newVal) => {
if (!newVal) {
console.log(props.item)
form.name = props.item.name
form.prompt = props.item.prompt
}
}, { immediate: true })
</script>
<style lang="scss" scoped>
.custom-header {
justify-content: space-between;
align-items: center;
.icon-guanbi {
cursor: pointer;
font-weight: bold;
}
}
</style>

View File

@ -3,10 +3,24 @@
<el-scrollbar height="100%">
<div class="template-list">
<el-row v-for="(item,index) in childTempList">
<el-row v-for="(item, index) in childTempList">
<el-col :span="24">
<div class="template-item" v-loading="item.loading">
<div class="item-header"><span class="blue">#</span>{{ item.name }}</div>
<div class="item-header">
<div>
<span class="blue">#</span>{{ item.name }}
</div>
<el-popover placement="bottom-end" trigger="hover" popper-class="template-custom-popover" >
<template #reference>
<el-button link type="primary">
<i class="iconfont icon-shenglvehao"></i></el-button>
</template>
<template #default>
<el-button type="primary" link @click="editKeyWord(item)">编辑</el-button>
<el-button type="primary" link>移除</el-button>
</template>
</el-popover>
</div>
<div class="item-text">
{{ item.prompt }}
</div>
@ -37,9 +51,11 @@
</div>
</el-scrollbar>
<!--编辑结果-->
<EditDialog v-model="isEdit" :item="editItem" @saveEdit="saveEdit"/>
<EditDialog v-model="isEdit" :item="editItem" @saveEdit="saveEdit" />
<!--AI 对话调整-->
<AdjustDialog v-model="isAdjust" :item="editItem" @saveAdjust="saveAdjust"/>
<AdjustDialog v-model="isAdjust" :item="editItem" @saveAdjust="saveAdjust" />
<!--编辑提示词-->
<keywordDialog v-model="isEditKeyWord" :isAdd="false" :item="keywordItem"/>
</div>
</template>
@ -47,6 +63,7 @@
import { ref, reactive, onMounted, watch } from 'vue';
import EditDialog from './edit-dialog.vue'
import AdjustDialog from './adjust-dialog.vue'
import keywordDialog from './keyword-dialog.vue';
import { sessionStore } from '@/utils/store'
import useUserStore from '@/store/modules/user'
import { conversation, completion, modelList } from '@/api/mode/index'
@ -102,10 +119,10 @@ const params = reactive(
)
const curNode = reactive({})
const getConversation = async () => {
const { user: { userId } } = userStore
const result = await conversation({ user_id: String(userId) })
console.log('result',result)
console.log('result', result)
params.conversation_id = result.data.data.id
getCompletion()
}
@ -120,7 +137,7 @@ const getCompletion = async () => {
let answer = res.data.data.answer
item.oldAnswer = answer
item.answer = getResult(answer);
} finally {
item.loading = false
}
@ -129,15 +146,15 @@ const getCompletion = async () => {
//
const againResult = async (index,item) =>{
try{
const againResult = async (index, item) => {
try {
childTempList.value[index].loading = true
params.messages[0].content = `根据${curNode.edustage}语文课标,提炼出${item.name}`
const res = await completion(params)
let answer = res.data.data.answer
item.oldAnswer = answer
item.answer = getResult(answer);
}finally {
} finally {
childTempList.value[index].loading = false
}
}
@ -155,35 +172,44 @@ let getResult = (text) => {
//
const curIndex = ref(-1)
const editItem = reactive({})
const onEdit = (index,item) =>{
const onEdit = (index, item) => {
curIndex.value = index
Object.assign(editItem, item)
isEdit.value = true
}
//
const saveEdit = (data) =>{
const saveEdit = (data) => {
childTempList.value[curIndex.value].oldAnswer = data
let answer = getResult(data);
childTempList.value[curIndex.value].answer = answer
}
const isAdjust = ref(false)
const onAdjust = (index, item) =>{
const onAdjust = (index, item) => {
curIndex.value = index
Object.assign(editItem, item)
isAdjust.value = true
}
const saveAdjust = (item) =>{
const saveAdjust = (item) => {
childTempList.value[curIndex.value].oldAnswer = item
let answer = getResult(item);
childTempList.value[curIndex.value].answer = answer
}
//
const keywordItem = reactive({})
const isEditKeyWord = ref(false)
const editKeyWord = (item) =>{
isEditKeyWord.value = true
Object.assign(keywordItem, item)
}
onMounted(() => {
let data = sessionStore.get('subject.curNode')
Object.assign(curNode, data);
})
defineExpose({
@ -249,6 +275,7 @@ defineExpose({
font-size: 16px;
font-weight: bold;
color: #000;
justify-content: space-between;
.blue {
font-size: 22px;
@ -290,20 +317,25 @@ defineExpose({
}
}
.text-answer{
.text-answer {
color: #409eff;
}
.ai-btn{
.ai-btn {
margin-top: 10px;
display: flex;
justify-content: flex-end;
.iconfont{
.iconfont {
margin-right: 3px;
}
:deep(.el-button){
:deep(.el-button) {
font-size: 13px;
}
.icon-ai1{
.icon-ai1 {
font-size: 18px;
}
}
@ -382,8 +414,22 @@ defineExpose({
}
}
.icon-shenglvehao{
font-weight: bold;
font-size: 22px;
}
:deep(.el-popover) {
min-width: 50px;
width: 50px !important;
}
.pl-25 {
padding-left: 25px;
}
</style>
</style>
<style>
.template-custom-popover {
width: 110px !important;
min-width: 110px !important;
}
</style>

View File

@ -0,0 +1,34 @@
import { ElMessageBox, ElMessage } from "element-plus";
/**
* @description 操作单条数据信息(二次确认删除禁用启用重置密码)
* @param {Function} api 操作数据接口的api方法(必传)
* @param {Object} params 携带的操作数据参数 {id,params}(必传)
* @param {String} message 提示信息(必传)
* @param {String} confirmType icon类型(不必传,默认为 warning) | "success" | "warning" | "info" | "error"
* @return Promise
*/
export const useHandleData = (
api,
params,
message,
confirmType= "warning"
) => {
return new Promise((resolve, reject) => {
ElMessageBox.confirm(`是否${message}?`, "温馨提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: confirmType,
draggable: true
}).then(async () => {
const res = await api(params);
if (!res) return reject(false);
ElMessage({
type: "success",
message: `${message}成功!`
});
resolve(true);
}).catch(() => { });
});
};

View File

@ -131,6 +131,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: 'classTask',
component: () => import('@/views/classTask/classTask.vue'),

View File

@ -465,10 +465,10 @@ function Apis(key) {
})
})
}
}
}
const client = new Apis('/paht');
const client = new Apis('/paht');
/**
@ -513,13 +513,6 @@ const handleQueryFromEntpCourseWork= async (queryType) => {
pageParams.value.loading = true;
// ( warn: )
// if (this.courseObj.edusubject=='' && this.courseObj.edustage=='') {
// // [+][+]
// queryForm.edusubject = '';
// }
client(t('任务1', 1500)).then(res => {
//console.log("",res);
// if(paginationParams.pageNum == 1){
@ -533,31 +526,31 @@ const handleQueryFromEntpCourseWork= async (queryType) => {
// }
const data = res.data || [];
if(data && data.length>0){
// workResource.entpCourseWorkList = entpcourseworkres.data;
// workResource.entpCourseWorkTotal = entpcourseworkres.data.length;
// workResource.entpCourseWorkList = entpcourseworkres.data;
// workResource.entpCourseWorkTotal = entpcourseworkres.data.length;
data.forEach(item=> {
if (item.worktype == '选择题') {
item.worktype = '单选题'
data.forEach(item=> {
if (item.worktype == '选择题') {
item.worktype = '单选题'
}
})
//
processList(data);
//workResource.entpCourseWorkList.push(...data);
workResource.entpCourseWorkList = data;
//
if (pageParams.value.isFirst) {
pageParams.value.isFirst = false;
pageParams.value.originCount = workResource.entpCourseWorkList.length;
pageParams.value.total = parseInt(res.msg);
paginationParams.pageNum = Math.ceil(parseInt(res.msg)/paginationParams.pageSize);
console.log('first->', pageParams.value, paginationParams);
}
})
//
processList(data);
//workResource.entpCourseWorkList.push(...data);
workResource.entpCourseWorkList = data;
//
if (pageParams.value.isFirst) {
pageParams.value.isFirst = false;
pageParams.value.originCount = workResource.entpCourseWorkList.length;
pageParams.value.total = parseInt(res.msg);
paginationParams.pageNum = Math.ceil(parseInt(res.msg)/paginationParams.pageSize);
console.log('first->', pageParams.value, paginationParams);
}
}
pageParams.value.loading = false;
});
pageParams.value.loading = false;
});
//const entpcourseworkres = await listEntpcourseworkNew(queryForm);
@ -741,10 +734,6 @@ const handleClassWorkSave = async () => {
return;
}
if (classWorkForm.worktype === "课堂展示") {
boardLoading.value = true
let canvasJson = proxy.$refs.boardref.getCanvasJson()

View File

@ -16,6 +16,7 @@
<!-- <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>
@ -26,8 +27,8 @@
<el-col :span="12">
<div class="classtype-right">
<el-form-item label="作业名称">
<el-input v-model="classWorkForm.uniquekey" type="text" placeholder="请输入作业名称"/>
</el-form-item>
<el-input v-model="classWorkForm.uniquekey" type="text" placeholder="请输入作业名称"/>
</el-form-item>
</div>
</el-col>
</el-row>
@ -80,6 +81,9 @@ const courseObj = reactive({
})
// ---------------------------------------------------
const goToNewClassTaskAssign = () => {
router.push({ path: '/newClassTaskAssign', query: { courseObj: JSON.stringify(courseObj)} });
}
//
const getData = (data) => {

View File

@ -0,0 +1,94 @@
<template>
<div class="list-container">
<div class="content-list" v-for="(item, index) in items" :key="index" @click="handleClick(item)">
<div class="item-content">
<div class="item-text">
<div class="item-title">{{ item.title }}</div>
<div class="item-description">{{ item.description }}</div>
</div>
<el-icon class="item-icon"><component :is="item.icon" /></el-icon>
</div>
</div>
</div>
</template>
<script setup>
import { shallowRef } from 'vue';
import { ElMessage } from 'element-plus'
import { Plus, ArrowDown, Document, User, Setting } from '@element-plus/icons-vue';
const emit = defineEmits(['itemClick'])
const items = shallowRef([
{ title: '自主搜题', description: '1111111', icon: Document },
{ title: '校本题库', description: '222222', icon: User },
{ title: '个人题库', description: '333333', icon: Setting },
{ title: '智能推荐', description: '444444', icon: Plus },
{ title: '课堂展示', description: '555555', icon: ArrowDown },
{ title: '常规作业', description: '555555', icon: ArrowDown },
{ title: 'AI设计作业', description: '555555', icon: ArrowDown },
]);
const handleClick = (item) => {
console.log('Clicked on:', item.title);
if(item.title === '智能推荐' || item.title === 'AI设计作业') {
ElMessage({
message: '该作业类型暂未开放!',
type: 'warning',
})
return;
}
emit('itemClick', item.title)
};
</script>
<style scoped>
.list-container {
display: flex;
flex-wrap: wrap;
gap: 16px;
padding: 16px;
/* background-color: #f5f5f5; */
}
.content-list {
background-color: #fff;
border-radius: 8px;
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
padding: 16px;
width: calc(33.333% - 32px); /* 3列布局每列减去gap */
cursor: pointer;
transition: all 0.3s ease;
}
.content-list:hover {
transform: translateY(-4px);
box-shadow: 0 4px 16px 0 rgba(0, 0, 0, 0.15);
}
.item-content {
display: flex;
align-items: center;
}
.item-icon {
font-size: 24px;
color: #409eff;
margin-right: 16px;
}
.item-text {
flex: 1;
}
.item-title {
font-size: 16px;
font-weight: 500;
color: #303133;
margin-bottom: 4px;
}
.item-description {
font-size: 14px;
color: #909399;
}
</style>

View File

@ -0,0 +1,813 @@
<template>
<div class="page">
<div class="page-top">
<div class="page-top-left">
<el-button type="danger" :icon="Delete" @click="handleDelete">删除</el-button>
<el-button type="success" @click="handleTaskAssignToAllClass()">批量推送</el-button>
</div>
<div v-if="currentRow.id > 0" class="page-top-right">
<el-button type="primary" @click="handleNewAllClass">设计新作业</el-button>
</div>
</div>
<div class="page-resource">
<div class="page-left">
<el-table
ref="taskTable"
v-loading="loading"
:data="taskList"
:tree-props="{checkStrictly: true}"
row-key="id"
style="width: 100%;height: 100%; border: 1px solid #dcdfe6;border-radius: 3px;flex:1"
highlight-current-row
@current-change="handleCurrentChange"
>
<el-table-column type="selection" min-width="2%" align="center" :selectable="selectable"/>
<el-table-column label="作业布置" min-width="18%" align="center">
<template #default="scope">
<div style="height: 100px;">
<div class="pageleft-table-top">
<span>{{ scope.row.uniquekey }}</span>
</div>
<div class="pageleft-table-top">
<el-tag :type="scope.row.workclass" size="default">{{ scope.row.worktype }}</el-tag>
<span>{{ scope.row.timestamp }}</span>
</div>
<div class="pageleft-table-cont">
<p class="ellipsis "> {{ scope.row.worktype == "课堂展示" ? scope.row.worktag : scope.row.title }}</p>
</div>
</div>
</template>
</el-table-column>
</el-table>
</div>
<div v-if="currentRow.id == 0" style="width: 100%; height: 100%;">
<!-- 默认的习题类型卡片 -->
<Right @itemClick="handleItemClick" />
</div>
<div v-if="(currentRow.worktype == '习题训练' || classWorkForm.worktype == '习题训练') && currentRow.id>0" class="page-center">
<el-tabs v-model="activeAptTab" style="height: 100%;">
<el-tab-pane label="自主搜题" name="自主搜题" class="prepare-center-zzst">
<SearchQuestion :bookobj="courseObj" @addQuiz="handleClassWorkQuizAdd" />
</el-tab-pane>
<el-tab-pane label="校本题库" name="校本题库" class="prepare-center-xbtk">
<SchoolQuestion />
</el-tab-pane>
<el-tab-pane label="个人题库" name="个人题库" class="prepare-center-grst">
<MyQuestion :bookobj="courseObj" @addQuiz="handleClassWorkQuizAdd"/>
</el-tab-pane>
</el-tabs>
</div>
<div v-if="(currentRow.worktype == '课堂展示' || classWorkForm.worktype == '课堂展示') && currentRow.id>0" class="page-center">
<div v-loading="boardLoading" class="board-wrap" style="height: 100%; flex: 1; overflow: hidden;">
<!-- <whiteboard v-if="isShowBoard" ref="boardref" :height="mainHeight - 150" :isShowSave="false" :data="whiteboardObj"/> -->
<whiteboard ref="boardref" height=" 100%" :isShowSave="false" :data="classWorkForm.whiteboardObj"/>
</div>
</div>
<div v-if="(currentRow.worktype == '常规作业' || classWorkForm.worktype == '常规作业')&& currentRow.id>0" class="page-center">
<div v-loading="fileLoading" class="upload-homework">
<FileUpload v-model="classWorkForm.fileHomeworkList" :fileSize="800" :fileType="['mp3','mp4','doc','docx','xlsx','xls','pdf','ppt','pptx','jpg','jpeg','gif','png','txt']"/>
</div>
</div>
<div v-if="currentRow.id>0 " class="page-right">
<div class="prepare-top" >
<el-button v-if="currentRow.id != 1 " type="success" @click="openSet(currentRow,'item')"> </el-button>
<el-button type="primary" @click="handleClassWorkSave"> </el-button>
</div>
<div class="prepare-con" >
<el-form
ref="classWorkFormRef"
:model="classWorkForm"
label-width="90"
style=" height: 100%; overflow: hidden;display: flex;flex-direction: column;"
>
<div >
<el-form-item label="作业名称">
<el-input v-model="classWorkForm.uniquekey" type="text" placeholder="请输入作业名称"/>
</el-form-item>
<el-form-item label="作业说明" style="margin: 10px 0;">
<el-input v-if="classWorkForm.worktype != '课堂展示'" v-model="classWorkForm.title" style="width: 400px" placeholder="请输入作业说明"/>
<!-- 课堂展示 这里字段不一样 -->
<el-input v-if="classWorkForm.worktype == '课堂展示'" v-model="classWorkForm.question" type="textarea" placeholder="请输入作业说明" />
</el-form-item>
</div>
<div v-if="classWorkForm.worktype == '习题训练'" class="pageRight-list">
<div :style="{height: '100%', 'overflow': 'auto', 'border':'1px dotted blue','border-radius':'5px', 'background-color': '#f7f7f7'}">
<template v-for="(item,index) in classWorkForm.quizlist" :key="item.id">
<div style="margin: 5px; background-color: white">
<div v-html="item.titleFormat" style="padding: 15px 20px 5px 20px"></div>
<div style="display: flex;">
<el-form-item label="分值">
<el-input-number v-model="item.score" :min="1" :max="100" size="small"></el-input-number >
</el-form-item>
<div style="margin-left: auto; padding: 0px 20px"><el-button size="small" type="danger" @click="handleClassWorkFormQuizRemove(index)">删除</el-button></div>
</div>
</div>
</template>
</div>
</div>
</el-form>
</div>
</div>
</div>
<!-- 推送作业的配置对话框 -->
<SetHomework v-model="setDialog" :entpcourseid="entpcourseid" :rows="rowsList" @on-close="closeHomework" @on-success="successHomework"/>
</div>
</template>
<script setup>
import { onMounted, ref,watch, reactive, getCurrentInstance,nextTick } from 'vue'
import { ElMessage } from 'element-plus'
import { cloneDeep } from 'lodash'
import { delClasswork } from '@/api/teaching/classwork'
import {listEntpcoursework, listEntpcourseworkNew, getEntpcoursework} from '@/api/education/entpCourseWork'
import { addClassworkReturnId } from '@/api/teaching/classwork'
import { updateClasswork, listEvaluationclue, listClassworkeval,delClassworkeval,addClassworkeval,updateClassworkeval } from '@/api/classTask'
import { processList } from '@/hooks/useProcessList'
import { editListItem } from '@/hooks/useClassTask'
import MyQuestion from '@/views/classTask/newClassTaskAssign/myQuestion/index.vue'
import SchoolQuestion from '@/views/classTask/newClassTaskAssign/schoolQuestion/index.vue'
import SearchQuestion from '@/views/classTask/newClassTaskAssign/searchQuestion/index.vue'
import whiteboard from '@/components/whiteboard/whiteboard.vue'
import FileUpload from "@/components/FileUpload/index.vue";
import Right from './Right/index.vue'
import SetHomework from '@/components/set-homework/index.vue'
import { useGetHomework } from '@/hooks/useGetHomework'
import { sessionStore } from '@/utils/store'
import { useRouter, useRoute } from 'vue-router'
import useUserStore from '@/store/modules/user'
const userStore = useUserStore().user
const route = useRoute();
const { proxy } = getCurrentInstance()
const props = defineProps({
})
const propsQueryCourseObj = route.query.courseObj;//
const courseObj = reactive({
// : id,id,id,
textbookId: '',
levelFirstId: '',
levelSecondId: '',
coursetitle:'',
node: null, //
//
})
const taskTable = ref(null);
const activeAptTab = ref("自主搜题");
const taskList = ref([]); //
const tasklist_loading = ref(false); //
const classWorkFormRef = ref(null);
//
const setDialog = ref(false); //
const rowsList = ref([]) //
const entpcourseid = ref('') // id
const currentRow = ref({id:0}); // --
// -------
const boardLoading = ref(false);
//----------
const fileLoading = ref(false); // loading
onMounted(() => {
currentRow.value = {id:0};
console.log('propsQueryCourseObj', JSON.parse(propsQueryCourseObj));
if(propsQueryCourseObj&&JSON.parse(propsQueryCourseObj)){
courseObj.textbookId = JSON.parse(propsQueryCourseObj).bookObj //
courseObj.levelFirstId = JSON.parse(propsQueryCourseObj).levelFirstId //
courseObj.levelSecondId = JSON.parse(propsQueryCourseObj).levelSecondId //
courseObj.coursetitle = JSON.parse(propsQueryCourseObj).coursetitle // (/)
courseObj.node = JSON.parse(propsQueryCourseObj).node; //
}
initHomeWork();
})
//------------
const handleItemClick = (itemName) => {
console.log('itemName', itemName);
currentRow.value = {id:1}; //
/**
* 智能推荐AI设计作业
* 习题训练 自主搜题 校本题库 个人题库
* 课堂展示
* 常规作业
*/
const typeName = itemName == "自主搜题" || itemName == "校本题库"|| itemName == "个人题库" ? "习题训练" : itemName;
activeAptTab.value = itemName;
//
classWorkForm.id = 0;
classWorkForm.uniquekey = ""; //
classWorkForm.worktype = typeName; //
classWorkForm.title = ""; //
classWorkForm.quizlist = []; //
classWorkForm.chooseWorkLists = []; // list
classWorkForm.fileHomeworkList = []; //
classWorkForm.whiteboardObj = ""; // -
classWorkForm.question = ""; // -
}
//-----------------------
const selectable=(row, index)=>{
return row.status == '10';
};
/**
* 获取 entpcourseid 获取作业列表
*/
const initHomeWork = async()=> {
tasklist_loading.value = true;
// const { res, chapterId } = await useGetHomework(courseObj.node);
const { res, chapterId } = await useGetHomework(sessionStore.get('subject.curNode'));
console.log('entpcourseid', chapterId);
console.log('res', res);
entpcourseid.value = chapterId;
taskList.value = res;
tasklist_loading.value = false;
}
const handleNewAllClass = () => {
taskTable.value.setCurrentRow({});//
currentRow.value = {id:0}; //
//--------
classWorkForm.id = 0;
classWorkForm.uniquekey = ""; //
classWorkForm.worktype = ''; //
classWorkForm.title = ""; //
classWorkForm.quizlist = []; //
classWorkForm.chooseWorkLists = []; // list
classWorkForm.fileHomeworkList = []; //
classWorkForm.whiteboardObj = ""; // -
classWorkForm.question = ""; // -
}
/**
* 删除按钮操作
* */
const handleDelete =() => {
let rows = proxy.$refs.taskTable.getSelectionRows();
if (rows.length > 0) {
proxy.$modal.confirm('是否确认选中的学习任务?').then(()=> {
let ids = [];
for (let i = 0; i < rows.length; i++) {
ids.push(rows[i].id);
}
return delClasswork(ids.join(','));
}).then(() => {
taskTable.value.setCurrentRow({});//
currentRow.value = {id:0}; //
taskList.value = [];
// initHomeWork();
setTimeout(() => {
initHomeWork();
}, 1500);
proxy.$modal.msgSuccess("删除成功");
}).catch(() => {})
}else{
proxy.$modal.alertWarning("请选择删除项")
}
};
/**
* 一键推送
*/
const handleTaskAssignToAllClass = () => {
let rows = proxy.$refs.taskTable.getSelectionRows();
if (rows.length > 0) {
proxy.$modal.confirm('是否确认推送选中的学习任务?').then(()=> {
}).then(() => {
//
openSet(rows,'list');
}).catch(() => {})
}else{
return proxy.$modal.alertWarning("请选择需要推送的任务!");
}
}
/**
* 推送作业配置
* //list
*/
//
const openSet=(row, type)=> {
if(type == 'list'){
// row rows
rowsList.value = row;
setDialog.value = true;
}else{
// row row,
rowsList.value = [row];
setDialog.value = true;
}
}
/**
* 关闭布置作业窗口
*/
const closeHomework = () => {
rowsList.value = [];
setDialog.value = false;
}
/**
* 推送布置作业成功
*/
const successHomework = () => {
rowsList.value = [];
setDialog.value = false;
//
nextTick(() => {
initHomeWork();
})
}
// --------------------
let classWorkForm = reactive({
id: '',// cloneDeep(props.propsformobj.id),
uniquekey: '',// props.propsformobj.uniquekey?cloneDeep(props.propsformobj.uniquekey):'', //
worktype: '',// props.propsformobj.worktype?cloneDeep(props.propsformobj.worktype): '', //
title: '',// props.propsformobj.title?cloneDeep(props.propsformobj.title):'',//
quizlist: [],// props.propsformobj.quizlist?cloneDeep(props.propsformobj.quizlist):[], //
chooseWorkLists: [],// props.propsformobj.chooseWorkLists?cloneDeep(props.propsformobj.chooseWorkLists):[], // list
fileHomeworkList: [],// props.propsformobj.fileHomeworkList?cloneDeep(props.propsformobj.fileHomeworkList):[], //
whiteboardObj: '',// props.propsformobj.whiteboardObj?cloneDeep(props.propsformobj.whiteboardObj):'', // -
question: '',// props.propsformobj.question?cloneDeep(props.propsformobj.question):'', // -
}); //
let propsformobj = reactive({
id: '',// cloneDeep(props.propsformobj.id),
uniquekey: '',// props.propsformobj.uniquekey?cloneDeep(props.propsformobj.uniquekey):'', //
worktype: '',// props.propsformobj.worktype?cloneDeep(props.propsformobj.worktype): '', //
title: '',// props.propsformobj.title?cloneDeep(props.propsformobj.title):'',//
quizlist: [],// props.propsformobj.quizlist?cloneDeep(props.propsformobj.quizlist):[], //
chooseWorkLists: [],// props.propsformobj.chooseWorkLists?cloneDeep(props.propsformobj.chooseWorkLists):[], // list
fileHomeworkList: [],// props.propsformobj.fileHomeworkList?cloneDeep(props.propsformobj.fileHomeworkList):[], //
whiteboardObj: '',// props.propsformobj.whiteboardObj?cloneDeep(props.propsformobj.whiteboardObj):'', // -
question: '',// props.propsformobj.question?cloneDeep(props.propsformobj.question):'', // -
}); //
/***
* 选中的布置作业行
*/
const handleCurrentChange = (val) => {
console.log(val,'???????????')
if(val && val.id >0 ) {
currentRow.value = val;
editListItem(val, courseObj).then((obj) => {
if(obj){
propsformobj = obj;
//
classWorkForm.id = obj.id;
classWorkForm.uniquekey = cloneDeep(obj.uniquekey); //
classWorkForm.worktype = cloneDeep(obj.worktype); //
classWorkForm.title = cloneDeep(obj.title); //
classWorkForm.quizlist = cloneDeep(obj.quizlist); //
classWorkForm.chooseWorkLists = cloneDeep(obj.chooseWorkLists); // list
classWorkForm.fileHomeworkList = cloneDeep(obj.fileHomeworkList); //
classWorkForm.whiteboardObj = cloneDeep(obj.whiteboardObj); // -
classWorkForm.question = cloneDeep(obj.question); // -
}
});
}
}
/**
* 添加作业
* @param entpcourseworkid
*/
const handleClassWorkQuizAdd = (entpcourseworkid) => {
var exist = false;
for (var i=0; i< classWorkForm.quizlist.length; i++) {
if (classWorkForm.quizlist[i].id == entpcourseworkid) {
exist = true;
break;
}
}
if (exist == false) {
getEntpcoursework(entpcourseworkid).then(res => {
//res.data.titletext = res.data.title.replace(/<[^>]+>/g, '');
//
if(res.data.score == null){
res.data.score = 4;
}
classWorkForm.quizlist.push(res.data);
//
processList(classWorkForm.quizlist);
})
} else {
ElMessage('试题已经存在')
}
}
/** 右侧资源删除按钮 习题list */
const handleClassWorkFormQuizRemove = (index) =>{
classWorkForm.quizlist.splice(index, 1);
}
/**
* 作业设计-提交
*/
const handleClassWorkSave = async () => {
await nextTick(); // DOM
proxy.$refs["classWorkFormRef"].validate(async valid => {
if (valid) {
//
// const { chapterId } = await useGetHomework(courseObj.node)
// this.entpcourseid = chapterId
const cform = {
id: 0,
workdate: classWorkForm.workdate, // //web
deaddate: '', //
entpid: userStore.deptId, //
level: 1,
parentid: 0,
worktype: classWorkForm.worktype, //
workkey: '',
worktag: '',
uniquekey: classWorkForm.uniquekey,//
classid: 0,
classcourseid: 0,
entpcourseid: entpcourseid.value, //
slideid: 0,
title: classWorkForm.title, //
workcodes: JSON.stringify(classWorkForm.workcodes), //
edusubject: userStore.edusubject, //
evalid: courseObj.levelSecondId, //userStore.evalid, // // ID
edustage: userStore.edustage, // ,,
status: '10', //2024-09-11
edituserid: userStore.userId, // id
entpcourseworklist: '', // list
};
// [] newWorkSpaceEdit true
if(classWorkForm.id != '' ) {// id
editWork(cform); //
return;
}
if (classWorkForm.worktype === "课堂展示") {
boardLoading.value = true
let canvasJson = proxy.$refs.boardref.getCanvasJson()
let canvasBase64 = await proxy.$refs.boardref.getCanvasBase64()
//
cform.worktag = classWorkForm.question;
cform.title = classWorkForm.title;
cform.workcodes = JSON.stringify({json: canvasJson, base64: canvasBase64});
cform.entpcourseworklist = JSON.stringify([{'id':-1, 'score': '10'}]);
try {
addClassworkReturnId(cform).then(() => {
ElMessage({ type: 'success', message: '作业设计成功!'});
//
classWorkForm.worktype = "课堂展示";
classWorkForm.uniquekey = '';// classWorkForm.uniquekey, //
classWorkForm.title = "";
classWorkForm.question = "";
classWorkForm.quizlist = [], //
//
classWorkForm.chooseWorkLists = []; // list
classWorkForm.whiteboardObj = ''; // ? //
boardLoading.value = false
})
} finally {
boardLoading.value = false
}
}
else if(classWorkForm.worktype === "常规作业"){
fileLoading.value = true
cform.workcodes = JSON.stringify(classWorkForm.fileHomeworkList);
cform.entpcourseworklist = JSON.stringify([{'id':-2, 'score': '10'}]);
try {
addClassworkReturnId(cform).then(() => {
ElMessage({ type: 'success', message: '作业设计成功!'});
//
classWorkForm.worktype = "常规作业";
classWorkForm.uniquekey = ''; // props.propsformobj.uniquekey, //
classWorkForm.title = "";
classWorkForm.quizlist = [], //
//
classWorkForm.chooseWorkLists = []; // list
classWorkForm.whiteboardObj = ''; // ? //
classWorkForm.fileHomeworkList = []; // list
fileLoading.value = false
})
} finally {
fileLoading.value = false
}
}
else {
//
var ll = [];
if (classWorkForm.worktype === "习题训练") {
for (var i=0; i< classWorkForm.quizlist.length; i++) {
//
ll.push({'id': classWorkForm.quizlist[i].id, 'score': classWorkForm.quizlist[i].score});
}
}else if( classWorkForm.worktype === "框架梳理") {
classWorkForm.chooseWorkLists.filter((item) => {
if (item.worktype === classWorkForm.worktype) {
ll.push({'id':item.id, 'score': item.score});
}
})
}
// list
if (ll.length > 0) {
cform.entpcourseworklist = JSON.stringify(ll);
} else {
cform.entpcourseworklist = '';
}
console.log(cform,'提交的数据');
if(cform.entpcourseworklist == '') return ElMessage({ type: 'warning', message: '请先添加作业资源!'});
addClassworkReturnId(cform).then(workres => {
ElMessage({ type: 'success', message: '作业设计成功!'});
//
classWorkForm.worktype = "习题训练";
classWorkForm.uniquekey = '',// props.propsformobj.uniquekey, //
classWorkForm.title = "";
classWorkForm.quizlist = [], //
//
classWorkForm.chooseWorkLists = [];
classWorkForm.whiteboardObj = ''; // ? //
// refresh the list
//
// this.getClassWorkAllList();
})
}
console.log('该清空左侧列表数据了');
//
currentRow.value = {id:0};
initHomeWork();
// if(props.isback){
// //
// router.back();
// }else{
// //
// router.push({ path: '/classTaskAssign' });
// }
}
});
};
/**
* 编辑作业内容
* @param cform 表单数据
*/
const editWork = async (cform) =>{
//
cform.id= classWorkForm.id;
// 0.
if (classWorkForm.worktype == '习题训练') {
if (classWorkForm.quizlist.length == 0) {
ElMessage.error('请先添加作业资源!');
return;
}
}else if (classWorkForm.worktype == '课堂展示' || classWorkForm.worktype == '常规作业') {
//
}else {
if (classWorkForm.chooseWorkLists.length == 0) {
//
ElMessage.error('请先添加作业资源!');
return;
}
}
//
if (classWorkForm.worktype=='习题训练'){
// 1.
let needUplEval = false;
if (classWorkForm.quizlist.length != propsformobj.quizlist.length) {
needUplEval = true;
}else {
//
needUplEval = classWorkForm.quizlist.some(cur =>
!propsformobj.quizlist.some(last =>
last.id === cur.id && last.score === cur.score
)
);
}
// 2.eval
if (needUplEval) {
// : , ,
// 2.1.workidid
let arrEvalids = [];
const wevalres = await listClassworkeval({'workid': classWorkForm.id});
wevalres.rows.forEach(element => {
arrEvalids.push(element.id);
});
const ids = arrEvalids.join(',');
// 2.2.
const delRes = await delClassworkeval(ids);
// 2.3.
for(let i=0; i< classWorkForm.quizlist.length; i++){
const addRes = await addClassworkeval({
'workid': classWorkForm.id,
'entpcourseworkid': classWorkForm.quizlist[i].id,
'workdataid': 0,
'score': classWorkForm.quizlist[i].score}
);
}
}
// 3.-
}
else if (classWorkForm.worktype=='框架梳理') {
// 1.workidid
const wevalres = await listClassworkeval({'workid': classWorkForm.id});
if (wevalres.rows.length == 0) {
ElMessage.error('未找到原框架梳理任务,请或退出重试');
return;
}
// 2.
let needUplEval = false;
if (classWorkForm.chooseWorkLists.length !== propsformobj.chooseWorkLists.length) {
needUplEval = true;
}else {
//
needUplEval = classWorkForm.chooseWorkLists.some(cur =>
!propsformobj.chooseWorkLists.some(last =>
last.id === cur.id && last.score === cur.score
)
);
}
if (needUplEval) {
const uplParams = {
id: wevalres.rows[0].id,
entpcourseworkid: classWorkForm.chooseWorkLists[0].id,
score: classWorkForm.chooseWorkLists[0].score,
}
//
let res = await updateClassworkeval(uplParams);
}
}
else if (classWorkForm.worktype=='课堂展示') {
let canvasJson = proxy.$refs.boardref.getCanvasJson()
let canvasBase64 = await proxy.$refs.boardref.getCanvasBase64()
cform.workcodes = JSON.stringify({json: canvasJson, base64: canvasBase64});
cform.worktag = classWorkForm.question;
}
else if (classWorkForm.worktype=='常规作业') {
// 1. (, )
cform.workcodes = JSON.stringify(classWorkForm.fileHomeworkList);
}
// 3.
let res = await updateClasswork(cform);
if (res.code == 200) {
ElMessage.success('更新成功');
//
currentRow.value = {id:0};
initHomeWork();
// //
// router.back()
}
}
//----
</script>
<style scoped lang="scss">
.page {
height: 100%;
.page-top {
height: 50px;
margin-bottom: 5px;
padding: 0 10px;
display: flex;
justify-content: space-between;
background-color: white;
border-radius: 10px;
box-shadow: 0px 0px 20px 0px rgba(99, 99, 99, 0.06);
align-items: center;
}
.page-resource {
user-select: none;
height: calc(100% - 55px);
display: flex;
flex-direction: row;
flex-wrap: nowrap;
:deep(.el-tabs__nav) {
.el-tabs__item{
font-weight: bold;
font-size: 18px;
}
}
.page-left {
width: 300px;
background-color: white;
border-radius: 10px;
box-shadow: 0px 0px 20px 0px rgba(99, 99, 99, 0.06);
.pageleft-table-top {
height: 35px;
display: flex;
justify-content: space-between;
align-items: center;
}
.pageleft-table-cont {
height: 35px;
// width: 100%;
// text-align: justify;
// display: flex;
// overflow: hidden;
// flex-direction: row;
// text-overflow: ellipsis;
width: 230px; /* 设置容器的宽度 */
overflow: hidden; /* 隐藏超出容器的部分 */
white-space: nowrap; /* 防止文本换行 */
text-overflow: ellipsis; /* 超出部分显示省略号 */
.ellipsis {
width: 100%;
text-align: left;
}
}
}
.page-center{
flex: 1;
// width: 100%;
height: 100%;
padding: 0 5px;
margin: 0 5px;
overflow: hidden;
border-radius: 10px;
background-color: white;
.prepare-center-zzst{
height: 100%;
display: flex;
flex-direction: column;
}
.prepare-center-xbtk{
height: 100%;
}
.prepare-center-grst{
height: 100%;
}
.upload-homework{
padding: 20px;
box-sizing: border-box;
}
}
.page-right {
overflow: hidden;
position: relative;
min-width: 375px;
width: 375px;
height: 100%;
background: #ffffff;
border-radius: 10px;
box-shadow: 0px 0px 20px 0px rgba(99, 99, 99, 0.06);
display: flex;
flex-direction: column;
.prepare-top {
display: flex;
height: 40px;
margin: 0 10px;
border-bottom: 2px solid #e5e7eb;
align-items: center;
justify-content: flex-end;
}
.prepare-con{
height: 100%;
padding: 5px 10px;
overflow: hidden;
display: flex;
flex-direction: column;
.pageRight-list {
height: 100%;
padding: 0 0 0 5px;
overflow: auto;
line-height: 26px;
overflow: hidden;
}
}
}
}
}
</style>

View File

@ -0,0 +1,420 @@
<template>
<div class="page">
<!-- 习题筛选1 -->
<el-row style="width: 100%; height: 50px;">
<el-col :span="7">
<el-form-item label="题型" label-width="70">
<el-select v-model="entpCourseWorkQueryParams.worktype" placeholder="请选择" >
<el-option v-for="(item, index) in entpCourseWorkTypeList" :key="index" :label="item.label" :value="item">
</el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="7">
<el-form-item label="题源" label-width="70">
<el-select v-model="entpCourseWorkQueryParams.workgroup" placeholder="请选择" >
<el-option v-for="(item, index) in entpCourseWorkGroupList" :key="index" :label="item.Value" :value="item.Key" ></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="7">
<el-form-item label="年份" label-width="70">
<el-select v-model="entpCourseWorkQueryParams.yearStr" placeholder="请选择" >
<el-option v-for="(item, index) in entpCourseWorkYearList" :key="index" :label="item.label" :value="item.value"></el-option>
</el-select>
</el-form-item>
</el-col>
</el-row>
<!-- 习题筛选2 -->
<el-row style="width: 100%; height: 50px;">
<el-col :span="12">
<el-form-item label="关键词" label-width="70">
<el-input
v-model="entpCourseWorkQueryParams.keyWord"
type="text"
placeholder="请输入关键词"
/>
</el-form-item>
</el-col>
<el-col :span="5">
<el-button @click="handleQueryParamFromEntpCourseWork(1)"><el-icon><Search /></el-icon> </el-button>
</el-col>
</el-row>
<!-- 习题表格 -->
<div class="page-table" >
<el-table
:data="workResource.entpCourseWorkList"
style="width: 100%; height: calc(100% - 55px);"
v-loading="pageParams.loading"
>
<el-table-column type="index" width="60" />
<el-table-column align="left" >
<template #header>
<div style="display: flex">
<div style="align-items: center;">题目内容</div>
</div>
</template>
<template #default="scope">
<div @click="showExamAnalyseDrawer(scope.row)">
<div style="overflow: hidden; text-overflow: ellipsis" v-html="scope.row.titleFormat"></div>
<div style="overflow: hidden; text-overflow: ellipsis; font-size: 0.9em; margin-top: 6px;" v-html="scope.row.workdescFormat"></div>
<el-col :span="24" style="display: flex">
<div style="font-size: 1em; color: silver; padding-top: 5px">{{ scope.row.entpname }} {{ scope.row.editusername }}</div>
<div style="margin-left: 30px; font-size: 1em; color: silver; padding-top: 5px">{{ scope.row.worktag }}</div>
</el-col>
</div>
</template>
</el-table-column>
<el-table-column width="100">
<template #default="scope">
<div>
<el-button type="primary" @click="handleClassWorkQuizAdd('entpcourseworklist', scope.row.id)">添加</el-button>
<div style="padding: 5px;"></div>
<el-button type="danger" @click="handleDelete(scope.row, scope.$index)">删除</el-button>
</div>
</template>
</el-table-column>
</el-table>
<!-- 分页-->
<div style="height: 55px;">
<el-pagination
v-show="workResource.entpCourseWorkTotal > 0"
v-model:page="paginationParams.pageNum"
v-model:limit="paginationParams.pageSize"
:total="workResource.entpCourseWorkTotal"
:style="{ position: 'relative', 'margin-top': '5px' }"
@change="getPaginationList" />
</div>
</div>
<!-- 试题详细信息 -->
<examDetailsDrawer ref="examDetailsDrawerRef"></examDetailsDrawer>
</div>
</template>
<script setup>
import { onMounted, ref,watch, reactive, getCurrentInstance,nextTick } from 'vue'
import { listEntpcoursework } from '@/api/education/entpCourseWork'
import { listEvaluationclue } from '@/api/classTask'
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 useUserStore from '@/store/modules/user'
// emit
const emit = defineEmits(['addQuiz'])
const { proxy } = getCurrentInstance()
const userStore = useUserStore().user
const props = defineProps({
bookobj: {
type: Object,
default: () => ({})
},
})
const entpCourseWorkTypeList = ref([
{value: 0, label: "不限"},
{value: 1, label: "单选题"},
{value: 2, label: "填空题"},
{value: 3, label: "多选题"},
{value: 4, label: "判断题"},
{value: 5, label: "主观题"},
{value: 6, label: "复合题"},
]); // -
const entpCourseWorkGroupList = ref([{
Key: -1,
Value: '不限',
}, {
Key: 1,
Value: '真题',
}, {
Key: 0,
Value: '非真题',
}]); // -
const knowledgePointProps = ref({value: 'thirdId', label: 'title'});
const entpCourseWorkYearList =ref([
{label: '不限', value: '-1'},
{label: '2024', value: '2024'},
{label: '2023', value: '2023'},
{label: '2022', value: '2022'},
{label: '2021', value: '2021'},
{label: '2020', value: '2020'},
]); // -
//
const entpCourseWorkQueryParams = reactive({
worktype: {
label: '不限',
value: 0,
},
workgroup: 0,
yearStr: '-1',
point: [],
keyWord: '',
});
const paginationParams = reactive({
pageNum: 1,
pageSize: 10,
}); //
const pageParams = ref({
loading: false, //
originCount: 0, //
isFirst: true, //
total: 0,
})
const workResource = reactive({
options: ['学习任务', '云题库'],
worktype: '全部',
activeIndex: "3",
dialogOfTaskOpen: false,
dislogOfAssignOpen: false,
quiztype: '',
queryForm: {},
classWorkList: [], //
entpCourseWorkList: [], //
entpCourseWorkTotal: 0, //
}); //
onMounted(() => {
debounceQueryData(); //
})
const initPageParams = () => {
//
workResource.entpCourseWorkList = [];
workResource.entpCourseWorkTotal = 0
//
pageParams.value.loading = false;
pageParams.value.isFirst = true;
pageParams.value.originCount = 0;
pageParams.value.total = 0;
//
paginationParams.pageNum = 1;
paginationParams.pageSize = 10;
}
/**
* @desc: 1习题训练 - 新查询试题
* @return: {*}
* @param {*} queryType
* 0 - 标准查询
* 1 - 按条件查询
* 2 - 按关键词查询
*/
let obj = {};
function Apis(key) {
obj[key] = [];
return function(task) {
return new Promise((resolve, reject) => {
obj[key].push(task);
Promise.all([...obj[key]]).then(res => {
const i = obj[key].findIndex(item => {
return item == task;
});
resolve(obj[key][i]);
//arr.splice(i, 1);
})
})
}
}
const client = new Apis('/paht');
const t = function(name, time) {
return new Promise(resolve => {
const queryForm = {
//
worktype: entpCourseWorkQueryParams.worktype.label == '不限' ? '' : entpCourseWorkQueryParams.worktype.label,
// TODO web
// workgroup: entpCourseWorkQueryParams.workgroup,
// TODO web
// yearStr: entpCourseWorkQueryParams.yearStr !== '-1' ? entpCourseWorkQueryParams.yearStr:'',
//
title: entpCourseWorkQueryParams.keyWord && entpCourseWorkQueryParams.keyWord !== '' ? entpCourseWorkQueryParams.keyWord:'',
//
pageNum: paginationParams.pageNum,
pageSize: paginationParams.pageSize,
//
edustage: userStore.edustage, // this.userStore.edustage,
edusubject: userStore.edusubject, // this.userStore.edusubject,
evalid: props.bookobj.levelSecondId, // this.activeParams.lession.id,
orderby: 'concat(worktype,timestamp) DESC',
}
const entpcourseworkres = listEntpcoursework(queryForm);
resolve(entpcourseworkres);
})
}
const handleQueryFromEntpCourseWork= async (queryType) => {
pageParams.value.loading = true;
client(t('任务1', 1500)).then(res => {
const data = res.rows || [];
if(data && data.length>0){
// data.forEach(item=> {
// if (item.worktype == '') {
// item.worktype = ''
// }
// })
//
processList(data);
workResource.entpCourseWorkList = data;
workResource.entpCourseWorkTotal = res.total;
}
pageParams.value.loading = false;
});
}
//
/**
* 2框架设计教学资源从课标分析教材分析里来
*/
const getQueryFromEvaluationclue = () => {
// props.bookobj.levelSecondId, //userStore.evalid, // // ID
listEvaluationclue({ cluegroup: 'teachresource', evalid: props.bookobj.levelSecondId, pageSize: 1000 }).then((clueres) => {
for (var i=0; i<clueres.rows.length; i++) {
if (clueres.rows[i].cluetag == 'standardview') {
clueres.rows[i].worktype = '课标研读';
} else if (clueres.rows[i].cluetag == 'targetview') {
clueres.rows[i].worktype = '目标设定';
} else if (clueres.rows[i].cluetag == 'contentview') {
clueres.rows[i].worktype = '教材研读';
} else if (clueres.rows[i].cluetag == 'frameview') {
clueres.rows[i].worktype = '框架梳理';
} else if (clueres.rows[i].cluetag == 'mapview') {
clueres.rows[i].worktype = '学科定位';
}
console.log("clueres.rows[i].childlist",clueres.rows[i].childlist);
if (clueres.rows[i].childlist != '') {
clueres.rows[i].childArray = JSON.parse('['+clueres.rows[i].childlist+']');
for (var j=0; j<clueres.rows[i].childArray.length; j++) {
clueres.rows[i].childArray[j].title = clueres.rows[i].childArray[j].title.replace(/(<([^>]+)>)/ig, '');
}
} else {
clueres.rows[i].childArray = {};
}
}
console.log("框架梳理、课标研读、目标设定、教材研读、学科定位的资源",clueres.rows);
workResource.teachResourceList = clueres.rows;
})
}
/**
* @desc: 根据查询参数查询试题
* @return: {*}
* @param {*} queryType
* 1 - 按条件查询
* 2 - 按关键词查询
*/
const handleQueryParamFromEntpCourseWork = (queryType) => {
//
// this.paginationParams = {pageNum: 1,pageSize: 10};
//
initPageParams();
handleQueryFromEntpCourseWork(queryType);
};
/**
* 查看试题详细信息
* @param row 单题数据
*/
const showExamAnalyseDrawer = (row) => {
nextTick(() => {
const activeParams = {
activeExam: row,
}
proxy.$refs.examDetailsDrawerRef.acceptParams(activeParams);
})
}
const getPaginationList = ( page, limit ) => {
paginationParams.pageNum = page;
paginationParams.pageSize = limit;
console.log(page, limit)
handleQueryFromEntpCourseWork(0);
}
/** 删除题目按钮操作 */
const handleDelete = async(item, index) => {
await useHandleData(delEntpcoursework, item.id, `确认删除编号为【${index+1}】的题目?` );
debounceQueryData();
}
/**
* 添加资源
* @param fromsrc - 试题来源
* @param entpcourseworkid
*/
const handleClassWorkQuizAdd = (fromsrc, entpcourseworkid) => {
emit('addQuiz', entpcourseworkid);
// var exist = false;
// for (var i=0; i< classWorkForm.quizlist.length; i++) {
// if (classWorkForm.quizlist[i].id == entpcourseworkid) {
// exist = true;
// break;
// }
// }
// if (exist == false) {
// getEntpcoursework(entpcourseworkid).then(res => {
// //res.data.titletext = res.data.title.replace(/<[^>]+>/g, '');
// //
// if(res.data.score == null){
// res.data.score = 4;
// }
// classWorkForm.quizlist.push(res.data);
// //
// processList(classWorkForm.quizlist);
// })
// } else {
// ElMessage('')
// }
};
//
const debounceQueryData = debounce(() => {
console.log("防抖 加载数据中...")
//
initPageParams();
// //
handleQueryFromEntpCourseWork(0);
// //
// getQueryFromEvaluationclue();
}, 1000);
watch(() => props.bookobj.levelSecondId, (newVal, oldVal) => {
console.log(props.bookobj,'课程选择')
debounceQueryData();
})
</script>
<style scoped lang="scss">
.page {
height: 100%;
display: flex;
flex-direction: column;
.page-table {
width: 100%;
height: calc(100% - 100px);
}
}
</style>
<style src="@/assets/styles/JYStyle.css"></style>

View File

@ -0,0 +1,34 @@
<template>
<div class="page">
校本题库
</div>
</template>
<script setup>
import { onMounted, ref,watch, reactive, getCurrentInstance,nextTick } from 'vue'
import { delClasswork } from '@/api/teaching/classwork'
import { useGetHomework } from '@/hooks/useGetHomework'
import { sessionStore } from '@/utils/store'
const { proxy } = getCurrentInstance()
const props = defineProps({
// courseObj: {
// type: Object,
// default: () => ({})
// }
})
onMounted(() => {
})
</script>
<style scoped lang="scss">
.page {
height: 100%;
}
</style>

View File

@ -0,0 +1,498 @@
<template>
<div class="page">
<!-- 习题筛选1 -->
<el-row style="width: 100%; height: 50px;">
<el-col :span="7">
<el-form-item label="题型" label-width="70">
<el-select v-model="entpCourseWorkQueryParams.worktype" placeholder="请选择" >
<el-option v-for="(item, index) in entpCourseWorkTypeList" :key="index" :label="item.label" :value="item">
</el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="7">
<el-form-item label="题源" label-width="70">
<el-select v-model="entpCourseWorkQueryParams.workgroup" placeholder="请选择" >
<el-option v-for="(item, index) in entpCourseWorkGroupList" :key="index" :label="item.Value" :value="item.Key" ></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="10">
<el-form-item label="知识点" label-width="70">
<el-cascader
v-model="entpCourseWorkQueryParams.point"
clearable
style="width: 100%"
:options="entpCourseWorkPointList"
:props="knowledgePointProps"
popper-class="my-popper"
:show-all-levels="false"
collapse-tags
collapse-tags-tooltip
/>
</el-form-item>
</el-col>
</el-row>
<!-- 习题筛选2 -->
<el-row style="width: 100%; height: 50px;">
<el-col :span="7">
<el-form-item label="年份" label-width="70">
<el-select v-model="entpCourseWorkQueryParams.yearStr" placeholder="请选择" >
<el-option v-for="(item, index) in entpCourseWorkYearList" :key="index" :label="item.label" :value="item.value"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="关键词" label-width="70">
<el-input
v-model="entpCourseWorkQueryParams.keyWord"
type="text"
placeholder="请输入关键词"
/>
</el-form-item>
</el-col>
<el-col :span="5">
<el-button @click="handleQueryParamFromEntpCourseWork(1)"><el-icon><Search /></el-icon> </el-button>
</el-col>
</el-row>
<!-- 习题表格 -->
<div class="page-table" >
<el-table
:data="workResource.entpCourseWorkList"
style="width: 100%; height: calc(100% - 55px);"
v-loading="pageParams.loading"
>
<el-table-column type="index" width="60" />
<el-table-column align="left" >
<template #header>
<div style="display: flex">
<div style="align-items: center;">题目内容</div>
</div>
</template>
<template #default="scope">
<div @click="showExamAnalyseDrawer(scope.row)">
<div style="overflow: hidden; text-overflow: ellipsis" v-html="scope.row.titleFormat"></div>
<div style="overflow: hidden; text-overflow: ellipsis; font-size: 0.9em; margin-top: 6px;" v-html="scope.row.workdescFormat"></div>
<el-col :span="24" style="display: flex">
<div style="font-size: 1em; color: silver; padding-top: 5px">{{ scope.row.entpname }} {{ scope.row.editusername }}</div>
<div style="margin-left: 30px; font-size: 1em; color: silver; padding-top: 5px">{{ scope.row.worktag }}</div>
</el-col>
</div>
</template>
</el-table-column>
<el-table-column align="left" width="100">
<template #default="scope">
<el-button type="primary" @click="handleClassWorkQuizAdd('entpcourseworklist', scope.row.id)">添加</el-button>
</template>
</el-table-column>
</el-table>
<!-- 分页-->
<div style="height: 55px;">
<el-pagination
v-show="pageParams.total > 0"
v-model:page="paginationParams.pageNum"
v-model:limit="paginationParams.pageSize"
:total="pageParams.total"
:style="{ position: 'relative', 'margin-top': '5px' }"
@change="getPaginationList" />
</div>
</div>
<!-- 试题详细信息 -->
<examDetailsDrawer ref="examDetailsDrawerRef"></examDetailsDrawer>
</div>
</template>
<script setup>
import { onMounted, ref,watch, reactive, getCurrentInstance,nextTick } from 'vue'
import {listEntpcoursework, listEntpcourseworkNew, getEntpcoursework} from '@/api/education/entpCourseWork'
import { updateClasswork, listEvaluationclue, listClassworkeval,delClassworkeval,addClassworkeval,updateClassworkeval } from '@/api/classTask'
import { listEvaluation } from '@/api/subject'
import { listKnowledgePoint } from "@/api/knowledge/knowledgePoint";
import examDetailsDrawer from '@/components/exam-question/examDetailsDrawer.vue'
import { processList } from '@/hooks/useProcessList'
import { useGetHomework } from '@/hooks/useGetHomework'
import { sessionStore } from '@/utils/store'
import {throttle,debounce } from '@/utils/comm'
import useUserStore from '@/store/modules/user'
// emit
const emit = defineEmits(['addQuiz'])
const { proxy } = getCurrentInstance()
const userStore = useUserStore().user
const props = defineProps({
bookobj: {
type: Object,
default: () => ({})
},
})
const entpCourseWorkTypeList = ref([
{value: 0, label: "不限"},
{value: 1, label: "单选题"},
{value: 2, label: "填空题"},
{value: 3, label: "多选题"},
{value: 4, label: "判断题"},
{value: 5, label: "主观题"},
{value: 6, label: "复合题"},
]); // -
const entpCourseWorkGroupList = ref([{
Key: -1,
Value: '不限',
}, {
Key: 1,
Value: '真题',
}, {
Key: 0,
Value: '非真题',
}]); // -
const entpCourseWorkPointList = ref([
{label: '不限', value: []},
]); // -
const knowledgePointProps = ref({value: 'thirdId', label: 'title'});
const entpCourseWorkYearList =ref([
{label: '不限', value: '-1'},
{label: '2024', value: '2024'},
{label: '2023', value: '2023'},
{label: '2022', value: '2022'},
{label: '2021', value: '2021'},
{label: '2020', value: '2020'},
]); // -
//
const entpCourseWorkQueryParams = reactive({
worktype: {
label: '不限',
value: 0,
},
workgroup: 0,
yearStr: '-1',
point: [],
keyWord: '',
});
const paginationParams = reactive({
pageNum: 1,
pageSize: 10,
}); //
const pageParams = ref({
loading: false, //
originCount: 0, //
isFirst: true, //
total: 0,
})
const workResource = reactive({
options: ['学习任务', '云题库'],
worktype: '全部',
activeIndex: "3",
dialogOfTaskOpen: false,
dislogOfAssignOpen: false,
quiztype: '',
queryForm: {},
classWorkList: [], //
entpCourseWorkList: [], //
entpCourseWorkTotal: 0, //
}); //
onMounted(() => {
debounceQueryData(); //
})
const initPageParams = () => {
//
workResource.entpCourseWorkList = [];
workResource.entpCourseWorkTotal = 0
//
pageParams.value.loading = false;
pageParams.value.isFirst = true;
pageParams.value.originCount = 0;
pageParams.value.total = 0;
//
paginationParams.pageNum = 1;
paginationParams.pageSize = 10;
}
/**
* @desc: 1习题训练 - 新查询试题
* @return: {*}
* @param {*} queryType
* 0 - 标准查询
* 1 - 按条件查询
* 2 - 按关键词查询
*/
let obj = {};
function Apis(key) {
obj[key] = [];
return function(task) {
return new Promise((resolve, reject) => {
obj[key].push(task);
Promise.all([...obj[key]]).then(res => {
const i = obj[key].findIndex(item => {
return item == task;
});
resolve(obj[key][i]);
//arr.splice(i, 1);
})
})
}
}
const client = new Apis('/paht');
const t = function(name, time) {
return new Promise(resolve => {
const queryForm = {
//
currentPage: paginationParams.pageNum,
pageSize: paginationParams.pageSize,
//
eid: props.bookobj.levelSecondId,
sectionName: props.bookobj.coursetitle,
edusubject: userStore.edusubject,
edustage: userStore.edustage,
//
//
worktype: entpCourseWorkQueryParams.worktype.label,
workTypeId: entpCourseWorkQueryParams.worktype.value,
//
workgroup: entpCourseWorkQueryParams.workgroup,
//
yearStr: entpCourseWorkQueryParams.yearStr !== '-1' ? entpCourseWorkQueryParams.yearStr:'',
//
thirdId: entpCourseWorkQueryParams.point&&entpCourseWorkQueryParams.point.length > 0 ? entpCourseWorkQueryParams.point[0]:'',
//
keyword: entpCourseWorkQueryParams.keyWord && entpCourseWorkQueryParams.keyWord !== '' ? entpCourseWorkQueryParams.keyWord:'',
}
const entpcourseworkres = listEntpcourseworkNew(queryForm);
resolve(entpcourseworkres);
})
}
const handleQueryFromEntpCourseWork= async (queryType) => {
pageParams.value.loading = true;
client(t('任务1', 1500)).then(res => {
//console.log("",res);
// if(paginationParams.pageNum == 1){
// workResource.entpCourseWorkList = [];
// workResource.entpCourseWorkTotal = 0;
// //
// // pageParams.value.loading = false;
// // pageParams.value.isFirst = true;
// // pageParams.value.originCount = 0;
// }
const data = res.data || [];
if(data && data.length>0){
// workResource.entpCourseWorkList = entpcourseworkres.data;
// workResource.entpCourseWorkTotal = entpcourseworkres.data.length;
data.forEach(item=> {
if (item.worktype == '选择题') {
item.worktype = '单选题'
}
})
//
processList(data);
//workResource.entpCourseWorkList.push(...data);
workResource.entpCourseWorkList = data;
//
if (pageParams.value.isFirst) {
pageParams.value.isFirst = false;
pageParams.value.originCount = workResource.entpCourseWorkList.length;
pageParams.value.total = parseInt(res.msg);
paginationParams.pageNum = Math.ceil(parseInt(res.msg)/paginationParams.pageSize);
console.log('first->', pageParams.value, paginationParams);
}
}
pageParams.value.loading = false;
});
}
//
/**
* 2框架设计教学资源从课标分析教材分析里来
*/
const getQueryFromEvaluationclue = () => {
// props.bookobj.levelSecondId, //userStore.evalid, // // ID
listEvaluationclue({ cluegroup: 'teachresource', evalid: props.bookobj.levelSecondId, pageSize: 1000 }).then((clueres) => {
for (var i=0; i<clueres.rows.length; i++) {
if (clueres.rows[i].cluetag == 'standardview') {
clueres.rows[i].worktype = '课标研读';
} else if (clueres.rows[i].cluetag == 'targetview') {
clueres.rows[i].worktype = '目标设定';
} else if (clueres.rows[i].cluetag == 'contentview') {
clueres.rows[i].worktype = '教材研读';
} else if (clueres.rows[i].cluetag == 'frameview') {
clueres.rows[i].worktype = '框架梳理';
} else if (clueres.rows[i].cluetag == 'mapview') {
clueres.rows[i].worktype = '学科定位';
}
console.log("clueres.rows[i].childlist",clueres.rows[i].childlist);
if (clueres.rows[i].childlist != '') {
clueres.rows[i].childArray = JSON.parse('['+clueres.rows[i].childlist+']');
for (var j=0; j<clueres.rows[i].childArray.length; j++) {
clueres.rows[i].childArray[j].title = clueres.rows[i].childArray[j].title.replace(/(<([^>]+)>)/ig, '');
}
} else {
clueres.rows[i].childArray = {};
}
}
console.log("框架梳理、课标研读、目标设定、教材研读、学科定位的资源",clueres.rows);
workResource.teachResourceList = clueres.rows;
})
}
/**
* 3知识点
*/
const getEntpCourseWorkPointList = () => {
//
//
listEvaluation({ itemkey: "subject", pageSize: 10, edustage: userStore.edustage, edusubject: userStore.edusubject }).then((res) => {
const evalId = res.rows
const queryParams = {
evalId: evalId[0]?.id,
pageNum: 1,
pageSize: 5000,
}
listKnowledgePoint(queryParams).then(res => {
entpCourseWorkPointList.value = res.rows;
});
});
}
/**
* @desc: 根据查询参数查询试题
* @return: {*}
* @param {*} queryType
* 1 - 按条件查询
* 2 - 按关键词查询
*/
const handleQueryParamFromEntpCourseWork = (queryType) => {
//
// this.paginationParams = {pageNum: 1,pageSize: 10};
//
initPageParams();
handleQueryFromEntpCourseWork(queryType);
};
/**
* 查看试题详细信息
* @param row 单题数据
*/
const showExamAnalyseDrawer = (row) => {
nextTick(() => {
const activeParams = {
activeExam: row,
}
proxy.$refs.examDetailsDrawerRef.acceptParams(activeParams);
})
}
const getPaginationList = ( page, limit ) => {
paginationParams.pageNum = page;
paginationParams.pageSize = limit;
console.log(page, limit)
handleQueryFromEntpCourseWork(0);
}
/**
* 添加资源
* @param fromsrc - 试题来源
* @param entpcourseworkid
*/
const handleClassWorkQuizAdd = (fromsrc, entpcourseworkid) => {
emit('addQuiz', entpcourseworkid);
// var exist = false;
// for (var i=0; i< classWorkForm.quizlist.length; i++) {
// if (classWorkForm.quizlist[i].id == entpcourseworkid) {
// exist = true;
// break;
// }
// }
// if (exist == false) {
// getEntpcoursework(entpcourseworkid).then(res => {
// //res.data.titletext = res.data.title.replace(/<[^>]+>/g, '');
// //
// if(res.data.score == null){
// res.data.score = 4;
// }
// classWorkForm.quizlist.push(res.data);
// //
// processList(classWorkForm.quizlist);
// })
// } else {
// ElMessage('')
// }
};
//
const debounceQueryData = debounce(() => {
console.log("防抖 加载数据中...")
//
initPageParams();
//
handleQueryFromEntpCourseWork(0);
//
getQueryFromEvaluationclue();
//
getEntpCourseWorkPointList();
}, 1000);
watch(() => props.bookobj.levelSecondId, (newVal, oldVal) => {
console.log(props.bookobj,'课程选择')
debounceQueryData();
})
</script>
<style scoped lang="scss">
.page {
height: 100%;
display: flex;
flex-direction: column;
.page-table {
width: 100%;
height: calc(100% - 100px);
}
// .el-form-work-list{
// display: flex;
// flex: 1;
// font-size: var(--font-size);
// line-height: 32px;
// min-width: 0;
// position: relative;
// flex-direction: column;
// :deep(.el-form-item__content){
// display: flex;
// flex: 1;
// font-size: var(--font-size);
// line-height: 32px;
// min-width: 0;
// position: relative;
// flex-direction: column;
// }
// .page-table {
// width: 100%;
// height: calc(100% - 100px);
// }
// }
}
</style>
<style src="@/assets/styles/JYStyle.css"></style>

View File

@ -92,6 +92,5 @@ onMounted(() => {
background-color: #fff;
padding:5px;
border-radius: 4px;
overflow-y: auto;
}
</style>

View File

@ -1,5 +1,6 @@
<template>
<div class="list-container">
<div class="list-content">
<div class="list-container">
<div class="content-list" v-for="(item, index) in items" :key="index" @click="handleClick(item)">
<div class="item-content">
<div class="item-text">
@ -15,6 +16,7 @@
</div>
</div>
</div>
</div>
</template>
@ -100,12 +102,16 @@ const handleClick = (item) => {
</script>
<style scoped>
.list-content{
padding: 8px;
background-color: #f5f5f5;
border-radius: 8px;
height: 100%;
}
.list-container {
display: flex;
flex-wrap: wrap;
gap: 16px;
padding: 8px;
background-color: #f5f5f5;
}
.content-list {

View File

@ -109,5 +109,7 @@ const listeners = computed(() => ({
.no-horizontal-scroll {
overflow: auto;
overflow-x: hidden;
scrollbar-width: none; /* Firefox */
-ms-overflow-style: none; /* Internet Explorer 10+ */
}
</style>