讲师认证

This commit is contained in:
zhangsir
2024-05-11 21:52:29 +08:00
parent 9edcbb0a7a
commit f58ae089f2
27 changed files with 4501 additions and 3 deletions

View File

@@ -7,7 +7,7 @@ import Cookies from 'vue-cookies'
axios.defaults.withCredentials = true;
const http = axios.create({
timeout: 1000 * 15,
headers: { "Content-Type": "application/json", },
headers: { "Content-Type":"application/json", },
});
http.interceptors.request.use(

115
src/api/examineApi.js Normal file
View File

@@ -0,0 +1,115 @@
import { data } from "jquery";
import http from "./configPublic";
//认证审批项目列表
export const getexamineList = (data) => {
return http({
url: "/activityApi/examine/list",
method: "post",
data: data
})
}
export const getexamine = (data) => {
return http({
url: "/activityApi/teacher/list",
method: "post",
data: data
})
}
//创建认证
export const CreateAuthentication = (data)=>{
return http({
url:'/activityApi/examine/launchOrUpdate',
method: "post",
data: data
})
}
//删除认证
export const delExamine = (data)=>{
return http({
url:'/activityApi/examine/deleteExamine',
method: "post",
data: data
})
}
//讲师列表
export const getTeacherList = (data)=>{
return http({
url:'/activityApi/teacher/list',
method: "post",
data: data
})
}
//删除教师
export const deleTeTeacher = (data)=>{
return http({
url:'/activityApi//teacher/deleTeTeacher',
method: "post",
data: data
})
}
//发起评审列表
export const getReview = (data) =>{
return http({
url:'/activityApi/review/list',
method: "post",
data: data
})
}
//删除评审
export const delreview=(data) =>{
return http({
url:'/activityApi/review/delete',
method: "post",
data: data
})
}
//查看评审
export const reviewdetail =(data)=>{
return http({
url:'/activityApi/review/detail',
method: "post",
data: data
})
}
//发起评审
export const reviewSave = (data) =>{
return http({
url:'/activityApi/review/save',
method: "post",
data: data
})
}
//添加教师
export const addTeacher= (data)=>{
return http({
url:'/activityApi/review/selectTeacher',
method: "post",
data: data
})
}
//结束评审并通知结果
export const endreview = (data) =>{
return http({
url:'/activityApi/review/endReview',
method: "post",
data: data
})
}
//编辑评审
export const editreview = (data) =>{
return http({
url:'/activityApi/review/edit',
method: "post",
data: data
})
}
//添加导师
export const addTutor = (data) =>{
return http({
url:'/activityApi/teacher/saveTeacher',
method: "post",
data: data
})
}

BIN
src/assets/2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

BIN
src/assets/33.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

BIN
src/assets/39.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 93 KiB

BIN
src/assets/44.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 145 KiB

BIN
src/assets/46.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

BIN
src/assets/47.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

BIN
src/assets/49.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

BIN
src/assets/50.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 98 KiB

BIN
src/assets/8.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@@ -495,6 +495,18 @@
}
];
}
if (
n.indexOf("/InstructorCertification") !== -1 ||
n.indexOf("/InstructorCertification") !== -1
) {
state.list = [
{
name: "感恩教师",
}, {
name:'讲师认证'
}
];
}
if (
n.indexOf("/tooldown") !== -1 ||
n.indexOf("/ToolDown") !== -1

View File

@@ -339,7 +339,7 @@
</a-menu-item>
</a-sub-menu>
<!-- 教师专区 -->
<a-sub-menu key="sub22" @titleClick="titleClick" v-if="checkMenu('gratefulnotice,gratefulcarousel,teacherempowerment,teachertopic,tooldown,teacheropinion')">
<a-sub-menu key="sub22" @titleClick="titleClick" v-if="checkMenu('gratefulnotice,gratefulcarousel,teacherempowerment,teachertopic,tooldown,teacheropinion,InstructorCertification')">
<template #icon>
<div class="imgBox">
<img
@@ -376,6 +376,17 @@
></span>
<router-link to="/teacherempowerment">教师赋能</router-link>
</a-menu-item>
<a-menu-item key="sub22-7" >
<span
:class="{
circleActive: selectedKeys[0] === 'sub22-7' ? true : false,
circle: selectedKeys[0] === 'sub22-7' ? false : true,
}"
></span>
<router-link to="/InstructorCertification">讲师认证</router-link>
</a-menu-item>
<a-menu-item key="sub22-4" v-if="checkMenu('teachertopic')">
<span
:class="{
@@ -929,6 +940,12 @@ export default {
selectedKeys: "sub22-6",
pagename: "意见",
},
{
href: "/InstructorCertification",
openKeys: "sub22",
selectedKeys: "sub22-7",
pagename: "讲师认证",
},
{
href: "/articlemanage",
openKeys: "sub13",

View File

@@ -8,7 +8,7 @@
>
<div class="drawerMain" id="stuadd">
<div class="header">
<div class="headerTitle">添加学员</div>
<div class="headerTitle">添加讲师</div>
<img
style="width: 29px; height: 29px; cursor: pointer"
src="../../assets/images/basicinfo/close.png"

14
src/utils/qrCode2.js Normal file
View File

@@ -0,0 +1,14 @@
import { createApp } from 'vue'
import QrCode from "../views/gratefulteacher/QrCode.vue";
import Antd from "ant-design-vue";
function mountContent (option = {}) {
const dom = document.createElement('div')
document.body.appendChild(dom)
const app = createApp(QrCode, {
close: () => { app.unmount(dom); document.body.removeChild(dom) },
...option
})
app.use(Antd).mount(dom)
}
export default mountContent

View File

@@ -0,0 +1,185 @@
<script setup >
import { ref } from 'vue'
import { ElMessageBox } from 'element-plus'
const props = defineProps(["AddSwitch"])
console.log(1111,props.AddSwitch);
const emit = defineEmits(['myClick'])
const handleClose = (done) => {
ElMessageBox.confirm('Are you sure to close this dialog?')
.then(() => {
emit('myClick', false)
done()
})
.catch(() => {
// catch error
})
}
const activeName = ref('first')
const handleNodeClick = (data) => {
console.log(data)
}
const data= [
{
label: 'Level one 1',
children: [
{
label: 'Level two 1-1',
children: [
{
label: 'Level three 1-1-1',
},
],
},
],
},
{
label: 'Level one 2',
children: [
{
label: 'Level two 2-1',
children: [
{
label: 'Level three 2-1-1',
},
],
},
{
label: 'Level two 2-2',
children: [
{
label: 'Level three 2-2-1',
},
],
},
],
},
{
label: 'Level one 3',
children: [
{
label: 'Level two 3-1',
children: [
{
label: 'Level three 3-1-1',
},
],
},
{
label: 'Level two 3-2',
children: [
{
label: 'Level three 3-2-1',
},
],
},
],
},
]
const defaultProps = {
children: 'children',
label: 'label',
}
const tags = ref([
{ name: 'Tag 1', type: 'primary' },
{ name: 'Tag 2', type: 'success' },
{ name: 'Tag 3', type: 'info' },
{ name: 'Tag 4', type: 'warning' },
{ name: 'Tag 5', type: 'danger' },
])
</script>
<template>
<div class="-page">
<el-drawer style="padding:0 10px;" :before-close="handleClose" v-model="props.AddSwitch" size="80%">
<template #title>
<h1 style="font-weight: 700;">添加讲师</h1>
</template>
<div style="width: 100%; height: 1px; background: #d8d8d8;margin-top: -16px; "></div>
<div style="width: 100%; height: 70%; display: flex; ">
<div style="width: 90%; height: 70%;">
<div style="width: 100%; margin-top: 16px">
<el-tabs v-model="activeName">
<el-tab-pane label="快速选人" name="first"></el-tab-pane>
<el-tab-pane label="添加组织" name="second"></el-tab-pane>
<el-tab-pane label="受众关联" name="thirdly"></el-tab-pane>
</el-tabs>
</div>
<div style="display: flex; margin-bottom: 15px">
<p style="width: 40px;">姓名:</p>
<el-input style="width: 200px;" placeholder="请输入姓名"></el-input>
<el-button type="primary" style="margin-left: 15px;">搜索</el-button>
<el-button type="primary">重置</el-button>
</div>
<div style="width: 100%; display: flex;">
<div style="width: 24%;">
<el-tree
style="max-width: 600px; border: 1px solid #d8d8d8;"
:data="data"
:props="defaultProps"
@node-click="handleNodeClick"
/>
</div>
<div style="width: 74%; flex: 1;margin-left: 10px;"></div>
<el-table :checked="true" :data="tableData" style="width: 100%">
<el-table-column fixed type="selection" style="width: 2%;" >
</el-table-column>
<el-table-column prop="date" label="姓名" />
<el-table-column prop="date" label="工号" />
<el-table-column prop="city" label="归属组织" />
<el-table-column prop="city" label="部门" />
</el-table>
</div>
</div>
<div style="width: 1px ;height: 70%;background-color: #f5f8fe; margin-left: 10px;margin-right: 10px;"></div>
<div style="width: 10%; height: 70%; margin-top: 25px;">
<div style="margin-bottom: 30px;">已选</div>
<div style="width: 100% ;height: 1px;background-color: #f5f8fe; "></div>
<div>快速选人</div>
<div class="flex gap-2">
<el-tag v-for="tag in tags" :key="tag.name" closable :type="tag.type" color="#fff" style="width: 64px; margin-top: 10px; display: block; color: #4fa5f8; border: 1px solid #4fa5f8;">
{{ tag.name }}
</el-tag>
</div>
<div style="margin-top: 30px;">添加组织</div>
<div style="width: 100% ;height: 1px;background-color: #f5f8fe; "></div>
<div style="margin-top: 30px;">受众关联</div>
<div style="width: 100% ;height: 1px;background-color: #f5f8fe; "></div>
</div>
</div>
<div style="width: 100%; text-align: center;" >
<el-button type="primary" plain style="width: 100px; height: 40px; margin-right: 10px;">取消</el-button>
<el-button type="primary" style="width: 100px; height: 40px; margin-left: 10px;">确认</el-button>
</div>
</el-drawer>
</div>
</template>
<style lang="scss" scoped>
::deep(.el-drawer__header){
margin-bottom: 0;
}
::deep(.el-table .cell){
color: #030303
}
</style>

View File

@@ -0,0 +1,645 @@
<template>
<a-drawer
:visible="AddImpStuvisible"
class="drawerStyle AddLevelImpStu"
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>
<a
class="up2"
:href="locationHref + template"
target="_blank"
style="cursor: pointer"
>模板</a
>
<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="importStudent"
name="uploadFile"
:headers="headers"
:multiple="false"
@change="handleChange"
:data="{
targetId: Number(courseId),
type: courseType,
userId: userInfo.userId,
userName: userInfo.realName,
}"
: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 v-if="uploadpercent !== -1" class="loadborder">
<div class="content">
<div class="img"></div>
<div class="timebox">
<div class="timetop">
<div class="tit" :title="fileName">{{ fileName }}</div>
<div
v-if="uploadErr"
class="stateloading"
style="color: red"
>
上传失败
</div>
<div v-else class="stateloading">
{{ uploadpercent == 100 ? "上传成功" : "正在上传" }}
</div>
</div>
<div class="prog">
<div
class="inprogloading"
:style="{
width: uploadpercent == -1 ? 0 : uploadpercent + '%',
background: uploadErr ? '#ff7474' : '#35ae69',
}"
></div>
</div>
</div>
<div class="curloading">
<div class="cur">
{{ uploadpercent == -1 ? 0 : uploadpercent }}%
</div>
<div
class="cancel"
style="margin-left: 20px; cursor: pointer"
@click="removeUpload"
>
删除
</div>
<div class="cancel" style="margin-left: 15px"></div>
</div>
<div v-if="downloadErrUrl !== ''" class="defeat">
<div class="detext" @click="downloadEeeorData">
下载失败数据
</div>
</div>
</div>
</div>
<div
v-if="showBottomBar"
:class="downloadErrUrl == '' ? 'succebox' : 'defeatbox'"
>
<div class="lefimg"></div>
<div class="tacl">
{{ succNum }}条数据导入成功{{
downloadErrUrl == "" ? 0 : errNum
}}条数据导入失败
</div>
</div>
<!-- <div class="loadborder">
<div class="content">
<div class="img"></div>
<div class="timebox">
<div class="timetop">
<div class="tit">{{ fileName }}</div>
<div class="statedefeat">上传失败</div>
</div>
<div class="prog">
<div class="inprogdefeat"></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 class="defeat">
<div class="detext">下载失败数据</div>
</div>
</div>
</div>
<div class="defeatbox">
<div class="lefimg"></div>
<div class="tacl">20条数据导入成功5条数据导入失败</div>
</div>
<div class="loadborder">
<div class="content">
<div class="img"></div>
<div class="timebox">
<div class="timetop">
<div class="tit">{{ fileName }}</div>
<div class="statesucce">上传成功</div>
</div>
<div class="prog">
<div class="inprogsucce"></div>
</div>
</div>
<div class="curloading">
<div class="cur">55%</div>
<div class="cancel" style="margin-left: 20px">删除</div>
</div>
</div>
</div>
<div class="succebox">
<div class="lefimg"></div>
<div class="tacl">20条数据导入成功5条数据导入失败</div>
</div> -->
</div>
</div>
</div>
</div>
<div class="btnn">
<button class="btn2" @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 { computed, reactive, toRefs } from "vue";
import { message } from "ant-design-vue";
import * as api from "../../api/index1";
import { BATCH_IMPORT_SCORE } from "@/api/config";
import { useStore } from "vuex";
import {getCookieForName} from "@/api/method";
export default {
name: "ImpStu",
props: {
AddImpStuvisible: {
type: Boolean,
default: false,
},
courseId: {
type: String,
default: "",
},
courseType: {
type: String,
default: "",
},
},
setup(props, ctx) {
const store = useStore();
const state = reactive({
locationHref: process.env.VUE_APP_FILE_PATH,
template: process.env.VUE_APP_UP_LOAD_STUDENT_TEMPLATE,
importStudent:
process.env.VUE_APP_BASE_API + "/admin/student/importStudent",
timers: "", // 定时器,用于清空定时器使用
isAddStudent: false, // 用于判断用户是否关闭弹框需要重新获取学员列表
uploadpercent: -1,
uploadErr: false, //上传失败
addLoading: false,
fileList: [],
succNum: 0, //成功数据数
errNum: 0, //失败数据数
downloadErrUrl: "",
showBottomBar: false, // 显示底部成功条数和失败条数
fileName: "",
});
const headers = { token: getCookieForName("token") };
const userInfo = computed(() => store.state.userInfo);
const closeDrawer = () => {
clearInterval(state.timers);
state.fileList = [];
state.uploadpercent = -1;
state.addLoading = false;
state.uploadErr = false; //上传失败
state.showBottomBar = false;
state.succNum = 0;
state.errNum = 0;
state.downloadErrUrl = "";
ctx.emit("update:AddImpStuvisible", false);
// 通知父组件重新获取学员列表
ctx.emit("AddImpStuvisibleClose", state.isAddStudent);
state.isAddStudent = false;
};
const afterVisibleChange = (bool) => {
console.log("state", bool);
console.log("store", store.state.userInfo);
};
//上传文件
const handleChange = (info) => {
console.log("info", 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.uploadErr = false;
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") {
console.log("上传成功返回的UUID", info.file.response.data);
console.log("上传成功返回的UUID----->", info);
console.log("我是导入学员接口传递的参数", {
uploadFile: info.file.originFileObj,
targetId: props.courseId,
type: 3,
});
state.fileName = info.file.name;
let i = 0;
state.timers = 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.showBottomBar = true;
state.addLoading = false;
state.isAddStudent = true;
}
state.succNum = res.data.data.successNum;
state.errNum = res.data.data.failedNum;
state.downloadErrUrl = res.data.data.url;
clearInterval(state.timers);
}
}
})
.catch((err) => {
clearInterval(state.timers);
state.showBottomBar = true;
state.addLoading = false;
console.log("查询导入状态失败", err);
});
}, 500);
} else if (status === "error") {
state.addLoading = false;
state.uploadErr = true;
message.error(`${info.file.name}上传失败`);
}
};
// 下载失败数据
const downloadEeeorData = () => {
if (state.downloadErrUrl !== "") {
window.open(process.env.VUE_APP_FILE_PATH + state.downloadErrUrl);
}
};
//删除
const removeUpload = () => {
state.isAddStudent = false;
state.showBottomBar = false;
state.fileList = [];
state.uploadpercent = -1;
state.addLoading = false;
state.uploadErr = false; //上传失败
state.succNum = 0;
state.errNum = 0;
state.downloadErrUrl = "";
};
return {
...toRefs(state),
afterVisibleChange,
userInfo,
closeDrawer,
// change,
headers,
handleChange,
BATCH_IMPORT_SCORE,
downloadEeeorData,
removeUpload,
};
},
};
</script>
<style lang="scss">
.AddLevelImpStu > .ant-drawer-content-wrapper {
min-width: 800px !important;
width: 800px !important;
}
.AddLevelImpStu {
.drawerMain {
min-width: 450px;
margin: 0px 32px 0px 32px;
display: flex;
flex-direction: column;
.header {
height: 73px;
border-bottom: 1px solid #e8e8e8;
display: flex;
justify-content: space-between;
align-items: center;
flex-shrink: 0;
// background-color: red;
margin-bottom: 20px;
.headerTitle {
font-size: 18px;
font-weight: 600;
color: #333333;
line-height: 25px;
// margin-left: 24px;
}
}
.main {
overflow: 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;
white-space: nowrap;
}
.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: 10px;
margin-top: 10px;
display: flex;
align-items: center;
.content {
display: flex;
margin-left: 20px;
position: relative;
.defeat {
position: absolute;
left: 46px;
top: 42px;
font-size: 14px;
font-weight: 500;
width: 120px;
height: 32px;
border-radius: 2px;
border: 1px solid #387df7;
display: flex;
justify-content: center;
align-items: center;
cursor: pointer;
.detext {
font-size: 14px;
font-weight: 400;
color: #387df7;
}
}
.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;
width: 200px;
height: 21px;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.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;
}
}
}
}
.defeatbox {
width: 500px;
height: 40px;
background: rgba(255, 116, 116, 0.1);
border: 1px solid #ff7474;
display: flex;
align-items: center;
.lefimg {
width: 14px;
height: 14px;
margin-left: 17px;
margin-right: 8px;
background-image: url(../../assets/images/leveladd/nodone.png);
background-size: 100%;
}
.tacl {
font-size: 14px;
font-weight: 400;
color: #ff7474;
}
}
.succebox {
width: 500px;
height: 40px;
background: rgba(53, 174, 105, 0.1);
border: 1px solid #35ae69;
display: flex;
align-items: center;
.lefimg {
width: 14px;
height: 14px;
margin-left: 17px;
margin-right: 8px;
background-image: url(../../assets/images/leveladd/done.png);
background-size: 100%;
}
.tacl {
font-size: 14px;
font-weight: 400;
color: rgba(0, 0, 0, 0.65);
}
}
}
}
}
}
.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

