Merge branch 'develop' into manage-release

# Conflicts:
#	src/App.vue
This commit is contained in:
yuping
2023-03-31 11:30:06 +08:00
45 changed files with 538 additions and 467 deletions

4
.env
View File

@@ -38,4 +38,6 @@ VUE_APP_H5=//u-pre.boe.com/student-h5
#用户头像
VUE_APP_AVATAR_PATH=/upload/
# 旧版管理员界面
VUE_APP_OLD_MANAGE=//u-pre.boe.com/resource/index.html
VUE_APP_OLD_MANAGE=//u-pre.boe.com/resource/index.html
# 批量面授报名模板
VUE_APP_FACE_STUDENT_TEMPLATE=批量面授报名模版-1673963663229.xlsx

View File

@@ -13,4 +13,6 @@ VUE_APP_UP_LOAD_STUDENT_SCORE_TEMPLATE=coursefile/外部考试学员成绩导入
#在线
VUE_APP_ONLINE_CLASS_URL=//u-pre.boe.com/mobile/pages/study/courseStudy?id=
VITE_BOE_CASS_DETAIL_URL=//u-pre.boe.com/pc/case/detail?id=
VUE_APP_EXAM_DETAIL_URL=//u-pre.boe.com/mobile/pages/exam/exam?id=
VUE_APP_EXAM_DETAIL_URL=//u-pre.boe.com/mobile/pages/exam/exam?id=
# 批量面授报名模板
VUE_APP_FACE_STUDENT_TEMPLATE=coursefile/批量面授报名模版-1679595849719.xlsx

View File

@@ -29,4 +29,6 @@ VUE_APP_FILE_PATH=/upload/boe/file/
#用户头像
VUE_APP_AVATAR_PATH=/upload/
# 旧版管理员界面
VUE_APP_OLD_MANAGE=//u.boe.com/resource/index.html
VUE_APP_OLD_MANAGE=//u.boe.com/resource/index.html
# 批量面授报名模板
VUE_APP_FACE_STUDENT_TEMPLATE=/file/批量面授报名模版-1679595925822.xlsx

View File

@@ -25,4 +25,6 @@ VUE_APP_H5=//u.boe.com/student-h5-release
#用户头像
VUE_APP_AVATAR_PATH=/upload/
# 旧版管理员界面
VUE_APP_OLD_MANAGE=//u-pre.boe.com/resource/index.html
VUE_APP_OLD_MANAGE=//u-pre.boe.com/resource/index.html
# 批量面授报名模板
VUE_APP_FACE_STUDENT_TEMPLATE=批量面授报名模版-1673963663229.xlsx

View File

@@ -33,9 +33,7 @@ import {USER_PERMISSION} from "@/api/ThirdApi";
const store = useStore();
const isLogin = ref(false);
console.log("版本1.4.9------------");
console.log("版本2.3.6------------");
// 监听关闭浏览器
let time1 = ref(0);

View File

