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_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= 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= 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_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_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 store = useStore();
const isLogin = ref(false); const isLogin = ref(false);
console.log("版本2.3.6------------");
console.log("版本1.4.9------------");
// 监听关闭浏览器 // 监听关闭浏览器
let time1 = ref(0); let time1 = ref(0);

View File

@@ -51,9 +51,8 @@ http.interceptors.response.use(
(response) => { (response) => {
// console.log('response', response) // console.log('response', response)
const { const {
data: {code, msg, show}, data: {code, msg ,show},
} = response; } = response;
console.log('code', code)
if (code === 0 || code === 200) { if (code === 0 || code === 200) {
return response; return response;
} }
@@ -65,7 +64,7 @@ http.interceptors.response.use(
localStorage.removeItem('refreshPage') localStorage.removeItem('refreshPage')
return Promise.reject(response); return Promise.reject(response);
} }
show && message.error(msg); show ? message.error(msg):message.error('系统接口数据异常,请联系管理员');
console.log("api %o", msg); console.log("api %o", msg);
return Promise.reject(response); 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 batchFinishTask = (obj) => http.post('/admin/student/batchFinishTask', obj)
//批量更新学员状态 //批量更新学员状态
export const batchUpdateStatus = (obj) => http.post('/admin/student/batchUpdateStatus', 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) => export const batchImportScore = (obj) =>
http.post('/admin/student/importHomeWork', obj, { http.post('/admin/student/importHomeWork', obj, {

View File

@@ -1,6 +1,8 @@
import {isRef, reactive, ref, toRefs, unref, watch, watchEffect} from "vue"; import {isRef, reactive, ref, toRefs, unref, watch, watchEffect} from "vue";
import {getCookieForName, throttle} from "@/api/method"; import {getCookieForName, throttle} from "@/api/method";
import JSONBigInt from "json-bigint"; import JSONBigInt from "json-bigint";
import router from "@/router";
import {message} from "ant-design-vue";
const JSONBigIntStr = JSONBigInt({ storeAsString: true }); const JSONBigIntStr = JSONBigInt({ storeAsString: true });
@@ -346,5 +348,18 @@ export async function request(_url, params) {
return res.text(); return res.text();
}).then(res => { }).then(res => {
return JSONBigIntStr.parse(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> </script>
<style scoped lang="scss"> <style scoped lang="scss">
.impotergroupleader > .ant-drawer-content-wrapper {
min-width: 800px !important;
width: 800px !important;
}
.impotergroupleader { .impotergroupleader {
.drawerMain { .drawerMain {
min-width: 600px; min-width: 600px;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,6 +1,6 @@
<!-- eslint-disable vue/no-use-v-if-with-v-for --> <!-- eslint-disable vue/no-use-v-if-with-v-for -->
<template> <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="drawerMain">
<div class="header"> <div class="header">
<div class="headerTitle">查看</div> <div class="headerTitle">查看</div>
@@ -193,14 +193,14 @@ export default {
}; };
const getStuRank = () => { 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 = () => { const showProMess = () => {
state.Provisible = true; state.Provisible = true;
}; };
const check = () => { const check = () => {
state.loading = true 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.loading = false
state.info = res.data.data; state.info = res.data.data;
}) })

View File

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

View File

@@ -128,7 +128,7 @@
<div class="lastbox"> <div class="lastbox">
<div class="sorcetext">非常不满意</div> <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 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>
<div class="sorcetext">非常满意</div> <div class="sorcetext">非常满意</div>
</div> </div>

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -85,10 +85,17 @@
<div <div
class="btn btn1" class="btn btn1"
style="margin-right: 20px" style="margin-right: 20px"
@click="qrcodeVisible()" @click="qrcodeVisibleSign()"
> >
<div class="wz">签到二维码</div> <div class="wz">签到二维码</div>
</div> </div>
<div
class="btn btn1"
style="margin-right: 20px"
@click="qrcodeVisible()"
>
<div class="wz">开课二维码</div>
</div>
<CommonStudent <CommonStudent
:type="3" :type="3"
:isGroup="true" :isGroup="true"
@@ -103,7 +110,7 @@
添加学员 添加学员
</a-button> </a-button>
</CommonStudent> </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="btn btn1" style="margin-right: 20px;margin-left: 20px">
<div class="img1"></div> <div class="img1"></div>
<div class="wz">导入学员</div> <div class="wz">导入学员</div>
@@ -293,7 +300,10 @@ watch(() => data.value, () => {
tableRef.value.fetch(); tableRef.value.fetch();
}); });
// 开课签到二维码名字
const openCourseName = ref("");
const ChoiceCourse = (n) => { const ChoiceCourse = (n) => {
openCourseName.value = data.value[n].name;
coursePlanIndex.value = n; coursePlanIndex.value = n;
params.value.pid = data.value[n].id; params.value.pid = data.value[n].id;
tableRef.value.fetch(); tableRef.value.fetch();
@@ -370,11 +380,29 @@ function resetStudentPage() {
//二维码 //二维码
const qrcodeVisible = () => { const qrcodeVisible = () => {
qrCode({ qrCode({
title: "【签到】二维码", title: "【开课】二维码",
name: props.datasource?.name, 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=${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> </script>

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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