@@ -0,0 +1,126 @@
<script setup >
import {ref} from 'vue'
import ViewReview from "./ViewReview.vue";
const column = [
{
name: 'Name',
dataIndex: 'name',
key: 'name',
},
{
title: '评审名称',
dataIndex: 'age',
key: 'age',
},
{
title: '认证讲师',
dataIndex: 'address',
key: 'address',
},
{
title: '认证时间',
key: 'tags',
dataIndex: 'tags',
},
{
title: '认证状态',
key: 'tags',
dataIndex: 'tags',
},
{
title: '操作',
key: 'action',
},
];
const datas = [
{
key: '1',
name: 'John Brown',
age: 32,
address: 'New York No. 1 Lake Park',
tags: ['nice', 'developer'],
},
{
key: '2',
name: 'Jim Green',
age: 42,
address: 'London No. 1 Lake Park',
tags: ['loser'],
},
{
key: '3',
name: 'Joe Black',
age: 32,
address: 'Sidney No. 1 Lake Park',
tags: ['cool', 'teacher'],
},
];
const InitiateReviewShow =ref(false)
</script>
<template>
<div class="-page">
<div class="table">
<a-table :columns="column" :data-source="datas" :scroll="{ x: 1000 }" :pagination="false">
<template #headerCell="{ column }">
<template v-if="column.key === 'name'">
<span>
序号
</span>
</template>
</template>
<template #bodyCell="{ column, record }">
<template v-if="column.key === 'name'">
<a>
{{ record.name }}
</a>
</template>
<template v-else-if="column.key === 'tags'">
<span>
<a-tag
v-for="tag in record.tags"
:key="tag"
:color="tag === 'loser' ? 'volcano' : tag.length > 5 ? 'geekblue' : 'green'"
>
{{ tag.toUpperCase() }}
</a-tag>
</span>
</template>
<template v-else-if="column.key === 'action'">
<span style="text-align: center;">
<a style="margin-right: 7px;" @click="centerDialogVisible=true">二维码</a>
<a style="margin-right: 7px;" @click='InitiateReviewShow=true'>查看</a>
<a style="margin-right: 7px;">
编辑
</a>
<a style="color: #de2139">删除</a>
</span>
</template>
</template>
</a-table>
</div>
<div style="text-align: center; margin-top: 18px;">
<a-pagination v-model:current="current1" show-quick-jumper :total="500" @change="onChange" />
</div>
<!-- <ViewReview :InitiateReviewShow="InitiateReviewShow"></ViewReview> -->
</div>
</template>
<style lang="scss" scoped>
.table {
margin-left: 14px;
margin-top: 28px;
display: flex;
flex-direction: column;
}
</style>

