Merge branch 'test11' into zcwy-zsx0223

# Conflicts:
#	src/components/drawers/router/RouterFaceStu.vue
This commit is contained in:
zhangsir
2024-02-23 10:37:22 +08:00
18 changed files with 1393 additions and 149 deletions

View File

@@ -21,8 +21,16 @@
</div>
<div class="downloadCode" style="">
<div class="qrm_body">
<div class="codename">
{{ codeInfo.name ? codeInfo.name : "" }}
<div :class="codeInfo.teacherName?'qrm_body_item':''">
<div v-if="codeInfo.name&&!codeInfo.teacherName" class="codename">
{{ codeInfo.name ? codeInfo.name : "" }}
</div>
<div v-if="codeInfo.name&&codeInfo.teacherName" class="codename">
开课{{ codeInfo.name ? codeInfo.name : "" }}
</div>
<div v-if="codeInfo.teacherName" class="codename">
讲师{{ codeInfo.teacherName ? codeInfo.teacherName : "" }}
</div>
</div>
<qrcode-vue
:value="codeInfo.url.startsWith('/')?(`${domain+codeInfo.url}&t=10`):`${codeInfo.url}&t=10`"
@@ -163,6 +171,7 @@ export default {
title: "",
name: "",
url: "",
teacherName: "",
};
state.codeInfo = Object.assign(obj, props.codeInfo);
console.log("codeInfo22222", state.codeInfo, props.index, props.type);
@@ -241,6 +250,10 @@ export default {
display: flex;
flex-direction: column;
align-items: center;
.qrm_body_item{
width: 100%;
margin-left: 270px;
}
.codename {
font-size: 18px;
font-weight: 400;
@@ -249,6 +262,10 @@ export default {
margin-bottom: 20px;
margin-left: 20px;
margin-right: 20px;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
max-width: 300px;
}
}
.codeUrl {

View File

@@ -18,7 +18,11 @@
</div>
<div class="downloadCode" style="">
<div class="qrm_body">
<div class="codename">{{ name }}</div>
<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>
@@ -65,6 +69,8 @@ const props = defineProps({
default: 800
},
name: String,
createName: String,
courseName: String,
title: {
type: String,
default: "二维码"
@@ -162,15 +168,23 @@ function copyUrl() {
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: 20px;
margin-bottom: 5px;
margin-left: 20px;
margin-right: 20px;
text-align: left;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
max-width: 300px;
}
}

View File

@@ -125,7 +125,7 @@
<span style="margin-right: 3px">面授时间</span>
</div>
<div class="select fitems">
<a-range-picker
<!-- <a-range-picker
style="width: 88%; height: 40px; border-radius: 8px"
:show-time="{ format: 'HH:mm' }"
format="YYYY-MM-DD HH:mm"
@@ -135,12 +135,46 @@
separator="至"
:placeholder="[' 开始时间', ' 结束时间']"
:disabled="editBeginClass"
/> -->
<a-date-picker
style="width: 41%; height: 40px; border-radius: 8px"
:show-time="{ format: 'HH:mm' }"
:format="['YYYY-MM-DD HH:mm','YYYY/MM/DD HH:mm']"
valueFormat="YYYY-MM-DD HH:mm"
v-model:value="dateTime[0]"
@change="timeChange"
:placeholder="' 开始时间'"
:disabled="editBeginClass"
@blur="onBlurStart"
@focus="onFocusStart"
@select="onDateSelect"
:open="openStart"
@ok="onOkStart"
ref="datePicker"
/>
<span style="margin: 0 10px;"></span>
<!-- 第二个日期选择器用于结束时间 -->
<a-date-picker
style="width: 41%; height: 40px; border-radius: 8px"
:show-time="{ format: 'HH:mm' }"
:format="['YYYY-MM-DD HH:mm','YYYY/MM/DD HH:mm']"
valueFormat="YYYY-MM-DD HH:mm"
v-model:value="dateTime[1]"
@change="timeChangeEnd"
:placeholder="' 结束时间'"
:disabled="editBeginClass"
@focus="onFocusEnd"
@blur="onBlurEnd"
@select="onDateEnd"
:open="openEnd"
@ok="onOkEnd"
/>
</div>
</div>
<div class="cstm_items">
<div class="signbox">
<div class="cstm_items" style="align-items: baseline;">
<div class="signbox" style="position: relative;top: -5px;">
<div class="sign">
<img
src="@/assets/images/coursewareManage/asterisk.png"
@@ -149,12 +183,22 @@
</div>
<span style="margin-right: 3px">授课教师</span>
</div>
<div class="select" style="width: 74.5%">
<ProjectManager
v-model:value="formData.teacherId"
v-model:name="formData.teacher"
:disabled="editBeginClass"
></ProjectManager>
<div class="teacher_input select" style="display: flex; flex-wrap: wrap;width: 74.5%">
<div v-for="(item, index) in formData.offteachers"
:key="index" style="display: flex;margin-bottom: 10px;width: 100%;">
<ProjectManager
v-model:value="item.teacherId"
v-model:name="item.teacherName"
:disabled="editBeginClass"
></ProjectManager>
<a-input-number :min="0" @change="inputWeightChange(index)" v-model:value="item.weight" placeholder="%"/>
<span style="margin-top: 10px;width: 34px;">权重</span>
<div style="display: flex;">
<a-button v-if="index===0" shape="circle" class="btn-circle btn-add" @click="inputAdd">+</a-button>
<a-button shape="circle" class="btn-circle" @click="inputRemove(index)" :disabled="formData.offteachers.length == 1"><template #icon><delete-outlined class="custom-icon"/></template></a-button>
</div>
</div>
</div>
</div>
<div class="cstm_items">
@@ -262,13 +306,15 @@
<div class="b_input" style="width: 88%;display: flex;flex-direction: column;">
<CheckBox v-model="formData.projectSignFlag"
:check-value="1"
:un-check-value="0">
<span style="color: #6d7584">允许项目内人员临时到场参加(不在本场次培训的人员可以临时签到参加)</span>
:un-check-value="0"
@change="toggleCheckboxes('projectSignFlag')">
<span style="color: #6d7584">允许项目内人员临时到场参加(不在本场次培训的人员可以临时签到评估)</span>
</CheckBox>
<CheckBox v-model="formData.outSignFlag"
:check-value="1"
style="margin-left: 0px;"
:un-check-value="0">
:un-check-value="0"
@change="toggleCheckboxes('outSignFlag')">
<span style="color: #6d7584">允许项目外人员临时到场参加</span>
</CheckBox>
</div>
@@ -370,31 +416,44 @@
</a-drawer>
</template>
<script setup lang="jsx">
import {defineProps, ref, nextTick, computed} from "vue";
import {defineProps, ref, nextTick, computed,defineEmits } from "vue";
import {Form, message} from "ant-design-vue";
import FJUpload from "@/components/common/FJUpload";
import CheckBox from "@/components/common/CheckBox";
import RangePicker from "@/components/common/RangePicker";
import ProjectManager from "@/components/project/ProjectManagerNew";
import ProjectManager from "@/components/project/ProjectManagerNewTeacher";
import AddHomework from "@/components/drawers/CommonHomework.vue";
import AddTest from "@/components/drawers/CommonTest.vue";
import NameInput from "@/components/project/NameInput";
import AssessmentList from "@/components/drawers/AssessmentList.vue";
import {COURSE_PLAN_EDIT, COURSE_PLAN_PAGE, DEL_PLAN, EXAM_DETAIL, WORK_DETAIL} from "@/api/apis";
import {COURSE_PLAN_EDIT, COURSE_PLAN_PAGE, DEL_PLAN, EXAM_DETAIL, WORK_DETAIL,PROJECT_DETAIL_MODIFY,PROJECT_RELEASE} from "@/api/apis";
import dayjs from "dayjs";
import BaseTable from "@/components/common/BaseTable";
import {request,useRowsPageNoInit} from "@/api/request";
import dialog from "@/utils/dialog";
import {useResetRef} from "@/utils/useCommon";
import { validateName } from "@/api/index1";
import moment from 'moment';
import * as api from "../../api/indexTaskadd";
import {useRoute} from "vue-router";
import { DeleteOutlined } from '@ant-design/icons-vue';
const props = defineProps({
type: Number,
});
const openCourseVisible = ref(false);
const offCourseNewVisiable = ref(false);
const tableRef = ref();
const toggleCheckboxes = (checkedName)=>{
if (checkedName === 'projectSignFlag') {
if(formData.value.projectSignFlag){
formData.value.outSignFlag = !formData.value.projectSignFlag;
}
} else if (checkedName === 'outSignFlag') {
if(formData.value.outSignFlag){
formData.value.projectSignFlag = !formData.value.outSignFlag;
}
}
}
const columns = ref([
{
title: "名称",
@@ -423,6 +482,19 @@ const columns = ref([
key: "teacher",
width: "20%",
align: "center",
customRender: ({ record }) => {
const teachers = record.offteachers;
return teachers.map((teacher, index) => {
// 如果需要显示为列表形式
return (
<div key={index}>
{teacher.teacherName}
{index !== teachers.length - 1 && ', '}
</div>
);
});
},
},
{
title: "学员数",
@@ -461,6 +533,13 @@ const params = ref({
taskId: "",
createBeginTime: '',
createEndTime: '',
offteachers:[
{
teacherId: '',
teacherName: '',
weight: '',
}
]
});
const validated = ref(0);
const dateTime = ref([]);
@@ -470,7 +549,7 @@ const formData = useResetRef({
name: "",
address: "",
teacherId: "",
teacher: "",
// teacher: "",
beforeValue: "",
afterStartValue: "",
applyFlag: 0,
@@ -487,6 +566,13 @@ const formData = useResetRef({
offcourseId: "",
draftTaskId: "",
taskId: "",
offteachers: [
{
teacherId: "",
teacherName: "",
weight:''
}
],
});
const formDataRule = {
name: [
@@ -495,46 +581,134 @@ const formDataRule = {
message: "请输入开课名称",
},
],
beginTime: [
{
required: true,
message: "请选择开始时间",
},
],
endTime: [
{
required: true,
message: "请选择结束时间",
},
],
teacher: [
{
required: true,
message: "请选择教师",
},
],
teacherId: [
{
required: true,
message: "请选择教师",
},
],
// duration: [
// beginTime: [
// {
// required: true,
// message: "请输入持续时间",
// message: "请选择开始时间",
// },
// ],
// endTime: [
// {
// required: true,
// message: "请选择结束时间",
// },
// ],
offteachers: [
{
validator: (rule, value, callback) => {
if (!value.every(item => item.teacherName)) {
callback(new Error('请填写教师名称和设置权重'));
} else {
callback();
}
},
message: '请填写教师名称和设置权重',
fields: {
teacherName: [
{
required: true,
message: "请填写教师名称和设置权重",
},
],
},
},
],
};
const { validate } = Form.useForm(formData, formDataRule);
const durationText = computed(() => dateTime.value?.length?dayjs(dateTime.value[1]).diff(dayjs(dateTime.value[0]),'minute'):'请输入持续时间');
function timeChange(time, timeStr) {
formData.value.beginTime = timeStr[0];
formData.value.endTime = timeStr[1];
function inputAdd() {
formData.value.offteachers.push({
teacherId: "",
teacherName: "",
weight: '',
});
}
function inputRemove(index) {
dialog({
content: "确定删除此授课教师吗?",
ok: async () => {
formData.value.offteachers.splice(index, 1);
message.success("删除成功");
},
});
}
const totalWeightSum = ref(0)
function inputWeightChange(index) {
let totalWeight = 0
formData.value.offteachers.forEach(item => {
totalWeight += Number(item.weight);
});
if (totalWeight > 100) {
message.info('权重值最大为100%')
formData.value.offteachers[index].weight -= totalWeight - 100;
totalWeight = 100;
}
totalWeightSum.value = totalWeight
}
function timeChange(timeStr) {
console.log(timeStr,'timeStr')
formData.value.beginTime = timeStr;
// formData.value.duration = durationText.value
// formData.value.duration || (formData.value.duration = dayjs(timeStr[1]).diff(dayjs(timeStr[0]),'minute'))
}
function onDateSelect(date) {
const month = String(date.$M+1).padStart(2, '0')
const day = String(date.$D).padStart(2, '0')
const hour = String(date.$H).padStart(2, '0')
const minute = String(date.$m).padStart(2, '0')
dateTime.value[0]=date.$y+'-'+month+'-'+day+' '+hour+':'+minute
}
const openStart = ref(false)
const onOkStart = ()=>{
openStart.value = false
}
function onBlurStart(e){
dateTime.value[0]=e.target.value
openStart.value = false
}
function onFocusStart(){
openStart.value = true
if(!dateTime.value[0]){
// dateTime.value[0] = moment().format('YYYY-MM-DD HH:mm')
// let now=new Date()
// let start=new Date(now.setFullYear(now.getFullYear(), now.getMonth(), now.getDate(), 0, 0))
// dateTime.value = [
// moment(start).format('YYYY-MM-DD HH:mm'),
// dateTime.value[1]
// ];
}
}
function timeChangeEnd(timeStr){
formData.value.endTime = timeStr;
}
const openEnd = ref(false)
const onOkEnd = ()=>{
openEnd.value = false
}
function onBlurEnd(e){
dateTime.value[1]=e.target.value
openEnd.value = false
}
function onDateEnd(date) {
const month = String(date.$M+1).padStart(2, '0')
const day = String(date.$D).padStart(2, '0')
const hour = String(date.$H).padStart(2, '0')
const minute = String(date.$m).padStart(2, '0')
dateTime.value[1]=date.$y+'-'+month+'-'+day+' '+hour+':'+minute
}
function onFocusEnd(){
openEnd.value = true
// if(!dateTime.value[1]){
// let now=new Date()
// let start=new Date()
// let end=new Date(now.setFullYear(now.getFullYear()))
// dateTime.value = [
// dateTime.value[0],
// moment(end).format('YYYY-MM-DD HH:mm')
// ];
// }
}
function search() {
tableRef.value.fetch();
}
@@ -557,9 +731,19 @@ const closeDrawer = () => {
draftTaskId: params.value.draftTaskId,
});
};
function confirm() {
const route = useRoute();
const projectInfo = ref({});
const emit = defineEmits(['call-parent-method']);
const confirm = async()=>{
closeDrawer();
await api.getDraftTask({projectId: route.query.projectId}).then((res) => {
projectInfo.value = res.data.data
});
request(PROJECT_DETAIL_MODIFY, { ...projectInfo.value });
if(projectInfo.value.projectInfo.status==3){
request(PROJECT_RELEASE, {projectId: route.query.projectId})
}
emit('call-parent-method');
}
const createNewCourse = () => {
@@ -568,10 +752,18 @@ const createNewCourse = () => {
type: props.type,
offcourseId: params.value.offcourseId,
draftTaskId: params.value.draftTaskId,
name:courseName.value
});
dateTime.value = [];
dateTime.value = [moment().format('YYYY-MM-DD HH:mm'),''];
validated.value = 0;
onceName.value = "";
formData.value.offteachers = [
{
teacherId: "",
teacherName: "",
weight: '',
},
];
offCourseNewVisiable.value = true;
};
const handleCancelStu = () => offCourseNewVisiable.value = false;
@@ -597,10 +789,45 @@ const del = (id,record) => {
};
async function coursePlanConfirm() {
if(!dateTime.value[0]){
message.info('开始时间未填写')
return
}
if(!dateTime.value[1]){
message.info('结束时间未填写')
return
}
await validate().catch(({ errorFields }) => {
message.warning(errorFields[0].errors.join());
throw Error("数据校验不通过");
});
inputWeightChange()
if(formData.value.offteachers.length==1&& totalWeightSum.value!=100){
message.error('单名教师您设置的权重应该是100%')
return
}else if(formData.value.offteachers.length>1&& totalWeightSum.value!=100){
console.log(totalWeightSum.value,'权重值不为100%')
message.error('多名教师权重合计值为100%')
return
}
const teacherNames = new Set(formData.value.offteachers.map(item => item.teacherName));
if (teacherNames.size !== formData.value.offteachers.length) {
message.error('教师重复,请检查');
return;
}
if(formData.value.offteachers.some(item => item.weight==0)){
message.error('权重值不能为0%')
return
}
if(editBeginClass.value){
message.info('讲师费已进入审批阶段,无法编辑')
return
}
if(dateTime.value.length<2){
message.info('请选择开始时间和结束时间')
return
}
await validate().catch(({ errorFields }) => {
message.warning(errorFields[0].errors.join());
throw Error("数据校验不通过");
@@ -623,7 +850,19 @@ async function coursePlanConfirm() {
// TODO 当点击选择了是否评估按钮 点击保存的时候没有选择评估 则是否需要评估重置为 0 不需要
formData.value.evalFlag = formData.value.assessmentName ? 1 : 0;
formData.value.duration = formData.value.duration ? formData.value.duration : durationText.value
formData.value.outSignFlag = formData.value.outSignFlag ? 1 : 0;
formData.value.projectSignFlag = formData.value.projectSignFlag ? 1 : 0;
formData.value.beginTime = dateTime.value[0]
formData.value.endTime = dateTime.value[1]
await request(COURSE_PLAN_EDIT, { ...formData.value });
await api.getDraftTask({projectId: route.query.projectId}).then((res) => {
projectInfo.value = res.data.data
});
request(PROJECT_DETAIL_MODIFY, { ...projectInfo.value });
if(projectInfo.value.projectInfo.status==3){
request(PROJECT_RELEASE, {projectId: route.query.projectId})
}
emit('call-parent-method');
handleCancelStu();
tableRef.value.fetch();
}
@@ -637,6 +876,8 @@ function planEdit(record) {
}
onceName.value = record.name;
formData.value = { ...record };
formData.value.duration = ''
console.log({ ...record },'{ ...record }')
validated.value = 0;
formData.value.homeWorkId && request(WORK_DETAIL(formData.value.homeWorkId), {}).then(res => formData.value.workInfo = res.data);
formData.value.testId && request(EXAM_DETAIL(formData.value.testId), {}).then(res => formData.value.examInfo = res.data);
@@ -675,6 +916,11 @@ const changevalue = (e) => {
const logT = () => {
formData.value.examInfo = {};
};
const removePG = () => {
formData.value.assessmentId = null;
formData.value.assessmentName = "";
// state.isEvaluate = "0";
};
defineExpose({ openDrawer });
</script>
@@ -1132,7 +1378,35 @@ defineExpose({ openDrawer });
margin: auto;
align-items: center;
margin-bottom: 23px;
.teacher_input{
.ant-input-number{
width: 15%;
height: 40px !important;
border-radius: 8px !important;
border: 1px solid #C7CBD2 !important;
margin: 0 10px 0 10px;
padding-top: 3px;
}
}
.btn-add{
margin: 0 10px 0 10px;
}
.btn-circle{
text-align: center;
line-height: 100%;
margin-top: 5px;
.custom-icon{
font-size: 20px;
svg{
margin: auto;
}
}
span{
width: 100%;
height: 100%;
font-size: 33px;
}
}
.signbox {
display: flex;
justify-content: end;

View File

@@ -37,7 +37,7 @@
</div>
<div style="font-size: 14px;">
<img src="../../../assets/images/courseManage/persion.png" style="width:16px;height:16px;">
{{ item.teacher }}
{{ item.offteachers.map(item => item.teacherName).join(',') }}
</div>
</div>
</div>
@@ -81,11 +81,12 @@
</div>
</div>
</div>
<div class="btnss" style="margin-top: 20px" v-if="checkPer(permissions,createId) && data?.length">
<div class="btnss" style="margin-top: 20px;flex-wrap: wrap;" v-if="checkPer(permissions,createId) && data?.length">
<div
class="btn btn1"
style="margin-right: 20px"
@click="qrcodeVisibleSign()"
:class="{ 'notClick': courseSelectRows.length > 0 }"
>
<div class="wz">签到二维码</div>
</div>
@@ -94,6 +95,7 @@
style="margin-right: 20px"
v-if="data[coursePlanIndex]?.assessmentId"
@click="qrcodeAssement()"
:class="{ 'notClick': courseSelectRows.length > 0 }"
>
<div class="wz">评估二维码</div>
</div>
@@ -101,6 +103,7 @@
class="btn btn1"
style="margin-right: 20px"
@click="qrcodeVisible()"
:class="{ 'notClick': courseSelectRows.length > 0 }"
>
<div class="wz">开课二维码</div>
</div>
@@ -112,14 +115,13 @@
:infoType="type"
@finash="submitCall"
>
<a-button class="cus-btn" style="background: #4ea6ff; color: #fff">
<template #icon><img style="margin-right: 10px" src="../../../assets/images/courseManage/add0.png"/>
</template>
添加学员
</a-button>
<div :class="{ 'notClick': courseSelectRows.length > 0 }" class="btn btn1">
<div class="img3"></div>
<div class="wz">添加学员</div>
</div>
</CommonStudent>
<CommonImport @change="change" title="导入学员" :template-url="stuTemplateUrl" :data="{ targetId: offcoursePlanId, type:3 }" :url="`/admin/student/importStudent`" name="uploadFile">
<div class="btn btn1" style="margin-right: 20px;margin-left: 20px">
<div :class="{ 'notClick': courseSelectRows.length > 0 }" class="btn btn1" style="margin-right: 20px;margin-left: 20px">
<div class="img1"></div>
<div class="wz">导入学员</div>
</div>
@@ -127,18 +129,21 @@
<div class="btn btn1" @click="batchSign" style="margin-right: 20px">
<div class="wz">批量签到</div>
</div>
<div class="btn btn1" @click="exportTaskStu" style="margin-right: 20px">
<div class="btn btn1" @click="batchSignAll" style="margin-right: 20px">
<div class="wz">全部签到</div>
</div>
<div class="btn btn1" @click="exportTaskStu" style="margin-right: 20px" :class="{ 'notClick': courseSelectRows.length > 0 }">
<div class="img2"></div>
<div class="wz">导出签到数据</div>
</div>
<div class="btn btn1" @click="exportAssessment" v-if="data[coursePlanIndex]?.assessmentId">
<div class="btn btn1" @click="exportAssessment" v-if="data[coursePlanIndex]?.assessmentId" :class="{ 'notClick': courseSelectRows.length > 0 }">
<div class="img2"></div>
<div class="wz">导出评估数据</div>
</div>
</div>
<div class="tableBox" style="margin-top: 30px">
<BaseTable ref="tableRef" :url="STUDENT_LIST" v-model:params="params" :columns="columns" :init="false"
v-model:selectedRows="courseSelectRows"
v-model:selectedRows="courseSelectRows" :showSizeChanger="true"
type="checkbox"/>
</div>
</div>
@@ -180,6 +185,11 @@ const signOptions = ref([
value: 0,
label: "请假",
},
{
id: 3,
value: 2,
label: "未签到",
},
]);
const props = defineProps({
type: {
@@ -198,6 +208,10 @@ const props = defineProps({
type: Boolean,
default: false,
},
courseName:{
type: String,
default: null,
},
datasource: {
type: Object,
default: function() {
@@ -277,7 +291,7 @@ const columns = ref([
ellipsis: true,
className: "h",
customRender: (text) =>
<span>{text.record.signStatus ? "签到" : text.record.leaveStatus ? "请假" : inAttendanceTime.value ? "-" : "缺勤"}</span>
<span>{text.record.signStatus ? "签到" : text.record.leaveStatus ? "请假" : inAttendanceTime.value ? "未签到" : "缺勤"}</span>
},
{
title: "签到状态",
@@ -288,7 +302,7 @@ const columns = ref([
ellipsis: true,
className: "h",
customRender: (text) =>
<span>{(text.record.signStatus || text.record.leaveStatus) ? "正常" : inAttendanceTime.value ? "-" : "异常"}</span>
<span>{(text.record.signStatus || text.record.leaveStatus) ? "正常" : inAttendanceTime.value ? "未签到" : "异常"}</span>
},
{
title: "考勤情况",
@@ -362,7 +376,19 @@ const batchSign = () => {
},
});
};
const batchSignAll = () => {
dialog({
content: "确定全部签到吗?",
ok: async () => {
message.success("全部签到成功");
tableRef.value.toLoading();
await api.attendanceSignAll({
courseId: offcoursePlanId.value
});
tableRef.value.fetch();
},
});
};
function stuSign(text) {
text.record.signStatus = !text.record.signStatus;
text.record.leaveStatus = !text.record.signStatus;
@@ -439,7 +465,7 @@ const qrcodeVisible = () => {
url: `${location.protocol}//${location.host}${process.env.VUE_APP_BASE_API}/stu/project/redirectDetail?courseId=${courseId}`,
});
}
// qrCode({
// title: "【开课】二维码",
// name: openCourseName.value?openCourseName.value:data.value[0]?.name,
@@ -484,11 +510,13 @@ const qrcodeVisibleSign = () => {
// url: `${location.protocol}//${location.host}${process.env.VUE_APP_BASE_API}/admin/student/studentSign?taskId=${data.value[coursePlanIndex.value]?.id}&taskType=${2}&type=${3}`,
// });
};
const qrcodeAssement = () =>{
qrCode({
title: "【评估】二维码",
name: data.value[coursePlanIndex.value]?.assessmentName,
courseName: props.courseName + '项目',
createName: data.value[coursePlanIndex.value].offteachers.map(teacher => teacher.teacherName).join(', '),
// name: data.value[coursePlanIndex.value]?.assessmentName + '课程评估',
name: openCourseName.value?openCourseName.value:data.value[coursePlanIndex.value]?.name + '课程评估',
url: `${location.protocol}//${location.host}/student-h5/investigatpage?id=${data.value[coursePlanIndex.value]?.id}&type=3&infoId=${data.value[coursePlanIndex.value]?.id}&courseId=${data.value[coursePlanIndex.value].assessmentId}&chapterOrStageId=0`,
});
}
@@ -504,6 +532,17 @@ const change = (e) => {
</script>
<style lang="scss">
.notClick{
// cursor: pointer;
// pointer-events: none;
width: 100px;
height: 40px;
border: 1px solid #d7d7d7 !important;
border-radius: 8px;
color: #fff !important;
background-color: #d7d7d7 !important;
}
.me {
.ant-modal-body {
padding: 0px;
@@ -748,6 +787,13 @@ const change = (e) => {
background-size: 100% 100%;
margin-right: 7px;
}
.img3 {
width: 15px;
height: 17px;
background-image: url(../../../assets/images/courseManage/add0.png);
background-size: 100% 100%;
margin-right: 7px;
}
}
.btn1 {
@@ -777,7 +823,7 @@ const change = (e) => {
display: flex;
justify-content: center;
align-items: center;
margin-bottom: 10px;
.img1 {
width: 19px;
height: 19px;
@@ -793,6 +839,13 @@ const change = (e) => {
background-size: 100% 100%;
margin-right: 7px;
}
.img3 {
width: 19px;
height: 19px;
background-image: url(../../../assets/images/courseManage/add0.png);
background-size: 100% 100%;
margin-right: 7px;
}
}
.btn1 {
@@ -874,7 +927,15 @@ const change = (e) => {
.tableBox {
// margin-bottom: 80px;
.ant-select-dropdown{
display: inline-block;
}
.ant-select-selection-item{
margin-left: 3px;
}
.ant-pagination-options-size-changer.ant-select{
width: 84px;
}
.classify {
// margin-left: 11px !important;
// padding-left: 9px !important;

View File

@@ -85,7 +85,7 @@ watch(props, () => {
isExistName.value = true;
}
modelV.value.value = props.value;
});
},{immediate: true});
watch(() => modelV.value.value, () => {
emit("update:validated", 1);

View File

@@ -45,13 +45,20 @@ const id = computed(() => {
});
const emit = defineEmits({});
const options = computed(() =>
store.state.project_level.map((e) => ({
const secondItem = store.state.project_level.find((e, index) => index === 1);
const options = computed(() =>{
const projectLevels = store.state.project_level.slice();
const lastItem = projectLevels.pop();
projectLevels.unshift(lastItem);
if (projectLevels.length >= 3) {
const thirdItem = projectLevels.splice(1, 1)[0];
projectLevels.splice(2, 0, thirdItem);
}
return projectLevels.map((e) => ({
value: parseInt(e.value),
label: e.name,
}))
);
}));
});
function change(key) {
emit("update:value", key);

View File

@@ -0,0 +1,121 @@
<template>
<a-select
:getPopupContainer="
(triggerNode) => {
return triggerNode.parentNode || document.body;
}
"
v-model:value="managerArray"
:placeholder="placeholder"
:filterOption="false"
:options="isOpen?options:selectOptions"
allowClear
showSearch
:mode="mode"
:disabled="disabled"
@popupScroll="memberScroll"
@search="searchMember"
:open="isOpen"
@change="change"
@blur="blur"
:show-arrow="false"
style="width: 60%"
>
<template v-if="loading" #notFoundContent>
<a-spin size="small"/>
</template>
</a-select>
</template>
<script setup>
import {computed, defineEmits, defineProps, onMounted, ref, watch} from "vue";
import {useThrottlePage} from "@/api/request";
import {USER_LIST} from "@/api/apis";
const props = defineProps({
value: {
type: String,
default: ''
},
name: {
type: String,
default: ''
},
disabled: Boolean,
placeholder: {
type: String,
default: "请输入搜索关键字",
},
mode: String
})
const selectOptions = ref([])
const managerArray = computed(() => props.mode === 'select' ? props.value : (props.value ? props.value.split(',') : []))
const emit = defineEmits({})
const isOpen = ref(false)
const memberParam = ref({keyword: '', pageNo:1, pageSize: 20})
const {data: userList, loading} = useThrottlePage(USER_LIST, memberParam.value, false)
const options = computed(() => userList.value.filter(e => !(props.value + '').includes(e.id)).map(e => ({
label: e.realName + e.userNo,
value: e.id,
...e,
audienceList: null
})))
watch(props, init)
function init() {
//第一次进来 编辑赋值
if (props.value && (props.value + '') !== selectOptions.value.map(e => e.value).join(',')) {
selectOptions.value = (props.value + '').split(',').map((e, i) => ({label: props.name.split(',')[i], value: e}))
}
}
onMounted(() => {
console.log('onMounted')
init()
})
const memberScroll = ({target: {scrollHeight, scrollTop, clientHeight}}) => {
scrollHeight === (clientHeight + scrollTop) && memberParam.value.pageNo++
};
//搜索学员
const searchMember = (keyword) => {
console.log('searchMember', keyword)
loading.value = true
isOpen.value = true
userList.value = []
memberParam.value.pageNo = 1
memberParam.value.keyword = keyword
console.log('searchMember', memberParam.value)
};
function blur() {
isOpen.value = false
memberParam.value.keyword = ''
memberParam.value.pageNo = 1
}
function change(e, l) {
memberParam.value.keyword = ''
memberParam.value.pageNo = 1
isOpen.value = false
Array.isArray(l) && (selectOptions.value = l)
Array.isArray(selectOptions.value) && emit('onChange', e, l, selectOptions.value.find(e => e.departId)?.departId, selectOptions.value.find(e => e.departId)?.departName, selectOptions.value.find(e => e.departId)?.orgName)
if (Array.isArray(l)) {
emit('update:name', l.map(t => t.label).join(','))
emit('update:value', l.map(t => t.value).join(','))
} else {
emit('update:name', l?.label)
emit('update:value', l?.value)
}
}
</script>