Merge pull request 'baigl' (#305) from baigl into main

Reviewed-on: #305
This commit is contained in:
baigl 2024-10-10 15:53:17 +08:00
commit 233d065f9c
12 changed files with 751 additions and 190 deletions

View File

@ -66,7 +66,7 @@
"xlsx": "^0.18.5",
"less": "^4.2.0",
"less-loader": "^7.3.0",
"whiteboard_lyc": "^0.0.8"
"whiteboard_lyc": "^0.1.3"
},
"devDependencies": {
"@electron-toolkit/eslint-config": "^1.0.2",

View File

@ -60,10 +60,12 @@
<el-button>{{ type == 'design' ? '形状' : '工具' }}</el-button>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item command="square">正方形</el-dropdown-item>
<el-dropdown-item command="rectangle">矩形</el-dropdown-item>
<el-dropdown-item command="diamond">菱形</el-dropdown-item>
<el-dropdown-item command="triangle">三角形</el-dropdown-item>
<el-dropdown-item command="circle">圆形</el-dropdown-item>
<el-dropdown-item command="elliptic">椭圆形</el-dropdown-item>
<el-dropdown-item command="line">线段</el-dropdown-item>
<el-dropdown-item command="arrow">箭头</el-dropdown-item>
<template v-if="type != 'design'">
@ -397,7 +399,7 @@ const scroll = reactive({
//
const showGrid = ref(false)
//
// const readonly = ref(false)
const readonly = ref(false)
//
const elReadonly = ref(false)
@ -675,8 +677,8 @@ const getCanvasBase64 = async () =>{
let base64 = await app.exportImage({
type: 'image/jpeg',
renderBg: exportRenderBackground.value,
paddingX: 0,
paddingY: 0,
paddingX: 10,
paddingY: 10,
onlySelected: exportOnlySelected.value,
backgroundColor: '#ffffff'
})

View File

@ -310,3 +310,44 @@ export function timeToStr(time,str = '时分秒', isPad = false) {
if (isPad) return `${h?toStr(h)+arr[0]:''}${m?toStr(m)+arr[1]:''}${toStr(s)}${arr[2]||''}`
return `${h?h+arr[0]:''}${m?m+arr[1]:''}${s?s+arr[2]||'':''}`
}
/**
* 防抖一定时间内如果函数被连续调用则只执行最后一次调用
* debounce(() => {
console.log('Input event handled');
}, 300);
* @param {*} func
* @param {*} wait
* @returns
*/
export function debounce(func, wait) {
let timeout;
return function() {
const context = this;
const args = arguments;
clearTimeout(timeout);
timeout = setTimeout(() => func.apply(context, args), wait);
};
}
/**
* 节流一定时间内函数最多只执行一次
* throttle(() => {
console.log('Scroll event handled');
}, 300);
* @param {*} func
* @param {*} wait
* @returns
*/
export function throttle(func, wait) {
let lastTime = 0;
return function() {
const context = this;
const args = arguments;
const now = new Date();
if (now - lastTime >= wait) {
func.apply(context, args);
lastTime = now;
}
};
}

View File

@ -100,6 +100,17 @@ export const getCurrentTime = (format)=> {
if(format == 'MMDD'){
return `${month}${day}`;
}
if(format == 'HH'){
return `${hours}`;
}
if(format == 'HH+3'){
//往后延时3个小时
const hours = (now.getHours()+3).toString().padStart(2, '0');
return `${hours}`
}
if(format == 'mm'){
return `${minutes}`;
}
}
/**
*

View File

@ -72,6 +72,7 @@ import { getCurrentTime, getTomorrow } from '@/utils/date'
import useUserStore from '@/store/modules/user'
import useClassTaskStore from "@/store/modules/classTask";
import {sessionStore, createWindow} from '@/utils/tool'
import {throttle,debounce } from '@/utils/comm'
const toolState = useToolState();
@ -377,7 +378,10 @@ const closeDialog = () => {
getStudentClassWorkDataPolling()
}
const openDialogTime = ref(null);//
const debounceOpenWin = debounce(() => {
toolState.isTaskWin=true; //
createWindow('open-taskwin',{url:'/teachClassTask'}); //
}, 1000);
/**
* 开启新批改弹窗
* @param item 作业对象
@ -385,17 +389,10 @@ const openDialogTime = ref(null);//弹窗
const onClickItem = (item) => {
console.log('开启弹窗,关闭作业进度轮询')
clearInterval(pollingST.value)
// itemDialogRef.value.openDialog(item)
if(openDialogTime.value) return;
clearTimeout(openDialogTime.value)
openDialogTime.value = setTimeout(() => {
openDialogTime.value = null;
toolState.isTaskWin=true; //
sessionStore.set('teachClassWorkItem', item); // item
//
createWindow('open-taskwin',{url:'/teachClassTask'})
}, 1000)
console.log('防抖开启弹窗')
sessionStore.set('teachClassWorkItem', item); // item
debounceOpenWin();
}

View File

@ -92,7 +92,7 @@
<el-table-column v-if="props.initDataProps.queryType!=='single'" label="推送配置" align="left" min-width="16%">
<template #default="scope">
<div style="display: flex">
<el-button link icon="Setting" @click="scope.row.status == '10' ? openClassWorkConfigDialog(scope.row, -1,'item') : ''" :style="formatStyle(scope.row)" v-hasPermi="['teaching:classwork:edit']">{{scope.row.status == '10'? '推送' : '已推送'}}</el-button>
<el-button v-hasPermi="['teaching:classwork:edit']" link icon="Setting" :style="formatStyle(scope.row)" @click="scope.row.status == '10' ? openClassWorkConfigDialog(scope.row, -1,'item') : ''">{{scope.row.status == '10'? '推送' : '已推送'}}</el-button>
</div>
</template>
</el-table-column>
@ -149,21 +149,103 @@
@click="submitWorkTitle('submit')"> </el-button>
</div>
</el-dialog>
<!-- 推送作业的配置对话框 -->
<el-dialog v-model="workConfDialogOpen" title="作业布置推送配置" width="60%" append-to-body>
<el-row>
<el-col :span="24">
<el-form ref="classWorkConfigFormRef" :model="classWorkConfigForm" label-width="100px">
<el-row>
<el-col :span="24">
<el-form-item label="班级" prop="grade">
<el-scrollbar max-height="300px" style="width: 100%">
<el-tree
ref="treeRef" :props="defaultProps" :load="getLoad" node-key="id" highlight-current show-checkbox
lazy @check="handleCheckChange" />
</el-scrollbar>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<el-form-item label="选中学生">
<div style="max-height: 150px; overflow: auto">
<template v-for="(item, index) in classWorkConfigForm.studentlist" :key="item" >
<el-tag :label="item.studentid" size="large" closable style="margin: 3px" @close="handleClassDialogClassStudentRemove(item, index)">{{ item.name }}</el-tag>
</template>
</div>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<el-form-item label="完成要求">
<el-radio-group v-model="classWorkConfigForm.feedtype">
<el-radio label="必做">必做</el-radio>
<el-radio label="选做">选做</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="8">
<el-form-item label="截止日期">
<el-date-picker v-model="classWorkConfigForm.deaddate" type="date" placeholder="选择日期"></el-date-picker>
</el-form-item>
</el-col>
<el-col :span="16">
<el-form-item label="截止时间">
<el-input-number v-model="classWorkConfigForm.deadhour" :min="8" :max="22"></el-input-number>
<el-input-number v-model="classWorkConfigForm.deadmin" :min="0" :max="60" :step="15" style="margin-left: 10px"></el-input-number>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="推荐用时">
<el-input-number v-model="classWorkConfigForm.timelength" :min="1"></el-input-number>分钟
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="8">
<el-form-item label="分值" v-show="false">
<el-input-number v-model="classWorkConfigForm.weights" :min="1"></el-input-number>
</el-form-item>
</el-col>
</el-row>
<el-row>
</el-row>
</el-form>
</el-col>
</el-row>
<div slot="footer" class="dialog-footer" style="text-align: right">
<el-button @click="handleWorkConfigUpdate('cancel')">取消</el-button>
<!-- <el-button type="primary" @click="handleTaskAssignToAllClassType()" :loading="classWorkToStudent_Loading">{{classWorkToStudent_Loading?'推送中……':'推送'}}</el-button> -->
<el-button type="primary" @click="handleTaskAssignToAllClassType()" >{{'推送'}}</el-button>
</div>
</el-dialog>
</div>
</div>
</template>
<script setup>
import { onMounted, ref, toRaw,watch, reactive, getCurrentInstance } from 'vue'
import { onMounted, ref,watch, reactive, getCurrentInstance,nextTick } from 'vue'
import { useRouter } from 'vue-router'
import ChooseTextbook from '@/components/choose-textbook/index.vue'
import { homeworklist, delClasswork } from '@/api/teaching/classwork'
import { listEntpcoursework, listClassworkeval,updateClasswork } from '@/api/classTask'
import { listEntpcoursework, listClassworkeval,updateClasswork,getEvaluationclue } from '@/api/classTask'
import { listClassmain, listClassgroup } from '@/api/classManage/index'
import { saveByClassWorkArray } from '@/api/teaching/classwork'
import { useGetHomework } from '@/hooks/useGetHomework'
import { processList } from '@/hooks/useProcessList'
import { uniqBy, groupBy } from 'lodash'
import { getCurrentTime } from '@/utils/date'
import useUserStore from '@/store/modules/user'
const userStore = useUserStore().user
@ -210,6 +292,22 @@ const workConfObj = reactive({
quizlist: [], // list
});
//
const defaultProps = ref({
children: 'children',
label: 'label',
isLeaf: 'leaf'
});
const gradeList = ref([]);//
const workConfDialogOpen = ref(false);//
const classWorkConfigForm = reactive({
formRowsType: '',//
formRowsList: null,
//
feedtype: '必做',
studentlist: [], //list
}); //
// ---------------------------------------------------
@ -454,13 +552,17 @@ const handleWorkEdit = (row, index) =>{
// --
let classtaskObj = reactive({
id: '', //
bookName: '', //
uniquekey: '', //
title: '', //
worktype: '', //
quizlist: [], //
chooseWorkLists: [],// list
fileHomeworkList: [],// list
whiteboardObj: '',//
})
// -
const newHandleWorkEdit2ClassWorkQuizAdd =(row, index) =>{
const newHandleWorkEdit2ClassWorkQuizAdd = async (row, index) =>{
// this.newWorkSpace = true;
// this.newWorkSpaceEdit = true;
// this.currentTask = row;
@ -485,10 +587,15 @@ const newHandleWorkEdit2ClassWorkQuizAdd =(row, index) =>{
if (listCourseWork.length > 0) {
classtaskObj.id= row.id; //
classtaskObj.bookObj = courseObj; //
classtaskObj.bookName = row.evaltitle? row.evalparenttitle+'/'+row.evaltitle: row.evalparenttitle// :/
classtaskObj.uniquekey= row.uniquekey; //
classtaskObj.title= row.title; //
classtaskObj.worktype= row.worktype; //
classtaskObj.quizlist= []; //
classtaskObj.chooseWorkLists = []; // list
classtaskObj.fileHomeworkList = []; // list
classtaskObj.whiteboardObj = ''; //
if (row.worktype == '框架梳理') {
@ -498,14 +605,16 @@ const newHandleWorkEdit2ClassWorkQuizAdd =(row, index) =>{
// queryParams.ppttype = '';
// queryParams.title = '';
// queryParams.filetype = 'draw';
// const res = await getEvaluationclue(listCourseWork[0].id);
// if ( res.data==null || res.data==undefined ) {
// return;
// }
const res = await getEvaluationclue(listCourseWork[0].id);
if ( res.data==null || res.data==undefined ) {
return;
}
console.log('res.data', res.data);
// this.chooseWorkLists = [];
// res.data.worktype = '';
// res.data.score = listCourseWork[0].score;
// this.chooseWorkLists.push(res.data);
res.data.worktype = '框架梳理';
res.data.score = listCourseWork[0].score;
classtaskObj.chooseWorkLists.push(res.data);
//
}
else if (row.worktype == '习题训练') {
const ids = listCourseWork.map(item => item.id).join(",");
@ -513,7 +622,6 @@ const newHandleWorkEdit2ClassWorkQuizAdd =(row, index) =>{
// for (var i=0; i<idres.rows.length; i++) {
// idres.rows[i].titletext = idres.rows[i].title.replace(/<[^>]+>/g, '');
// }
//
if(idres.rows&&idres.rows.length > 0){
processList(idres.rows);
@ -527,43 +635,417 @@ const newHandleWorkEdit2ClassWorkQuizAdd =(row, index) =>{
});
classtaskObj.quizlist = idres.rows;
//
router.push({
path: '/newClassTask',
query: {
classtaskObj: JSON.stringify(classtaskObj),
}
})
//
}
})
}
else if (this.classWorkForm.worktype == '课堂展示') {
// const workcodes = JSON.parse(this.currentTask.workcodes);
// const jsonString = JSON.stringify(workcodes.json);
// await this.$nextTick();
// this.isShowBoard = true
// this.whiteboardObj = jsonString;
else if (row.worktype == '课堂展示') {
console.log('row.课堂展示', row.workcodes);
const workcodes = JSON.parse(row.workcodes);
classtaskObj.whiteboardObj = JSON.stringify(workcodes.json);
//
}
else if (this.classWorkForm.worktype == '常规作业') {
// this.fileHomeworkList = [];
// if(isJson(this.currentTask.workcodes)){
// this.fileHomeworkList = JSON.parse(this.currentTask.workcodes);
// }
else if (row.worktype == '常规作业') {
if(isJson(row.workcodes)){
classtaskObj.fileHomeworkList = JSON.parse(row.workcodes);
//
}
}
//
router.push({
path: '/newClassTask',
query: {
classtaskObj: JSON.stringify(classtaskObj),
}
})
}
};
const isJson = (str) => {
if (typeof str == 'string') {
try {
let obj = JSON.parse(str)
if (typeof obj == 'object' && obj) {
return true
} else {
return false
}
} catch (e) {
return false
}
}
}
//
const getGradeList = async() => {
let { rows } = await listClassmain({
classuserid: userStore.userId,
pageSize: 100,
status: 'open'
})
rows.forEach((item) => {
item.label = item.caption
item.level = 0
item.leaf = false
item.children = []
item.classstudentlist = JSON.parse('[' + item.classstudentlist + ']')
item.classstudentlist.forEach((el) => {
el.classid = item.id
})
})
return rows
};
//
const getLoad = async (node, resolve) =>{
//
if (node.level == 0) {
gradeList.value = await getGradeList()
resolve(gradeList.value)
}
//
if (node.level == 1) {
listClassgroup({ classid: node.key, orderby: 'orderidx', pageSize: 100 }).then((res) => {
if (res.rows.length > 0) {
let ary = []
res.rows.forEach((item) => {
if (item.parentid === 0) {
//studentGroup
let studentGroup = JSON.parse('[' + item.studentlist + ']')
studentGroup.forEach((el) => {
el.label = el.name
el.leaf = true
el.level = 2
el.id = el.studentid
el.classid = item.classid
})
ary.push({
label: item.groupname,
leaf: false,
...item,
level: 1,
// children
children: studentGroup
})
}
})
resolve(ary)
} else {
//
let students = node.data.classstudentlist
students.forEach((item) => {
item.label = item.name
item.level = 2
item.leaf = true
})
resolve(students)
}
})
}
//
if (node.level == 2) {
resolve(node.data.children)
}
}
//
const handleCheckChange = (data, checked) => {
classWorkConfigForm.studentlist = [];
//
let checkNodes = checked.checkedNodes
let ary = []
checkNodes.forEach((item) => {
//
if (item.level == 0) {
ary = [...ary, ...item.classstudentlist]
}
//
if (item.level == 1) {
ary = [...ary, ...item.children]
}
//
if (item.level == 2) {
ary = [...ary, item]
}
})
classWorkConfigForm.studentlist = uniqBy(ary, 'studentid')
};
//
const handleClassDialogClassStudentRemove = (item,index) => {
classWorkConfigForm.studentlist.splice(index, 1);
// []]
proxy.$refs.treeRef.setChecked(item.id, false, true);
//TODO
// const ids = this.$refs.treeRef.getCheckedKeys();
// console.log(ids)
// console.log(ids.filter((_item)=>_item == item.id),'???????')
// if(ids&&ids.filter((_item)=>_item == item.id).length>0){
// console.log(ids,'?====?')
// console.log(item.id,'?=item.id===?')
// // ?
// this.$refs.treeRef.setChecked(item.id, false, true);
// // setCheckedKeys
// }
};
/**
* 处理在作业推送前的任务配置
*/
const openClassWorkConfigDialog = (row, configindex, type) => {
//
workConfDialogOpen.value = true;
classWorkConfigForm.formRowsType = '';//
classWorkConfigForm.formRowsList = null;
if(type == 'list'){
classWorkConfigForm.formRowsType = 'list';
classWorkConfigForm.formRowsList = row;
}else{
classWorkConfigForm.formRowsType = 'item';
classWorkConfigForm.formRowsList = [row];
}
// TODO
// if (configindex > -1) {
// this.handleClassDialogConfigShow(configindex, 0)
// }
classWorkConfigForm.deaddate = getCurrentTime('YYYY-MM-DD');
classWorkConfigForm.deadhour = getCurrentTime('HH+3');// 3
classWorkConfigForm.deadmin = getCurrentTime('mm');
classWorkConfigForm.timelength = 1;
};
/**
* 推送配置保存配置
* @param key 'cancel' or 'submit'
*/
const handleWorkConfigUpdate = (key,row) => {
if (key == 'cancel') {
workConfDialogOpen.value = false;
} else if (key == 'submit') {
// 2024-04-08, by jackyshen
// this.classWorkConfigForm.classlist
var clist = [];
var cidlist = [];
for (var i=0; i< classWorkConfigForm.studentlist.length; i++) {
if (cidlist.indexOf(classWorkConfigForm.studentlist[i].classid) == -1) {
// UI
var clsname = '';
for (var d = 0; d<gradeList.value.length; d++) {
if (gradeList.value[d].id == classWorkConfigForm.studentlist[i].classid) {
clsname = gradeList.value[d].caption;
}
}
clist.push({id: classWorkConfigForm.studentlist[i].classid, caption: clsname});
cidlist.push(classWorkConfigForm.studentlist[i].classid);
}
}
// 20240408207
// index > -1
//
//
//
// if (classWorkConfigForm.index > -1) {
// classWorkConfigForm.classWorkConfigList.splice(classWorkConfigForm.activeClassWorkIndex);
// }
//
var hh = classWorkConfigForm.deadhour;
hh = "0"+hh;
hh = hh.substr(hh.length-2, 2);
var mm = classWorkConfigForm.deadmin;
mm = "0"+mm;
mm = mm.substr(mm.length-2, 2);
//
classWorkConfigForm.deaddate = '' + classWorkConfigForm.deaddate;
if (isNaN(classWorkConfigForm.deaddate.substring(0,4))) {
var dd = new Date(classWorkConfigForm.deaddate);
var year = dd.getFullYear(); //
var month = dd.getMonth() + 1; //0-11
month = "0"+month;
month = month.substr(month.length-2,2);
var day = dd.getDate(); //131
day = "0"+day;
day = day.substr(day.length-2,2);
classWorkConfigForm.deaddate = year+'-'+month+'-'+day;
}
classWorkConfigForm.classWorkConfigList = [];
//
for (var i=0; i<clist.length; i++) {
classWorkConfigForm.classWorkConfigList.push({
id: 0,
classid: clist[i].id,
classcaption: clist[i].caption, //
parentid: 0,
worktype: '',
workkey: classWorkConfigForm.workkey,
worktag: '',
entpcourseid: 0,
evalid: 0,
edusubject: '',
edudegree: '',
workdate: '',
title: '',
workcodes: '',
studentlist: classWorkConfigForm.studentlist,
timelength: classWorkConfigForm.timelength,
weights: classWorkConfigForm.weights,
feedtype: classWorkConfigForm.feedtype,
deaddate: classWorkConfigForm.deaddate+' '+hh+":"+mm,
});
}
if(classWorkConfigForm.formRowsType == 'list'){
// list
for(var d=0;d<classWorkConfigForm.formRowsList.length;d++){
classWorkConfigForm.rowid = classWorkConfigForm.formRowsList[d].id;
// 20240308by jackyshen
// classWorkConfigForm.classWorkConfigListtaskList[i]
// classWorkConfigForm.classWorkConfigList
for (var i=0; i<taskList.value.length; i++) {
if (taskList.value[i].id == classWorkConfigForm.rowid) {
taskList.value[i].taskconfig = classWorkConfigForm.classWorkConfigList;
break;
}
}
}
}else{
// item
classWorkConfigForm.rowid = classWorkConfigForm.formRowsList[0].id;
// 20240308by jackyshen
// classWorkConfigForm.classWorkConfigListtaskList[i]
// classWorkConfigForm.classWorkConfigList
for (var i=0; i<taskList.value.length; i++) {
if (taskList.value[i].id == classWorkConfigForm.rowid) {
taskList.value[i].taskconfig = classWorkConfigForm.classWorkConfigList;
break;
}
}
}
//
classWorkConfigForm.id = 0;
classWorkConfigForm.index = -1;
classWorkConfigForm.selclassid = 0;
classWorkConfigForm.classlist = [];
classWorkConfigForm.studentlist = [];
classWorkConfigForm.feedtype = '必做';
classWorkConfigForm.workkey = '';
classWorkConfigForm.selgroupid = 0;
classWorkConfigForm.classGroups = [];
classWorkConfigForm.availableStudents = [];
classWorkConfigForm.deaddate = getCurrentTime('YYYY-MM-DD');
classWorkConfigForm.deadhour = getCurrentTime('HH+3');
classWorkConfigForm.deadmin = getCurrentTime('mm');
classWorkConfigForm.timelength = 1;
classWorkConfigForm.weights = 1;
}
};
/**
* 推送
*/
const handleTaskAssignToAllClassType = async() => {
if(classWorkConfigForm.studentlist.length == 0){
return proxy.$modal.msgWarning('请选择需要推送的学生!');
}
// this.classWorkToStudent_Loading = true;
//
handleWorkConfigUpdate('submit', '')
const { chapterId } = await useGetHomework(courseObj.node)
// this.entpcourseid = chapterId
console.log(taskList.value,'===============this.taskListthis.taskList')
var ttt = [];
for (var i=0; i<taskList.value.length; i++) {
// 20240408, by jackyshen
// taskconfig.classWorkList
for (var t=0; t<taskList.value[i].taskconfig.length; t++) {
if (taskList.value[i].taskconfig[t].id == 0) {
ttt.push({
id: 0,
parentid: taskList.value[i].id,
classid: taskList.value[i].taskconfig[t].classid,
classcourseid: 0,
entpcourseid: chapterId,
studentlist: JSON.stringify(taskList.value[i].taskconfig[t].studentlist),
feedback: taskList.value[i].taskconfig[t].feedtype,
workkey: taskList.value[i].taskconfig[t].workkey,
timelength: taskList.value[i].taskconfig[t].timelength,
weights: taskList.value[i].taskconfig[t].weights,
deaddate: taskList.value[i].taskconfig[t].deaddate,
workdate: getCurrentTime('YYYY-MM-DD'),
uniquekey: taskList.value[i].uniquekey,
entpcourseworklist: '['+taskList.value[i].entpcourseworklist+']', // JSON
needMsgNotifine: 'false',
msgkey: 'newclasswork',
title: taskList.value[i].title,
status:'1',
msgcontent: '', // classworkjson
teachername: userStore.nickName,
unixstamp: new Date().getTime(),
});
}
}
}
console.log(ttt,'===============ttt')
if(ttt.length == 0){
proxy.$modal.msgError('您还未进行作业配置,请配置后再推送');
return;
}
var wForm = {};
wForm.classworkarray = JSON.stringify(ttt);
saveByClassWorkArray(wForm).then(response => {
console.log(response,'===============response');
// this.classWorkToStudent_Loading = false;
workConfDialogOpen.value = false;
proxy.$modal.msgSuccess("作业推送成功");
//
proxy.$refs.treeRef.setCheckedKeys([]);
//
nextTick(() => {
getTaskList();
})
}).catch((error) =>{
// this.classWorkToStudent_Loading = false;
workConfDialogOpen.value = false;
});
};
/**
* 一键推送
*/
const handleTaskAssignToAllClass = () => {
let rows = proxy.$refs.taskTable.getSelectionRows();
if (rows.length > 0) {
proxy.$modal.confirm('是否确认推送选中的学习任务?').then(()=> {
}).then(() => {
//
openClassWorkConfigDialog(rows, -1,'list')
}).catch(() => {})
}else{
return proxy.$modal.alertWarning("请选择需要推送的任务!");
}
}
/**
* 设计作业
*/
const handleNewClassWorkDialog = () => {
//
router.push({ path: '/newClassTask' });
}
// -
const submitWorkTitle = () => {

View File

@ -81,12 +81,17 @@
>
<el-table-column type="index" label="序号" width="52" reserve-selection align="center" />
<el-table-column label="姓名" prop="studentname" width="100" align="center" />
<el-table-column label="提交时间" prop="updatedate" width="170" align="center" />
<el-table-column :label="tableRadio.value==0?'提交状态':'提交时间'" prop="updatedate" width="170" align="center">
<template #default="scope">
<span v-if="tableRadio.value==0" style="color: #2196f3">未提交</span>
<span v-if="tableRadio.value==1">{{ scope.row.updatedate }}</span>
</template>
</el-table-column>
<el-table-column label="批阅状态" prop="teacherRating" align="center" width="120" sortable>
<template #default="scope">
<template v-if="scope.row.teacherRating == 0"
><span style="color: #2196f3">待批阅</span></template
>
<template v-if="scope.row.teacherRating == 0">
<span v-if="tableRadio.value==1" style="color: #2196f3">待批阅</span>
</template>
<!-- 1- 2-优减 3- 4-良减 5- -->
<template v-if="scope.row.teacherRating == 1"
><el-tag type="danger"></el-tag></template

View File

@ -7,9 +7,9 @@
<el-row class="top">
<el-col :span="24">
<el-form-item label="作业类型:">
<el-radio-group v-model="formType" @change="changeFormType">
<el-radio-group v-model="classWorkForm.worktype" @change="changeFormType">
<template v-for="(item) in listWorkType" :key="item">
<el-radio :value="item" >{{ item }}</el-radio>
<el-radio :value="item" :disabled="props.isedit">{{ item }}</el-radio>
</template>
</el-radio-group>
</el-form-item>
@ -21,12 +21,12 @@
<div v-if="classWorkForm.worktype == '课堂展示'" style="height: 100%; display: flex; flex-direction: column;">
<div style="flex: 0 0 auto;">
<el-form-item label="问题">
<el-input v-model="question" type="text" placeholder="请输入问题" />
<el-input v-model="classWorkForm.title" type="text" placeholder="请输入问题" />
</el-form-item>
</div>
<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="mainHeight - 150" :isShowSave="false" :data="whiteboardObj"/>
<whiteboard ref="boardref" :height="mainHeight - 150" :isShowSave="false" :data="classWorkForm.whiteboardObj"/>
</div>
</div>
<div v-else class="el-form-work-list">
@ -154,7 +154,7 @@
</template>
<template v-if="classWorkForm.worktype =='常规作业'">
<div v-loading="fileLoading" class="upload-homework">
<FileUpload v-model="fileHomeworkList" :fileSize="800" :fileType="['mp3','mp4','doc','docx','xlsx','xls','pdf','ppt','pptx','jpg','jpeg','gif','png','txt']"/>
<FileUpload v-model="classWorkForm.fileHomeworkList" :fileSize="800" :fileType="['mp3','mp4','doc','docx','xlsx','xls','pdf','ppt','pptx','jpg','jpeg','gif','png','txt']"/>
</div>
</template>
</div>
@ -180,7 +180,7 @@
<div v-if="classWorkForm.worktype!='习题训练'" :style="{'overflow': 'auto', 'border':'1px dotted blue','border-radius':'5px', 'background-color': '#f7f7f7'}">
<div style="margin: 5px; background-color: white">
<template v-for="(item) in chooseWorkLists" :key="item.id">
<template v-for="(item) in classWorkForm.chooseWorkLists" :key="item.id">
<div v-if="item.worktype==classWorkForm.worktype">
<div class="choose-work">
<div class="choose-work-title">{{ item.worktype }}</div>
@ -252,7 +252,7 @@ import { useRouter } from 'vue-router'
import {listEntpcoursework, listEntpcourseworkNew, getEntpcoursework} from '@/api/education/entpCourseWork'
import { addClassworkReturnId } from '@/api/teaching/classwork'
import { updateClasswork, listEvaluationclue,readFile, listClassworkeval,delClassworkeval,addClassworkeval } from '@/api/classTask'
import { updateClasswork, listEvaluationclue,readFile, listClassworkeval,delClassworkeval,addClassworkeval,updateClassworkeval } from '@/api/classTask'
import { listEvaluation } from '@/api/subject'
import { listEntpcoursefile } from '@/api/education/entpcoursefile'
import { listKnowledgePoint } from "@/api/knowledge/knowledgePoint";
@ -279,6 +279,10 @@ const props = defineProps({
propsformobj: {
type: Object,
default: () =>({})
},
isedit: {
type: Boolean,
default: false
}
})
@ -289,11 +293,6 @@ const openDialog = () => {
isDialogOpen.value = true
}
const classWorkFormRef = ref(null);
const formType = ref('习题训练')
const newWorkSpaceEdit = ref(false); //
// ---------------------------------------------------
const listWorkType = ref(['习题训练', '框架梳理', '课堂展示', '常规作业']); //
const entpCourseWorkTypeList = ref([
{value: 0, label: "不限"},
{value: 1, label: "单选题"},
@ -360,17 +359,19 @@ const workResource = reactive({
}); //
let classWorkForm = reactive({
id: cloneDeep(props.propsformobj.id),
uniquekey: cloneDeep(props.propsformobj.uniquekey), //
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):[] //
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):'', // -
}); //
const chooseWorkLists = ref([]); //
const whiteboardObj = ref(''); // -
// ---------------------------------------------------
const listWorkType = ref(['习题训练', '框架梳理', '课堂展示', '常规作业']); //
// -------
const boardLoading = ref(false);
const isShowBoard = ref(false); //
const question = ref(''); // --
const prevReadMsg = reactive({
visible: false,
type: ""
@ -379,14 +380,12 @@ const prevReadMsg = reactive({
const flowData = ref({})//
//----------
const fileLoading = ref(false); // loading
const fileHomeworkList = ref([]);//
/***
* 作业类型切换
*/
const changeFormType = (val) => {
console.log(val)
classWorkForm.worktype = val;
classWorkForm.worktype = val;
}
console.log(props.propsformobj)
@ -628,7 +627,7 @@ const prevRead = async (item) => {
//
const handleClassWorkAddOfResource = (work) => {
//
let arrSole = chooseWorkLists.value.filter((item) => {
let arrSole = classWorkForm.chooseWorkLists.filter((item) => {
return item.worktype === classWorkForm.worktype
})
//
@ -637,25 +636,29 @@ const handleClassWorkAddOfResource = (work) => {
return;
}
//
let arr = chooseWorkLists.value.filter((item) => {
let arr = classWorkForm.chooseWorkLists.filter((item) => {
return item.id === work.id
})
if (arr.length===0) {
work.score = 1;
chooseWorkLists.value.push(work);
classWorkForm.chooseWorkLists.push(work);
}
};
/**
* 删除作业
* 右侧资源删除作业 非习题list
*/
const deleteClassWorkAddOfResource = (work) => {
chooseWorkLists.value.filter((item, index) => {
classWorkForm.chooseWorkLists.filter((item, index) => {
if (item.id === work.id) {
chooseWorkLists.value.splice(index, 1);
classWorkForm.chooseWorkLists.splice(index, 1);
return;
}
})
}
/** 右侧资源删除按钮 习题list */
const handleClassWorkFormQuizRemove = (index) =>{
classWorkForm.quizlist.splice(index, 1);
}
@ -713,8 +716,7 @@ const handleClassWorkSave = async () => {
let canvasJson = proxy.$refs.boardref.getCanvasJson()
let canvasBase64 = await proxy.$refs.boardref.getCanvasBase64()
//
// cform.worktag = question.value;
cform.title = question.value;
cform.title = classWorkForm.title;
cform.workcodes = JSON.stringify({json: canvasJson, base64: canvasBase64});
cform.entpcourseworklist = JSON.stringify([{'id':-1, 'score': '10'}]);
try {
@ -727,8 +729,8 @@ const handleClassWorkSave = async () => {
classWorkForm.quizlist = [], //
//
chooseWorkLists.value = [];
whiteboardObj.value = ''; // ? //
classWorkForm.chooseWorkLists = []; // list
classWorkForm.whiteboardObj = ''; // ? //
// refresh the list
//
// this.getClassWorkAllList();
@ -747,7 +749,7 @@ const handleClassWorkSave = async () => {
}
else if(classWorkForm.worktype === "常规作业"){
fileLoading.value = true
cform.workcodes = JSON.stringify(fileHomeworkList.value);
cform.workcodes = JSON.stringify(classWorkForm.fileHomeworkList);
cform.entpcourseworklist = JSON.stringify([{'id':-2, 'score': '10'}]);
try {
addClassworkReturnId(cform).then(() => {
@ -759,9 +761,9 @@ const handleClassWorkSave = async () => {
classWorkForm.quizlist = [], //
//
chooseWorkLists.value = [];
whiteboardObj.value = ''; // ? //
fileHomeworkList.value = []; // list
classWorkForm.chooseWorkLists = []; // list
classWorkForm.whiteboardObj = ''; // ? //
classWorkForm.fileHomeworkList = []; // list
// refresh the list
//
// this.getClassWorkAllList();
@ -788,7 +790,7 @@ const handleClassWorkSave = async () => {
ll.push({'id': classWorkForm.quizlist[i].id, 'score': classWorkForm.quizlist[i].score});
}
}else if( classWorkForm.worktype === "框架梳理") {
chooseWorkLists.value.filter((item) => {
classWorkForm.chooseWorkLists.filter((item) => {
if (item.worktype === classWorkForm.worktype) {
ll.push({'id':item.id, 'score': item.score});
}
@ -812,8 +814,8 @@ const handleClassWorkSave = async () => {
classWorkForm.quizlist = [], //
//
chooseWorkLists.value = [];
whiteboardObj.value = ''; // ? //
classWorkForm.chooseWorkLists = [];
classWorkForm.whiteboardObj = ''; // ? //
// refresh the list
//
// this.getClassWorkAllList();
@ -844,7 +846,7 @@ const editWork = async (cform) =>{
//
}else {
if (chooseWorkLists.value.length == 0) {
if (classWorkForm.chooseWorkLists.length == 0) {
//
ElMessage.error('请先添加作业资源!');
return;
@ -893,74 +895,55 @@ const editWork = async (cform) =>{
}
}
// 3.
// const evalid = this.homeworkLesson.length==0 ? '' : this.homeworkLesson.length==1 ? this.homeworkLesson[0] : this.homeworkLesson[1];
// const formObj = {
// id: this.currentTask.id,
// uniquekey: this.classWorkForm.uniquekey, // []
// // warn:
// //evalid = evalid, // []
// }
// let res = await updateClasswork(cform);
let res = await updateClasswork(cform);
if (res.code == 200) {
ElMessage.success('更新成功');
//
router.back()
// 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 !== props.propsformobj.chooseWorkLists.length) {
needUplEval = true;
}else {
//
needUplEval = classWorkForm.chooseWorkLists.some(cur =>
!props.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});
}
else if (classWorkForm.worktype=='常规作业') {
// 1. (, )
cform.workcodes = JSON.stringify(classWorkForm.fileHomeworkList);
}
// else if (classWorkForm.worktype=='') {
// // 1.workidid
// const wevalres = await listClassworkeval({'workid': this.currentTask.id});
// if (wevalres.rows.length == 0) {
// ElMessage.error('退');
// return;
// }
// // 2.
// let needUplEval = false;
// if (this.chooseWorkLists.length !== this.currentTask.entpcourseworklistarray.length) {
// needUplEval = true;
// }else {
// //
// needUplEval = this.chooseWorkLists.some(cur =>
// !this.currentTask.entpcourseworklistarray.some(last =>
// last.id === cur.id && last.score === cur.score
// )
// );
// }
// if (needUplEval) {
// const uplParams = {
// id: wevalres.rows[0].id,
// entpcourseworkid: this.chooseWorkLists[0].id,
// score: this.chooseWorkLists[0].score,
// }
// let res = await updateClassworkeval(uplParams);
// }
// }else if (classWorkForm.worktype=='') {
// }else if (classWorkForm.worktype=='') {
// // 1. (, )
// classWorkParams.workcodes = JSON.stringify(this.fileHomeworkList);
// }
// // 3.
// let res = await updateClasswork(cform);
// this.fileHomeworkList = [];
// this.chooseWorkLists = [];
// // 4.
// //
// // this.getClassWorkAllList();
// this.classWorkForm.worktype = "";
// this.newWorkSpace = false;
// this.newWorkSpaceEdit = false;
// this.workEdit = false;
// 3.
let res = await updateClasswork(cform);
if (res.code == 200) {
ElMessage.success('更新成功');
//
router.back()
}
}
@ -968,7 +951,12 @@ const editWork = async (cform) =>{
onMounted(() => {
})
watch(() => props.propsformobj.uniquekey, (newVal) => {
console.log(props.propsformobj,'propsformobj')
if(props.propsformobj.uniquekey){
classWorkForm.uniquekey = props.propsformobj.uniquekey?cloneDeep(props.propsformobj.uniquekey):''; //
}
})
watch(() => props.bookobj.levelSecondId, (newVal) => {
console.log(props.bookobj,'课程选择')
//

View File

@ -77,6 +77,7 @@ const props = defineProps({
border-radius: 10px;
padding: 10px 5px;
margin-bottom: 10px;
cursor: pointer;
.class-reserv-item-body {
flex: 1;

View File

@ -15,11 +15,16 @@
<!-- 标题 -->
<el-row style="align-items: center; margin-bottom: 0px; flex: 0 0 auto">
<el-col :span="12" style="padding-left: 20px; text-align: left;">
<div class="unit-top-left" @click="isCollapse = !isCollapse">
<div v-if="!isOpenLeftBook" class="unit-top-left cursor-pointer" @click="onOpenLeftBook">
<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>
</div>
<div v-else class="unit-top-left">
<i class="iconfont icon-xiangzuo cursor-pointer" style="color: blue;" @click="goBack">返回上页</i>
<span>课程</span>
<span>{{bookTitle}}</span>
</div>
</el-col>
<el-col :span="12">
<div class="classtype-right">
@ -30,13 +35,13 @@
</el-col>
</el-row>
<!-- 作业类型:内容 -->
<task-type-view :bookobj="courseObj" :propsformobj="classWorkForm" style="flex: 1; overflow: hidden;"/>
<task-type-view :bookobj="courseObj" :propsformobj="classWorkForm" :isedit="isOpenLeftBook" style="flex: 1; overflow: hidden;"/>
</div>
</div>
</template>
<script setup>
import { onMounted, ref, toRaw,watch, reactive } from 'vue'
import { onMounted, ref, toRaw,watch, reactive, getCurrentInstance } from 'vue'
import { useRouter, useRoute } from 'vue-router'
import ChooseTextbook from '@/components/choose-textbook/index.vue'
@ -45,8 +50,13 @@ import { getCurrentTime } from '@/utils/date'
import useUserStore from '@/store/modules/user'
const userStore = useUserStore().user
const route = useRoute();
const router = useRouter()
const { proxy } = getCurrentInstance()
const classtaskObj = route.query.classtaskObj;//
const bookTitle = ref(classtaskObj? JSON.parse(classtaskObj).bookName: '');//
const isOpenLeftBook = ref(classtaskObj? JSON.parse(classtaskObj).id ? true : false: false ); //
const isCollapse = ref(isOpenLeftBook.value?true:false); // : false
// ---------------------------------------------------
const classWorkForm = reactive({
id: classtaskObj? JSON.parse(classtaskObj).id : '', // id
@ -54,9 +64,11 @@ const classWorkForm = reactive({
title: classtaskObj? JSON.parse(classtaskObj).title : '', //
worktype: classtaskObj? JSON.parse(classtaskObj).worktype : '', //
quizlist: classtaskObj? JSON.parse(classtaskObj).quizlist : [], //
chooseWorkLists: classtaskObj? JSON.parse(classtaskObj).chooseWorkLists : [],// list
fileHomeworkList: classtaskObj? JSON.parse(classtaskObj).fileHomeworkList : [],// list
whiteboardObj: classtaskObj? JSON.parse(classtaskObj).whiteboardObj : '',//
})
const isCollapse = ref(false)
const courseObj = reactive({
// : id,id,id,
@ -67,7 +79,6 @@ const courseObj = reactive({
node: null, //
//
})
// ---------------------------------------------------
@ -94,16 +105,32 @@ const getData = (data) => {
localStorage.setItem('unitId', JSON.stringify({ levelFirstId, levelSecondId}))
}
const onOpenLeftBook = () => {
if(isOpenLeftBook.value){
//
proxy.$modal.msgError(`当前为编辑状态不可选择课程!`);
}else{
//
isCollapse.value = !isCollapse.value
}
}
// ---
const goBack = () =>{
router.back()
}
onMounted(() => {
// init()
// sourceStore.getCreate()
//
if(classtaskObj&&JSON.parse(classtaskObj).bookObj){
const bookobj = JSON.parse(classtaskObj).bookObj;
courseObj.textbookId = bookobj.bookObj //
courseObj.levelFirstId = bookobj.levelFirstId //
courseObj.levelSecondId = bookobj.levelSecondId //
courseObj.coursetitle = bookobj.node.itemtitle // (/)
courseObj.node = bookobj.node; //
}
})
// const init = () => {
// classWorkForm.uniquekey = userStore.edusubject+'-' + getCurrentTime('MMDD')+'-'+(1);
// }
</script>
<style lang="scss" scoped>
@ -120,8 +147,10 @@ onMounted(() => {
width: 300px;
min-height: 100%;
}
.cursor-pointer {
cursor: pointer;//
}
.unit-top-left {
cursor: pointer;
.icon-xiangzuo {
margin-right: 5px;

View File

@ -71,12 +71,17 @@
>
<el-table-column type="index" label="序号" width="52" reserve-selection align="center" />
<el-table-column label="姓名" prop="studentname" width="100" align="center" />
<el-table-column label="提交时间" prop="updatedate" width="170" align="center" />
<el-table-column :label="tableRadio.value==0?'提交状态':'提交时间'" prop="updatedate" width="170" align="center">
<template #default="scope">
<span v-if="tableRadio.value==0" style="color: #2196f3">未提交</span>
<span v-if="tableRadio.value==1">{{ scope.row.updatedate }}</span>
</template>
</el-table-column>
<el-table-column label="批阅状态" prop="teacherRating" align="center" width="120" sortable>
<template #default="scope">
<template v-if="scope.row.teacherRating == 0"
><span style="color: #2196f3">待批阅</span></template
>
<template v-if="scope.row.teacherRating == 0">
<span v-if="tableRadio.value==1" style="color: #2196f3">待批阅</span>
</template>
<!-- 1- 2-优减 3- 4-良减 5- -->
<template v-if="scope.row.teacherRating == 1"
><el-tag type="danger"></el-tag></template

View File

@ -37,6 +37,7 @@ import { homeworklist } from '@/api/teaching/classwork'
import { getCurrentTime, getTomorrow } from '@/utils/date'
import {sessionStore, createWindow} from '@/utils/tool'
import { useToolState } from '@/store/modules/tool'
import {throttle,debounce } from '@/utils/comm'
const user = useUserStore().user
const toolState = useToolState();
@ -68,19 +69,17 @@ const getHomework = async () => {
}
}
const openDialogTime = ref(null);//
const debounceOpenWin = debounce(() => {
toolState.isTaskWin=true; //
createWindow('open-taskwin',{url:'/teachClassTask'}); //
}, 1000);
//
const onClickItem = (item) => {
console.log('开启弹窗')
if(openDialogTime.value) return;
clearTimeout(openDialogTime.value)
openDialogTime.value = setTimeout(() => {
openDialogTime.value = null;
toolState.isTaskWin=true; //
sessionStore.set('teachClassWorkItem', item); // item
//
createWindow('open-taskwin',{url:'/teachClassTask'})
}, 1000)
console.log('防抖开启弹窗')
sessionStore.set('teachClassWorkItem', item); // item
debounceOpenWin();
}
const tagType = (time) => {
@ -136,6 +135,7 @@ watch(
border-radius: 5px;
margin-bottom: 10px;
padding: 10px;
cursor: pointer;
.class-left {
flex-direction: column;