View File

@@ -0,0 +1,77 @@
<script setup >
const props = defineProps(['InitiateReviewShow'])
import { reactive } from 'vue';
import InitiateReviewTable from './InitiateReviewTable.vue'
const formState = reactive({
username: '',
password: '',
remember: true,
});
</script>
<template>
<div class="-page">
<el-drawer v-model="props.InitiateReviewShow" title="发起评审" size="45%">
<div style="display: flex;flex-direction: column;">
<div style="width: 100%;height: 1px;background-color: #b6b7b8;"></div>
<div style="display: flex;">
<div style="display: flex;flex-direction: column;">
<a-form
:model="formState"
name="basic"
:label-col="{ span: 8 }"
:wrapper-col="{ span: 16 }"
autocomplete="off"
@finish="onFinish"
@finishFailed="onFinishFailed"
>
<a-form-item
style="margin-top: 29px;"
label="评审名字"
name="username"
:rules="[{ required: true, message: 'Please input your username!' }]"
>
<a-input v-model:value="formState.username" />
</a-form-item>
<a-form-item
label="评审时间"
name="password"
:rules="[{ required: true, message: 'Please input your password!' }]"
>
<a-date-picker v-model:value="value8" placeholder="请选择评审时间" />
</a-form-item>
<div>选择讲师</div>
<div style="width: 430px; height: 1px;background-color: #e2e0e0;margin-top: 8px;"></div>
<div style="display: flex;margin-top: 13px;">
<a-input placeholder="请输入姓名/工号" style="width: 150px;"/>
<a-button type="primary" style="width: 70px; height: 31px; border-radius: 5px;margin-left: 15px;">搜索</a-button>
<a-button type="primary" style="width: 70px; height: 31px; border-radius: 5px;margin-left: 12px;" ghost>重置</a-button>
</div>
<p style="margin-top: 11px; color: #b6b7b8;">说明列表仅显示终稿已上传且未认证的讲师</p>
<div style="display: flex;flex-direction: column;">
<InitiateReviewTable></InitiateReviewTable>
</div>
<a-pagination size="small" v-model:current="current1" show-quick-jumper :total="500" @change="onChange" />
</a-form>
</div>
<div style="height: 500px; width: 1px; background: #b9e6fb;margin-left: 91px; margin-top: 10px"></div>
<div style="display: flex; flex-direction: column;width: 160px;margin-left: 24px;margin-top: 20px;">
<div style="font-size: 16px; font-weight: 900;">已选</div>
<div style="width: 16opx; height: 1px;background-color: #b9e6fb;margin: 11px 0;"></div>
<a-tag closable @close="log" style="border:1px solid #3da8f0; color: #3da8f0;">Tag 2</a-tag>
</div>
</div>
<div style="width: 100%;text-align: center;margin-top: 65px">
<a-button type="primary" style="width: 70px; height: 31px; border-radius: 5px ;margin: 0 15px 0 15px;" ghost>取消</a-button>
<a-button type="primary" style="width: 70px; height: 31px; border-radius: 5px" >确认</a-button>
</div>
</div>
</el-drawer>
</div>
</template>
<style lang="scss" scoped>
</style>

View File

@@ -0,0 +1,109 @@
<script setup >
const columns = [
{
name: 'Name',
dataIndex: 'name',
key: 'name',
},
{
title: 'Tags',
key: 'tags',
dataIndex: 'tags',
},
{
title: 'Action',
key: 'action',
},
];
const data = [
{
key: '1',
age: 32,
address: 'New ',
},
{
key: '2',
age: 42,
address: 'London ',
},
{
key: '3',
age: 32,
},
];
const rowSelection = {
onChange: (selectedRowKeys, selectedRows) => {
console.log(`selectedRowKeys: ${selectedRowKeys}`, 'selectedRows: ', selectedRows);
},
getCheckboxProps: record => ({
disabled: record.name === 'Disabled User',
// Column configuration not to be checked
name: record.name,
}),
};
</script>
<template>
<div class="-page">
<a-table
:row-selection="rowSelection"
:pagination="false"
:row-class-name="(_record, index) => (index % 2 === 1 ? 'table-striped' : null)"
:columns="columns"
:data-source="data"
class="ant-table-striped"
size="middle"
>
<template #headerCell="{ column }">
<template v-if="column.key === 'name'">
<span >
<smile-outlined />
Name
</span>
</template>
</template>
<template #bodyCell="{ column, record }">
<template v-if="column.key === 'name'">
<a>
{{ record.name }}
</a>
</template>
<template v-else-if="column.key === 'tags'">
<span>
<a-tag
v-for="tag in record.tags"
:key="tag"
:color="tag === 'loser' ? 'volcano' : tag.length > 5 ? 'geekblue' : 'green'"
>
{{ tag.toUpperCase() }}
</a-tag>
</span>
</template>
<template v-else-if="column.key === 'action'">
<span>
<a>Delete</a>
</span>
</template>
</template>
</a-table>
</div>
</template>
<style lang="scss" scoped>
// [data-doc-theme='light'] .ant-table-striped :deep(.ant-table-striped .table-striped ) td {
// background-color: #fafafa;
// }
</style>

View File

