Files
fe-manage/src/components/drawers/router/RouterFaceStu.vue

1145 lines
31 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<a-drawer
:visible="FSvisible"
class="drawerStyle RouterFaceStu"
placement="right"
width="80%"
@after-visible-change="afterVisibleChange"
>
<div class="drawerMain">
<div class="header">
<div class="headerTitle">面授{{ datasource?.name }}</div>
<img
style="width: 29px; height: 29px; cursor: pointer"
src="../../../assets/images/basicinfo/close.png"
@click="closeDrawer"
/>
</div>
<div class="main">
<div class="titl">
<div class="endtime">
起止时间{{
datasource && datasource.startTime ? datasource.startTime : "-"
}}
{{ datasource && datasource.endTime ? datasource.endTime : "-" }}
</div>
<div class="endtime" style="margin-left: 64px">签到时间14:00</div>
</div>
<div class="search">
<div class="leftchoose">
<div class="namecon" style="margin-right: 30px">
<div class="name">姓名</div>
<a-input
v-model:value="name"
style="width: 270px; height: 40px; border-radius: 8px"
placeholder="请输入姓名"
/>
</div>
<!-- <div class="namecon" style="margin-right: 30px">
<div class="name">考勤</div>
<div class="select">
<a-select
v-model:value="projectName"
style="width: 160px"
placeholder="请选择"
:options="projectNameList"
@change="selectProjectName"
allowClear
showSearch
></a-select>
</div>
</div> -->
<div class="namecon">
<div class="name">签到状态</div>
<div class="select">
<a-select
v-model:value="projectName2"
style="width: 160px"
placeholder="请选择"
:options="projectNameList2"
@change="selectProjectName2"
allowClear
showSearch
></a-select>
</div>
</div>
</div>
<div class="btns">
<div
class="btn btn1"
style="margin-right: 20px"
@click="searchTaskList"
>
<div class="img1"></div>
<div class="wz">搜索</div>
</div>
<div class="btn btn2" @click="resetTaskList">
<div class="img2"></div>
<div class="wz">重置</div>
</div>
</div>
</div>
<div class="btnss" style="margin-top: 20px">
<div
class="btn btn1"
style="margin-right: 20px"
@click="qrcodeVisible()"
>
<div class="wz">签到二维码</div>
</div>
<div class="btn btn1" style="margin-right: 20px" @click="showImpStu">
<div class="img1"></div>
<div class="wz">导入学员</div>
</div>
<div class="btn btn2" @click="showCopyModal">
<div class="wz">批量签到</div>
</div>
<div class="btn btn2" @click="exportTaskStu">
<div class="img2"></div>
<div class="wz">导出数据</div>
</div>
</div>
<div class="line">
<div class="inline">
<div class="left">
<div class="img"></div>
<div class="text" style="margin-left: 10px">已选择</div>
<div class="text2">{{ selectedRowKeys.length }}</div>
<div class="text"></div>
<div class="text3">列表选项总计</div>
<div class="text4">{{ tableDataTotal2 }}</div>
</div>
<div class="right" @click="clearLine">清空</div>
</div>
</div>
<!-- <div class="pad"></div> -->
<div class="tableBox" style="margin-top: 30px">
<a-table
style="border: 1px solid #f2f6fe"
:columns="tableDataFunc()"
:data-source="tabledata"
:loading="tableDataTotal === -1 ? true : false"
expandRowByClick="true"
@expand="expandTable"
:scroll="{ x: 1300 }"
:pagination="false"
:row-selection="{
columnWidth: 30,
selectedRowKeys: selectedRowKeys,
onChange: onSelectChange,
}"
/>
<div class="pa">
<a-pagination
:showSizeChanger="false"
showQuickJumper="true"
hideOnSinglePage="true"
:pageSize="pageSize"
:current="currentPage"
:total="tableDataTotal"
class="pagination"
v-if="tableDataTotal > 10"
@change="changePaginationStu"
/>
</div>
</div>
<!-- <div class="tab" style="margin-top: 20px; margin-bottom: 100px">
<a-table
style="border: 1px solid #f2f6fe"
:columns="tablecolumns"
:data-source="tabledata"
:loading="tableDataTotal === -1 ? true : false"
expandRowByClick="true"
:scroll="{ x: 900, y: 350 }"
@expand="expandTable"
:pagination="false"
:row-selection="{
columnWidth: 30,
selectedRowKeys: selectedRowKeys,
onChange: onSelectChange,
}"
/>
</div> -->
</div>
<div class="btnn">
<button class="btn1" @click="closeDrawer">取消</button>
<button class="btn2" @click="closeDrawer">确定</button>
</div>
</div>
</a-drawer>
<!-- 二维码签到弹窗 -->
<SignQR v-model:signQRvisible="signQRvisible" />
<!-- 导入学员抽屉 -->
<imp-stu v-model:AddImpStuvisible="AddImpStuvisible" />
<!-- 批量签到弹窗 -->
<a-modal
v-model:visible="copyModal"
:footer="null"
:closable="closeCopy"
wrapClassName="CopyModal"
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="closeCopyModal"></div>
</div>
<div class="body">
<span>您确定要批量签到吗</span>
</div>
<div class="del_btnbox">
<div class="del_btn btn1">
<div class="btnText" @click="delete_exit">取消</div>
</div>
<div class="del_btn btn2">
<div class="btnText" @click="delete_exit">确定</div>
</div>
</div>
</div>
</div>
</a-modal>
<!-- 二维码弹窗 -->
<two-dimensional-code
v-model:codevisible="codevisible"
:codeInfo="codeInfo"
:index="codeIndex"
:type="codeType == 1 ? '课程二维码' : codeType == 2 ? '签到二维码' : ''"
/>
<!-- 二维码弹窗 -->
</template>
<script>
import { toRefs, reactive } from "vue";
import ImpStu from "../../../components/drawers/AddLevelImportStu";
import SignQR from "../SignQR.vue";
import * as api from "../../../api/index1";
import TwoDimensionalCode from "../../../components/TwoDimensionalCode";
export default {
name: "FaceManage",
components: {
ImpStu,
SignQR,
TwoDimensionalCode,
},
props: {
FSvisible: {
type: Boolean,
default: false,
},
datasource: {
type: Object,
default: function () {
return {};
},
},
},
setup(props, ctx) {
const state = reactive({
Evisible: false, //录入成绩抽屉
AddImpStuvisible: false, //导入学员抽屉
copyModal: false, //批量签到弹窗
closeCopy: false, //签到弹窗关闭图标
stopModal: false, //签退弹窗
closeStop: false, //签退弹窗关闭图标
signQRvisible: false, //二维码弹窗
name: null,
projectName2: null,
showmodal: false, //勾选提示框
closable: false, //modal右上角的关闭按钮
pageSize: 10,
currentPage: 1,
tableDataTotal: -1,
tableDataTotal2: 0,
selectedRowKeys: [],
projectNameList: [
{
id: 1,
value: "项目一",
label: "项目一",
},
{
id: 2,
value: "项目二",
label: "项目二",
},
{
id: 3,
value: "项目三",
label: "项目三",
},
{
id: 4,
value: "项目四",
label: "项目四",
},
],
projectNameList2: [
{
id: 1,
value: "1",
label: "正常",
},
{
id: 2,
value: "2",
label: "异常",
},
],
tabledata: [
// {
// key: 1,
// name: "张三",
// com: "产研部",
// gang: "产品经理",
// cur: "-",
// jin: "-",
// time: "缺勤",
// state: "异常",
// signIn: false, //签到
// signOut: false, //签退
// leave: false, //请假
// },
],
tableOptions: [
{
label: "签到",
value: "1",
},
{
label: "签退",
value: "2",
},
{
label: "请假",
value: "3",
},
],
// selectOption: [],
codevisible: false, //二维码弹窗
codeType: null,
codeIndex: null,
codeInfo: null, //二维码内容
});
const afterVisibleChange = (bol) => {
if (bol == true) {
getStudent();
}
};
//考勤
const selectProjectName = (value, index) => {
console.log("value", value, index);
};
//签到状态
const selectProjectName2 = (value, index) => {
console.log("value", value, index);
};
const closeDrawer = () => {
ctx.emit("update:FSvisible", false);
state.name = null;
state.projectName2 = null;
state.selectedRowKeys = [];
state.currentPage = 1;
state.tableDataTotal = -1;
state.tableDataTotal2 = 0;
state.tabledata = [];
};
//导入学员
const showImpStu = () => {
state.AddImpStuvisible = true;
};
//批量签到
const showCopyModal = () => {
state.copyModal = true;
};
const closeCopyModal = () => {
state.copyModal = false;
};
// const closeStopModal = () => {
// state.stopModal = false;
// };
//显示签到二维码弹窗
const signQR = () => {
state.signQRvisible = true;
};
const onSelectChange = (selectedRowKeys) => {
console.log("selectedRowKeys changed: ", selectedRowKeys);
state.selectedRowKeys = selectedRowKeys;
};
//表头清空
const clearLine = () => {
state.selectedRowKeys = [];
};
const tableDataFunc = () => {
const columns = [
{
title: "工号",
dataIndex: "studentUserNo",
// width: "30%",
key: "studentUserNo",
width: 50,
align: "center",
className: "h",
customRender: (text) => {
return (
<div class="racona">
<span>
{text.record.studentUserNo ? text.record.studentUserNo : "-"}
</span>
</div>
);
},
},
{
title: "姓名",
dataIndex: "studentName",
// width: "30%",
key: "studentName",
width: 50,
align: "left",
className: "classify",
scopedSlots: { customRender: "action" }, //引入的插槽
customRender: (text) => {
return (
<div class="racona">
<span>
{text.record.studentName ? text.record.studentName : "-"}
</span>
</div>
);
},
},
{
title: "所在部门",
dataIndex: "studentDepartName",
// width: "30%",
key: "studentDepartName",
width: 50,
align: "center",
className: "h",
customRender: (text) => {
return (
<div class="racona">
<span>
{text.record.studentDepartName
? text.record.studentDepartName
: "-"}
</span>
</div>
);
},
},
{
title: "所在岗位",
dataIndex: "studentJobName",
key: "studentJobName",
width: 50,
align: "center",
className: "h",
customRender: (text) => {
return (
<div class="racona">
<span>
{text.record.studentJobName
? text.record.studentJobName
: "-"}
</span>
</div>
);
},
},
{
title: "签到时间",
dataIndex: "cur",
key: "cur",
width: 110,
align: "center",
className: "h",
},
// {
// title: "签退时间",
// dataIndex: "jin",
// key: "jin",
// width: 110,
// align: "center",
// className: "h",
// },
{
title: "考勤",
dataIndex: "time",
key: "time",
width: 50,
align: "center",
className: "h",
},
{
title: "签到状态",
dataIndex: "state",
key: "state",
width: 50,
align: "center",
className: "h",
},
{
title: "考勤情况",
className: "h",
dataIndex: "opacation",
key: "opacation",
width: 130,
align: "center",
// scopedSlots: { customRender: "action" }, //引入的插槽
customRender: (text) => {
return (
<div class="opa">
<a-checkbox
checked={text.record.signIn}
onChange={(e) => {
let obj = {
courseId: Number(props.datasource.courseId),
// projectId: 0,
routerId: Number(props.datasource.routerId),
studentId: Number(text.record.studentId),
studentName: text.record.studentName,
taskId: Number(props.datasource.routerTaskId),
taskType: Number(props.datasource.type),
type: 2,
// userName: "",
};
api
.attendanceSign(obj, (res) => {
console.log("签到结果", res, obj, e);
if (res.data.code === 200) {
text.record.signIn = true;
}
})
.catch((err) => {
console.log("签到失败", err, obj);
text.record.signIn = false;
});
// console.log(
// "点击签到",
// e,
// text.record,
// props.datasource,
// obj
// );
}}
>
签到
</a-checkbox>
{/**
<a-checkbox
checked={value.signOut}
onChange={(e) => {
console.log("点击签退", e);
}}
>
签退
</a-checkbox>
*/}
<a-checkbox
checked={text.record.leave}
onChange={(e) => {
console.log("点击请假", e, props.datasource);
let obj = {
courseId: Number(props.datasource.courseId),
// projectId: 0,
routerId: Number(props.datasource.routerId),
studentId: Number(text.record.studentId),
studentName: text.record.studentName,
taskId: Number(props.datasource.routerTaskId),
taskType: Number(props.datasource.type),
type: 2,
// userName: "",
};
api
.attendanceLeave(obj, (res) => {
console.log("请假结果", res, obj, e);
if (res.data.code === 200) {
text.record.leave = true;
}
})
.catch((err) => {
console.log("请假结果", err, obj);
text.record.leave = false;
});
}}
>
请假
</a-checkbox>
</div>
);
},
},
];
return columns;
};
//获取学员
const getStudent = () => {
console.log("我是传递的查询参数", props.datasource, {
pageNo: state.currentPage,
pageSize: state.pageSize,
currentStageId: props.datasource.chapterId,
type: 2,
pid: props.datasource.routerId,
// status: Number(state.name),
studentName: state.name,
currentTaskId: props.datasource.routerTaskId,
});
api
.AssessmentManagementMessage({
pageNo: state.currentPage,
pageSize: state.pageSize,
currentStageId: props.datasource.chapterId,
type: 2,
pid: props.datasource.routerId,
// status: Number(state.name),
studentName: state.name,
currentTaskId: props.datasource.routerTaskId,
taskType: props.datasource.type,
})
.then((res) => {
console.log("获取面授管理学员", res);
if (res.data.code == 200) {
let newData = [];
for (let i = 0; i < res.data.data.records.length; i++) {
res.data.data.records[i].key = res.data.data.records[i].id;
newData.push(res.data.data.records[i]);
}
state.tabledata = newData;
state.tableDataTotal = res.data.data.total;
state.tableDataTotal2 = res.data.data.total;
}
})
.catch((err) => {
console.log(err);
state.tabledata = [];
});
};
//搜索学员
const searchTaskList = () => {
state.currentPage = 1;
state.tableDataTotal = -1;
state.tableDataTotal2 = 0;
getStudent();
};
// 重置按钮
function resetTaskList() {
state.currentPage = 1;
state.name = null;
state.projectName2 = null;
state.tableDataTotal = -1;
state.tableDataTotal2 = 0;
getStudent();
}
//分页
const changePaginationStu = (page) => {
state.currentPage = page;
state.tableDataTotal = -1;
state.tableDataTotal2 = 0;
getStudent();
};
// 导出数据
function exportTaskStu() {
console.log("props.datasource", props.datasource);
window.open(
`${
process.env.VUE_APP_PROXY_URL
}admin/student/exportTaskStudent?currentStageId=${
props.datasource.chapterId
}&type=${2}&pid=${props.datasource.routerId}&taskType=0`
);
// api
// .exportTaskStudent({
// pageNo: state.currentPage,
// pageSize: state.pageSize,
// currentStageId: props.datasource.stageId,
// currentTaskId: props.datasource.projectTaskId,
// type: 1,
// pid: props.datasource.projectId,
// })
// .then((res) => {
// console.log(res);
// })
// .catch((err) => {
// console.log(err);
// });
}
//二维码
const qrcodeVisible = () => {
state.codevisible = true;
state.codeInfo = {
title: "【签到】二维码",
name: props.datasource?.name,
url:
process.env.VUE_APP_BOE_API_URL +
`/admin/student/studentSign?taskId=${
props.datasource.routerTaskId
}&type=${2}`,
};
console.log("codeInfo", state.codeInfo);
state.codeIndex = 1;
state.codeType = 2;
};
return {
...toRefs(state),
selectProjectName,
selectProjectName2,
closeDrawer,
onSelectChange,
tableDataFunc,
showImpStu,
showCopyModal,
closeCopyModal,
// closeStopModal,
signQR,
afterVisibleChange,
searchTaskList,
resetTaskList,
changePaginationStu,
exportTaskStu,
clearLine,
qrcodeVisible,
};
},
};
</script>
<style lang="scss">
.me {
.ant-modal-body {
padding: 0px;
}
}
.CopyModal {
.ant-modal {
width: 424px !important;
height: 258px !important;
.ant-modal-content {
width: 424px !important;
height: 258px !important;
.ant-modal-body {
width: 424px !important;
height: 258px !important;
padding: 0 !important;
.delete {
z-index: 999;
width: 424px;
height: 258px;
background: #ffffff;
box-shadow: 0px 1px 35px 0px rgba(118, 136, 166, 0.21);
border-radius: 4px;
// position: absolute;
// left: 50%;
// top: 10%;
// transform: translate(-50%, -50%);
.del_header {
position: absolute;
width: calc(100%);
height: 68px;
background: linear-gradient(
rgba(78, 166, 255, 0.2) 0%,
rgba(78, 166, 255, 0) 100%
);
}
.del_main {
width: 100%;
position: relative;
.header {
display: flex;
align-items: center;
padding-top: 20px;
padding-left: 26px;
font-size: 16px;
.icon {
width: 16px;
height: 16px;
margin-right: 10px;
background-image: url(@/assets/images/coursewareManage/QR.png);
background-size: 100% 100%;
}
.close_exit {
position: absolute;
right: 42px;
cursor: pointer;
width: 20px;
height: 20px;
background-image: url(@/assets/images/coursewareManage/close.png);
background-size: 100% 100%;
}
}
.body {
width: 100%;
margin: 34px auto 56px auto;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
// background-color: red;
position: relative;
.back {
position: absolute;
top: 30px;
font-size: 12px;
font-weight: 400;
color: #666666;
}
}
.del_btnbox {
display: flex;
margin: 30px auto;
justify-content: center;
.del_btn {
width: 100px;
height: 40px;
background: rgba(64, 158, 255, 0);
border-radius: 8px;
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
cursor: pointer;
.btnText {
font-size: 14px;
font-weight: 400;
line-height: 40px;
}
}
.btn1 {
border: 1px solid rgba(64, 158, 255, 1);
color: #4ea6ff;
margin-right: 14px;
}
.btn2 {
background-color: #4ea6ff;
color: #ffffff;
}
}
}
}
}
}
}
}
.RouterFaceStu {
// // width: 80%;
// .ant-drawer-content-wrapper {
// // max-width: 1000px;
// .ant-drawer-header {
// display: none !important;
// }
// .ant-drawer-body {
// padding: 0;
// }
// }
.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;
.headerTitle {
font-size: 18px;
font-weight: 600;
color: #333333;
line-height: 25px;
// margin-left: 24px;
}
}
.main {
width: 100%;
height: 100%;
overflow: auto;
padding-right: 10px;
padding-bottom: 90px;
.titl {
display: flex;
.endtime {
font-size: 16px;
font-weight: 500;
color: #333333;
}
}
.search {
width: 100%;
display: flex;
flex-wrap: wrap;
margin-top: 20px;
justify-content: space-between;
.leftchoose {
display: flex;
margin-right: 20px;
.namecon {
display: flex;
flex-wrap: nowrap;
margin-bottom: 10px;
.name {
margin-top: 8px;
white-space: nowrap;
}
// .name {
// margin-top: 8px;
// color: rgba(0, 0, 0, 0.85);
// font-size: 14px;
// font-weight: 400;
// }
}
}
.btns {
display: flex;
flex-wrap: nowrap;
.btn {
cursor: pointer;
width: 100px;
height: 40px;
border-radius: 8px;
display: flex;
justify-content: center;
align-items: center;
.img1 {
width: 15px;
height: 17px;
background-image: url(../../../assets/images/courseManage/search0.png);
background-size: 100% 100%;
margin-right: 7px;
}
.img2 {
width: 16px;
height: 18px;
background-image: url(../../../assets/images/courseManage/reset1.png);
background-size: 100% 100%;
margin-right: 7px;
}
}
.btn1 {
background: #4ea6ff;
color: #ffffff;
}
.btn2 {
background: #ffffff;
color: #4ea6ff;
border: 1px solid #4ea6ff;
}
}
}
.btnss {
display: flex;
flex-wrap: nowrap;
.btn {
cursor: pointer;
width: 130px;
height: 40px;
border-radius: 8px;
display: flex;
justify-content: center;
align-items: center;
.img1 {
width: 19px;
height: 19px;
background-image: url(../../../assets/images/basicinfo/in.png);
background-size: 100% 100%;
margin-right: 7px;
}
.img2 {
width: 17px;
height: 16px;
background-image: url(../../../assets/images/coursewareManage/export.png);
background-size: 100% 100%;
margin-right: 7px;
}
}
.btn1 {
background: #4ea6ff;
color: #ffffff;
}
.btn2 {
background: #ffffff;
margin-right: 20px;
color: #4ea6ff;
border: 1px solid #4ea6ff;
}
}
.line {
width: 100%;
height: 40px;
background-color: #e9f6fe;
display: flex;
justify-content: center;
align-items: center;
margin-top: 20px;
border: 1px solid #c3e6fc;
.inline {
width: 95%;
height: 100%;
display: flex;
justify-content: space-between;
// background-color: #bfa;
.left {
height: 100%;
display: flex;
align-items: center;
.img {
width: 14px;
height: 15px;
background-image: url(../../../assets/images/leveladd/gan.png);
background-size: 100% 100%;
}
.text {
color: #999ba3;
}
.text2 {
color: #4ea6ff;
margin-left: 5px;
margin-right: 5px;
}
.text3 {
color: #999ba3;
margin-left: 20px;
}
}
.right {
font-size: 14px;
font-weight: 400;
color: #387df7;
height: 100%;
display: flex;
align-items: center;
cursor: pointer;
}
}
}
.pad {
width: 96%;
height: 10px;
background-color: #fff;
position: absolute;
}
.tableBox {
// margin-bottom: 80px;
.classify {
// margin-left: 11px !important;
// padding-left: 9px !important;
padding-left: 0px !important;
}
.ant-checkbox-wrapper {
align-items: center;
margin-top: -2px;
}
.ant-table-selection-column {
padding: 0px !important;
// padding-left: 45px !important;
}
.ant-table-thead > tr > th {
background-color: rgba(239, 244, 252, 1);
}
th.h {
background-color: #eff4fc !important;
}
.ant-table-tbody
> tr:hover:not(.ant-table-expanded-row):not(.ant-table-row-selected)
> td {
background: #f6f9fd;
}
.opa {
background-color: rgba(255, 255, 255, 0);
.ant-checkbox + span {
font-size: 14px;
font-weight: 400;
color: rgba(0, 0, 0, 0.65);
line-height: 22px;
margin-top: 5px;
}
}
}
// .tab {
// .ant-table-thead > tr > th {
// background-color: rgba(239, 244, 252, 1) !important;
// }
// th.h {
// background-color: #eff4fc !important;
// }
// .ant-table-tbody
// > tr:hover:not(.ant-table-expanded-row):not(.ant-table-row-selected)
// > td {
// background: #f6f9fd;
// }
// }
}
.btnn {
height: 72px;
width: 100%;
position: absolute;
bottom: 0;
left: 0;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0px 1px 35px 0px rgba(118, 136, 166, 0.16);
background-color: #fff;
.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;
}
}
}
// .botm {
// width: 100%;
// height: 100%;
// background-color: red;
// // flex-shrink: 1;
// }
}
</style>