@@ -51,9 +51,8 @@ http.interceptors.response.use(
(response) => {
// console.log('response', response)
const {
data: {code, msg, show},
data: {code, msg ,show},
} = response;
console.log('code', code)
if (code === 0 || code === 200) {
return response;
}
@@ -65,7 +64,7 @@ http.interceptors.response.use(
localStorage.removeItem('refreshPage')
return Promise.reject(response);
}
show && message.error(msg);
show ? message.error(msg):message.error('系统接口数据异常,请联系管理员');
console.log("api %o", msg);
return Promise.reject(response);
},

View File

@@ -184,6 +184,7 @@ export const attendanceLeave = (obj) => http.post('/stu/task/attendance/leave',
export const batchFinishTask = (obj) => http.post('/admin/student/batchFinishTask', obj)
//批量更新学员状态
export const batchUpdateStatus = (obj) => http.post('/admin/student/batchUpdateStatus', obj)
export const auditStudentBatch = (obj) => http.post('/admin/student/auditStudentBatch', obj)
// //面授课批量导入成绩
export const batchImportScore = (obj) =>
http.post('/admin/student/importHomeWork', obj, {

View File

@@ -1,6 +1,8 @@
import {isRef, reactive, ref, toRefs, unref, watch, watchEffect} from "vue";
import {getCookieForName, throttle} from "@/api/method";
import JSONBigInt from "json-bigint";
import router from "@/router";
import {message} from "ant-design-vue";
const JSONBigIntStr = JSONBigInt({ storeAsString: true });
@@ -346,5 +348,18 @@ export async function request(_url, params) {
return res.text();
}).then(res => {
return JSONBigIntStr.parse(res);
}).then(res => {
if (res.code === 0 || res.code === 200) {
return res;
}
if (res.code === 1000) {
(process.env.NODE_ENV === 'development' || process.env.NODE_ENV === 'alpine') ?
router.push({path: 'login', query: { returnUrl: router.currentRoute.value.fullPath }}) :
(window.location.href = process.env.VUE_APP_LOGIN_URL + encodeURIComponent(window.location.protocol + process.env.VUE_APP_BOE_API_URL + process.env.VUE_APP_BASE + router.currentRoute.value.fullPath))
localStorage.removeItem('refreshPage')
return Promise.reject(res);
}
res.show ? message.error(res.msg):message.error('系统接口数据异常,请联系管理员');
return Promise.reject(res);
});
}

View File

@@ -148,6 +148,10 @@ function handleChange({ file }) {
</script>
<style scoped lang="scss">
.impotergroupleader > .ant-drawer-content-wrapper {
min-width: 800px !important;
width: 800px !important;
}
.impotergroupleader {
.drawerMain {
min-width: 600px;

View File

@@ -86,12 +86,10 @@ function download() {
document.querySelector(".downloadCode"),
{ useCORS: true }
).then((canvas) => {
let filename = `${new Date().getTime()}.png`;
let imageUrl = canvas.toDataURL("image/png");
let a = document.createElement("a");
a.style.display = "none";
a.download = filename;
a.href = imageUrl;
a.download = `${new Date().getTime()}.png`;
a.href = canvas.toDataURL("image/png");
document.body.appendChild(a);
a.click();
});

View File

@@ -745,7 +745,7 @@ export default {
title: "签到时间",
dataIndex: "signTime",
key: "signTime",
width: 110,
width: 100,
align: "center",
className: "h",
customRender: (text) => {
@@ -812,7 +812,7 @@ export default {
className: "h",
dataIndex: "opacation",
key: "opacation",
width: 130,
width: 100,
align: "center",
customRender: (value) => {
return (
@@ -1079,6 +1079,11 @@ export default {
</script>
<style lang="scss">
.largeDrawerStyle > .ant-drawer-content-wrapper {
width: 1400px !important;
min-width: 1400px !important;
}
.me {
.ant-modal-body {
padding: 0px;

View File

@@ -65,7 +65,7 @@
<span style="margin-right: 3px">讨论设置</span>
</div>
<div class="btnbox">
<a-checkbox v-model:checked="formData.discussSettings">允许评论</a-checkbox>
<a-checkbox v-model:checked="formData.discussSettings" @click="discussSettings">允许评论</a-checkbox>
</div>
</div>
</div>
@@ -87,7 +87,7 @@ const props = defineProps({
taskList: []
})
const visible = ref(false)
const formData = useResetRef({discussName: '', discussExplain: '', discussSettings: ''})
const formData = useResetRef({discussName: '', discussExplain: '', discussSettings: true})
const emit = defineEmits({})
const taskIndex = ref(-1);
const dateTime = ref([]);
@@ -133,11 +133,17 @@ async function confirm() {
}
function openDrawer(i, row) {
console.log(i,row)
row && (formData.value = {...row.info});
(i >= 0) && (taskIndex.value = i);
row && (formData.value.discussSettings = row.info.discussSettings === "false" || row.info.discussSettings === false ? false : true);
visible.value = true
}
const discussSettings = () => {
formData.value.discussSettings = !formData.value.discussSettings;
}
defineExpose({openDrawer})
</script>
<style lang="scss">

View File

@@ -25,14 +25,16 @@
</a-drawer>
</template>
<script setup>
import {defineEmits, defineProps, ref} from "vue";
import {computed, defineEmits, defineProps, ref} from "vue";
import {Form, message} from "ant-design-vue";
import FaceClassAll from "@/components/drawers/FeaceClassAll.vue";
import {useResetRef} from "@/utils/useCommon";
const props = defineProps({
type: Number,
taskList: []
taskList: [],
chapterList: [],
infoType: Number,
});
const visible = ref(false);
const formData = useResetRef({
@@ -58,6 +60,8 @@ const rulesRef = ref({
const { validate } = Form.useForm(formData, rulesRef);
const selectIds = computed(()=>props.chapterList.flatMap(t=>props.infoType===1?t.taskDraftDtoList:props.infoType===2?t.draftTaskList:t.taskTemplateList)?.filter(s=>s?.type==props.type).map(t=>t.courseId).join(',') || '')
const closeDrawer = () => {
visible.value = false;
taskIndex.value = -1;
@@ -69,6 +73,11 @@ async function confirm() {
message.warning(errorFields[0].errors.join());
throw Error("数据校验不通过");
});
if (selectIds.value.includes(formData.value.courseId)) {
message.warning("本项目中已经包含此在线课!");
return;
}
if (taskIndex.value === -1) {
const list = props.taskList;
list.push({

View File

@@ -355,6 +355,10 @@ export default {
</script>
<style lang="scss">
.AddLevelImpStu > .ant-drawer-content-wrapper {
min-width: 800px !important;
width: 800px !important;
}
.AddLevelImpStu {
.drawerMain {
min-width: 450px;

View File

@@ -238,7 +238,7 @@
:un-check-value="0">
<span style="color: #6d7584">允许项目内人员临时到场参加(不在本场次培训的人员可以临时签到参加)</span>
</CheckBox>
<CheckBox v-model="formData.signFlag"
<CheckBox v-model="formData.outSignFlag"
:check-value="1"
style="margin-left: 0px;"
:un-check-value="0">
@@ -570,6 +570,8 @@ async function coursePlanConfirm() {
}
offCourseNewVisiable.value = false;
tableRef.value.toLoading();
// TODO 当点击选择了是否评估按钮 点击保存的时候没有选择评估 则是否需要评估重置为 0 不需要
formData.value.evalFlag = formData.value.assessmentName ? 1 : 0;
await request(COURSE_PLAN_EDIT, { ...formData.value });
handleCancelStu();
tableRef.value.fetch();
@@ -614,12 +616,16 @@ const changevalue = (e) => {
console.log("changevalue", e, newarr, formData.value.attach);
}
const logT = () => {
formData.value.examInfo = {};
};
defineExpose({ openDrawer });
</script>
<style lang="scss">
.ant-drawer-content-wrapper {
width: 1500px !important;
min-width: 1500px !important;
.addonlineDrawer > .ant-drawer-content-wrapper {
width: 1300px !important;
min-width: 1300px !important;
}
.ant-table-striped :deep(.table-striped) td {

View File

@@ -21,7 +21,7 @@
<iframe
id="iframe"
style="width: 100%; height: 100%;"
:src="iframeUrl + '/exam/viewanswer?id=' + datasource.answerId "
:src="iframeUrl+'/exam/viewanswer?id='+(answerId?answerId:datasource.answerId)"
frameborder="0"
name="myframe"
security="restricted"
@@ -54,6 +54,10 @@ export default {
default: function () {
return {};
},
},
answerId:{
type: String,
default: "",
}
},
setup(props,ctx){
@@ -143,6 +147,7 @@ export default {
console.log(bool);
if(bool == true) {
console.log(props.datasource)
console.log(props.answerId?props.answerId:props.datasource.answerId)
}
}
const getQue = () => {

View File

@@ -106,8 +106,8 @@
</div>
</div>
<div class="btnn">
<button class="btn1">取消</button>
<button class="btn2">确定</button>
<button class="btn1" @click="closeDrawer">取消</button>
<button class="btn2" @click="closeDrawer">确定</button>
</div>
</div>

View File

@@ -19,20 +19,40 @@
</div>
<div style="display: flex; flex-direction: row; padding-top: 0px; margin-top: 20px; margin-left: 32px;">
<div>
<button
style="width: 100px; cursor: pointer;"
@click="changeOuter(1)"
:class="formData.examType === 1 ? 'outer' : 'notOuter'"
>
系统考试
</button>
<button
style="width: 100px; cursor: pointer;"
@click="changeOuter(2)"
:class="formData.examType === 2 ? 'outer' : 'notOuter'"
>
外部考试
</button>
<div v-if="info?.examinationName >= 0">
<button
v-if="info?.examType == 1"
style="width: 100px; cursor: pointer;"
@click="changeOuter(1)"
:class="formData.examType === 1 ? 'outer' : 'notOuter'"
>
系统考试
</button>
<button
v-else
style="width: 100px; cursor: pointer;"
@click="changeOuter(2)"
:class="formData.examType === 2 ? 'outer' : 'notOuter'"
>
外部考试
</button>
</div>
<div v-else>
<button
style="width: 100px; cursor: pointer;"
@click="changeOuter(1)"
:class="formData.examType === 1 ? 'outer' : 'notOuter'"
>
系统考试
</button>
<button
style="width: 100px; cursor: pointer;"
@click="changeOuter(2)"
:class="formData.examType === 2 ? 'outer' : 'notOuter'"
>
外部考试
</button>
</div>
</div>
</div>
@@ -50,6 +70,7 @@
</div>
<div class="btnbox">
<a-input
:disabled="info?.examinationName >= 0?true:false"
v-model:value="formData.examinationName"
style="width: 400px; height: 40px; border-radius: 8px"
placeholder="请输入考试名称"
@@ -70,7 +91,7 @@
</div>
<s-test v-model:id="formData.examinationPaperId" v-model:name="formData.examinationTestName">
<div class="btnbox">
<button class="xkbtn" style="margin:0">
<button class="xkbtn" style="margin:0" :disabled="info?.examinationName >= 0?true:false">
{{ formData.examinationPaperId ? "重选" : "选择" }}试卷
</button>
</div>
@@ -117,6 +138,7 @@
</div>
<div class="select">
<a-input-number
:disabled="info?.examinationName >= 0?true:false"
:min="0"
:max="999999"
:precision="0"
@@ -138,6 +160,7 @@
</div>
<div class="btnbox">
<a-input
:disabled="info?.examinationName >= 0?true:false"
v-model:value="formData.passLine"
type="number"
style="width: 400px; height: 40px; border-radius: 8px"
@@ -152,6 +175,7 @@
</div>
<div class="textarea">
<a-textarea
:disabled="info?.examinationName >= 0?true:false"
v-model:value="formData.examinationExplain"
placeholder="请输入考试说明"
allow-clear
@@ -170,6 +194,7 @@
<div class="timerbox">
<span>允许重复考试</span>
<a-input-number
:disabled="info?.examinationName >= 0?true:false"
:min="-1"
:max="999999"
:precision="0"
@@ -194,6 +219,7 @@
</div>
<div class="btnbox">
<a-radio-group
:disabled="info?.examinationName >= 0?true:false"
style="margin-right: 12px"
v-model:value="formData.showAnswers"
>
@@ -208,6 +234,7 @@
</div>
<div class="btnbox">
<a-radio-group
:disabled="info?.examinationName >= 0?true:false"
style="margin-right: 12px"
v-model:value="formData.showAnalysis"
>
@@ -222,6 +249,7 @@
</div>
<div class="btnbox">
<a-radio-group
:disabled="info?.examinationName >= 0?true:false"
style="margin-right: 12px"
v-model:value="formData.scoringModel"
>
@@ -238,6 +266,7 @@
</div>
<div class="btnbox">
<a-radio-group
:disabled="info?.examinationName >= 0?true:false"
style="margin-right: 12px"
v-model:value="formData.questionArrangement"
>
@@ -405,6 +434,7 @@ watch(() => formData.value.examType, () => {
})
watch([props, visible], () => {
console.log(props.info)
resetFields(props.info)
dateTime.value = [props.info?.examinationStartTime || '', props.info?.examinationEndTime || '']
})

View File

@@ -1,6 +1,6 @@
<!-- eslint-disable vue/no-use-v-if-with-v-for -->
<template>
<a-drawer :visible="Seevisible" class="drawerStyle seestu" placement="right" width="70%">
<a-drawer :visible="Seevisible" class="drawerStyle seestu" placement="right" width="70%" :zIndex="1005">
<div class="drawerMain">
<div class="header">
<div class="headerTitle">查看</div>
@@ -193,14 +193,14 @@ export default {
};
const getStuRank = () => {
projectStudentRank({projectId: props.projectId, studentId: props.checkStuId}).then(res => state.rank = res.data.data)
props.projectId && props.checkStuId && projectStudentRank({projectId: props.projectId, studentId: props.checkStuId}).then(res => state.rank = res.data.data)
}
const showProMess = () => {
state.Provisible = true;
};
const check = () => {
state.loading = true
projectStudentProcess({projectId: props.projectId, userId: props.checkStuId}).then((res) => {
props.projectId && props.checkStuId && projectStudentProcess({projectId: props.projectId, userId: props.checkStuId}).then((res) => {
state.loading = false
state.info = res.data.data;
})

View File

@@ -22,17 +22,14 @@
style="border: 1px solid #f2f6fe"
:columns="tablecolumns"
:data-source="tabledata"
:loading="tableDataTotal === -1 ? true : false"
@expand="expandTable"
:pagination="false"
/>
<div class="pa">
<a-pagination
v-if="tableDataTotal > 10"
:showSizeChanger="false"
showQuickJumper="true"
hideOnSinglePage="true"
:showQuickJumper="true"
:hideOnSinglePage="true"
:pageSize="pageSize"
:current="currentPage"
:total="tableDataTotal"
@@ -138,7 +135,7 @@ export default {
studentScoreList(obj).then((res) => {
console.log("dede", res.data.data);
let result = res.data.data;
state.tableDataTotal = result.pageSize;
state.tableDataTotal = result.total;
if (result.pageSize > 0) {
setTable(result.rows);
}

View File

@@ -128,7 +128,7 @@
<div class="lastbox">
<div class="sorcetext">非常不满意</div>
<div class="sorcebox" v-for="(iittem, index) in [1,2,3,4,5,6,7,8,9,10] " :key="index">
<div v-if="iittem >= values.assessmentMinScore && iittem <= values.assessmentMaxScore" :class="(iittem - values.assessmentMinScore) == values.selectAnswer ? 'numbox' : 'numbox1'">{{ iittem }}</div>
<div v-if="iittem >= values.assessmentMinScore && iittem <= values.assessmentMaxScore" :class="iittem == values.selectAnswer ? 'numbox' : 'numbox1'">{{ iittem }}</div>
</div>
<div class="sorcetext">非常满意</div>
</div>

View File

@@ -580,11 +580,10 @@ export default {
state.selectTaskId = info.finishType == 3 ? info.finishValue : null;
state.selectExamId = info.finishType == 4 ? info.finishValue : null;
state.score = info.finishType == 5 ? info.finishValue : null; //积分
let timer = setInterval(() => {
if (
state.stageList.length !== 0 &&
state.taskList.length !== 0 &&
state.stageList.length !== 0 ||
state.taskList.length !== 0 ||
state.examList.length !== 0
) {
if (info.finishType == 2) {
@@ -691,6 +690,10 @@ export default {
};
</script>
<style lang="scss">
.AddCertificate > .ant-drawer-content-wrapper {
min-width: 800px !important;
width: 800px !important;
}
.ant-table-striped :deep(.table-striped) td {
background-color: #fafafa !important;
}

View File

@@ -18,13 +18,11 @@
/>
</div>
<div class="main">
<div class="minatitl">
<div class="up1" style="font-weight: bolder">导入小组长</div>
<!--<div class="up2" @click="downTemplate" style="cursor: pointer">-->
<!--模板-->
<!--</div>-->
<div class="up1" v-if="templateUrl">
请下载
<a :href="templateUrl" target="_blank">模版</a>
按要求填写并导入
</div>
<div class="up1">请先导出小组填写小组长按要求填写数据并导入</div>
<div class="upload">
<div class="text">上传</div>
<div class="right">
@@ -65,7 +63,7 @@
<div class="curloading">
<div style="color: #387df7; margin-left: 20px; cursor: pointer"
v-if="file.uploadState?.status === 'FAILED'" @click="downloadErrorData(file.uploadState?.url)">
下载失败数据1
下载失败数据
</div>
</div>
</div>
@@ -129,10 +127,6 @@ const closeDrawer = () => {
function openDrawer() {
visible.value = true
}
//
// function downTemplate() {
// window.open(process.env.VUE_APP_BASE_API + props.templateUrl);
// }
function downloadErrorData(url) {
window.open(process.env.VUE_APP_FILE_PATH + url)

View File

@@ -259,8 +259,8 @@ export default {
},
{
title: "考试次数",
dataIndex: "num",
key: "num",
dataIndex: "testNumber",
key: "testNumber",
width: 60,
align: "center",
ellipsis: true,
@@ -268,15 +268,15 @@ export default {
customRender: (text) => {
return (
<div class="racona">
<span> {text.record.num?text.record.num:"-"}</span>
<span> {text.record.testNumber?text.record.testNumber:"-"}</span>
</div>
);
},
},
{
title: "成绩",
dataIndex: "examinationScore",
key: "examinationScore",
dataIndex: "score",
key: "score",
width: 60,
align: "center",
ellipsis: true,
@@ -284,7 +284,7 @@ export default {
customRender: (text) => {
return (
<div class="racona">
<span> {text.record.examinationScore?text.record.examinationScore:"-"}</span>
<span> {text.record.score?text.record.score:"-"}</span>
</div>
);
},
@@ -292,8 +292,8 @@ export default {
{
title: "完成时间",
dataIndex: "examinationSubmitTime",
key: "examinationSubmitTime",
dataIndex: "finishedTime",
key: "finishedTime",
width: 60,
align: "center",
ellipsis: true,
@@ -301,7 +301,7 @@ export default {
customRender: (text) => {
return (
<div class="racona">
<span> {text.record.examinationSubmitTime?text.record.examinationSubmitTime:"-"}</span>
<span> {text.record.finishedTime?text.record.finishedTime:"-"}</span>
</div>
);
},

View File

@@ -92,7 +92,7 @@
<div class="btn btn1" @click="batchFinish" style="margin-right: 20px">
<div class="wz">批量标注完成</div>
</div>
<CommonImport title="录入成绩" v-if="homeWorkId" :template-url="scoreTemplateUrl"
<CommonImport @change="change" title="录入成绩" v-if="homeWorkId" :template-url="scoreTemplateUrl"
:data="{ targetId: offcoursePlanId, type:3,workId:homeWorkId }" :url="`/admin/student/importHomeWork`"
name="uploadFile">
<div class="btn btn1" style="margin-right: 20px;margin-left: 20px">
@@ -121,11 +121,11 @@
</div>
</div>
</a-drawer>
<CheckAnsware v-model:CAvisible="CAvisible" :datasource="answerDatasource"/>
<CheckAnsware v-model:CAvisible="CAvisible" :datasource="datasource" :answerId="answerId"/>
<!-- 查看作业抽屉 -->
<CKWork
v-model:CWvisible="CWvisible"
:workId="props.datasource?.courseId"
:workId="homeWorkId"
:stuId="stuId"
/>
<ExportHomeWork
@@ -253,7 +253,7 @@ const columns = ref([
align: "center",
ellipsis: true,
className: "h",
customRender: ({ record: { workScore } }) => <span> {workScore !== -2 ? workScore : "-" || "-"}</span>
customRender: ({ record: { workScore } }) => <span> {workScore < 0 ? "-" : workScore || "-"}</span>
},
{
title: "考试成绩",
@@ -297,43 +297,11 @@ const columns = ref([
key: "opacation",
width: 100,
align: "center",
customRender: (text) => {
return (
customRender: ({record:{workStatus,answerId,examinationScore,studentId}}) =>
<div style="display:flex;justify-content:center;">
{
text.record.answerId ?
<a
class="opa"
style="margin-right:12px;"
onClick={() => {
showExamAnswer(text);
}}>
查看答卷
</a>
: <div
class="opa"
style="margin-right:12px;color:#666">
查看答卷
</div>
}
{
text.record.workScore !== -2 ?
<a
class="opa"
onClick={() => {
showCWvisible(text.record.studentId);
}}>
查看作业
</a>
: <div
class="opa"
style="color:#666;">
查看作业
</div>
}
</div>);
}
<a class="opa" style={{color:examinationScore?'':'#666',marginRight:'12px'}} onClick={() =>examinationScore && showExamAnswer(answerId)}>查看答卷</a>
<a class="opa" style={{color:workStatus?'':'#666'}} onClick={() => workStatus && showCWvisible(studentId)}>查看作业</a>
</div>
},
]);
watch(() => data.value, () => {
@@ -371,11 +339,9 @@ const batchFinish = () => {
});
};
const answerDatasource = ref(props.datasource);
const showExamAnswer = (text) => {
answerDatasource.value.answerId = text.record.answerId;
console.log(answerDatasource.value)
const answerId = ref('');
const showExamAnswer = (id) => {
answerId.value = id;
CAvisible.value = true;
};
@@ -423,6 +389,13 @@ function resetStudentPage() {
tableRef.value.reset({ pid: data.value[coursePlanIndex.value]?.id, type: 3 });
}
function change(e) {
console.log('导入作业完成了吗',e)
if(e=="end"){
resetStudentPage()
}
}
</script>
<style lang="scss">

View File

@@ -240,8 +240,8 @@ export default {
},
{
title: "考试次数",
dataIndex: "num",
key: "num",
dataIndex: "testNumber",
key: "testNumber",
width: 60,
align: "center",
ellipsis: true,
@@ -249,7 +249,7 @@ export default {
customRender: (text) => {
return (
<div class="racona">
<span> {text.record.num ? text.record.num : "-"}</span>
<span> {text.record.testNumber ? text.record.testNumber : "-"}</span>
</div>
);
},
@@ -265,7 +265,7 @@ export default {
customRender: (text) => {
return (
<div class="racona">
<span> {text.record.examinationScore ? text.record.examinationScore : "-"}</span>
<span> {text.record.score ? text.record.score : "-"}</span>
</div>
);
},
@@ -273,8 +273,8 @@ export default {
{
title: "完成时间",
dataIndex: "examinationSubmitTime",
key: "examinationSubmitTime",
dataIndex: "finishedTime",
key: "finishedTime",
width: 60,
align: "center",
ellipsis: true,
@@ -282,7 +282,7 @@ export default {
customRender: (text) => {
return (
<div class="racona">
<span> {text.record.examinationSubmitTime ? text.record.examinationSubmitTime : "-"}</span>
<span> {text.record.finishedTime ? text.record.finishedTime : "-"}</span>
</div>
);
},

View File

@@ -85,10 +85,17 @@
<div
class="btn btn1"
style="margin-right: 20px"
@click="qrcodeVisible()"
@click="qrcodeVisibleSign()"
>
<div class="wz">签到二维码</div>
</div>
<div
class="btn btn1"
style="margin-right: 20px"
@click="qrcodeVisible()"
>
<div class="wz">开课二维码</div>
</div>
<CommonStudent
:type="3"
:isGroup="true"
@@ -103,7 +110,7 @@
添加学员
</a-button>
</CommonStudent>
<CommonImport title="导入学员" :template-url="stuTemplateUrl" :data="{ targetId: offcoursePlanId, type:3 }" :url="`/admin/student/importStudent`" name="uploadFile">
<CommonImport @change="change" title="导入学员" :template-url="stuTemplateUrl" :data="{ targetId: offcoursePlanId, type:3 }" :url="`/admin/student/importStudent`" name="uploadFile">
<div class="btn btn1" style="margin-right: 20px;margin-left: 20px">
<div class="img1"></div>
<div class="wz">导入学员</div>
@@ -293,7 +300,10 @@ watch(() => data.value, () => {
tableRef.value.fetch();
});
// 开课签到二维码名字
const openCourseName = ref("");
const ChoiceCourse = (n) => {
openCourseName.value = data.value[n].name;
coursePlanIndex.value = n;
params.value.pid = data.value[n].id;
tableRef.value.fetch();
@@ -370,11 +380,29 @@ function resetStudentPage() {
//二维码
const qrcodeVisible = () => {
qrCode({
title: "【签到】二维码",
name: props.datasource?.name,
url: `${location.protocol}//${location.host}${process.env.VUE_APP_BASE_API}/admin/student/studentSign?taskId=${props.datasource.id}&taskType=${props.datasource.type}&type=${props.type}`,
title: "【开课】二维码",
name: openCourseName.value?openCourseName.value:data.value[0]?.name,
// url: `${location.protocol}//${location.host}${process.env.VUE_APP_BASE_API}/admin/student/studentSign?taskId=${props.datasource.id}&taskType=${props.datasource.type}&type=${props.type}`,
url: `${location.protocol}//${location.host}${process.env.VUE_APP_BASE_API}/stu/project/redirectDetail?courseId=${data.value[coursePlanIndex.value]?.id}`,
});
};
// 签到二维码
const qrcodeVisibleSign = () => {
qrCode({
title: "【签到】二维码",
name: openCourseName.value?openCourseName.value:data.value[0]?.name,
// url: `${location.protocol}//${location.host}${process.env.VUE_APP_BASE_API}/admin/student/studentSign?taskId=${props.datasource.id}&taskType=${props.datasource.type}&type=${props.type}`,
url: `${location.protocol}//${location.host}${process.env.VUE_APP_BASE_API}/admin/student/studentSign?taskId=${data.value[coursePlanIndex.value]?.id}&taskType=${2}&type=${3}`,
});
};
const change = (e) => {
console.log(e)
if(e==="end"){
// 请求刷新数据
tableRef.value.fetch();
}
}
</script>

View File

@@ -112,27 +112,26 @@
</div>-->
</div>
</a-drawer>
<!-- 学员查看抽屉 -->
<check-stu
v-model:CheckStuvisible="CheckStuvisible"
v-model:routerId="routerId"
v-model:studentId="studentId"
/>
<see-stu
v-model:Seevisible="CheckStuvisible"
:checkStuId="studentId"
:projectId="datasource.courseId"
:certificateNum="datasource.certCount"
/>
</template>
<script>
import { toRefs, reactive, onMounted, onUnmounted } from "vue";
import { message } from "ant-design-vue";
// import * as api from "../../../api/index";
import SeeStu from "@/components/drawers/SeeStu";
import * as api from "../../../api/indexTaskManage";
import CheckStu from "../CheckStu";
import {checkPer} from "@/utils/utils";
import { batchSendMessage } from "@/api/index1";
export default {
name: "RouterProjectManage",
components:{
CheckStu,
SeeStu,
},
props: {
createId: {
@@ -203,8 +202,6 @@
CVvisible:false, //查看投票抽屉
voteID: "",
courseID: "",
routerId: '',
studentId: '',
CheckStuvisible: false,

View File

@@ -67,9 +67,10 @@ const { data: options, loading: orgLoading } = useBoeApi(
);
watch(props, () => {
stuTreeExpandedKeys.value = [];
console.log("labelValue.value", labelValue.value, props.value);
labelValue.value = props.value;
// stuTreeExpandedKeys.value = [];
// console.log("labelValue.value", labelValue.value, props.value);
// labelValue.value = props.value;
// if (labelValue.value.value !== props.value) {
// labelValue.value = { value: props.value, label: props.name };
// }

View File

@@ -27,7 +27,7 @@
</template>
搜索
</a-button>
<a-button @click="resetProjectStu" style="margin-left: 20px; border-radius: 4px">重置
<a-button type="primary" @click="resetProjectStu" style="margin-left: 20px; border-radius: 4px">重置
</a-button>
</a-form-item>
</div>
@@ -47,7 +47,7 @@
<a-button type="primary" @click="onSearchStu" style="margin-left: 20px; border-radius: 4px">
<template #icon>
<SearchOutlined/>
</template>
</template>
搜索
</a-button>
<a-button type="primary" @click="resetStu" style="margin-left: 20px; border-radius: 4px">重置
@@ -93,7 +93,7 @@
<template #icon>
<SearchOutlined/>
</template>
搜索
搜索
</a-button>
<a-button type="primary" @click="resetOrg" style="margin-left: 20px; border-radius: 4px">重置
</a-button>
@@ -122,8 +122,8 @@
<a-button type="primary" @click="searchAudi" style="margin-left: 20px; border-radius: 4px">
<template #icon>
<SearchOutlined/>
</template>
搜索
</template>
搜索
</a-button>
<a-button type="primary" @click="resetAudienceInfo" style="margin-left: 20px; border-radius: 4px">
重置
@@ -374,10 +374,13 @@ const member = ref(false);
const dept = ref(false);
const projectStuTableRef = ref();
const stuTableRef = ref();
const projectParams = ref({ pid: props.infoId, type: props.infoType });
const projectParams = ref({ pid: props.infoId, type: props.infoType, studentName:"" });
const getProjectStu = () => projectStuTableRef.value.fetch();
const resetProjectStu = () => projectStuTableRef.value.reset();
const resetProjectStu = () => {
projectParams.value.studentName = "";
projectStuTableRef.value.reset()
};
const person = ref(false);
const group = ref(false);
@@ -602,9 +605,13 @@ function onOrgSelectChange(e, l) {
deptList.value = l.selectedNodes;
}
const resetStu = () => stuTableRef.value.reset({ keyword: "", departId: null });
const resetStu = () => {
nameSearch.value.keyword = "";
stuTableRef.value.reset({ keyword: "", departId: null })
};
//清空选择部门信息
const deleteDepSelect = () => {
stuSelectRows.value = [];
selectedOrgKeys.value = [];
projectSelectKeys.value = [];
};
@@ -613,7 +620,10 @@ const resetOrg = () => {
searchOrgName.value = { keyword: "", page: 1, pageSize: 10 };
};
//重置受众
const resetAudienceInfo = () => auditTableRef.value.reset({ keyword: "" });
const resetAudienceInfo = () => {
audienceName.value.keyword = "";
auditTableRef.value.reset({ keyword: "" })
};
//确定添加授权
const submitAuth = () => {
@@ -671,14 +681,27 @@ watch(visiable, () => {
stuTreeExpandedKeys.value = [];
stuTreeSelectKeys.value = [];
activeKey.value = props.isGroup ? 4 : 1;
projectParams.value.studentName = "";
nameSearch.value.keyword = "";
searchOrgName.value.keyword = "";
audienceName.value.keyword = "";
if (!visiable.value) {
auditTableRef.value && auditTableRef.value.clear();
stuTableRef.value && stuTableRef.value.clear();
projectStuTableRef.value && projectStuTableRef.value.clear();
auditTableRef.value && auditTableRef.value.resetSelected() && auditTableRef.value.clear();
auditTableRef.value && auditTableRef.value.reset({ keyword: "" });
stuTableRef.value && stuTableRef.value.resetSelected() && stuTableRef.value.clear();
stuTableRef.value && stuTableRef.value.reset({ keyword: "", departId: null });
projectStuTableRef.value && projectStuTableRef.value.resetSelected() && projectStuTableRef.value.clear();
projectStuTableRef.value && projectStuTableRef.value.reset();
}
});
</script>
<style lang="scss">
.CommonStudent > .ant-drawer-content-wrapper {
min-width: 1200px !important;
width: 1200px !important;
}
.CommonStudent {
.ant-btn-primary {
background-color: #4ea6ff !important;

View File

@@ -77,7 +77,7 @@
@finash="submitCall"
:stage="stage"
>
<a-button class="cus-btn" style="background: #4ea6ff; color: #fff">
<a-button class="cus-btn" style="background: #4ea6ff; color: #fff" :loading="stuAsyncLoading">
<template #icon><img style="margin-right: 10px" src="../../assets/images/courseManage/add0.png"/>
</template>
添加学员
@@ -120,7 +120,7 @@ import {checkPer} from "@/utils/utils";
import dialog from "@/utils/dialog";
import {ONLINE_COURSE_DEL} from "@/api/ThirdApi";
import {useStore} from "vuex";
import {useResetRef} from "@/utils/useCommon";
import {useAsyncStu, useResetRef} from "@/utils/useCommon";
const props = defineProps({
permissions: {
@@ -147,7 +147,7 @@ const searchParams = useResetRef({
pageSize: 10,
type: props.type || "",
types: props.types,
pid: props.id || "",
pid: "",
});
const columns = ref([
@@ -238,12 +238,12 @@ const columns = ref([
// },
{
title: "状态",
dataIndex: "status",
key: "status",
dataIndex: "finishStatus",
key: "finishStatus",
width: 80,
align: "center",
ellipsis: true,
customRender: ({ record: { status } }) => status ? "已完成" : "未开始",
customRender: ({ record: { finishStatus } }) => finishStatus ? "已完成" : "未开始",
},
{
title: "操作",
@@ -268,6 +268,7 @@ const sysTypeOption2 = computed(() => sysTypeOption1.value?.children.find(({ cod
const sysTypeOption3 = computed(() => sysTypeOption2.value?.children.find(({ code }) => code == formData.value.sysType2));
const { data: studentList, fetch: searchStu, total, loading } = usePage(STUDENT_LIST, searchParams, false);
const { loading: stuAsyncLoading, start } = useAsyncStu(formData.value.id, props.type, searchStu);
const stuPagination = computed(() => ({
total: total.value,
@@ -302,6 +303,7 @@ function del(id) {
}
function submitCall(flag) {
flag && start({ id: formData.value.id });
flag && searchStu();
}
@@ -315,7 +317,7 @@ function reset() {
}
function exportStu() {
window.open(`${process.env.VUE_APP_BASE_API}/admin/student/exportOnlineStudent?type=3&&thirdType=8&pid=${props.id}`);
window.open(`${process.env.VUE_APP_BASE_API}/admin/student/exportOnlineStudent?type=3&&thirdType=8&pid=${searchParams.value.pid}`);
}
defineExpose({

View File

@@ -408,7 +408,7 @@ export default {
justify-content: center;
margin-left: 32px;
cursor: pointer;
background: #388be1;
background: #4ea6ff;
border-radius: 8px;
font-size: 14px;
font-weight: 400;

View File

@@ -149,11 +149,13 @@
<div
class="b_zk"
:style="{ display: hideshow ? 'block' : 'none', color: '#fff', lineHeight: '9px', transform: 'rotate(180deg)'}"
>^</div>
>^
</div>
<div
class="b_sq"
:style="{ display: hideshow ? 'none' : 'block', color: '#fff', lineHeight: '12px'}"
>^</div>
>^
</div>
</div>
<div
class="btn4_sup"
@@ -166,10 +168,10 @@
<div class="btn4_op1" @click="updateStatus(1)">
<span>批量结业</span>
</div>
<div class="btn4_op2" @click="updateStatus(0)">
<div class="btn4_op2" @click="auditStatus(0)">
<span>批量通过</span>
</div>
<div class="btn4_op3" @click="updateStatus(2)">
<div class="btn4_op3" @click="auditStatus(2)">
<span>批量拒绝</span>
</div>
</div>
@@ -220,14 +222,14 @@
<a-button
v-if="type === 3 && record.status !== 2 && record.status !== 0 && checkPer(permissions)"
@click="updateStatus(0, record.id)"
@click="auditStatus(0, record.id)"
type="link"
>通过
</a-button
>
<a-button
v-if="type === 3 && record.status !== 2 && record.status !== 0 && checkPer(permissions)"
@click="updateStatus(2, record.id)"
@click="auditStatus(2, record.id)"
type="link"
>拒绝
</a-button
@@ -390,7 +392,7 @@
</template>
<script setup>
import {computed, defineProps, onMounted, ref, watch} from "vue";
import {delStudentList, getStuPage, batchUpdateStatus} from "@/api/index1";
import {delStudentList, getStuPage, batchUpdateStatus, auditStudentBatch} from "@/api/index1";
import ChangeGroupModal from "@/components/student/ChangeGroupModal.vue";
import CommonStudent from "@/components/student/CommonStudent";
import ChangeLevelModal from "./ChangeLevelModal.vue";
@@ -697,6 +699,7 @@ const deleteModalVisible = ref(false);
const deleteId = ref(null);
const deleteTargetId = ref(null);
const deleteType = ref(null);
function del(id, row) {
if (row.isLeader === "1") {
return message.warning("" + row.name + "是小组长,请勿删除!");
@@ -704,7 +707,7 @@ function del(id, row) {
deleteModalVisible.value = true;
deleteId.value = id;
deleteTargetId.value = row.pid;
deleteType.value = row.type
deleteType.value = row.type;
// Modal.confirm({
// title: () => "确定删除?",
@@ -727,7 +730,11 @@ function del(id, row) {
const sureSameModal = () => {
if (deleteId.value) {
tableData.value.loading = true;
delStudentList({ ids: [deleteId.value],targetId: deleteTargetId.value,type:deleteType.value}).then(() => getStuList());
delStudentList({
ids: [deleteId.value],
targetId: deleteTargetId.value,
type: deleteType.value
}).then(() => getStuList());
deleteModalVisible.value = false;
}
};
@@ -864,7 +871,7 @@ const exportStu = () => {
}
};
//批量操作 结业、通过、拒绝等
//批量操作 结业、拒绝等
const updateStatus = (status, id) => {
if (!id && stuSelectKeys.value.length === 0) {
message.warning("请选择学员");
@@ -889,7 +896,19 @@ const updateStatus = (status, id) => {
console.log("批量更新学员状态失败", err);
});
};
//批量通过
const auditStatus = (status, id) => {
if (!id && stuSelectKeys.value.length === 0) {
message.warning("请选择学员");
}
auditStudentBatch({
ids: id ? [id] : stuSelectKeys.value,
status
}).then(() => {
getStuList();
stuSelectKeys.value = [];
});
};
//导入学员
const AddImpStuvisible = ref(false); //导入学员抽屉
const showImpStu = () => {

View File

@@ -150,6 +150,10 @@ function itemDel(i) {
}
</script>
<style lang="scss">
.createvoteDrawer > .ant-drawer-content-wrapper {
min-width: 800px !important;
width: 800px !important;
}
.researchadd {
.header {
height: 73px;

View File

@@ -58,8 +58,8 @@ export function useTimeout(asyncFun, time) {
export function useAsyncStu(id, type, func) {
const loading = ref(false);
const { start } = useTimeout(async () => {
const { data } = await request(ASYNC_STUDENT_STATUS, { id, type });
const { start } = useTimeout(async (d = {}) => {
const { data } = await request(ASYNC_STUDENT_STATUS, { ...{ id, type }, ...d });
if (!data) {
loading.value = false;
throw Error("查询任务结束");

View File

@@ -31,20 +31,20 @@ export function traverseArr(arr, traverseObj, saveOld = false) {
const admin = [5, 6, 8, 9, 11, 12];
//检查 管理权和归属权
export function checkPer(per,createId) {
if(createId && store?.state?.userInfo?.id === createId){
export function checkPer(per, createId) {
if (createId && store?.state?.userInfo?.id === createId) {
return true;
}
if (store?.state?.userInfo?.roleList.some(t => t.code === "system-admin")) {
return true;
}
if(per){
if (per) {
return (per + "").split(",").some(t => admin.some(s => s == t));
}
if (store?.state?.userInfo?.isHrbp) {
return true;
}
return false
return false;
}
const adminOwner = [6, 9, 12];
@@ -201,3 +201,20 @@ export function newFile(code) {
URL.revokeObjectURL(linkNode.href); // 释放URL 对象
document.body.removeChild(linkNode);
}
//保留两位小数
export function fixDouble(v) {
const f = parseFloat(v);
if (isNaN(f)) {
return 0;
}
return Math.round(f * 100) / 100;
}
//输出两位百分小数
export function fixDoublePer(v) {
const f = parseFloat(v);
if (isNaN(f)) {
return 0;
}
return Math.round(f * 10000) / 100;
}

View File

@@ -682,7 +682,7 @@
<a-modal
v-model:visible="stm_hs"
title="Title"
@ok="closeModal"
@ok="stm_exit"
:footer="null"
:closable="false"
wrapClassName="modalStyle schtimeModal"
@@ -1042,7 +1042,7 @@
<span style="margin-right: 3px">报名设置</span>
</div>
<div class="b_input">
<a-checkbox v-model:checked="checked1">
<a-checkbox v-model:checked="checked1" :disabled = "itemType!=3">
<span style="color: #6d7584">是否允许公开报名</span>
</a-checkbox>
</div>
@@ -1053,17 +1053,9 @@
<span style="margin-right: 3px">签到设置</span>
</div>
<div class="b_input">
<a-radio-group v-model:value="xjkkradioV1">
<a-radio :value="0" @click="clear_xjkkradioV1">
<span style="color: #6d7584; margin-right: 30px">
是否允许未报名的学员签到
</span>
</a-radio>
<!--
<a-radio :value="1" @click="clear_xjkkradioV1">
<span style="color: #6d7584">签到是否需要口令</span>
</a-radio>-->
</a-radio-group>
<a-checkbox v-model:checked="xjkkradioV1" :disabled = "itemType!=3">
<span style="color: #6d7584">是否允许未报名的学员签到</span>
</a-checkbox>
</div>
</div>
@@ -1255,7 +1247,7 @@
:permissions="permissions"
:isgetStudent="isgetStudent"
>
<template #extension="{ data: { record } }">
<!-- <template #extension="{ data: { record } }">
<a-button
v-if="record.source === 4 && record.status === 1 && checkPer(permissions,createId)"
@click="
@@ -1293,7 +1285,7 @@
type="link"
>撤回
</a-button>
</template>
</template> -->
</TableStudent>
</div>
</div>
@@ -1797,6 +1789,15 @@ const columns2 = [
customRender: ({ record: { courseName, routerName } }) =>
courseName || routerName || "开课",
},
{
title: "是否开课学员",
dataIndex: "infoType",
key: "infoType",
ellipsis: true,
width: "10%",
align: "center",
customRender: ({ record: { infoType } }) => infoType ===1 ? '是':'否'
},
{
title: "学习时间",
dataIndex: "lastStudyTime",
@@ -2162,6 +2163,7 @@ export default defineComponent({
workInfo: {},
examInfo: {},
tableLoading: false,
itemType: null,
columns1: [
{
title: "课程编号",
@@ -2570,7 +2572,7 @@ export default defineComponent({
kkinputV1: "",
kkinputV2: "",
//新建开课
xjkkradioV1: "",
xjkkradioV1: false,
completeType: "",
xjkkinputV1: "",
onceName: "",
@@ -2634,7 +2636,7 @@ export default defineComponent({
assessment: {},
assessmentId: null,
workName: null,
EditTestId: 0,
EditTestId: null,
testName: null,
assessmentName: "",
assessmentVisible: false,
@@ -3608,10 +3610,12 @@ export default defineComponent({
};
const stm_exit = () => {
state.stm_hs = false;
handleCancelStu();
handleRestTable();
};
const createkk = () => {
state.offcoursePlanId = null;
state.itemType = 3;
state.member = {};
state.cstm_hs = true;
};
@@ -3620,7 +3624,7 @@ export default defineComponent({
state.attach = "";
state.kk_eidt = false;
state.xjkkradioV1 = "";
state.xjkkradioV1 = false;
state.completeType = "";
state.xjkkinputV1 = "";
state.onceName = "";
@@ -3629,7 +3633,7 @@ export default defineComponent({
state.xjkkinputV4 = null;
state.checked1 = false;
state.checked4 = false;
state.EditTestId = 0;
state.EditTestId = null;
state.assessmentId = null;
state.assessmentName = "";
state.workInfo = {};
@@ -3676,10 +3680,10 @@ export default defineComponent({
endTime: endTime,
evalFlag: Number(state.assessmentId) > 0 && state.checked4 ? 1 : 0,
assessmentId: Number(state.assessmentId),
testId: state.examInfo.examinationName ? state.EditTestId : 0,
testId: state.examInfo.examinationName ? state.EditTestId : null,
homeWorkId: state.EditWorkId,
name: state.xjkkinputV1,
signFlag: state.xjkkradioV1 === 0 ? 1 : 0, //是否允许未报名的签到:1是0否
signFlag: state.xjkkradioV1 ? 1 : 0, //是否允许未报名的签到:1是0否
// signWordFlag: state.xjkkradioV1 === 1 ? 1 : 0, //签到是否需要口令:1是0否
teacherId: state.member.value,
teacher: state.member.name,
@@ -3720,6 +3724,7 @@ export default defineComponent({
//编辑开课
const handelEditStu = async (item) => {
state.offcourseId = item.offcourseId;
state.itemType = item.type;
state.offcoursePlanId = item.id;
if (item.homeWorkId) {
@@ -3762,7 +3767,7 @@ export default defineComponent({
state.afterStartValue = item.afterStart; //考勤 开始后
if (item.signFlag === 1) {
//是否允许未报名的签到:1是0否
state.xjkkradioV1 = 0;
state.xjkkradioV1 = true;
}
state.member = { value: item.teacherId, name: item.teacher };
state.cstm_hs = true;
@@ -3882,20 +3887,12 @@ export default defineComponent({
customRender: ({ record }) => {
return (
<div class="racona">
{record.workScore === -2 ? (
"-"
) : record.workScore ? (
<span>{record.workScore}</span>
) : (
<span
style={{ color: "#4EA6FF", cursor: "pointer" }}
onClick={() => {
handlJoinStu(record);
}}
>
成绩录入
</span>
)}
{record.workStatus? record.workScore?<span>{record.workScore || '-'}</span>:
<span style={{ color: "#4EA6FF", cursor: "pointer" }} onClick={() => handlJoinStu(record)}>
成绩录入
</span>
: <span>-</span>
}
</div>
);
// switch (String(record.status)) {
@@ -3999,7 +3996,7 @@ export default defineComponent({
};
const clear_xjkkradioV1 = (value) => {
if (value != "") {
state.xjkkradioV1 = "";
state.xjkkradioV1 = false;
}
};
const clear_xjkkradioV2 = (value) => {
@@ -4295,7 +4292,6 @@ export default defineComponent({
// ]
// commonExport(heads,list,"课程导出")
// })
window.open(
`${process.env.VUE_APP_BASE_API}/admin/offcourse/export?pageNo=${
state.currentPage1
@@ -4305,8 +4301,8 @@ export default defineComponent({
state.projectName ? state.projectName : ""
}&name=${state.name ? state.name : ""}&createName=${
state.createName ? state.createName : ""
}&endTime=${endTime ? endTime : ""}&beginTime=${
startTime ? startTime : ""
}&endTime=${endTime ? dayjs(new Date(state.projectTime[1].$d)).format('YYYY-MM-DD') : ""}&beginTime=${
startTime ? dayjs(new Date(state.projectTime[0].$d)).format('YYYY-MM-DD') : ""
}&type=3`
);

View File

@@ -138,11 +138,11 @@
<a-button @click="showCopyModal(record.id)" type="link"
>复制</a-button
>
<a-button @click="showDeleteModal(record.id)" type="link" danger
<a-button v-if="record.state !== '已发布'" @click="showDeleteModal(record.id)" type="link" danger
>删除</a-button
>
<a-button
v-if="record.state === '已发布'"
v-if="record.state === '已发布' && record.status!== -1"
@click="showBackModal(record.id)"
type="link"
>撤回</a-button

View File

@@ -160,9 +160,7 @@
</div>
<div class="nubbox">
<div>
<span class="nub1" style="color: #a497ff">{{
routerInfoOverview.completeRatio
}}</span
<span class="nub1" style="color: #a497ff">{{(routerInfoOverview.completeRatio * 100).toFixed(2)}}</span
><span style="color: #a497ff; font-size: 14px">%</span>
</div>
<div class="nub2">总完成率</div>
@@ -195,9 +193,7 @@
<a-progress
type="dashboard"
gapDegree="0"
:percent="
chapterOverviewList[choosedStageIndex]?.completeCourseRatio
"
:percent=" fixDoublePer(chapterOverviewList[choosedStageIndex]?.completeCourseRatio || 0) "
:width="140"
/>
<div class="protext">课程完成率</div>
@@ -206,9 +202,7 @@
<a-progress
type="dashboard"
gapDegree="0"
:percent="
chapterOverviewList[choosedStageIndex]?.completeExamRatio
"
:percent="fixDoublePer(chapterOverviewList[choosedStageIndex]?.completeExamRatio || 0)"
:width="140"
/>
<div class="protext">考试通过率</div>
@@ -217,65 +211,47 @@
<a-progress
type="dashboard"
gapDegree="0"
:percent="
chapterOverviewList[choosedStageIndex]?.completeRatio
"
:percent="fixDoublePer(chapterOverviewList[choosedStageIndex]?.completeRatio || 0)"
:width="140"
/>
<div class="protext">作业完成率</div>
</div>
<div class="proright">
<div class="pronub" style="margin-left: 142px">
{{
chapterOverviewList[choosedStageIndex]
? chapterOverviewList[choosedStageIndex].totalTaskCnt
: 0
}}
{{ chapterOverviewList[choosedStageIndex].completeTaskCnt || 0}}
</div>
<div class="proright1">
<span class="textpro">关卡任务总数</span>
<a-progress
:percent="
chapterOverviewList[choosedStageIndex]
? chapterOverviewList[choosedStageIndex].totalTaskCnt
: 0
"
:percent="fixDoublePer(chapterOverviewList[choosedStageIndex].completeTaskCnt / (chapterOverviewList[choosedStageIndex].totalTaskCnt || 0))"
style="width: 369px"
/>
</div>
<div class="pronub" style="margin-left: 142px">
{{
chapterOverviewList[choosedStageIndex]
? chapterOverviewList[choosedStageIndex].totalReqCnt
? chapterOverviewList[choosedStageIndex].completeReqCnt
: 0
}}
</div>
<div class="proright1">
<span class="textpro">必修</span>
<span class="textpro">必修任务</span>
<a-progress
:percent="
chapterOverviewList[choosedStageIndex]
? chapterOverviewList[choosedStageIndex].totalReqCnt
: 0
"
:percent="fixDoublePer(chapterOverviewList[choosedStageIndex].completeReqCnt / (chapterOverviewList[choosedStageIndex].totalReqCnt || 0))"
style="width: 369px"
/>
</div>
<div class="pronub" style="margin-left: 142px">
{{
chapterOverviewList[choosedStageIndex]
? chapterOverviewList[choosedStageIndex].totalOptCnt
? chapterOverviewList[choosedStageIndex].completeOptCnt
: 0
}}
</div>
<div class="proright1">
<span class="textpro">选修</span>
<span class="textpro">选修任务</span>
<a-progress
:percent="
chapterOverviewList[choosedStageIndex]
? chapterOverviewList[choosedStageIndex].totalOptCnt
: 0
"
:percent="fixDoublePer(chapterOverviewList[choosedStageIndex].completeOptCnt / (chapterOverviewList[choosedStageIndex].totalOptCnt || 0))"
style="width: 369px"
/>
</div>
@@ -325,9 +301,9 @@
<div style="flex: 1">
<div class="onerow">
<div class="taskmain">任务大纲</div>
<!-- <ImpoterGroupLeader title="批量面授报名" :data="{targetId:routerId,type:2}" :url="`/admin/offcourse/importCourse`" :template-url="`/admin/router/exportTaskCoursePlan/${routerId}?type=1&taskType=2&thirdType=3`">
<ImpoterGroupLeader title="批量面授报名" :data="{targetId:routerId,type:2}" :url="`/admin/offcourse/importCourse`" :template-url="templateUrl">
<button class="btn">批量面授报名</button>
</ImpoterGroupLeader> -->
</ImpoterGroupLeader>
<router-link
:to="{ path: '/leveladddetail', query: { routerId: routerId } }"
class="editright"
@@ -468,20 +444,12 @@
<div style="display: flex">
<a-progress
:showInfo="false"
:percent="
parseInt(
(item.finishStuNum / item.totalStuNum) * 100
)
"
:percent=" parseInt((item.finishStuNum / item.totalStuNum) * 100)"
strokeColor="#FFC067"
trailColor="rgba(253, 209, 98, 0.2)"
/>
<span class="progresstext" style="margin-left: 10px"
>{{
parseInt(
(item.finishStuNum / item.totalStuNum) * 100
) || 0
}}%</span
>{{parseInt((item.finishStuNum / item.totalStuNum) * 100) || 0}}%</span
>
</div>
</div>
@@ -1443,15 +1411,15 @@ import RouterHomeworkManage from "../../components/drawers/router/RouterHomework
import RouterCommonManage from "../../components/drawers/router/RouterCommonManage";
import RouterVoteManage from "../../components/drawers/router/RouterVoteManage";
import RouterProjectManage from "../../components/drawers/router/RouterProjectManage";
// import ImpoterGroupLeader from "@/components/drawers/project/ImpoterGroupLeader.vue";
import ImpoterGroupLeader from "@/components/drawers/project/ImpoterGroupLeader.vue";
import TaskImpStu from "../../components/drawers/TaskFaceIn";
import { checkPer } from "@/utils/utils";
import { checkPer,fixDoublePer } from "@/utils/utils";
export default {
name: "LevelAdd",
components: {
// ImpoterGroupLeader,
ImpoterGroupLeader,
ProjectFaceTaskManage,
ProjCheckShip,
ImpStu,
@@ -1691,6 +1659,7 @@ export default {
isreload: true,
TaskFaceImpStuvisible: false,
uploadAction: process.env.VUE_APP_BASE_API + "/file/uploadunlimit",
templateUrl:process.env.VUE_APP_FILE_PATH+process.env.VUE_APP_FACE_STUDENT_TEMPLATE
});
const levelList = reactive({
@@ -2661,22 +2630,7 @@ export default {
item.courseId;
}
if (item.type == 2) {
// let date1 = new Date(item.endTime).getTime();
// let date2 = new Date().getTime();
// if (date1 < date2) return message.warning("当前面授课已结束");
// if (item.taskStatus == 1 || item.taskStatus == 2)
// return message.error("该任务无法学习,请联系管理员进行替换。");
// codeUrl =
// window.location.protocol +
// process.env.VUE_APP_H5 +
// "/faceteach?type=2&courseId=" +
// item.courseId +
// "&id=" +
// item.id; pathmappage?routerId=513&chapterId=730&isStudy=true
// codeUrl = window.location.protocol + process.env.VUE_APP_H5 + "/pathdetails?routerId=" + state.routerId;
codeUrl = window.location.protocol + process.env.VUE_APP_H5 + "/pathmappage?routerId=" + state.routerId + "&chapterId=" + item.chapterId + "&isStudy=true";
codeUrl = `${window.location.protocol + process.env.VUE_APP_H5}/FaceTeachCourseList?courseId=${item.courseId}&type=2&taskId=${item.id}`;
}
if (item.type == 3) return message.error("请在pc端完成");
@@ -3011,7 +2965,7 @@ export default {
showCodeModel2,
editLearnInfo,
pubIcon,
fixDoublePer,
faceTeachModel,
examinationModel,
evaluationModel,

View File

@@ -60,7 +60,7 @@
</div>
</div>
</div>
<a-modal v-model:visible="modal" :centered="true" :footer="null" wrapClassName="AddLevell" @cancel="closeModal">
<a-modal v-model:visible="modal" :centered="true" :footer="null" wrapClassName="AddLevell" @cancel="closeModal" :closable="false">
<div class="header">
<div class="headmain">
<div class="add">编辑/添加关卡</div>
@@ -294,7 +294,7 @@
编辑
</span>
<span
v-if="!element.routerTaskId && element.type===2"
v-if="routerInfo.routerInfo.status !== 1 && element.type===2"
style="color: #4ea6ff;cursor: pointer;"
@click="editTaskForType(element,index)">
编辑
@@ -431,6 +431,7 @@ const showModal = () => {
function showEditModal(ele) {
formValue.value = ele;
formValue.value.edit = true;
modal.value = true;
}
@@ -443,7 +444,7 @@ const editChapter = () => {
if (!formValue.value.name) {
return message.warning("请输入关卡名称");
}
if (formValue.value.id) {
if (formValue.value.edit) {
closeModal();
return;
}
@@ -597,10 +598,7 @@ const cancelStorage = async () => {
};
// 开课按钮
const openCourse = (ele) => {
coursePlanRef.value.openDrawer(ele);
};
const openCourse = (ele) => coursePlanRef.value.openDrawer(ele);
</script>
<style lang="scss">
.ConfirmModal {

View File

@@ -60,7 +60,7 @@
<!-- <button class="btn" @click="showFaceIn">批量面授报名</button> -->
<router-link
class="edit"
:to="{ path: `/temTask`, query: { projectId: projectTemplateId } }"
:to="{ path: `/temTask`, query: { projectId: projectId } }"
>
<img
class="editimg"
@@ -927,7 +927,7 @@ export default defineComponent({
const value = ref("");
const textnum = "150";
const routered = useRouter();
const {query: {projectTemplateId}} = useRoute();
const {query: {projectTemplateId:projectId}} = useRoute();
const changeopclo = () => {
state.projectInfo.noticeFlag = state.checked ? 1 : 0;
api
@@ -999,7 +999,7 @@ export default defineComponent({
});
// 获取详情
const getDetail = () => {
api.templateEditDetail(projectTemplateId).then((res) => {
api.templateEditDetail(projectId).then((res) => {
state.templateInfo = res.data.data
state.taskSyllabus = [];
state.projectInfo = res.data.data.projectTemplateInfo;
@@ -1023,7 +1023,7 @@ export default defineComponent({
console.log("what ------ > ", i, data);
// if (data[i].taskTemplateList.length !== 0) {
if (!data[i].name) {
continue;
// continue;
}
state.taskSyllabus.push({
text: data[i].name ? data[i].name : "无阶段任务",
@@ -1097,7 +1097,7 @@ export default defineComponent({
routered.push({
path: "/templateAdd",
query: {
projectTemplateId: projectTemplateId,
projectTemplateId: projectId,
},
});
};
@@ -1106,7 +1106,7 @@ export default defineComponent({
const stateEdit = () => {
let obj = {
name: "",
projectTemplateId: localStorage.getItem("projectTemplateId"),
projectTemplateId: projectId,
remark: "",
stageId: 0,
};
@@ -1129,7 +1129,7 @@ export default defineComponent({
flag: true,
name: "",
projectTaskId: 0,
projectTemplateId: localStorage.getItem("projectTemplateId"),
projectTemplateId: projectId,
stageId: 0,
type: 0
};
@@ -1146,7 +1146,7 @@ export default defineComponent({
};
const getScoreRule = () => {
scoreRule({
projectId: projectTemplateId,
projectId: Number(projectId),
})
.then((res) => {
let result = res.data.data;
@@ -1203,7 +1203,7 @@ export default defineComponent({
courseSyncFlag: state.projectInfo.courseSyncFlag ? 1 : 0,
notice: state.projectInfo.notice,
noticeFlag: state.projectInfo.noticeFlag,
projectTemplateId: localStorage.getItem("projectTemplateId"),
projectTemplateId: projectId,
remark: state.projectInfo.remark,
status: state.projectInfo.status,
attach: str,
@@ -1211,6 +1211,7 @@ export default defineComponent({
//要编辑项目
api
.templateEdit({
id: projectId,
name: state.projectInfo.name,
category: state.projectInfo.category,
picUrl: state.projectInfo.picUrl,
@@ -1223,7 +1224,7 @@ export default defineComponent({
courseSyncFlag: state.projectInfo.courseSyncFlag ? 1 : 0,
notice: state.projectInfo.notice,
noticeFlag: state.projectInfo.noticeFlag,
projectTemplateId: localStorage.getItem("projectTemplateId"),
projectTemplateId: projectId,
remark: state.projectInfo.remark,
status: state.projectInfo.status,
attach: str,
@@ -1255,7 +1256,7 @@ export default defineComponent({
api
.templateEdit({
sourceBelongId: state.projectInfo.sourceBelongId,
projectTemplateId: localStorage.getItem("projectTemplateId"),
projectTemplateId: projectId,
attach: str,
})
.then((res) => {
@@ -1275,7 +1276,7 @@ export default defineComponent({
// 设置上传图片开关
const checkedClose = (data, a) => {
console.log(data, a);
console.log("模板id" + projectTemplateId);
console.log("模板id" + projectId);
console.log("开关数据:" + JSON.stringify(data) + "====" + JSON.stringify(a))
state.attachSwitch = data;
@@ -1283,7 +1284,7 @@ export default defineComponent({
api
.templateEdit({
sourceBelongId: state.projectInfo.sourceBelongId,
projectTemplateId: projectTemplateId,
projectTemplateId: projectId,
attachSwitch: state.attachSwitch ? 1 : -1,
})
.then((res) => {
@@ -1297,7 +1298,7 @@ export default defineComponent({
//设置积分规则
const editRule = () => {
let obj = {
projectId: projectTemplateId,
projectId: projectId,
datas:[
{
"type": 1,
@@ -1397,7 +1398,7 @@ export default defineComponent({
return {
...toRefs(state),
value,
projectTemplateId,
projectId,
textnum,
changeopclo,
changecheck2,

View File

@@ -198,13 +198,13 @@
type="link"
>结束</a-button
>
<a-button
</DropDown>
<!-- <a-button
v-if="record.status == -1"
@click="showBackFinashModal(record.id)"
type="link"
>撤回</a-button
>
</DropDown>
> -->
</a-space>
</template>
</template>

View File

@@ -262,9 +262,9 @@
style="color: #4ea6ff;cursor: pointer;"
@click="editTaskForType(element,index)">
编辑
</span>
</span>
<span
v-if="!element.projectTaskId && element.type===2"
v-if="projectInfo.projectInfo.status !==3 && element.type===2"
style="color: #4ea6ff;cursor: pointer;"
@click="editTaskForType(element,index)">
编辑
@@ -533,6 +533,7 @@ const showModal = () => {
};
const editModal = () => {
formValue.value = projectInfo.value.stageList[activeIndex.value]
formValue.value.edit = true
stage.value = true
};
@@ -542,7 +543,7 @@ function editStage() {
message.warning("请输入阶段名称!");
return
}
if(formValue.value.id){
if(formValue.value.edit){
stage.value = false
return
}

View File

@@ -313,26 +313,26 @@
<div class="second" style="margin-top: 0">
<div class="nubbox">
<span class="nub1">{{
projectInfoOverview.totalStudentCnt
projectInfoOverview.totalStudentCnt || 0
}}</span>
<div class="nub2">总人数</div>
</div>
<div class="nubbox">
<span class="nub1" style="color: #ff90ae">{{
projectInfoOverview.studyStudentCnt
projectInfoOverview.studyStudentCnt || 0
}}</span>
<div class="nub2">学习人数</div>
</div>
<div class="nubbox">
<span class="nub1" style="color: #a497ff">{{
projectInfoOverview.completeStudentCnt
projectInfoOverview.completeStudentCnt || 0
}}</span>
<div class="nub2">完成人数</div>
</div>
<div class="nubbox">
<div>
<span class="nub1" style="color: #5dc988">{{
projectInfoOverview.onlineCourseCnt
projectInfoOverview.onlineCourseCnt || 0
}}</span>
<!-- <span style="color: #5dc988; font-size: 14px">%</span> -->
</div>
@@ -341,7 +341,7 @@
<div class="nubbox">
<div>
<span class="nub1" style="color: #ff90ae">{{
projectInfoOverview.offLineCourseCnt
projectInfoOverview.offLineCourseCnt || 0
}}</span>
<!-- <span style="color: #ff90ae; font-size: 14px">%</span> -->
</div>
@@ -350,7 +350,7 @@
<div class="nubbox">
<div>
<span class="nub1" style="color: #a497ff">{{
projectInfoOverview.completeRatio
((projectInfoOverview.completeRatio || 0) * 100).toFixed(2)
}}</span
><span style="color: #a497ff; font-size: 14px">%</span>
</div>
@@ -390,7 +390,7 @@
type="dashboard"
gapDegree="0"
:percent="
stageOverviewList[choosedStageIndex]?.completeCourseRatio
fixDoublePer( stageOverviewList[choosedStageIndex]?.completeCourseRatio || 0)
"
:width="140"
/>
@@ -401,7 +401,7 @@
type="dashboard"
gapDegree="0"
:percent="
stageOverviewList[choosedStageIndex]?.completeExamRatio
fixDoublePer(stageOverviewList[choosedStageIndex]?.completeExamRatio || 0)
"
:width="140"
/>
@@ -411,41 +411,39 @@
<a-progress
type="dashboard"
gapDegree="0"
:percent="stageOverviewList[choosedStageIndex]?.completeRatio"
:percent="fixDoublePer(stageOverviewList[choosedStageIndex]?.completeRatio || 0)"
:width="140"
/>
<div class="protext">作业完成率</div>
</div>
<div class="proright">
<div class="pronub" style="margin-left: 142px">
{{ stageOverviewList[choosedStageIndex]?.completeTaskCnt }}
{{ stageOverviewList[choosedStageIndex]?.completeTaskCnt || 0}}
</div>
<div class="proright1">
<span class="textpro">阶段任务总数</span>
<a-progress
:percent="
stageOverviewList[choosedStageIndex]?.totalTaskCnt
"
:percent="fixDoublePer(stageOverviewList[choosedStageIndex]?.completeTaskCnt/(stageOverviewList[choosedStageIndex]?.totalTaskCnt || 0))"
style="width: 369px"
/>
</div>
<div class="pronub" style="margin-left: 142px">
{{ stageOverviewList[choosedStageIndex]?.totalReqCnt }}
{{ stageOverviewList[choosedStageIndex]?.completeReqCnt || 0}}
</div>
<div class="proright1">
<span class="textpro">必修</span>
<span class="textpro">必修任务</span>
<a-progress
:percent="stageOverviewList[choosedStageIndex]?.totalReqCnt"
:percent="fixDoublePer(stageOverviewList[choosedStageIndex]?.completeReqCnt/(stageOverviewList[choosedStageIndex]?.totalReqCnt || 0))"
style="width: 369px"
/>
</div>
<div class="pronub" style="margin-left: 142px">
{{ stageOverviewList[choosedStageIndex]?.totalOptCnt }}
{{ stageOverviewList[choosedStageIndex]?.completeOptCnt || 0}}
</div>
<div class="proright1">
<span class="textpro">选修</span>
<span class="textpro">选修任务</span>
<a-progress
:percent="stageOverviewList[choosedStageIndex]?.totalOptCnt"
:percent="fixDoublePer(stageOverviewList[choosedStageIndex]?.completeOptCnt/(stageOverviewList[choosedStageIndex]?.totalOptCnt || 0))"
style="width: 369px"
/>
</div>
@@ -459,14 +457,14 @@
<div class="split"></div>
<div class="onerow">
<div class="taskmain">任务大纲</div>
<!-- <ImpoterGroupLeader
<ImpoterGroupLeader
title="批量面授报名"
:data="{ targetId: projectId, type: 1 }"
:url="`/admin/offcourse/importCourse`"
:template-url="`/admin/project/exportTaskCoursePlan/${projectId}?type=1&taskType=2&thirdType=3`"
:template-url="templateUrl"
>
<button class="btn">批量面授报名</button>
</ImpoterGroupLeader> -->
</ImpoterGroupLeader>
<router-link
v-if="checkPer(permissions, createId)"
:to="{ path: `/taskadd`, query: { projectId: projectId } }"
@@ -816,9 +814,10 @@
<span class="btn1text">导出小组</span>
</div>
<ImpoterGroupLeader
title="导入小组长"
@change="handleChangeGroupLeader"
:data="{ targetId: projectId, type: 1 }"
:url="`/admin/studentGroup/importGroup`"
:template-url="`/admin/studentGroup/exportGroup/${projectId}`"
>
<div class="btn1">
<span class="btn1text">导入小组长</span>
@@ -899,6 +898,19 @@
</div>
</div>
</div>
<!-- 小组列表分页 -->
<div style="width: 100%;display:flex;justify-content:center;align-items:center;margin-top: 12px;">
<a-pagination
:showSizeChanger="false"
showQuickJumper="true"
hideOnSinglePage="true"
:pageSize="stupageSize"
:current="currentPageStu"
:total="groupTotal"
class="pagination"
@change="changePagination"
/>
</div>
</a-tab-pane>
</a-tabs>
</div>
@@ -1096,7 +1108,6 @@
>
<div class="certificatelistMain">
<img
@click="previewPic"
style="cursor: pointer; width: 140px; height: 200px"
:src="item.url"
alt=""
@@ -2311,7 +2322,7 @@ import TableStudent from "@/components/student/TableStudent";
import TableCertificateStudent from "@/components/student/TableCertificateStudent";
import { getStuPage } from "@/api/index1";
import ChangeGroupModal from "@/components/student/ChangeGroupModal.vue";
import { checkPer } from "@/utils/utils";
import { checkPer,fixDoublePer } from "@/utils/utils";
import ImpoterGroupLeader from "@/components/drawers/project/ImpoterGroupLeader.vue";
export default {
name: "taskPage",
@@ -2497,7 +2508,7 @@ export default {
valuestu1: 0,
//进度排行阶段
rankjieduan: [],
valuestu2: "",
valuestu2: 0,
//积分排行
rankxuefen: [
{ value: 0, label: "学员" },
@@ -2564,6 +2575,7 @@ export default {
groupInfo: { leaderName: "", leaderId: "" }, //创建小组
groupMemberCountContrast: null,
groupPageList: [], //小组列表
groupTotal: 0,
groupNumber: 0, //组员人数
valuestun: "", //学员管理姓名
valuegood: "",
@@ -2843,6 +2855,7 @@ export default {
certificatelist: [],
fileUrl: process.env.VUE_APP_FILE_PATH,
uploadAction: process.env.VUE_APP_BASE_API + "/file/uploadunlimit",
templateUrl:process.env.VUE_APP_FILE_PATH+process.env.VUE_APP_FACE_STUDENT_TEMPLATE
});
// 排行榜 - start
// 积分排行榜 Top10
@@ -3020,17 +3033,17 @@ export default {
}
}
levelList.stageList = res.data.data.stageList;
state.valuestu2 = 0;
if (
levelList.stageList.length === 1 &&
levelList.stageList[0].id === "0"
) {
// 无解段任务
state.rankjieduan = [{ value: 0, label: "无阶段" }];
state.valuestu2 = 0;
state.rankjieduan = [{ value: 0, label: "全部" }];
} else {
// 有阶段任务
console.log("有阶段任务", levelList.stageList);
let arrStage = [];
let arrStage = [{ value: 0, label: "全部" }];
for (let i = 0; i < levelList.stageList.length; i++) {
if (levelList.stageList[i].id !== "0") {
let obj = {
@@ -3041,7 +3054,6 @@ export default {
}
}
state.rankjieduan = arrStage;
state.valuestu2 = arrStage[0].value;
state.choosedStageName = levelList.stageList[0].name;
}
//暂时传个固定的id用 到时候看数据里面是否有在更换
@@ -4022,9 +4034,15 @@ export default {
};
getGroupList(objf).then((res) => {
state.groupPageList = res.data.data.rows;
state.groupTotal = res.data.data.total;
setGroupList(res.data.data.rows);
});
};
//分页
const changePagination = (page) => {
state.currentPageStu = page;
getGroup();
};
//删除小组
const deleteGroupBtn = (projectGroupId) => {
deleteGroup({ projectGroupId }).then(() => {
@@ -4614,15 +4632,7 @@ export default {
item.courseId;
}
if (item.type == 2) {
// codeUrl =
// window.location.protocol +
// process.env.VUE_APP_H5 +
// "/faceteach?type=1&courseId=" +
// item.courseId +
// "&id=" +
// item.id;
codeUrl = window.location.protocol + process.env.VUE_APP_H5 + "/projectdetails?type=1&projectId=" + state.projectId;
codeUrl = `${window.location.protocol + process.env.VUE_APP_H5}/FaceTeachCourseList?courseId=${item.courseId}&type=1&taskId=${item.id}`;
}
if (item.type == 3) return message.error("请在pc端完成");
if (item.type == 4) {
@@ -4887,6 +4897,14 @@ export default {
function previewPic() {
state.modal1Visible = true;
}
// 导入小组长成功回调
function handleChangeGroupLeader(e) {
if(e=="end"){
message.destroy();
message.success("导入小组长成功");
getGroup();
}
}
return {
...toRefs(state),
...toRefs(levelList),
@@ -4996,6 +5014,7 @@ export default {
checkType,
downloadFile,
checkPer,
fixDoublePer,
addCertificate,
editCertificate,
deleteCertificate,
@@ -5009,6 +5028,8 @@ export default {
jdSelectChange1,
studytimeRank,
xsSelectChange,
changePagination,
handleChangeGroupLeader
};
},
};

View File

@@ -8,7 +8,7 @@
<img src="../../assets/images/projectadd/right.png" style="margin-left: 10px; cursor: pointer"
@click="showCancel" v-show="projectInfo.stageList[0].id != '0'" />
</div>
<div class="btn btn3" @click="showModal({}, 'add')" style="margin-left: 19px">
<div class="btn btn3" @click="showModal()" style="margin-left: 19px">
<div class="search"></div>
<div class="btnText">添加阶段</div>
</div>
@@ -33,10 +33,10 @@
<span style="font-size: 12px; color: #ffffff">说明</span>
</div>
</a-popover>
<div class="imgIcon" @click="showModal(element, 'edit')"></div>
<div class="imgIcon" @click="editModal()"></div>
</div>
<div class="boxs_right">
<div class="imgIcon" @click="showDeleteStage(index)"></div>
<div class="imgIcon" @click="deleteStage()"></div>
</div>
</div>
<div class="items2">
@@ -98,7 +98,8 @@
<div class="mid">
<div class="item" v-for="(value, key) in TASK_TYPE" :key="key">
<div v-if="key != 13">
<component :is="value.component" :ref="el => courseRef['el' + key] = el" :type="key" :infoType="1" :id="projectInfo.projectTemplateInfo?.id"
<component :is="value.component" :ref="el => courseRef['el' + key] = el" :type="key" :infoType="3" :id="projectInfo.projectTemplateInfo?.id"
:chapter-list="projectInfo.stageList"
v-model:task-list="projectInfo.stageList[activeIndex].taskTemplateList">
<div class="itcon">
<div class="img">
@@ -317,8 +318,8 @@
<div class="namebox">
<div class="inname">阶段说明</div>
</div>
<div class="intext" style="margin-left: 14px">
<a-textarea v-model:value="formValue.remark" style="height: 88px" show-count :maxlength="100"
<div class="intext" style="margin-left: 14px;width:384px">
<a-textarea v-model:value="formValue.remark" style="height: 88px;width:384px" show-count :maxlength="100"
placeholder="请输入阶段说明" />
</div>
</div>
@@ -357,7 +358,7 @@
</a-modal>
</div>
<!-- 确认添加阶段弹窗 -->
<a-modal v-model:visible="confirmModal" :footer="null" wrapClassName="ConfirmModal" centered="true">
<a-modal v-model:visible="confirmModal" :footer="null" wrapClassName="ConfirmModal" :centered="true">
<div class="delete">
<div class="del_header"></div>
<div class="del_main">
@@ -381,7 +382,7 @@
</div>
</a-modal>
<!-- 确认取消阶段弹窗 -->
<a-modal v-model:visible="cancelModal" :footer="null" wrapClassName="ConfirmModal" centered="true">
<a-modal v-model:visible="cancelModal" :footer="null" wrapClassName="ConfirmModal" :centered="true">
<div class="delete">
<div class="del_header"></div>
<div class="del_main">
@@ -482,68 +483,35 @@
</div>
</div>
</a-modal>
<!-- 是否删除阶段弹窗 -->
<a-modal v-model:visible="deleteStageModal" :footer="null" :closable="cC" wrapClassName="ConfirmModal"
centered="true">
<div class="delete">
<div class="del_header"></div>
<div class="del_main">
<div class="header">
<div class="icon"></div>
<span>提示</span>
<!-- <div class="close_exit" @click="closeDeleteStage"></div> -->
</div>
<div class="body">
<span style="width:320px;display:flex;justify-content:center;align-items:center;">{{
projectInfo.stageList?.length === 1 ? "当前为最后一个阶段,删除后任务将被移出,为无阶段模式,确认删除阶段吗?" : "您确定要删除此阶段"
}}</span>
</div>
<div class="del_btnbox">
<div class="del_btn btn2" @click="closeDeleteStage" style="margin-right: 32px;">
<div class="btnText">取消</div>
</div>
<div class="del_btn btn2" @click="deleteStage">
<div class="btnText">确定</div>
</div>
</div>
</div>
</div>
</a-modal>
</div>
</template>
<script setup>
import { computed, onMounted, onUnmounted, ref, watch, } from "vue";
import { computed, onMounted, ref, watch, } from "vue";
import { message } from "ant-design-vue";
import * as api from "../../api/indexTemplate";
import * as api from "@/api/indexTemplate";
import Draggable from "vuedraggable";
import { useRoute } from "vue-router";
import { TASK_TYPE } from "@/utils/const";
import { request } from "@/api/request";
import { PROJECT_TEMPLATE_DETAIL_MODIFY } from "@/api/apis";
import dialog from "@/utils/dialog";
const route = useRoute();
const courseRef = ref({})
const visiblene = ref(false);
const deAll = ref(false);
const deleteModal = ref(false);
const confirmModal = ref(false);
const stage = ref(false);
const ischapterEdit = ref(false);//修改阶段标志
const cancelModal = ref(false);
const deleteStageModal = ref(false);
const templateLoading = ref(false);
const cancleLoading = ref(false);
const projectInfo = ref({
stageList: [{
"id": "0",
taskTemplateList: [{
}]
taskTemplateList: [{}]
}],
projectTemplateInfo: {
}
projectTemplateInfo: {}
});
const activeIndex = ref(0);
const moveChapterIndex = ref(0);
@@ -579,7 +547,7 @@ function changeStageIndex(index) {
const getTask = async () => {
await api.templateEditDetail(route.query.projectId).then((res) => {
projectInfo.value = res.data.data
if (projectInfo.value.stageList.length == 0) {
if (projectInfo.value.stageList.length === 0) {
projectInfo.value.stageList = [{
"id": "0",
taskTemplateList: []
@@ -635,94 +603,80 @@ const closeModal = () => {
stage.value = false
};
//显示添加阶段弹窗
const showModal = (e, type) => {
ischapterEdit.value = (type === "edit");
console.log(ischapterEdit.value)
if (type == 'edit') {
console.log("阶段信息:" + e.name);
formValue.value = e;//回传修改的信息
} else {
formValue.value = {};
}
const showModal = () => {
formValue.value = {taskTemplateList: []}
stage.value = true
};
const editModal = () => {
formValue.value = projectInfo.value.stageList[activeIndex.value]
formValue.value.edit = true
stage.value = true
};
//添加阶段
function editStage() {
if (!formValue.value.name) {
message.warning("请输入阶段名称!");
return
}
//是否修改阶段2023-02-27add
if (ischapterEdit.value) {//修改
projectInfo.value.stageList[activeIndex.value] = formValue.value;
} else {//添加
projectInfo.value.stageList.push({ ...formValue.value })
if(formValue.value.edit){
stage.value = false
return
}
//替换 默认阶段
if (projectInfo.value.stageList.length === 1 && projectInfo.value.stageList[0].id === '0') {
formValue.value.taskTemplateList = [...projectInfo.value.stageList[0].taskTemplateList]
console.log("修改后的阶段信息:" + JSON.stringify(projectInfo.value.stageList[activeIndex.value]))
projectInfo.value.stageList.push({...formValue.value})
projectInfo.value.stageList.splice(0, 1)
} else {
projectInfo.value.stageList.push({...formValue.value})
activeIndex.value = activeIndex.value + 1
console.log("activeIndex.value" + activeIndex.value);
}
formValue.value = { taskTemplateList: [] }
console.log(projectInfo.value.stageList);
formValue.value = {taskTemplateList: []}
stage.value = false
}
//打开删除阶段弹窗
const showDeleteStage = (index) => {
deleteStageModal.value = true;
deleteIndex.value = index;
};
//关闭删除阶段弹窗
const closeDeleteStage = () => {
deleteStageModal.value = false;
};
//删除阶段
const deleteStage = () => {
console.log("删除阶段前的数据:" + JSON.stringify(projectInfo.value));
if (projectInfo.value.stageList.length === 1) {
projectInfo.value.stageList = [{ id: '0', stageId: '0', name: '', remark: '', taskTemplateList: [] }];
deleteStageModal.value = false;
return
}
projectInfo.value.stageList[activeIndex.value].deleted = true;
console.log("删除阶段后的数据:" + JSON.stringify(projectInfo.value));
activeIndex.value = activeIndex.value - 1;
deleteStageModal.value = false;
dialog({
content: projectInfo.value.stageList.length === 1 ? "当前为最后一个阶段,删除后任务将被移出,为无阶段模式,确认删除阶段吗?" : '确认删除此阶段吗?',
ok: () => {
message.success("删除成功");
if (projectInfo.value.stageList[activeIndex.value].id) {
projectInfo.value.stageList[activeIndex.value].deleted = true
projectInfo.value.stageList[activeIndex.value].taskTemplateList?.forEach((t, i) => t.id ? (t.deleted = true) : projectInfo.value.stageList[activeIndex.value].taskTemplateList.splice(i, 1));
} else {
projectInfo.value.stageList.splice(activeIndex.value, 1)
}
activeIndex.value && (activeIndex.value = activeIndex.value - 1);
},
});
};
onMounted(() => {
document.getElementsByTagName("main")[0].style.background = "rgb(245, 247, 250,1)";
document.getElementsByTagName("main")[0].style.boxShadow = "none";
getTask();
});
onMounted(getTask);
const showCancel = () => cancelModal.value = true;
const closeCancel = () => cancelModal.value = false;
onUnmounted(() => {
document.getElementsByTagName("main")[0].style.background = "#ffffff";
document.getElementsByTagName("main")[0].style.boxShadow = "0px 1px 35px 0px rgba(118, 136, 166, 0.07)";
});
const closeConfirm = () => {
confirmModal.value = false;
};
const showCancel = () => {
cancelModal.value = true;
};
const closeCancel = () => {
cancelModal.value = false;
};
const showDelete = (index) => {
deleteModal.value = true;
deleteIndex.value = index
};
const closeDelete = () => {
deleteModal.value = false;
};
const closeDelete = () => deleteModal.value = false;
// 删除所有阶段
const removeAllLevel = () => {
dialog({
content: '确定要删除所有阶段吗?',
ok: () => {
message.success("删除成功");
projectInfo.value.stageList.forEach((t, i) => {
if (t.id) {
t.checked = false;
t.deleted = true;
} else {
projectInfo.value.stageList.splice(i, 1)
}
})
},
});
};
//全选任务或全不选任务
const selectRowAll = () => {