@@ -0,0 +1,505 @@
<script setup >
import { ref,onMounted } from 'vue';
import { useRoute, useRouter } from 'vue-router'
import {getexamineList,CreateAuthentication,delExamine} from '@/api/examineApi.js'
import dialog from "@/utils/dialog";
import DropDown from "@/components/common/DropDown";
import OwnerTableModelStudent from "@/components/student/OwnerTableModelStudent";
import CommonStudent from "@/components/student/CommonStudent";
const route = useRoute()
const router = useRouter()
const visible = ref(false);
const loading = ref(false);
const columns = [
{
name: 'serial',
dataIndex: 'serial',
key: 'serial',
},
{
title: '认证项目名称',
dataIndex: 'name',
key: 'name',
},
{
title: '创建人',
dataIndex: 'createName',
key: 'createName',
},
{
title: '创建时间',
key: 'createTime',
dataIndex: 'createTime',
},
{
title: '操作',
key: 'action',
},
];
//认证审批项目列表数据
const data = ref([{
id: 1,
"deleted": false,
"createTime": "2024-05-10 13:38:37",
"createId": null,
"createName": null,
"updateTime": "2024-05-10 13:49:16",
"updateId": 965342027497607168,
"updateName": "李玉冰",
"number": 1,
"name": "测试1",
"description": "认证项目详情",
"cover": "/www/elearning/upload/activityfile/blue.png"
},
{
"id": 6,
"deleted": false,
"createTime": "2024-05-10 13:24:50",
"createId": null,
"createName": null,
"updateTime": null,
"updateId": null,
"updateName": null,
"number": 2,
"name": "认证项目003修改",
"description": "认证项目详情",
"cover": "/www/elearning/upload/activityfile/blue.png"
},])
const delVisible = ref(false)
//页数
const current1 = ref(1);
//表格行数
const pageSize = ref(10)
//总条数
const total = ref(0)
//封面图
const url = ref('http://localhost:8070/manage/img/50.34e94524.png')
//搜索值
const searchValue = ref('')
//搜索功能
const Administrator= ref(0)
const search = async()=>{
loading.value = true
const res = await getexamineList({
pageNo: current1.value,
pageSize: pageSize.value,
name: searchValue.value,
isSuper:Administrator.value
})
loading.value = false
data.value= res.data.records
total.value = res.data.total
console.log(999);
}
//重置
const handleRest = ()=>{
getlist()
}
//删除认证
const deleteExamine = async(id)=>{
await delExamine({
id
})
getlist()
}
const onChange = (pageNo,pageSize) => {
current1.value = pageNo
getlist()
};
const ViewReviewShow =ref(null)
const centerDialogVisible = ref(false)
const SkipManagement = (id)=>{
router.push({
path: '/LecturerManagement',
query: {id,
description:data.value[0].description,
name:data.value[0].name
}
})
}
//讲师认证列表数据
const InstructorCertificationlist = ref([])
const getlist = async() =>{
loading.value = true
const res = await getexamineList({
pageNo: current1.value,
pageSize: pageSize.value,
name: "",
isSuper:Administrator.value
})
console.log(res.data,'认证列表数据');
loading.value = false
total.value = res.data.total
data.value= res.data.records
}
//创建认证
const launchOrUpdate = async()=>{
CreateAuthentication()
}
onMounted(()=>{
getlist()
})
const customRow=(column) =>{
column.forEach((e, index) => {
column[index].className = 'tableClass'
})
}
const handleMsg = {
del: "你确定删除该教师信息吗?",
};
function handleOper(record, type, status = "") {
dialog({
content: "确认删除吗?数据删除后不可恢复",
// ok:deleteExamine(record.id)
ok:()=>{
deleteExamine(record.id)
}
});
}
</script>
<template>
<div class="page">
<!-- 线上学习课程设置 -->
<a-drawer v-model:visible="ViewReviewShow"
class="custom-class"
:closable="false"
placement="right"
width="726px">
<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 style="display: flex;flex-direction: column;">
<div @click="ViewReviewShow=true" style="margin-bottom: 15px; height: 38px; width: 150px;background: #4ea6ff;line-height: 40px;text-align: center;border-radius: 8px;color: #ffffff;">选择/新建课程</div>
<div>
<a-table
:row-selection="rowSelection"
:pagination="false"
:row-class-name="(_record, index) => (index % 2 === 1 ? 'table-striped' : null)"
:columns="ViewReviewcolumns"
:data-source="ViewReviewdata"
class="ant-table-striped"
size="middle"
/>
</div>
<div style=" display: flex;justify-content: center;">
<div style="margin-right: 30px; border-radius: 8px; color: #fff;font-size: 16px; display: flex; justify-content: center;align-items: center; width: 100px; height: 38px; margin-top: 36px;background: #3da8f0;">取消</div>
<div style="border-radius: 8px; color: #fff;font-size: 16px; display: flex; justify-content: center;align-items: center; width: 100px; height: 38px; margin-top: 36px;background: #3da8f0;">确定</div>
</div>
</div>
</a-drawer>
<div class="filter">
<div class="filterItems">
<div style="display: flex;">
<a-input :max="50" v-model:value="searchValue" style="width: 270px; height: 41px; border-radius: 8px"
placeholder="请输入认证项目名称" />
<div style="display: flex; margin-left: 20px">
<div class="btn btn1" @click="search()">
<div class="search"></div>
<div class="btnText ">搜索</div>
</div>
<div class="btn btn2" style="width: 105px" @click="handleRest">
<div class="search"></div>
<div class="btnText">重置</div>
</div>
</div>
</div>
<div v-if="Administrator===0" @click="ViewReviewShow=true" style="height: 38px; width: 150px;background: #4ea6ff;line-height: 40px;text-align: center;border-radius: 8px;color: #ffffff;">线上学习课程设置</div>
<div class="btns" @click="centerDialogVisible=true">
<div class="btn btn3">
<div class="search"></div>
<div class="btnText" @click="visible=true">创建认证</div>
</div>
</div>
</div>
</div>
<!-- 表格 -->
<div class="table">
<a-table :columns="columns"
:customHeaderRow="customRow"
:data-source="data"
:scroll="{ x: 1000 }"
:loading="loading"
class="ant-table"
:row-class-name="(_record, index) => 'table' "
:pagination="false">
<template #headerCell="{ column }">
<template v-if="column.key === 'serial'">
<span>
序号
</span>
</template>
</template>
<template #bodyCell="{ column, record,index }">
<template v-if="column.key === 'serial'">
<span>
{{ index+1 }}
</span>
</template>
<template v-else-if="column.key === 'tags'">
<span>
{{ record.name }}
</span>
</template>
<template v-else-if="column.key === 'action'">
<span style="text-align: center;">
<a style="margin-right: 7px;" @click="visible=true">编辑</a>
<a style="margin-right: 7px;" @click='SkipManagement(record.id)'>管理</a>
<a style="margin-right: 7px;">
评审
</a>
<DropDown v-if="Administrator===0" value="授权">
<OwnerTableModelStudent
:types="[7, 8, 9]"
:id="record.id"
:type="9"
>权限名单</OwnerTableModelStudent
>
<CommonStudent :type="7" :id="record.id" title="查看权"
>查看权</CommonStudent
>
<CommonStudent :type="8" :id="record.id" title="管理权"
>管理权</CommonStudent
>
</DropDown>
<a style="color: #de2139" @click="handleOper(record, 'del')">删除</a>
</span>
</template>
</template>
</a-table>
</div>
<div style="text-align: center; margin-top: 18px;">
<a-pagination :defaultPageSize="pageSize" :showSizeChanger="false" v-model:current="current1" show-quick-jumper :total="total" @change="onChange" />
</div>
<!--创建认证和编辑认证 -->
<a-modal v-model:visible="visible" title="编辑认证" @ok="handleOk" width="610px">
<a-form>
<a-form-item :rules="[{ required: true, message: 'Please input your password!' }]" label="Username" style="width: 381px;margin-left: 32px;margin-top: 24px">
<a-input placeholder="认证项目名称" style=" border-radius: 8px;" />
</a-form-item>
<a-form-item :rules="[{ required: true, message: 'Please input your password!' }]" label="封面图" style="width: 560px;margin-left: 32px;margin-top: 24px">
<img style="width: 127px; height: 70px;margin-bottom: 13px;" src="../../assets/50.png" alt="">
<!-- <a-image style="width: 127px; height: 70px;margin-bottom: 13px;" src="../../assets/50.png"></a-image> -->
<img style="width: 127px; height: 70px;margin-bottom: 13px;margin-left: 15px" src="../../assets/39.png" alt="">
<img style="width: 127px; height: 70px;margin-bottom: 13px;margin-left: 15px" src="../../assets/46.png" alt="">
<img style="width: 127px; height: 70px;margin-bottom: 13px;" src="../../assets/33.png" alt="">
<img style="width: 127px; height: 70px;margin-bottom: 13px;margin-left: 15px" src="../../assets/47.png" alt="">
<img style="width: 127px; height: 70px;margin-bottom: 13px;margin-left: 15px" src="../../assets/49.png" alt="">
</a-form-item>
<a-form-item style="margin-left: 32px;margin-top: 24px" label="具体说明">
<a-textarea
style="width: 408px;"
v-model:value="value2"
:auto-size="{ minRows: 2, maxRows: 5 }"
/>
</a-form-item>
</a-form>
</a-modal>
</div>
</template>
<style lang="scss" scoped>
.btn3 {
margin-right: 0;
.search {
width: 17px;
height: 18px;
background-image: url("@/assets/images/courseManage/add0.png");
}
}
.btn3:active {
background: #0982ff;
}
.btn1 {
.search {
width: 15px;
height: 17px;
background-image: url("@/assets/images/courseManage/search0.png");
}
}
.btn2 {
.search {
width: 16px;
height: 18px;
background-image: url("@/assets/images/courseManage/reset0.png");
}
}
.btn1:active {
background: #0982ff;
}
.btn2:active {
background: rgba(64, 158, 255, 0.2);
}
.btn {
padding: 0 26px 0 26px;
height: 38px;
background: #4ea6ff;
border-radius: 8px;
display: flex;
align-items: center;
justify-content: center;
margin-right: 14px;
flex-shrink: 0;
cursor: pointer;
.search {
background-size: 100%;
}
.btnText {
font-size: 14px;
font-weight: 400;
color: #ffffff;
line-height: 36px;
margin-left: 5px;
}
}
.page {
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
position: relative;
}
.filter {
margin-left: 40px;
margin-right: 62px;
margin-top: 28px;
display: flex;
justify-content: space-between;
flex-wrap: wrap;
.filterItems{
width: 100%;
height: 41px;
display: flex;
flex-wrap: wrap;
justify-content: space-between;
align-items: center;
}
}
.table {
margin-left: 40px;
margin-right: 62px;
margin-top: 28px;
display: flex;
flex-direction: column;
}
:deep(.ant-table-container table > thead > tr:first-child th:first-child) {
width: 83px;
}
:deep(.ant-table-container table > thead > tr:first-child th:last-child) {
width: 199px;
text-align: center;
}
:deep(.ant-table-container table > thead > tr:first-child th:last-child) {
width: 199px;
}
:deep(.ant-table-container table > thead > tr:first-child th:nth-last-child(2)) {
width: 143px;
}
:deep(.ant-table-container table > thead > tr:first-child th:nth-last-child(3)) {
width: 113px;
}
:deep(.ant-table-container table > thead > tr:first-child th:nth-last-child(4)) {
width: 326px;
}
:deep(.ant-table-tbody > tr > td ){
background-color: #f9f9f9;
}
.custom-dialog-title {
text-align: left; /* 让标题文本居左 */
/* 其他你需要的样式 */
}
.imgs {
width: 560px;
margin-left: 44.5px;
}
.explain {
width: 560px;
margin-left: 44.5px;
}
:deep(.imgs .el-form-item__label){
margin-top: 29px;
}
:deep(.demo-pagination-block) {
width: 100%;
}
:deep(.ant-table-tbody > tr > td){
text-align: center;
} .header {
margin-top: -20px;
height: 73px;
border-bottom: 1px solid #e8e8e8;
display: flex;
justify-content: space-between;
align-items: center;
flex-shrink: 0;
// background-color: red;
margin-bottom: 20px;
.headerTitle {
font-size: 18px;
font-weight: 600;
color: #333333;
line-height: 25px;
// margin-left: 24px;
}
}
</style>

