feat:增加小组导入导出

This commit is contained in:
lixg
2023-02-12 19:44:22 +08:00
parent fe4711ad68
commit 727fd1578d
7 changed files with 1402 additions and 660 deletions

View File

@@ -2,7 +2,7 @@
* @Author: lixg lixg@dongwu-inc.com
* @Date: 2022-11-04 22:45:31
* @LastEditors: lixg lixg@dongwu-inc.com
* @LastEditTime: 2023-02-09 09:36:11
* @LastEditTime: 2023-02-11 16:22:43
* @FilePath: /fe-manage/src/api/index1.js
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
@@ -220,3 +220,7 @@ export const updateStuCert = (obj) => http.post('/admin/certificate/updateStuCer
// 外部考试导入成绩
export const ImportExternalExamScore = (obj) => http.post('/admin/external/exam/manage/importExternalExamScore', obj, { headers: { "Content-Type": "multipart/form-data" } })
//分组
export const changeGroupByStudentId = (obj) => http.post('/admin/student/changeGroupByStudentId', obj)
//导入小组
export const importGroup = (uuid) => http.post('/admin/studentGroup/importGroup/{pid}', { params: { uuid: uuid } })

View File

@@ -2,7 +2,7 @@
* @Author: lixg lixg@dongwu-inc.com
* @Date: 2022-11-18 14:09:43
* @LastEditors: lixg lixg@dongwu-inc.com
* @LastEditTime: 2022-12-05 15:27:36
* @LastEditTime: 2023-02-11 18:55:44
* @FilePath: /fe-manage/src/api/indexProjStu.js
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
@@ -43,3 +43,5 @@ export const studentScoreList = (obj) => http.post('/admin/project/studentScoreL
//添加项目学员
export const addStudent = (obj) => http.post('/admin/project/addStudent', obj)
//获取组员名单
export const groupMemberList = (obj) => http.post('/admin/studentGroup/groupMemberList', obj)

View File

@@ -39,7 +39,7 @@
type: type,
targetId: Number(targetId),
chapterId: chapterId,
taskId:taskId
taskId: taskId,
}"
>
<p class="ant-upload-drag-icon">
@@ -235,7 +235,8 @@
const state = reactive({
fileType: ["xls", "xlsx"],
importScore:
process.env.VUE_APP_BASE_API + "/admin/external/exam/manage/ImportExternalScore",
process.env.VUE_APP_BASE_API +
"/admin/external/exam/manage/ImportExternalScore",
uploadpercent: -1,
uploadErr: false, //上传失败
addLoading: false,
@@ -244,10 +245,11 @@
errNum: 0, //失败数据数
downloadErrUrl: null, //下载失败数据
fileName: "",
locationHref:location.href.indexOf("http://") !== -1
locationHref:
location.href.indexOf("http://") !== -1
? "http://43.143.139.204:12016/"
: location.href.slice(0, location.href.indexOf("/m")) + "/upload/",
template: process.env.VUE_APP_UP_LOAD_STUDENT_SCORE_TEMPLATE
template: process.env.VUE_APP_UP_LOAD_STUDENT_SCORE_TEMPLATE,
});
const closeDrawer = () => {
ctx.emit("closeDraw", true);
@@ -260,7 +262,7 @@
const afterVisibleChange = (bool) => {
console.log("state", bool);
if (bool) {
console.log('当前是 1 项目 2 路径图', props.type)
console.log("当前是 1 项目 2 路径图", props.type);
}
};
@@ -288,7 +290,7 @@
state.fileName = info.file.name;
let i = 0;
let timeouts = setTimeout(() => {
clearInterval(timer)
clearInterval(timer);
state.addLoading = false;
message.destroy();
message.error(`文件导入超时`);
@@ -325,7 +327,6 @@
console.log("查询导入状态失败", err);
});
}, 500);
} else if (status === "error") {
state.uploadErr = true;
message.error(`${info.file.name}上传失败`);
@@ -384,7 +385,7 @@
}
};
function downTemplate() {
console.log(state.locationHref + state.template)
console.log(state.locationHref + state.template);
window.open(state.locationHref + state.template);
}