View File

@@ -0,0 +1,55 @@
<script setup >
import { ElMessageBox } from 'element-plus'
import { UploadFilled } from '@element-plus/icons-vue'
import { ref } from 'vue'
const props = defineProps(["imprtlecturer"])
const emit = defineEmits(['CloseImprt'])
const Closeimprtlecturer = (done) => {
ElMessageBox.confirm('Are you sure to close this dialog?')
.then(() => {
emit('CloseImprt', false)
done()
})
.catch(() => {
// catch error
})
}
</script>
<template>
<div class="-page" >
<el-drawer v-model="props.imprtlecturer" :before-close="Closeimprtlecturer" style="padding:0 10px; width: 100%;" size="65%">
<template #title>
<h1 style="font-weight: 700;">导入讲师</h1>
</template>
<div >
<div style="width: 100%;">请下载 <span style="color: #409EFF;">模板</span> 按要求填写数据并导入</div>
</div>
<div style="margin-left: 20px; margin-top: 37px;">
<el-upload
style="width: 33%;"
class="upload-demo"
drag
action="https://run.mocky.io/v3/9d059bf9-4660-45f2-925d-ce80ad6c4d15"
multiple
>
<el-icon class="el-icon--upload"><upload-filled /></el-icon>
<div class="el-upload__text">
点击或将文件拖拽到此处上传件
</div>
<div style="color: #d7d7d7;">支持.xls .xlsx</div>
</el-upload>
</div>
<div style="text-align: center;">
<el-button plain type="primary" style="width: 100px; height: 40px;margin-right: 20px;" >取消</el-button>
<el-button type="primary" style="width: 100px; height: 40px;margin-left: 20px; ">确认</el-button>
</div>
</el-drawer>
</div>
</template>
<style lang="scss" scoped></style>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,281 @@
<template>
<a-modal
:visible="true"
:footer="null"
:title="null"
:centere="true"
:closable="false"
style="margin-top: 400px"
:zIndex="9999"
@cancel="close"
>
<div id="qrcode" class="QR">
<div class="qr_header"></div>
<div class="qr_main">
<div class="qrm_header">
<span>{{ title }}</span>
<div class="close_exit" @click="close"></div>
</div>
<div class="downloadCode" style="">
<div class="qrm_body">
<div class="qrm_body_info">
<div class="codename" v-if="courseName">项目{{ courseName }}</div>
<div class="codename">{{ name }}</div>
<div class="codename" v-if="createName">讲师{{ createName }}</div>
</div>
<QrcodeVue :value="url" :size="size" style="width: 200px; height: 200px"></QrcodeVue>
</div>
</div>
<div v-if="copyAble" class="codeUrl" :style="{ display: 'flex'}">
<div class="codeUrlLink">链接</div>
<a-input :value="url" disabled class="codeUrlInp"/>
<a-input
:value="url"
id="courseUrl"
class="codeUrlInp"
style="position: absolute; opacity: 0; z-index: -1"
/>
<div @click="copyUrl" class="codeUrlCopy">复制链接</div>
</div>
<div class="qrm_footer">
<span style="color: #387df7; cursor: pointer" @click="download(200)">下载二维码</span>
</div>
</div>
</div>
</a-modal>
</template>
<script setup>
import {defineProps, onMounted} from "vue";
import html2canvas from "html2canvas";
import QrcodeVue from "qrcode.vue";
import {message} from "ant-design-vue";
const props = defineProps({
close: {
type: Function,
default: () => ({})
},
ok: {
type: Function,
default: () => ({})
},
url: String,
copyAble: {
type: Boolean,
default: false
},
size: {
type: Number,
default: 800
},
name: String,
createName: String,
courseName: String,
title: {
type: String,
default: "二维码"
},
cancel: {
type: Boolean,
default: true
},
duration: {
type: Number,
default: 0
},
});
onMounted(() => props.duration && setTimeout(() => props.close(), props.duration));
function download() {
html2canvas(
document.querySelector(".downloadCode"),
{ useCORS: true,
allowTaint: true,
logging: true,
}
).then((canvas) => {
let a = document.createElement("a");
a.style.display = "none";
a.download = `${new Date().getTime()}.png`;
a.href = canvas.toDataURL("image/png");
document.body.appendChild(a);
a.click();
}).catch((err) => console.log('html2canvas',err));
}
function copyUrl() {
const input = document.createElement("input"); // 创建input对象
input.value = props.url;
document.body.appendChild(input); // 添加临时实例
input.select(); // 选择实例内容
document.execCommand("Copy"); // 执行复制
document.body.removeChild(input); // 删除临时实例
message.success("复制成功!");
}
</script>
<style lang="scss" scoped>
.QR {
z-index: 9999;
width: 520px;
background: #ffffff;
box-shadow: 0px 1px 35px 0px rgba(118, 136, 166, 0.21);
position: absolute;
left: 50%;
top: 10%;
transform: translate(-50%, -50%);
.qr_header {
position: absolute;
width: calc(100%);
height: 40px;
background: linear-gradient(
rgba(78, 166, 255, 0.2) 0%,
rgba(78, 166, 255, 0) 100%
);
}
.qr_main {
width: 100%;
position: relative;
.qrm_header {
display: flex;
align-items: center;
padding-top: 20px;
padding-left: 26px;
font-size: 16px;
.title {
font-size: 16px;
font-weight: 600;
color: #333333;
line-height: 22px;
}
.close_exit {
position: absolute;
right: 42px;
cursor: pointer;
width: 20px;
height: 20px;
background-image: url(@/assets/images/coursewareManage/close.png);
background-size: 100% 100%;
}
}
.qrm_body {
width: 100%;
padding-top: 22px;
padding-bottom: 32px;
display: flex;
flex-direction: column;
align-items: center;
.qrm_body_info{
width: 100%;
margin-left: 278px;
}
.codename {
font-size: 18px;
font-weight: 400;
color: #333333;
line-height: 25px;
margin-bottom: 5px;
margin-left: 20px;
margin-right: 20px;
text-align: left;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
max-width: 300px;
}
}
.codeUrl {
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 24px;
.codeUrlLink {
width: 72px;
height: 40px;
display: flex;
align-items: center;
justify-content: center;
font-size: 14px;
font-weight: 400;
color: #c7cbd2;
line-height: 20px;
border: 1px solid #c7cbd2;
border-right: 0px solid #c7cbd2;
}
.codeUrlInp {
width: 305px;
height: 40px;
border: 1px solid #c7cbd2;
}
.ant-input-disabled {
background-color: rgba(0, 0, 0, 0) !important;
}
.ant-input[disabled] {
background-color: rgba(0, 0, 0, 0) !important;
}
.codeUrlCopy {
width: 96px;
height: 40px;
background-color: #4ea6ff;
border-radius: 8px;
display: flex;
align-items: center;
justify-content: center;
font-size: 14px;
font-weight: 400;
color: #ffffff;
line-height: 20px;
cursor: pointer;
margin-left: 8px;
}
}
.qrm_footer {
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 44px;
.qrmbtn {
width: 80px;
height: 32px;
display: flex;
line-height: 32px;
justify-content: center;
border-radius: 4px;
border: 1px solid #387df7;
cursor: pointer;
.btntext {
color: #387df7;
}
}
}
}
}
.codeModal {
.ant-modal {
.ant-modal-content {
width: 479px !important;
}
}
}
</style>
<style lang="scss">
.ant-modal-body {
padding: 0 !important;
}
</style>

View File

@@ -0,0 +1,33 @@
<script setup>
const props = defineProps({
showViewInstructor: {
type: Boolean,
default: false,
},
});
const emit = defineEmits(["update:visible"]);
const afterVisibleChange = (bool) => {
console.log("visible", bool);
};
</script>
<template>
<div class="-page">
<a-drawer
v-model:visible="visible"
class="custom-class"
style="color: red"
title="Basic Drawer"
placement="right"
@after-visible-change="afterVisibleChange"
>
<p>Some contents...</p>
<p>Some contents...</p>
<p>Some contents...</p>
</a-drawer>
</div>
</template>
<style lang="scss" scoped></style>

View File

@@ -0,0 +1,83 @@
<script setup >
const props = defineProps(['ViewReviewShow'])
import { reactive } from 'vue';
import InitiateReviewTable from './InitiateReviewTable.vue'
const formState = reactive({
username: '',
password: '',
remember: true,
});
const ViewReviewcolumns = [
{
title: 'Name',
dataIndex: 'name',
},
{
title: 'Age',
dataIndex: 'age',
},
{
title: 'Address',
dataIndex: 'address',
},
];
const ViewReviewdata = [
{
key: '1',
name: 'John Brown',
age: 32,
address: 'New York No. 1 Lake Park',
},
{
key: '2',
name: 'Jim Green',
age: 42,
address: 'London No. 1 Lake Park',
},
{
key: '3',
name: 'Joe Black',
age: 32,
address: 'Sidney No. 1 Lake Park',
},
{
key: '4',
name: 'Ben Kang',
age: 15,
address: 'Sidney No. 1 Lake Park',
},
];
</script>
<template>
<div class="-page">
<el-drawer v-model="props.ViewReviewShow" title="查看评审" size="65%">
<div style="display: flex;flex-direction: column;">
<div style="font-size: 16px;"> 评审名称<span>第三场二次认证</span></div>
<div style="font-size: 16px;margin: 20px 0;"> 评审时间<span>2024.05.30 14:00</span></div>
<div style="font-size: 16px;">评审结果</div>
<div>
<a-table
:row-selection="rowSelection"
:pagination="false"
:row-class-name="(_record, index) => (index % 2 === 1 ? 'table-striped' : null)"
:columns="ViewReviewcolumns"
:data-source="ViewReviewdata"
class="ant-table-striped"
size="middle"
/>
</div>
<div style="align-self: center;">
<div style="border-radius: 8px; color: #fff;font-weight: 900;font-size: 16px; display: flex; justify-content: center;align-items: center; width: 176px; height: 55px; margin-top: 36px;background: #3da8f0;">结束评审并通知结果</div>
</div>
</div>
</el-drawer>
</div>
</template>
<style lang="scss" scoped>
</style>

View File