View File

@@ -161,7 +161,11 @@
<script>
import { toRefs, reactive } from "vue";
// import StuAdd from "./StuAdd.vue";
import { getProjStu, removeGroupStudent } from "../../api/indexProjStu";
import {
// getProjStu,
removeGroupStudent,
groupMemberList,
} from "../../api/indexProjStu";
import { toDate } from "../../api/method";
import { message } from "ant-design-vue";
import AddGroupMembers from "./AddGroupMembers.vue";
@@ -332,27 +336,23 @@ export default {
totalStageCnt: value.totalStageCnt, //总阶段数
progress: value.completeStageCnt + "/" + value.totalStageCnt,
stutime: toDate(value.beginStudyTime / 1000, "Y-M-D"), //开始学习时间
};
array.push(obj);
});
state.tabledata = array;
};
//获取员列表
//获取员列表
const getStu = (obj) => {
let objf = obj || {
deptIds: [], //部门
groupName: "",
name: "",
studentName: "",
pageNo: state.currentPage,
pageSize: 10,
projectId: props.projectId,
topFlag: "",
pid: props.projectId,
groupId: props.chooseGroupId, //暂时写死
};
state.tableDataTotal = -1;
getProjStu(objf).then((res) => {
groupMemberList(objf).then((res) => {
console.log(res.data.data, "获取学员列表");
if (res.data.code === 200) {
state.total = res.data.data.total;

View File

@@ -0,0 +1,652 @@
<template>
<a-drawer
:visible="ImpoterGroupLeaderV"
class="drawerStyle impotergroupleader"
placement="right"
width="800px"
@after-visible-change="afterVisibleChange"
>
<div class="drawerMain">
<div class="header">
<div class="headerTitle">导入小组长</div>
<img
style="width: 29px; height: 29px; cursor: pointer"
src="../../../assets/images/basicinfo/close.png"
@click="closeDrawer"
/>
</div>
<div class="main">
<div class="minatitl">
<div class="up1">请下载</div>
<div class="up2" @click="downTemplate" style="cursor: pointer">
模板
</div>
<div class="up1">按要求填写数据并导入</div>
</div>
<div class="upload">
<div class="text">上传</div>
<div class="right">
<div style="height: 176px; margin-bottom: 20px">
<a-upload-dragger
v-model:fileList="fileList"
:action="importLeader"
name="uploadFile"
:multiple="true"
@change="handleChange"
:showUploadList="false"
>
<p class="ant-upload-drag-icon">
<inbox-outlined></inbox-outlined>
</p>
<p class="ant-upload-text">点击或将文件拖拽到此处上传</p>
<p class="ant-upload-hint">支持扩展名.xls/.xlsx</p>
</a-upload-dragger>
</div>
<!-- <div class="load">
<div class="cloud"></div>
<div class="tip">点击或将文件拖拽到此处上传</div>
<div class="tipz">支持扩展名.xls/.xlsx</div>
</div> -->
<div class="loadstate">
<div
class="loadborder"
v-if="uploadpercent < 100 && uploadpercent !== -1"
>
<div class="content">
<div class="img"></div>
<div class="timebox">
<div class="timetop">
<div class="tit">{{ fileName }}</div>
<div class="stateloading">正在上传</div>
</div>
<a-progress :percent="uploadpercent" />
<!-- <div class="prog">
<div class="inprogloading"></div>
</div> -->
</div>
<div class="curloading">
<!-- <div class="cur">55%</div> -->
<!-- <div class="cancel" style="margin-left: 20px">暂停</div>
<div class="cancel" style="margin-left: 15px">取消</div> -->
</div>
</div>
</div>
<div class="loadborder" v-if="uploadErr">
<div class="content">
<div class="img"></div>
<div class="timebox">
<div class="timetop">
<div class="tit">{{ fileName }}</div>
<div class="statedefeat">上传失败</div>
</div>
<a-progress :percent="uploadpercent" />
<!-- <div class="prog">
<div class="inprogdefeat"></div>
</div> -->
</div>
<div class="curloading">
<!-- <div class="cur">55%</div> -->
<div
style="color: #387df7; margin-left: 20px; cursor: pointer"
>
下载失败数据
</div>
<!-- <div class="cancel" style="margin-left: 20px">暂停</div>
<div class="cancel" style="margin-left: 15px">取消</div> -->
</div>
<div
class="defeat"
style="display: flex; align-items: center"
>
<div style="color: #ff7474">
{{ succNum }}条数据导入成功{{ errNum }}条数据导入失败
</div>
</div>
</div>
</div>
<!-- v-if="uploadpercent === 100" -->
<div class="loadborder" v-if="uploadpercent === 100">
<div class="content">
<div class="img"></div>
<div class="timebox">
<div class="timetop">
<div class="tit">{{ fileName }}</div>
<div class="statesucce">上传成功</div>
</div>
<a-progress :percent="uploadpercent" />
<!-- <div class="prog">
<div class="inprogsucce"></div>
</div> -->
</div>
<div class="curloading">
<!-- <div class="cur">100%</div> -->
<div
class="cancel"
style="margin-left: 20px; cursor: pointer"
@click="removeUpload"
>
删除
</div>
</div>
</div>
<div v-if="errNum">
<div class="downloadErr" @click="downloadEeeorData">
下载失败数据
</div>
</div>
</div>
<div
v-if="uploadpercent === 100"
class="defeat"
style="
display: flex;
align-items: center;
width: 500px;
height: 40px;
"
:style="{
background: errNum
? 'rgba(255, 116, 116, 0.1)'
: 'rgba(53, 174, 105, 0.1)',
border: errNum ? '1px solid #ff7474' : '1px solid #35AE69',
}"
>
<img
style="width: 14px; height: 14px; margin-left: 16px"
:src="
errNum
? require('../../../assets/images/err.png')
: require('../../../assets/images/success.png')
"
/>
<div
style="margin-left: 8px"
:style="{ color: errNum ? '#ff7474' : 'rgba(0,0,0,0.65)' }"
>
{{ succNum }}条数据导入成功{{ errNum }}条数据导入失败
</div>
</div>
</div>
</div>
</div>
</div>
<div class="btnn">
<button class="btn1" @click="closeDrawer">取消</button>
<button class="btn2" @click="closeDrawer">确定</button>
</div>
</div>
<!-- 加载动画 -->
<div class="aeLoading" :style="{ display: addLoading ? 'flex' : 'none' }">
<a-spin :spinning="addLoading" tip="" />
</div>
</a-drawer>
</template>
<script>
import { reactive, toRefs } from "vue";
import { message } from "ant-design-vue";
import * as api from "../../../api/index1";
import { BATCH_IMPORT_SCORE } from "@/api/config";
export default {
name: "EScore",
props: {
ImpoterGroupLeaderV: {
type: Boolean,
default: false,
},
projectId: {
type: Number,
default: null,
},
//type=1 路径图 type=2 项目
type: {
type: String,
default: null,
},
id: {
type: Number,
default: null,
},
targetId: {
type: Number,
default: null,
},
taskId: {
type: Number,
default: null,
},
chapterId: {
type: Number,
default: null,
},
pid: {
type: Number,
default: null,
},
searchTaskList: {
type: Function,
default: null,
},
},
setup(props, ctx) {
const state = reactive({
fileType: ["xls", "xlsx"],
importLeader:
process.env.VUE_APP_BASE_API +
`/admin/studentGroup/importGroup/${props.projectId}`,
uploadpercent: -1,
uploadErr: false, //上传失败
addLoading: false,
fileList: [],
succNum: 0, //成功数据数
errNum: 0, //失败数据数
downloadErrUrl: null, //下载失败数据
fileName: "",
locationHref:
location.href.indexOf("http://") !== -1
? "http://43.143.139.204:12016/"
: location.href.slice(0, location.href.indexOf("/m")) + "/upload/",
template: process.env.VUE_APP_UP_LOAD_STUDENT_SCORE_TEMPLATE,
});
const closeDrawer = () => {
ctx.emit("closeDraw", true);
ctx.emit("update:ImpoterGroupLeaderV", false);
state.fileList = [];
state.uploadpercent = -1;
state.uploadErr = false; //上传失败
};
const afterVisibleChange = (bool) => {
console.log("state", bool);
if (bool) {
console.log("当前是 1 项目 2 路径图", props.type);
}
};
//上传文件
const handleChange = (info) => {
if (info) {
var FileExt = info.file.name.replace(/.+\./, "");
if (["xls", "xlsx"].indexOf(FileExt.toLowerCase()) === -1) {
state.fileList = [];
state.uploadpercent = -1;
message.destroy();
message.error("请上传正确的文件格式");
return;
}
}
state.addLoading = true;
state.uploadpercent = parseInt(info.file.percent);
console.log("我是文件上传的进度---------->", info.file.percent);
const status = info.file.status;
if (status !== "uploading") {
// console.log(info.file, info.fileList);
}
if (status === "done") {
state.fileName = info.file.name;
let i = 0;
let timeouts = setTimeout(() => {
clearInterval(timer);
state.addLoading = false;
message.destroy();
message.error(`文件导入超时`);
}, 30000);
let timer = setInterval(() => {
let uid = info.file.response.data;
api
.getImportStatus(uid)
.then((res) => {
console.log("查询导入状态", res);
if (res.data.code === 200) {
if (res.data.data.status !== "START") {
i++;
if (i === 1) {
message.destroy();
message.success(`${info.file.name}上传成功`);
state.addLoading = false;
props.searchTaskList && props.searchTaskList();
}
state.succNum = res.data.data.successNum;
state.errNum = res.data.data.failedNum;
state.downloadErrUrl = res.data.data.url;
console.log("props.getStudent", props.getStudent);
clearInterval(timer);
clearTimeout(timeouts);
}
}
})
.catch((err) => {
state.addLoading = false;
clearInterval(timer);
clearTimeout(timeouts);
console.log("查询导入状态失败", err);
});
}, 500);
} else if (status === "error") {
state.uploadErr = true;
message.error(`${info.file.name}上传失败`);
}
};
const beforeUpload = (file) => {
return new Promise((resolve, reject) => {
// const isJpgOrPng =
// file.name.indexOf(".xlsx") !== "-1" ||
// file.name.indexOf(".xls") !== "-1";
// if (!isJpgOrPng) {
// message.destroy();
// message.error("仅支持xls、xlsx格式!");
// return reject(false);
// }
const formData = new FormData();
formData.append("uploadFile", file);
// let progress = { percent: 1 };
// const intervalId = setInterval(() => {
// if (progress.percent < 100) {
// progress.percent++;
// file.onProgress(progress);
// } else {
// clearInterval(intervalId);
// }
// }, 100);
api.batchImportScore(formData).then((res) => {
if (res.data.code === 200) {
console.log("上传成功", res);
return reject(true);
}
});
return reject(false);
});
};
const handleUpload = (e) => {
console.log("handleUpload", e);
};
//删除
const removeUpload = () => {
state.fileList = [];
state.uploadpercent = -1;
state.uploadErr = false; //上传失败
state.succNum = 0;
state.errNum = 0;
state.downloadErrUrl = null;
state.addLoading = false;
};
// 下载失败数据
const downloadEeeorData = () => {
if (state.downloadErrUrl !== "") {
window.open(process.env.VUE_APP_FILE_PATH + state.downloadErrUrl);
}
};
function downTemplate() {
// console.log(state.locationHref + state.template);
// window.open(state.locationHref + state.template);
}
return {
...toRefs(state),
afterVisibleChange,
closeDrawer,
handleChange,
downTemplate,
BATCH_IMPORT_SCORE,
beforeUpload,
handleUpload,
removeUpload,
downloadEeeorData,
};
},
};
</script>
<style scoped lang="scss" >
.impotergroupleader {
.drawerMain {
min-width: 600px;
margin: 0px 32px 0px 32px;
overflow-x: auto;
display: flex;
flex-direction: column;
.header {
height: 73px;
border-bottom: 1px solid #e8e8e8;
display: flex;
justify-content: space-between;
align-items: center;
// background-color: red;
margin-bottom: 20px;
flex-shrink: 0;
.headerTitle {
font-size: 18px;
font-weight: 600;
color: #333333;
line-height: 25px;
// margin-left: 24px;
}
}
.main {
overflow-y: auto;
.minatitl {
display: flex;
.up1 {
font-size: 16px;
font-weight: 400;
color: #333333;
}
.up2 {
font-size: 16px;
font-weight: 400;
color: #4ea6ff;
margin-left: 4px;
}
}
.upload {
margin-top: 32px;
display: flex;
.text {
font-size: 14px;
font-weight: 400;
color: #333333;
}
.right {
margin-left: 6px;
.load {
width: 500px;
height: 176px;
background: #f5f9fd;
border-radius: 4px;
// opacity: 0.3;
border: 1px dashed #caddfd;
display: flex;
flex-direction: column;
align-items: center;
margin-bottom: 20px;
.cloud {
margin-top: 52px;
width: 28px;
height: 28px;
background-image: url(../../../assets/images/basicinfo/cloud.png);
}
.tip {
font-size: 14px;
font-weight: 400;
color: #4ea6ff;
margin-top: 15px;
cursor: pointer;
}
.tipz {
font-size: 14px;
font-weight: 400;
color: #999999;
margin-top: 10px;
}
}
.loadstate {
width: 500px;
margin-bottom: 100px;
.loadborder {
width: 500px;
height: 173px;
border-radius: 4px;
border: 1px dashed #eaeaea;
margin-bottom: 30px;
display: flex;
flex-direction: column;
justify-content: center;
position: relative;
.content {
display: flex;
margin-left: 20px;
position: relative;
.defeat {
width: 400px;
position: absolute;
left: 46px;
top: 38px;
font-size: 14px;
font-weight: 500;
justify-content: space-between;
}
.img {
width: 30px;
height: 34px;
background-image: url(../../../assets/images/basicinfo/exl.png);
}
.timebox {
margin-left: 15px;
margin-top: -5px;
.timetop {
display: flex;
width: 262px;
justify-content: space-between;
// margin-bottom: 8px;
.tit {
font-size: 14px;
font-weight: 400;
color: #333333;
}
.stateloading {
font-size: 14px;
font-weight: 400;
color: #4ea6ff;
}
.statedefeat {
font-size: 14px;
font-weight: 400;
color: #ff7474;
}
.statesucce {
font-size: 14px;
font-weight: 400;
color: #35ae69;
}
}
.prog {
width: 262px;
height: 5px;
background: #eaf1fe;
border-radius: 4px;
.inprogloading {
width: 55%;
height: 5px;
border-radius: 4px;
background: #4ea6ff;
}
//下载失败条
.inprogdefeat {
width: 55%;
height: 5px;
border-radius: 4px;
background: #ff7474;
}
//下载成功条
.inprogsucce {
width: 100%;
height: 5px;
border-radius: 4px;
background: #57c887;
}
}
}
.curloading {
margin-left: 15px;
margin-top: 15px;
display: flex;
.cur {
font-size: 14px;
font-weight: 400;
color: #333333;
}
.cancel {
font-size: 14px;
font-weight: 400;
color: #387df7;
}
}
}
.downloadErr {
width: 120px;
height: 32px;
display: flex;
align-items: center;
justify-content: center;
border-radius: 2px;
border: 1px solid #387df7;
font-size: 14px;
font-weight: 400;
color: #387df7;
line-height: 20px;
cursor: pointer;
margin-left: 66px;
margin-top: 16px;
position: absolute;
bottom: 28;
}
}
}
}
}
}
.btnn {
height: 72px;
width: 100%;
position: absolute;
background-color: #fff;
bottom: 0;
left: 0;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0px 1px 35px 0px rgba(118, 136, 166, 0.16);
.btn1 {
width: 100px;
height: 40px;
border: 1px solid #4ea6ff;
border-radius: 8px;
color: #4ea6ff;
background-color: #fff;
cursor: pointer;
}
.btn2 {
cursor: pointer;
width: 100px;
height: 40px;
background: #4ea6ff;
border-radius: 8px;
border: 0;
margin-left: 15px;
color: #fff;
}
}
}
}
</style>

View File

@@ -2,7 +2,7 @@
* @Author: lixg lixg@dongwu-inc.com
* @Date: 2022-12-20 17:00:37
* @LastEditors: lixg lixg@dongwu-inc.com
* @LastEditTime: 2023-01-31 16:14:39
* @LastEditTime: 2023-02-11 15:06:13
* @FilePath: /fe-manage/src/components/student/ChangeLevelModal.vue
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
-->
@@ -28,11 +28,12 @@
<!-- <div class="cur">当前关卡关卡2</div> -->
<div class="select">
<a-select
v-model:value="selectStage"
v-model:value="selectGroupId"
style="width: 100%"
placeholder="请选择小组"
:options="option"
allowClear
@change="selectGroup"
></a-select>
</div>
<div class="btn">
@@ -58,7 +59,8 @@
</template>
<script setup>
import { computed, defineEmits, defineProps, ref } from "vue";
// import { moveStudent } from "@/api/index1";
import * as api from "@/api/index1";
import { message } from "ant-design-vue";
// import { message } from "ant-design-vue";
const props = defineProps({
@@ -66,30 +68,56 @@ const props = defineProps({
type: Boolean,
default: false,
},
stage: {
groupList: {
type: Array,
default: () => [],
},
ids: {
type: Array,
default: () => [],
checkgroupStuId: {
type: Number,
default: null,
},
});
const option = computed(() => {
return props.stage.map((e) => ({ label: e.name, value: e.id }));
console.log("props.groupList", props.groupList);
return props.groupList.map((e) => ({
label: e.groupName,
value: e.projectGroupId,
}));
});
console.log("changegroupV", props.changegroupV);
const selectStage = ref();
const selectGroupId = ref();
const selectGroupName = ref();
const emit = defineEmits({});
const closeChangeModal = () => {
emit("update:changegroupV", false);
selectGroupId.value = null;
};
const selectGroup = (e, v) => {
console.log("选择小组", e, v);
selectGroupName.value = v.label;
};
//确认换组
const changeGroup = (item) => {
console.log("换组", item);
console.log("换组", selectGroupId.value, item);
let obj = {
groupId: selectGroupId.value,
groupName: selectGroupName.value,
studentId: props.checkgroupStuId,
};
console.log("换组obj", obj);
api
.changeGroupByStudentId(obj)
.then((res) => {
console.log("换组成功", res);
if (res.data.code === 200) {
message.success("换组成功");
}
})
.catch((err) => {
console.log("换组失败", err);
});
};
</script>

View File

@@ -725,7 +725,7 @@
<a-button @click="settingTopFlag(record)" type="link">{{
record.topFlag ? "取消优秀" : "优秀学员"
}}</a-button>
<a-button type="link" @click="showChangeGroupModal()"
<a-button type="link" @click="showChangeGroupModal(record)"
>换组</a-button
>
</template>
@@ -761,10 +761,10 @@
<img src="../../assets/images/courseManage/reset2.png" />
<span class="btn2text">随机分组</span>
</div>
<div class="btn2">
<div class="btn2" @click="exportGroup">
<span class="btn2text">导出小组</span>
</div>
<div class="btn2">
<div class="btn2" @click="importGroupLeader">
<span class="btn2text">导入小组长</span>
</div>
</div>
@@ -806,7 +806,7 @@
@click="showMemberList(item.projectGroupId)"
>
<div class="ftext">组员名单 ></div>
<div class="peoples">
<!-- <div class="peoples">
<div class="people1">
<img
src="../../assets/images/taskpage/people1.png"
@@ -827,7 +827,7 @@
src="../../assets/images/taskpage/people4.png"
/>
</div>
</div>
</div> -->
</div>
</div>
</div>
@@ -1676,6 +1676,24 @@
/>
</div>
</div>
<div class="name">
<div class="star" style="margin-top: -4px">
<img
style="width: 10px; height: 10px"
src="../../assets/images/basicinfo/asterisk.png"
/>
</div>
<div class="inname">组员人数:</div>
<div class="in">
<a-input-number
:min="0"
:max="300"
:precision="0"
style="width: 395px; height: 40px; border-radius: 8px"
v-model:value="groupNumber"
></a-input-number>
</div>
</div>
<div class="name">
<div class="star" style="margin-top: -4px">
<img
@@ -2092,8 +2110,18 @@
<!-- 二维码弹窗 -->
<!-- 换组弹窗 -->
<ChangeGroupModal v-model:changegroupV="changegroupV" />
<ChangeGroupModal
v-model:changegroupV="changegroupV"
:groupList="groupList"
:checkgroupStuId="checkgroupStuId"
/>
<!-- 换组弹窗 -->
<!-- 导入小组长 -->
<ImpoterGroupLeader
v-model:ImpoterGroupLeaderV="ImpoterGroupLeaderV"
:projectId="projectId"
/>
<!-- 导入小组长 -->
</div>
</template>
<script>
@@ -2154,7 +2182,7 @@ import TableCertificateStudent from "@/components/student/TableCertificateStuden
import { getStuPage } from "@/api/index1";
import ChangeGroupModal from "@/components/student/ChangeGroupModal.vue";
import { checkPer } from "@/utils/utils";
import ImpoterGroupLeader from "@/components/drawers/project/ImpoterGroupLeader.vue";
export default {
name: "taskPage",
components: {
@@ -2189,6 +2217,7 @@ export default {
CreateCertificate,
ProjectVoteManage,
ChangeGroupModal,
ImpoterGroupLeader,
},
setup() {
const store = useStore();
@@ -2380,6 +2409,7 @@ export default {
inputValue3: 5,
valueaddm: "", //创建小组输入小组长
valueaddg: "", //创建小组输入名称
groupNumber: 0, //组员人数
valuestun: "", //学员管理姓名
valuegood: "",
valuestub: "", //学员管理部门
@@ -2741,7 +2771,8 @@ export default {
modal1Visible: false, // 证书预览
changegroupV: false, //换组弹窗
checkgroupStuId: null, //换组id
ImpoterGroupLeaderV: false, //导入小组长抽屉
certificatelist: [],
fileUrl: process.env.VUE_APP_FILE_PATH,
});
@@ -2761,11 +2792,11 @@ export default {
const jdSelectChange1 = (e) => {
console.log(e);
completionRank();
}
};
const xsSelectChange = (e) => {
console.log(e)
console.log(e);
studytimeRank();
}
};
//项目积分榜单
const scoreRank = (period, type) => {
state.scoreRankLoading = true;
@@ -2855,11 +2886,13 @@ export default {
startTime: state.rankStartTime ? state.rankStartTime : 0, // 数据查询的起始时间 10位时间戳
endTime: state.rankEndTime ? state.rankEndTime : 0,
type: Number(state.valuestu4), // 查询类型 0 学员积分榜 1 小组积分榜
}
};
console.log('我是获取得项目学时排行榜--》', obj)
api.studytimeRank(obj).then(res=>{
console.log('项目学时榜单获取',res)
console.log("我是获取得项目学时排行榜--》", obj);
api
.studytimeRank(obj)
.then((res) => {
console.log("项目学时榜单获取", res);
if (res.data.datas) {
state.xueshitabledata = res.data.datas;
state.studytimeRankLoading = false;
@@ -2867,13 +2900,13 @@ export default {
state.xueshitabledata = [];
state.studytimeRankLoading = false;
}
}).catch(err=>{
console.log(err)
})
.catch((err) => {
console.log(err);
state.xueshitabledata = [];
state.studytimeRankLoading = false;
})
}
});
};
// 排行榜 - end
@@ -3106,9 +3139,10 @@ export default {
};
//显示学员换组弹窗
const showChangeGroupModal = () => {
const showChangeGroupModal = (record) => {
state.changegroupV = true;
console.log("点击换组", state.changegroupV);
console.log("点击换组", record.studentId);
state.checkgroupStuId = record.studentId;
};
const showModal2 = (classify, item) => {
@@ -3119,6 +3153,7 @@ export default {
console.log("item", item);
if (item) {
state.valueaddg = item.groupName;
state.groupNumber = item.groupMemberCount;
state.stuGroupName = item.leaderName;
state.stuGroupId = item.leaderId;
}
@@ -3127,6 +3162,7 @@ export default {
const closeModal2 = () => {
state.stugroup = false;
state.valueaddg = null;
state.groupNumber = 0;
state.stuGroupName = null;
state.stuGroupId = null;
state.projectGroupId = null;
@@ -3134,7 +3170,11 @@ export default {
};
//点击确定创建小组
const createG = () => {
if (state.stuGroupName == "" || state.valueaddg == "") {
if (
state.stuGroupName == "" ||
state.valueaddg == "" ||
state.groupNumber == null
) {
message.destroy();
return message.warning("请输入必填项");
} else {
@@ -3628,7 +3668,6 @@ export default {
completionRank();
// 获取学时排行榜
studytimeRank();
} else if (e == 3) {
state.tabFlag = true;
} else {
@@ -3821,6 +3860,7 @@ export default {
groupName: value.groupName, //小组名称
leaderId: value.leaderId, //组长id
leaderName: value.leaderName, //组长名称
groupMemberCount: value.groupMemberCount, //组员人数
source: value.source == 1 ? "指定添加" : "随机分组",
completeTaskCnt: value.completeTaskCnt, //完成任务数
totalTaskCnt: value.totalTaskCnt, //累计任务数
@@ -4051,6 +4091,7 @@ export default {
if (state.stuMemberClassify === 1) {
let obj = {
groupName: state.valueaddg,
groupMemberCount: state.groupNumber,
leaderId: state.stuGroupId,
leaderName: state.stuGroupName,
// projectGroupId: 0,
@@ -4073,6 +4114,7 @@ export default {
if (state.stuMemberClassify === 2) {
let obj = {
groupName: state.valueaddg,
groupMemberCount: state.groupNumber,
leaderId: state.stuGroupId,
leaderName: state.stuGroupName,
projectGroupId: state.projectGroupId,
@@ -4115,6 +4157,16 @@ export default {
console.log(data);
getStu();
};
//导入小组长
const importGroupLeader = () => {
state.ImpoterGroupLeaderV = true;
};
//导出小组
const exportGroup = () => {
window.open(
`${process.env.VUE_APP_BASE_API}/admin/studentGroup/exportGroup/${state.projectId}`
);
};
//end---------学员------
//start---------项目概览
@@ -4652,7 +4704,9 @@ export default {
window.location.protocol +
process.env.VUE_APP_H5 +
"/faceteach?type=2&courseId=" +
item.courseId+'&id='+ item.projectTaskId;
item.courseId +
"&id=" +
item.projectTaskId;
}
if (item.type == 4) {
@@ -4989,6 +5043,8 @@ export default {
closeStartModal,
templateProject,
changeGrouped,
importGroupLeader,
exportGroup,
deFile,
toDate,
routered,
@@ -5019,8 +5075,7 @@ export default {
jdSelectChange1,
studytimeRank,
xsSelectChange
xsSelectChange,
};
},
};