@@ -0,0 +1,929 @@
<!-- eslint-disable vue/no-parsing-error -->
<!-- eslint-disable vue/require-v-for-key -->
<template>
<div class="CommonStudent">
<a-drawer :visible="visiable" class="drawerStyle ProjCheckship CommonStudent" placement="right" width="60%">
<div class="drawerMain" id="ProjCheckship" style="">
<div class="header">
<div class="headerTitle">
{{ { 1: "添加学员", 2: "添加学员", 3: "添加学员" }[type] || title }}
</div>
<img style="width: 29px; height: 29px; cursor: pointer" src="../../assets/images/basicinfo/close.png"
@click="closeDrawer"/>
</div>
<div style="display: flex; overflow-x: auto; overflow-y: auto">
<div class="tabs" style="min-width: 800px">
<a-tabs v-model:activeKey="activeKey">
<a-tab-pane v-if="infoType" :key="4" tab="项目内学员">
<div :style="{ height: screenHeight - 235 + 'px' }">
<div>
<a-form-item label="姓名:">
<a-input v-model:value="projectParams.studentName"
style="width: 260px; height: 40px; border-radius: 8px"
placeholder="请输入姓名"/>
<a-button type="primary" @click="getProjectStu" style="margin-left: 20px; border-radius: 4px">
<template #icon>
<SearchOutlined/>
</template>
搜索
</a-button>
<a-button type="primary" @click="resetProjectStu" style="margin-left: 20px; border-radius: 4px">重置
</a-button>
</a-form-item>
</div>
<div class="tableBox tabb">
<BaseTable ref="projectStuTableRef" :columns="projectStuColumns" :url="STUDENT_LIST"
v-model:params="projectParams" v-model:selectedRows="projectSelectRows"
type="checkbox"></BaseTable>
</div>
</div>
</a-tab-pane>
<a-tab-pane :key="1" tab="快速选人">
<div :style="{ height: screenHeight - 235 + 'px' }">
<div class="tab1">
<a-form-item label="姓名">
<a-input v-model:value="nameSearch.keyword" style="width: 270px; height: 40px; border-radius: 8px"
placeholder="请输入姓名"/>
<a-button type="primary" @click="onSearchStu" style="margin-left: 20px; border-radius: 4px">
<template #icon>
<SearchOutlined/>
</template>
搜索
</a-button>
<a-button type="primary" @click="resetStu" style="margin-left: 20px; border-radius: 4px">重置
</a-button>
</a-form-item>
</div>
<div class="chooseLeft" style="display: grid; grid-template-columns: 250px auto">
<div :style="{
height: screenHeight - 180 + 'px',
overflowY: 'auto',
}" style="border: 1px solid #f0f0f0">
<div class="tree" style="margin: 10px 4px 220px 10px">
<a-tree allow-clear tree-default-expand-all :tree-data="treeData" :loading="orgLoading"
:load-data="onLoadData" v-model:selectedKeys="stuTreeSelectKeys"
v-model:expandedKeys="stuTreeExpandedKeys" :fieldNames="{
children: 'treeChildList',
key: 'id',
title: 'name',
value: 'name',
}" @select="stuStuOrgSelect">
</a-tree>
</div>
</div>
<div class="tableBox tabb" style="
margin: 0px 4px 120px 10px;
border: 1px solid #f0f0f0;
">
<BaseTable ref="stuTableRef" :columns="stuColumns" :url="USER_LIST_PAGE" pageKey="pageNo"
v-model:params="nameSearch" :request="useNewRowsPageNoInit"
v-model:selectedRows="stuSelectRows" type="checkbox"></BaseTable>
</div>
</div>
</div>
</a-tab-pane>
<a-tab-pane v-if="!selectStu" :key="2" tab="添加组织">
<div :style="{ height: screenHeight - 235 + 'px' }">
<div class="tab2">
<a-form-item label="组织:">
<a-input v-model:value="searchOrgName.keyword"
style="width: 230px; height: 40px; border-radius: 8px" placeholder="请输入组织"
@click="orgValue"/>
<a-button type="primary" @click="searchOrg" style="margin-left: 20px; border-radius: 4px">
<template #icon>
<SearchOutlined/>
</template>
搜索
</a-button>
<a-button type="primary" @click="resetOrg" style="margin-left: 20px; border-radius: 4px">重置
</a-button>
</a-form-item>
</div>
<div class="boeTree">
<a-tree v-model:selectedKeys="selectedOrgKeys"
:tree-data="searchOrgName.keyword ? orgData : treeOrgData" @select="onOrgSelectChange"
:loading="orgOrgLoading" :load-data="onLoadOrgData" :fieldNames="{
children: 'treeChildList',
key: 'id',
title: 'name',
value: 'name',
}" row-key="id" :row-selection="orgRowSelection" multiple>
</a-tree>
</div>
</div>
</a-tab-pane>
<a-tab-pane v-if="!selectStu" :key="3" tab="受众关联">
<div :style="{ height: screenHeight - 235 + 'px' }">
<div>
<a-form-item label="受众名称:">
<a-input v-model:value="audienceName.keyword"
style="width: 260px; height: 40px; border-radius: 8px"
placeholder="请输入受众名称"/>
<a-button type="primary" @click="searchAudi" style="margin-left: 20px; border-radius: 4px">
<template #icon>
<SearchOutlined/>
</template>
搜索
</a-button>
<a-button type="primary" @click="resetAudienceInfo" style="margin-left: 20px; border-radius: 4px">
重置
</a-button>
</a-form-item>
</div>
<div class="tableBox tabb">
<BaseTable ref="auditTableRef" :columns="audiColums" :url="AUDIENCE_LIST" page-key="pageNo"
v-model:params="audienceName" :request="useTotalPage"
v-model:selectedRows="auditSelectRows" v-model:selectedRowKeys="auditSelectRowKeys"
type="checkbox"></BaseTable>
</div>
</div>
</a-tab-pane>
</a-tabs>
</div>
<div class="right1" style="min-width: 200px">
<div class="onerow">
<div class="onleft">
<div class="already">已选</div>
</div>
</div>
<div :style="{ 'max-height': screenHeight - 235 + 'px' }" style="overflow-y: auto">
<div class="selecteds" v-if="infoType">
<div class="person">项目内学员</div>
<div v-for="(item, i) in projectSelectRows" :key="i">
<div v-if="i < 11">
<div class="chose">
{{ item.studentName }}
<div class="ch" @click="auditTableRef.remove(i)"></div>
</div>
</div>
<div v-else>
<div v-if="person">
<div class="chose">
{{ item.studentName }}
<div class="ch" @click="auditTableRef.remove(i)"></div>
</div>
</div>
</div>
</div>
<div v-if="!member && projectSelectRows?.length > 10" class="ifsw">
<div @click="member = !member" class="“sw”">查看更多></div>
</div>
<div v-if="member && projectSelectRows?.length > 10" class="ifsw">
<div @click="member = !member" class="sw">收起&lt;</div>
</div>
</div>
<div class="selecteds">
<div class="person">快速选人</div>
<div v-for="(item, i) in stuSelectRows" :key="i">
<div v-if="i < 11">
<div class="chose">
{{ item.realName }}
<div class="ch" @click="stuTableRef.remove(i)"></div>
</div>
</div>
<div v-else>
<div v-if="person">
<div class="chose">
{{ item.realName }}
<div class="ch" @click="stuTableRef.remove(i)"></div>
</div>
</div>
</div>
</div>
<div v-if="!person && stuSelectRows.length > 10" class="ifsw">
<div @click="person = !person" class="“sw”">查看更多></div>
</div>
<div v-if="person && stuSelectRows.length > 10" class="ifsw">
<div @click="person = !person" class="sw">收起&lt;</div>
</div>
</div>
<div v-if="!selectStu" class="selecteds">
<div class="dept">添加组织</div>
<div v-for="(item, i) in deptList" :key="i">
<div v-if="i < 11">
<div class="chose1">
<div class="span">{{ item.name }}</div>
<div class="ch1" @click="orgDel(i)" style="cursor: pointer;"></div>
</div>
</div>
<div v-else>
<div v-if="dept">
<div class="chose1">
<div class="span">{{ item.name }}</div>
<div class="ch1" @click="orgDel(i)"></div>
</div>
</div>
</div>
</div>
<div v-if="!dept && deptList.length > 10" class="ifsw">
<div @click="dept = !dept" class="“sw”">查看更多></div>
</div>
<div v-if="dept && deptList.length > 10" class="ifsw">
<div @click="dept = !dept" class="sw">收起&lt;</div>
</div>
</div>
<!--受众-->
<div v-if="!selectStu" class="selecteds">
<div class="group">受众关联</div>
<div v-for="(item, i) in auditSelectRows" :key="i">
<div v-if="i < 11">
<div class="chose2">
<div class="span">{{ item.audienceName }}</div>
<div class="ch2" @click="auditTableRef.remove(i)"></div>
</div>
</div>
<div v-else>
<div v-if="group">
<div class="chose2">
<div class="span">{{ item.audienceName }}</div>
<div class="ch2" @click="auditTableRef.remove(i)"></div>
</div>
</div>
</div>
</div>
<div v-if="!group && auditSelectRows.length > 10" class="ifsw">
<div @click="group = !group" class="“sw”">查看更多></div>
</div>
<div v-if="group && auditSelectRows.length > 10" class="ifsw">
<div @click="group = !group" class="sw">收起&lt;</div>
</div>
</div>
</div>
</div>
</div>
<div class="btnn">
<button class="btn2" style="width: 100px; height:38px;background:
#4ea6ff;border: none;margin-right: 15px; border-radius: 8px;color:aliceblue" @click="closeDrawer">取消</button>
<button class="btn2" style="width: 100px;
height:38px;background: #4ea6ff;border: none; border-radius: 8px ;color:aliceblue" @click="submitAuth">确定</button>
</div>
</div>
</a-drawer>
<a-button @click="openDrawer" type="link">
<slot></slot>
</a-button>
</div>
<a-modal :style="{ padding: 0, position:'relative', right: '-20%' }" :closable="true" :visible="stageVisible"
:footer="null" centered="true" @ok="handleStageOk" wrapClassName="changeModal">
<div class="con">
<div class="header">
<div class="inhe">
<div class="tz">{{ type === 1 ? "选择阶段" : "添加学员到关卡" }}</div>
<div class="mg" @click="closeChangeModal"></div>
</div>
</div>
<div class="mid">
<div class="inher">
<div class="select">
<a-select style="width: 400px" :placeholder="type === 1 ? '选择阶段' : '选择关卡'" v-model:value="stageId"
className="cus-select">
<a-select-option v-for="(item, i) in stageIds" :key="i" :value="item.id">{{ item.name || "默认" }}
</a-select-option>
</a-select>
</div>
<span style="color: #999999; margin-left: 10px"><minus-circle-outlined/>已在其他关卡的学员不会被添加到该关卡</span>
<div class="btn" style="margin-top: 50px">
<button class="sameb btn1" @click="closeChangeModal" style="cursor: pointer">
取消
</button>
<button class="sameb btn2" @click="handleDialogOk" style="cursor: pointer">
确定
</button>
</div>
</div>
</div>
</div>
</a-modal>
</template>
<script setup>
import {message} from "ant-design-vue";
import {computed, defineEmits, defineProps, ref, watch} from "vue";
import {useNewRowsPageNoInit, request, useRequest, useTotalPage} from "@/api/request";
import {
saveStu,
} from "@/api/index1";
import dialog from "@/utils/dialog";
import BaseTable from "@/components/common/BaseTable";
import {AUDIENCE_LIST, ORG_CHILD_LIST, ORG_LIST, STUDENT_LIST, USER_LIST_PAGE} from "@/api/apis";
import {addTutor}from '@/api/examineApi.js'
const emit = defineEmits({});
const props = defineProps({
type: Number,
infoType: Number,
infoId: Number,
id: String,
title: {
type: String,
default: "",
},
clear: {
type: Boolean,
default: false,
},
selectStu: {
type: Boolean,
default: false,
},
selectOne: {
type: Boolean,
default: false,
},
stage: {
type: Array,
default: () => [],
},
isGroup: {
type: Boolean,
default: false,
},
projectId: {
type: Number,
default: null,
},
groupId: {
type: Number,
default: null,
},
groupName: {
type: String,
default: null,
},
groupMemberCount: {
type: Number,
default: null,
},
groupMemberNumber: {
type: Number,
default: null,
},
activeKey1: {
type: String,
default: null,
},
});
const projectSelectKeys = ref([]);
const projectSelectRows = ref([]);
const stuSelectRows = ref([]);
const auditSelectRows = ref([]);
const auditSelectRowKeys = ref([]);
const deptList = ref([]);
const member = ref(false);
const dept = ref(false);
const projectStuTableRef = ref();
const stuTableRef = ref();
const projectParams = ref({ pid: props.infoId, type: props.infoType, studentName: "" });
const getProjectStu = () => projectStuTableRef.value.fetch();
const resetProjectStu = () => {
projectParams.value.studentName = "";
projectStuTableRef.value.reset();
};
const teaunm = ref([])
watch(stuSelectRows,(val)=>{
console.log(val,'val')
teaunm.value = val.map((res,index)=>res.id)
console.log(teaunm.value);
})
const person = ref(false);
const group = ref(false);
const visiable = ref(false);
const activeKey = ref(props.infoType ? 4 : 1);
const stageVisible = ref(false);
const stageId = ref();
const nameSearch = ref({
keyword: "",
departId: '',
});
const stuTreeSelectKeys = ref([]);
const stuTreeExpandedKeys = ref([]);
const audienceName = ref({
keyword: "",
});
const searchOrgName = ref({
keyword: "",
pageNo: 1,
pageSize: 10,
});
const stageIds = computed(() => props.stage);
const { data: orgData, fetchData: searchOrg } = useRequest(
ORG_LIST,
searchOrgName.value,
);
const { data: treeData, loading: orgLoading } = useRequest(
ORG_LIST,
{ keyword: "" },
);
const { data: treeOrgData, loading: orgOrgLoading } = useRequest(
ORG_LIST,
{ keyword: "" },
);
const projectStuColumns = ref([
{
title: "姓名",
dataIndex: "studentName",
key: "studentName",
width: 80,
align: "center",
className: "h",
ellipsis: true,
},
{
title: "工号",
dataIndex: "studentUserNo",
key: "studentUserNo",
width: 80,
align: "center",
className: "h",
ellipsis: true,
},
{
title: "归属组织",
dataIndex: "studentOrgName",
key: "studentOrgName",
width: 80,
align: "center",
className: "h",
ellipsis: true,
},
{
title: "部门",
dataIndex: "studentDepartName",
key: "studentDepartName",
width: 80,
align: "center",
className: "h",
ellipsis: true,
},
]);
const stuColumns = ref([
{
title: "姓名",
dataIndex: "realName",
key: "realName",
width: 80,
align: "center",
className: "h",
ellipsis: true,
},
{
title: "工号",
dataIndex: "userNo",
key: "userNo",
width: 80,
align: "center",
className: "h",
ellipsis: true,
},
{
title: "归属组织",
dataIndex: "orgName",
key: "orgName",
width: 80,
align: "center",
className: "h",
ellipsis: true,
},
{
title: "部门",
dataIndex: "departName",
key: "departName",
width: 80,
align: "center",
className: "h",
ellipsis: true,
},
]);
const audiColums = ref([
{
title: "受众名称",
dataIndex: "audienceName",
key: "audienceName",
width: 30,
align: "left",
className: "h",
ellipsis: true,
},
{
title: "人数",
dataIndex: "totalMember",
key: "totalMember",
width: 30,
align: "center",
className: "h",
},
]);
const orgSelectKeys = ref([]);
const auditTableRef = ref();
const screenHeight = ref(document.body.clientHeight);
const orgRowSelection = computed(() => ({
columnWidth: 20,
selectedRowKeys: orgSelectKeys.value,
onChange: onOrgSelectChange,
preserveSelectedRowKeys: true,
}));
const closeDrawer = () => {
deleteDepSelect();
visiable.value = false;
nameSearch.value.keyword = "";
selectedOrgKeys.value = [];
};
function searchAudi() {
auditTableRef.value.reset(audienceName.value);
}
function onLoadData(treeNode) {
return request(ORG_CHILD_LIST, { keyword: "", orgId: treeNode.id }).then(
(r) => {
treeNode.dataRef.treeChildList = r.data;
treeData.value = [...treeData.value];
}
);
}
function onLoadOrgData(treeNode) {
return request(ORG_CHILD_LIST, { keyword: "", orgId: treeNode.id }).then(
(r) => {
treeNode.dataRef.treeChildList = r.data;
treeOrgData.value = [...treeOrgData.value];
}
);
}
const closeChangeModal = () => {
stageVisible.value = false;
};
const openDrawer = () => {
visiable.value = true;
};
function onSearchStu() {
stuTableRef.value.reset(nameSearch.value);
}
function stuStuOrgSelect(e) {
nameSearch.value.departId = e.join("");
stuTableRef.value.fetch();
}
const selectedOrgKeys = ref([]);
watch(selectedOrgKeys, () => {
console.log("selectedKeys", selectedOrgKeys);
});
function orgDel(i) {
orgSelectKeys.value = orgSelectKeys.value.filter(e => e !== deptList.value[i].id);
selectedOrgKeys.value.splice(i, 1);
deptList.value.splice(i, 1);
}
function onOrgSelectChange(e, l) {
orgRowSelection.value = e;
deptList.value = l.selectedNodes;
}
const resetStu = () => {
nameSearch.value.keyword = "";
stuTableRef.value.reset({ keyword: "", departId: '' });
};
//清空选择部门信息
const deleteDepSelect = () => {
stuSelectRows.value = [];
selectedOrgKeys.value = [];
projectSelectKeys.value = [];
};
//重置组织
const resetOrg = () => {
searchOrgName.value = { keyword: "" };
};
//重置受众
const resetAudienceInfo = () => {
audienceName.value.keyword = "";
auditTableRef.value.reset({ keyword: "" });
};
//确定添加授权
const submitAuth = () => {
if (props.type === 2) {
stageVisible.value = true;
} else {
handleDialogOk();
}
};
function handleDialogOk() {
if (auditSelectRowKeys.value.length || deptList.value.length) {
dialog({ content: "您选择了组织或受众,此添加为异步添加,请稍后手动刷新学员!", ok: handleStageOk });
return;
}
handleStageOk();
}
import { useRoute, useRouter } from 'vue-router'
const route = useRoute()
function handleStageOk() {
if (props.type === 1 && props.groupId && (props.groupMemberCount < (props.groupMemberNumber * 1 + projectSelectRows.value.length + stuSelectRows.value.length))) {
return message.warning("添加小组学员超过最大值");
}
stageVisible.value = false;
visiable.value = false;
emit("finash", false);
nameSearch.value.keyword = "";
addTutor({
examineId:route.query.id.toString(),
teacherIds: teaunm.value
}).then(() => {
deleteDepSelect();
emit("finash", true);
message.info('添加成功');
});
// saveStu({
// targetId: props.id,
// type: props.type,
// clear: props.clear,
// deptIds: deptList.value?.map((e) => e.id),
// stageId: stageId.value,
// groupIds: auditSelectRows.value?.map((e) => e.id),
// studentList: stuSelectRows.value,
// projectList: projectSelectRows.value,
// groupName: props.groupName,
// groupId: props.groupId,
// }).then(() => {
// deleteDepSelect();
// emit("finash", true);
// });
}
// 搜索受众值发生变化
function orgValue(value) {
console.log("", value.target.value);
searchOrgName.value.keyword = value.target.value;
}
watch(visiable, () => {
orgSelectKeys.value = [];
deptList.value = [];
audienceName.value.keyword = "";
nameSearch.value.departId = '';
stuTreeExpandedKeys.value = [];
stuTreeSelectKeys.value = [];
activeKey.value = props.isGroup ? 4 : 1;
projectParams.value.studentName = "";
nameSearch.value.keyword = "";
searchOrgName.value.keyword = "";
audienceName.value.keyword = "";
if (!visiable.value) {
auditTableRef.value && auditTableRef.value.clear();
auditTableRef.value && auditTableRef.value.reset({ keyword: "" });
stuTableRef.value && stuTableRef.value.clear();
stuTableRef.value && stuTableRef.value.reset({ keyword: "", departId: '' });
projectStuTableRef.value && projectStuTableRef.value.clear();
projectStuTableRef.value && projectStuTableRef.value.reset({ pid: props.infoId, type: props.infoType, studentName: "" });
}
});
</script>
<style lang="scss">
.CommonStudent > .ant-drawer-content-wrapper {
min-width: 1200px !important;
width: 1200px !important;
}
.CommonStudent {
.ant-btn-primary {
background-color: #4ea6ff !important;
}
.cus-select {
height: 40px;
border-radius: 8px;
}
.tableBox .ant-table-row .ant-table-cell {
height: 48px;
font-size: 14px;
font-weight: 400;
color: #4f5156;
line-height: 29px;
padding: 0px;
}
.tableBox .ant-table-thead tr th {
font-size: 14px;
}
.ant-tabs-tabpane {
height: 100%;
}
.ant-tabs {
overflow: visible;
}
.right1 {
border-left: 1px solid #f2f6fe;
margin-left: 20px;
.onerow {
display: flex;
justify-content: space-between;
align-items: center;
margin-right: 40px;
flex-wrap: wrap;
width: 100%;
.onleft {
display: flex;
text-align: center;
.already {
color: rgba(51, 51, 51, 1);
font-size: 16px;
font-weight: 500;
margin-left: 32px;
white-space: nowrap;
// margin-bottom: 20px;
}
.count {
color: #4ea6ff;
font-size: 16px;
margin: 0 6px;
}
.peo {
color: rgba(51, 51, 51, 1);
font-size: 16px;
font-weight: 500;
}
}
.clbox {
margin-right: 50px;
display: flex;
justify-content: center;
align-items: center;
cursor: pointer;
width: 104px;
height: 32px;
border-radius: 4px;
background: #4ea6ff;
.colose {
width: 16px;
height: 16px;
// border-radius: 8px;
// background: #ffffff;
// position: relative;
background-image: url(../../assets/images/basicinfo/ch.png);
background-size: 100%;
margin-right: 4px;
}
.allclear {
color: rgba(255, 255, 255, 1);
font-size: 14px;
}
}
}
.selecteds {
display: flex;
flex-wrap: wrap;
margin-left: 32px;
.person {
width: 100%;
margin-top: 20px;
border-top: 1px solid #f2f6fe;
}
.chose {
width: 64px;
height: 24px;
margin-top: 25px;
margin-right: 25px;
display: flex;
align-items: center;
justify-content: center;
border-radius: 2px;
border: 1px solid rgba(56, 139, 225, 1);
color: rgba(56, 139, 225, 1);
font-size: 12px;
position: relative;
.ch {
position: absolute;
width: 18px;
height: 18px;
background-image: url(../../assets/images/basicinfo/ch.png);
right: -8px;
top: -8px;
}
}
.ifsw {
display: flex;
align-items: end;
justify-content: center;
color: #4ea6ff;
}
.sw {
display: flex;
align-items: center;
justify-content: center;
text-align: justify;
color: #4ea6ff;
margin-top: 23px;
margin-left: 10px;
}
.dept {
width: 100%;
margin-top: 30px;
border-top: 1px solid #f2f6fe;
}
.chose1 {
//width: 90px;
height: 24px;
margin-top: 25px;
margin-right: 25px;
display: flex;
align-items: center;
justify-content: center;
border-radius: 2px;
border: 1px solid rgba(56, 139, 225, 1);
color: rgba(56, 139, 225, 1);
font-size: 12px;
position: relative;
.span {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.ch1 {
position: absolute;
width: 18px;
height: 18px;
background-image: url(../../assets/images/basicinfo/ch.png);
right: -8px;
top: -8px;
}
}
.group {
width: 100%;
margin-top: 30px;
border-top: 1px solid #f2f6fe;
}
.chose2 {
//width: 120px;
height: 24px;
margin-top: 25px;
margin-right: 25px;
display: flex;
align-items: center;
justify-content: center;
border-radius: 2px;
border: 1px solid rgba(56, 139, 225, 1);
color: rgba(56, 139, 225, 1);
font-size: 12px;
position: relative;
.span {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.ch2 {
position: absolute;
width: 18px;
height: 18px;
background-image: url(../../assets/images/basicinfo/ch.png);
right: -8px;
top: -8px;
}
}
}
}
}
</style>