Files
learning-system-portal/src/views/course/CourseManage.vue

1387 lines
52 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<div id="courseManage">
<!--课程管理-->
<div class="course-info">
<div class="course-desc-item"><span class="title">课程名称:</span><span class="desc">{{courseDetail.name}}</span>
</div>
<div class="course-desc-item"><span class="title">类型:</span><span
class="desc">{{courseType(courseDetail.type)}}</span></div>
<div class="course-desc-item"><span class="title">课程分类:</span><span
class="desc">{{sysTypeName(courseDetail.sysType1)}}{{courseDetail.sysType2 == ''? '': '/'}}{{sysTypeName(courseDetail.sysType2)}}{{courseDetail.sysType3 == ''? '': '/'}}{{sysTypeName(courseDetail.sysType3)}}</span>
</div>
</div>
<!-- <div style="color: red;">下面的表格标题及内容需要调整完善</div> -->
<div>
<el-tabs style="width: 100%;" v-model="tabName" @tab-click="handleTabClick">
<el-tab-pane label="报名记录" name="second">
<el-row style="margin: 20px 0;" :gutter="20">
<el-col :span="4">
<div class="grid-content bg-purple">
<!-- <el-input v-model="signup.name" clearable placeholder="姓名" maxlength="50" /> -->
<NameFilterSelect @handleNameChange="aids => signup.aid = aids" ref="signupNameFilter"
@handleClose="signup.aid = []" />
<!-- <el-select :key="2" style="width:100%" clearable multiple v-model="signup.aid" filterable
placeholder="姓名" v-limit-input="50" remote reserve-keyword :remote-method="initNameList"
:multiple-limit="5" :loading="nameListLoading">
<el-option v-for="item in nameList" :key="item.userId" :label="item.name" :value="item.userId">
<span>{{ item.name }}</span>
<span v-if="item.code" class="option-code">{{ item.code }}</span>
</el-option>
</el-select> -->
</div>
</el-col>
<el-col :span="4">
<div class="grid-content bg-purple">
<el-select style="width: 100%;" v-model="signup.signType" placeholder="报名方式" clearable>
<el-option label="自主报名" :value="1"></el-option>
<el-option label="手动加入" :value="2"></el-option>
</el-select>
</div>
</el-col>
<el-col :span="6">
<div class="grid-content bg-purple">
<el-button type="primary" @click="getSignupList()"> </el-button>
<el-button @click="resetSignupList()"> </el-button>
</div>
</el-col>
<el-col :span="6" :offset="4">
<div class="grid-content bg-purple" style="text-align: right;">
<el-button
v-if="showSignupActions"
type="primary"
icon="el-icon-plus"
style="margin-right: 10px;"
@click="handleAddSignupClick"
>
添加报名
</el-button>
<el-button type="primary" icon="el-icon-upload2" @click="handleExportSignup">
导出报名记录
</el-button>
</div>
</el-col>
</el-row>
<div class="tab-content">
<el-table border max-height="350" :data="study.list" :header-cell-style="{textAlign: 'center'}"
:cell-style="{ textAlign: 'center' }" style="width: 100%">
<!-- <el-table-column type="selection" width="55"></el-table-column> -->
<el-table-column prop="name" label="姓名"></el-table-column>
<el-table-column prop="code" label="工号">
</el-table-column>
<el-table-column prop="orgInfo" label="部门">
<template slot-scope="scope">
<el-tooltip class="item" effect="dark" :content="scope.row.orgInfo" placement="top-start">
<p class="no-wrap">
{{scope.row.orgInfo && scope.row.orgInfo.split('/')[scope.row.orgInfo.split('/').length - 1]}}</p>
</el-tooltip>
</template>
</el-table-column>
<el-table-column prop="signType" label="报名方式">
<template slot-scope="scope">
<p>{{scope.row.signType == '1' ? '自主报名' : '手动加入' }}</p>
</template>
</el-table-column>
<el-table-column prop="signTime" label="报名时间"></el-table-column>
<el-table-column
v-if="showSignupActions"
label="操作"
width="140"
>
<template slot-scope="scope">
<el-button
type="text"
size="mini"
class="delete-action-link--danger"
@click="handleDeleteSignup(scope.row)"
>
删除
</el-button>
</template>
</el-table-column>
</el-table>
<div style="padding: 10px;">
<div style="text-align:center; padding: 10px;">
<el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange"
:current-page="study.pageIndex" :page-sizes="[10, 20, 30, 40]" :page-size="study.pageSize"
layout="total, sizes, prev, pager, next, jumper" :total="study.count"></el-pagination>
</div>
</div>
</div>
</el-tab-pane>
<el-tab-pane lazy label="学习记录" name="third">
<el-row style="margin: 20px 0;" :gutter="20">
<el-col :span="4">
<div class="grid-content bg-purple">
<!-- <el-input clearable v-model="learningRecords.name" maxlength="50"
placeholder="姓名"></el-input> -->
<NameFilterSelect @handleNameChange="aids => learningRecords.aid = aids" ref="learningRecordsNameFilter"
@handleClose="learningRecords.aid = []" />
<!-- <el-select :key="1" style="width:100%" clearable multiple v-model="learningRecords.aid" filterable
placeholder="姓名" v-limit-input="50" reserve-keyword remote :remote-method="initNameList"
:multiple-limit="5" :loading="nameListLoading">
<el-option v-for="item in nameList" :key="item.userId" :label="item.name" :value="item.userId">
<span>{{ item.name }}</span>
<span v-if="item.code" class="option-code">{{ item.code }}</span>
</el-option>
</el-select> -->
</div>
</el-col>
<el-col :span="4">
<div class="grid-content bg-purple">
<el-select style="width: 100%;" v-model="learningRecords.status" clearable placeholder="学习状态">
<el-option label="未开始" :value="1"></el-option>
<el-option label="进行中" :value="2"></el-option>
<el-option label="已完成" :value="9"></el-option>
</el-select>
</div>
</el-col>
<el-col style="width: 270px;">
<div
:class="['grid-content', 'bg-purple', 'resetDatePicker', !studyDateTime||studyDateTime.length==0?'noSplitDatePicker':'']">
<el-date-picker value-format="yyyy-MM-dd" v-model="studyDateTime" type="daterange" align="right"
unlink-panels range-separator="" start-placeholder="学习时长" :picker-options="pickerOptions">
</el-date-picker>
</div>
</el-col>
<el-col :span="5">
<div class="grid-content bg-purple">
<el-button type="primary" @click="getStudyRecords()"> </el-button>
<el-button @click="resetStudyRecords()"> </el-button>
</div>
</el-col>
<el-col style="float: right; width:185px">
<div class="grid-content bg-purple" style="text-align: right;">
<el-button type="primary" icon="el-icon-upload2" @click="handleExportStudyDetail">导出学习课程记录</el-button>
</div>
</el-col>
</el-row>
<div class="tab-content">
<el-table max-height="350" border :data="learningRecords.list" :header-cell-style="{textAlign: 'center'}"
:cell-style="{ textAlign: 'center' }" style="width: 100%">
<el-table-column prop="aname" label="姓名"></el-table-column>
<el-table-column prop="code" label="工号"></el-table-column>
<el-table-column prop="orgInfo" label="部门">
<template slot-scope="scope">
<el-tooltip class="item" effect="dark" :content="scope.row.orgInfo" placement="top-start">
<p class="no-wrap">
{{scope.row.orgInfo && scope.row.orgInfo.split('/')[scope.row.orgInfo.split('/').length - 1]}}</p>
</el-tooltip>
</template>
</el-table-column>
<el-table-column prop="addTime" width="300" label="学习时间"></el-table-column>
<el-table-column prop="totalDuration" label="学习时长">
<template slot-scope="scope">
{{ scope.row.totalDuration == 0? '0': (scope.row.totalDuration/60).toFixed(2)}}
</template>
</el-table-column>
<el-table-column label="学习状态">
<template slot-scope="scope">
{{ recourseStudyStatusEnum[scope.row.status] }}
</template>
</el-table-column>
<el-table-column prop="progress" label="学习进度">
<template slot-scope="scope">
{{ scope.row.progress }}%
</template>
</el-table-column>
<el-table-column prop="orgInfo" label="操作" width="120">
<template slot-scope="scope">
<!--弹出每一项资源的学习情况列表-->
<el-link :underline="false" type="primary" @click.stop="showStudyDetails(scope.row)">查看</el-link>
</template>
</el-table-column>
</el-table>
<div style="text-align: center; padding: 10px;">
<el-pagination @size-change="handleSizeChangeRecords" @current-change="handleCurrentChangeRecords"
:current-page="learningRecords.pageIndex" :page-sizes="[10, 20, 30, 40]"
:page-size="learningRecords.pageSize" layout="total, sizes, prev, pager, next, jumper"
:total="learningRecords.count">
</el-pagination>
</div>
</div>
</el-tab-pane>
<el-tab-pane lazy label="资源学习情况" name="first">
<el-row style="margin: 20px 0;" :gutter="20">
<el-col :span="4">
<div class="grid-content bg-purple"><el-input clearable v-model="recourseListQuery.contentName"
placeholder="资源名称"></el-input></div>
</el-col>
<el-col :span="5">
<div class="grid-content bg-purple">
<el-button type="primary" @click="getResourseList"> </el-button>
<el-button @click="resetResourseList"> </el-button>
</div>
</el-col>
<el-col :span="6" :offset="9">
<div class="grid-content bg-purple" style="text-align: right;">
<el-button type="primary" icon="el-icon-upload2" @click="handleExportStudyResource">导出资源学习记录</el-button>
</div>
</el-col>
</el-row>
<div class="tab-content">
<el-table max-height="350" border :header-cell-style="{textAlign: 'center'}"
:cell-style="{ textAlign: 'center' }" :data="recourseList" style="width: 100%">
<el-table-column label="资源名称">
<template slot-scope="scope">
{{scope.row.contentName}}
</template>
</el-table-column>
<el-table-column prop="finishCount" label="完成人数"></el-table-column>
<el-table-column label="操作" width="200">
<template slot-scope="scope">
<el-button type="text" size="mini" @click="handleShowResourdeDetailList(scope.row)">学习人员</el-button>
<el-button v-if="scope.row.contentType == '60' || scope.row.contentType == '61'" type="text"
size="mini" @click="handleExportRecourseDetail(scope.row)">导出</el-button>
</template>
</el-table-column>
</el-table>
<div style="text-align: center; padding: 10px;">
<el-pagination @size-change="handleSizeRecourseList" @current-change="handleCurrentChangeRecourseList"
:current-page="recourseListQuery.pageIndex" :page-sizes="[10, 20, 30, 40]"
:page-size="recourseListQuery.pageSize" layout="total, sizes, prev, pager, next, jumper"
:total="recourseListQuery.count">
</el-pagination>
</div>
</div>
</el-tab-pane>
</el-tabs>
</div>
<AudienceModal
v-if="showSignupActions && hasCourseCrowds"
:visible.sync="audienceDialogVisible"
@confirm="handleAudienceConfirm"
:audience-ids="courseCrowds.map(item => item.id)"
/>
<SignupModal
v-if="showSignupActions && !hasCourseCrowds"
:visible.sync="addSignupVisible"
@confirm="handleSignupCreate"
/>
<!-- 学习详情 -->
<el-dialog title="学习详情" :visible.sync="study.detailShow" width="900px" :append-to-body="true">
<div>
<!-- <div v-if="study.detailType == 10"><auditCourse1 :isDetails="true" :isShow="false" :id="study.examineId"></auditCourse1></div>
<div v-if="study.detailType == 20"><auditCourse2 :isDetails="true" :isShow="false" :id="study.examineId"></auditCourse2></div> -->
<el-table max-height="500" :header-cell-style="{textAlign: 'center'}" :cell-style="{ textAlign: 'center' }"
border :data="courseStudyList" style="width: 100%">
<el-table-column label="课程章节">
<template slot-scope="scope">
<el-tooltip class="item" effect="dark" :content="scope.row.contentName" placement="top-start">
<p class="no-wrap">{{scope.row.contentName}}</p>
</el-tooltip>
</template>
</el-table-column>
<el-table-column prop="status" label="学习状态">
<template slot-scope="scope">
<span>{{ recourseStudyStatusEnum[scope.row.status] }}</span>
</template>
</el-table-column>
<el-table-column prop="studyDuration" label="学习时长">
<template slot-scope="scope">
<span> {{ scope.row.learningDuration == 0? '0': (scope.row.learningDuration/60).toFixed(2)}}</span>
</template>
</el-table-column>
<el-table-column prop="progress" label="学习进度">
<template slot-scope="scope">
{{scope.row.studyDuration}}%
</template>
</el-table-column>
</el-table>
<div style="text-align: center;padding: 10px;" v-if="showStudyDetailPage">
<el-pagination @size-change="handleSizeChangeStudyDetail" @current-change="handleCurrentStudyDetail"
:current-page="studyDetailQuery.pageIndex" :page-sizes="[10, 20, 30, 40]"
:page-size="studyDetailQuery.pageSize" layout="total, sizes, prev, pager, next, jumper"
:total="studyDetailQuery.count"></el-pagination>
</div>
</div>
<span slot="footer" class="dialog-footer">
<el-button @click="study.detailShow = false">关 闭</el-button>
</span>
</el-dialog>
<el-dialog title="学习详情" v-if="commonResourceStudyPeopleShow" :visible.sync="commonResourceStudyPeopleShow"
width="50%" :append-to-body="true">
<el-row style="margin: 20px 0 20px -10px;" :gutter="20">
<el-col :span="6">
<div class="grid-content bg-purple">
<NameFilterSelect ref="commonResourceStudyPeopleNameFilter"
@handleNameChange="aids => commonResourceStudyPeopleQuery.aid = aids"
@handleClose="commonResourceStudyPeopleQuery.aid = []" />
<!-- <el-select :key="3" style="width:100%" clearable multiple v-model="commonResourceStudyPeopleQuery.aid"
filterable placeholder="姓名" v-limit-input="50" remote reserve-keyword :remote-method="initNameList"
:multiple-limit="5" :loading="nameListLoading">
<el-option v-for="item in nameList" :key="item.userId" :label="item.name" :value="item.userId">
<span>{{ item.name }}</span>
<span v-if="item.code" class="option-code">{{ item.code }}</span>
</el-option>
</el-select> -->
<!-- <el-input v-model="commonResourceStudyPeopleQuery.name" clearable
maxlength="50" placeholder="姓名" /> -->
</div>
</el-col>
<el-col :span="6">
<div class="grid-content bg-purple">
<el-select style="width: 100%;" v-model="commonResourceStudyPeopleQuery.status"
v-if="rousourceRow.contentType == '60' || rousourceRow.contentType == '62'" :placeholder="'完成状态'"
clearable>
<el-option label="已完成" :value="2"></el-option>
<el-option label="未完成" :value="4"></el-option>
</el-select>
<el-select style="width: 100%;" v-else v-model="commonResourceStudyPeopleQuery.status" placeholder="学习状态"
clearable>
<el-option label="未开始" :value="1"></el-option>
<el-option label="已完成" :value="2"></el-option>
<el-option label="进行中" :value="3"></el-option>
</el-select>
</div>
</el-col>
<el-col :span="8">
<div class="grid-content bg-purple">
<el-button type="primary" @click="queryResourceStudyPeopleList">查 询</el-button>
<el-button @click="resetCommonResourceQuery">重 置</el-button>
</div>
</el-col>
</el-row>
<el-table max-height="500" border :data="commonResourceStudyPeopleList" style="width: 100%"
:header-cell-style="{textAlign: 'center'}" :cell-style="{ textAlign: 'center' }">
<el-table-column prop="aname" label="姓名"></el-table-column>
<el-table-column prop="code" label="工号"></el-table-column>
<el-table-column prop="orgInfo" label="部门">
<template slot-scope="scope">
<el-tooltip class="item" effect="dark" :content="scope.row.orgInfo" placement="top-start">
<p class="no-wrap">
{{scope.row.orgInfo && scope.row.orgInfo.split('/')[scope.row.orgInfo.split('/').length - 1]}}</p>
</el-tooltip>
</template>
</el-table-column>
<el-table-column
:label="rousourceRow.contentType == '60' || rousourceRow.contentType == '62' ? '完成状态' : '学习状态'">
<template slot-scope="scope">
{{ rousourceRow.contentType == '60' || rousourceRow.contentType == '62' ? (scope.row.status == '9'?'已完成': '未完成') : recourseStudyStatusEnum[scope.row.status] }}
</template>
</el-table-column>
<el-table-column v-if="rousourceRow.contentType != '60' && rousourceRow.contentType != '62'" prop="progress"
label="学习进度">
<template slot-scope="scope">
{{ scope.row.progress }}%
</template>
</el-table-column>
<el-table-column v-if="rousourceRow.contentType == '62'" prop="studyAssesses[0].asScore"
label="满意度分数"></el-table-column>
<el-table-column prop="finishTime" width="200" label="完成时间"></el-table-column>
</el-table>
<div style="text-align: center;padding: 10px;">
<el-pagination @size-change="handleSizeChangeStudyPeople" @current-change="handleCurrentChangeStudyPeople"
:current-page="commonResourceStudyPeopleQuery.pageIndex" :page-sizes="[10, 20, 30, 40]"
:page-size="commonResourceStudyPeopleQuery.pageSize" layout="total, sizes, prev, pager, next, jumper"
:total="commonResourceStudyPeopleQuery.count"></el-pagination>
</div>
<span slot="footer" class="dialog-footer">
<el-button @click="commonResourceStudyPeopleShow = false">关 闭</el-button>
<!-- <el-button type="primary" @click="study.detailShow = false">提交</el-button> -->
</span>
</el-dialog>
<el-dialog title="学习详情" v-if="examResourceStudyPeopleShow" :visible.sync="examResourceStudyPeopleShow" width="50%"
:append-to-body="true">
<el-row style="margin: 20px 0 20px -10px;" :gutter="20">
<el-col :span="6">
<div class="grid-content bg-purple">
<NameFilterSelect ref="examResourceStudyPeopleNameFilter"
@handleNameChange="aids => examResourceStudyPeopleQuery.aid = aids"
@handleClose="examResourceStudyPeopleQuery.aid = []" />
<!--
<el-select :key="4" style="width:100%" clearable multiple v-model="examResourceStudyPeopleQuery.aid"
filterable placeholder="姓名" v-limit-input="50" remote reserve-keyword :remote-method="initNameList"
:multiple-limit="5" :loading="nameListLoading">
<el-option v-for="item in nameList" :key="item.userId" :label="item.name" :value="item.userId">
<span>{{ item.name }}</span>
<span v-if="item.code" class="option-code">{{ item.code }}</span>
</el-option>
</el-select> -->
<!-- <el-input v-model="examResourceStudyPeopleQuery.name" clearable
maxlength="50" placeholder="姓名" /> -->
</div>
</el-col>
<el-col :span="6">
<div class="grid-content bg-purple">
<el-select style="width: 100%;" v-model="examResourceStudyPeopleQuery.status" placeholder="考试状态" clearable>
<el-option label="已通过" :value="2"></el-option>
<el-option label="未通过" :value="4"></el-option>
</el-select>
</div>
</el-col>
<el-col :span="8">
<div class="grid-content bg-purple">
<el-button type="primary" @click="queryExamStudyPeopleList">查 询</el-button>
<el-button @click="resetExamCommonResourceQuery">重 置</el-button>
</div>
</el-col>
</el-row>
<el-table max-height="500" :border="false" :data="examResourceStudyPeopleList" style="width: 100%"
:header-cell-style="{textAlign: 'center'}" :cell-style="{ textAlign: 'center' }">
<el-table-column type="expand">
<template slot-scope="props">
<el-table max-height="500" :border="false" :data="props.row.studyExams" style="width: 80%;margin: 0 auto;"
:header-cell-style="{textAlign: 'center'}" :cell-style="{ textAlign: 'center' }">
<el-table-column prop="aname" label="考试状态">
<template slot-scope="scope">
{{ scope.row.score >= scope.row.passLine ? '已通过' : '未通过' }}
</template>
</el-table-column>
<el-table-column prop="score" label="考试成绩"></el-table-column>
<el-table-column prop="endTime" width="200" label="完成时间"></el-table-column>
</el-table>
</template>
</el-table-column>
<el-table-column prop="aname" label="姓名"></el-table-column>
<el-table-column prop="code" label="工号"></el-table-column>
<el-table-column prop="orgInfo" label="部门">
<template slot-scope="scope">
<el-tooltip class="item" effect="dark" :content="scope.row.orgInfo" placement="top-start">
<p class="no-wrap">
{{scope.row.orgInfo && scope.row.orgInfo.split('/')[scope.row.orgInfo.split('/').length - 1]}}</p>
</el-tooltip>
</template>
</el-table-column>
<el-table-column label="考试状态">
<template slot-scope="scope">
{{ scope.row.status == '9' ? '已通过' : '未通过' }}
</template>
</el-table-column>
<el-table-column prop="score" label="成绩"></el-table-column>
<el-table-column prop="finishTime" width="200" label="完成时间"></el-table-column>
</el-table>
<div style="text-align: center;padding: 10px;">
<el-pagination @size-change="handleSizeChangeExamStudyPeople"
@current-change="handleCurrentChangeExamStudyPeople" :current-page="examResourceStudyPeopleQuery.pageIndex"
:page-sizes="[10, 20, 30, 40]" :page-size="examResourceStudyPeopleQuery.pageSize"
layout="total, sizes, prev, pager, next, jumper" :total="examResourceStudyPeopleQuery.count"></el-pagination>
</div>
<span slot="footer" class="dialog-footer">
<el-button @click="examResourceStudyPeopleShow = false">关 闭</el-button>
<!-- <el-button type="primary" @click="study.detailShow = false">提交</el-button> -->
</span>
</el-dialog>
</div>
</template>
<script>
import {
courseType,
resOwnerListMap,
// sysTypeList,
getType,
} from "../../utils/tools.js";
import apiUserbasic from "@/api/boe/userbasic.js";
import apicourseStudy from "@/api/modules/courseStudy.js";
import apiCoursePortal from "@/api/modules/coursePortal.js";
import { mapGetters, mapActions } from "vuex";
import apiUser from "@/api/system/user.js";
import apiStudy from "@/api/modules/courseStudy.js";
import apiCourse from "@/api/modules/course.js";
import { getToken } from "@/utils/token";
import axios from "axios";
import NameFilterSelect from "@/components/NameFilterSelect/index.vue";
import SignupModal from "@/components/signup/SignupModal.vue";
import AudienceModal from "@/components/signup/AudienceModal.vue";
NameFilterSelect;
export default {
components: { NameFilterSelect, SignupModal, AudienceModal },
props: {
showSignupActions: {
type: Boolean,
default: false,
},
},
computed: {
...mapGetters(["resOwnerMap", "sysTypeMap"]),
hasCourseCrowds() {
return Array.isArray(this.courseCrowds) && this.courseCrowds.length > 0;
},
},
data() {
return {
pickerOptions: {
shortcuts: [
{
text: "今年以来",
onClick(picker) {
const end = new Date();
const start = new Date(end.getFullYear(), 0, 1);
picker.$emit("pick", [start, end]);
},
},
{
text: "最近一年",
onClick(picker) {
const end = new Date();
const start = new Date();
start.setFullYear(start.getFullYear() - 1);
picker.$emit("pick", [start, end]);
},
},
{
text: "最近三个月",
onClick(picker) {
const end = new Date();
const start = new Date();
start.setTime(start.getTime() - 3600 * 1000 * 24 * 90);
picker.$emit("pick", [start, end]);
},
},
{
text: "最近一个月",
onClick(picker) {
const end = new Date();
const start = new Date();
start.setTime(start.getTime() - 3600 * 1000 * 24 * 30);
picker.$emit("pick", [start, end]);
},
},
{
text: "最近一周",
onClick(picker) {
const end = new Date();
const start = new Date();
start.setTime(start.getTime() - 3600 * 1000 * 24 * 7);
picker.$emit("pick", [start, end]);
},
},
],
},
studyDateTime: [],
courseDetail: JSON.parse(sessionStorage.getItem("courseDetail")),
// 课程详情中的 crowds 信息(通过 apiCourse.detail 获取)
courseCrowds: [],
downParams: {},
typePress: false,
isHomeWork: false,
isTrue: false,
catalogRecordTree: [],
catalogRecordList: [],
resOwnerListMap: [],
sysTypeListMap: [],
catalogList: [],
courseStudyList: [],
sysType: "",
// sysTypeList: sysTypeList,
treeList: [],
contentId: "",
catalogTree: [],
signup: {
name: "",
signType: "",
aid: [],
},
courseType: courseType,
value: "",
input: "",
tabName: "second",
audienceDialogVisible: false,
addSignupVisible: false,
selectedAudiences: [],
learningSituation: {
pageIndex: 1, //第几页
pageSize: 10, // 每页多少条
count: 0,
type: "",
list: [],
status: "",
name: "",
},
learningRecords: {
pageIndex: 1, //第几页
pageSize: 10, // 每页多少条
count: 0,
type: "",
list: [],
name: "",
status: "",
queryStartTime: "",
queryFinishTime: "",
aid: [],
},
study: {
detailType: "",
examineId: "",
pageIndex: 1, //第几页
pageSize: 10, // 每页多少条
count: 0,
type: "",
list: [],
catalogueShow: false,
detailsList: [],
detailShow: false,
},
studyDetailQuery: {
pageIndex: 1, //第几页
pageSize: 10, // 每页多少条
count: 0,
courseId: "",
aid: "",
},
showStudyDetailPage: true, // 处理章节为空学习详情展示
studyDetailRow: null, // 处理章节为空学习详情展示
studyStatusEnum: {
1: "未开始学习",
2: "学习中",
8: "已终止",
9: "学习完成",
},
recourseStudyStatusEnum: {
1: "未开始",
2: "进行中",
9: "已完成",
},
recourseListQuery: {
pageIndex: 1, //第几页
pageSize: 10, // 每页多少条
count: 0,
courseId: "",
contentName: "",
},
recourseList: [],
rousourceRow: null,
commonResourceStudyPeopleShow: false,
commonResourceStudyPeopleList: [],
commonResourceStudyPeopleQuery: {
pageIndex: 1, //第几页
pageSize: 10, // 每页多少条
count: 0,
name: "",
status: "",
aid: [],
},
examResourceStudyPeopleShow: false,
examResourceStudyPeopleList: [],
examResourceStudyPeopleQuery: {
pageIndex: 1, //第几页
pageSize: 10, // 每页多少条
count: 0,
name: "",
status: "",
aid: [],
},
};
},
mounted() {
this.getCourseDetailCrowds();
this.getSignupList();
this.getResOwnerTree().then((rs) => {
this.resOwnerListMap = rs;
});
this.getSysTypeTree().then((rs) => {
this.sysTypeListMap = rs;
});
},
methods: {
...mapActions({
getResOwnerTree: "resOwner/getResOwnerTree",
loadResOwners: "resOwner/loadResOwners",
getSysTypeTree: "sysType/getSysTypeTree",
loadSysTypes: "sysType/loadSysTypes",
}),
// 查询课程详情,获取 crowds 信息
getCourseDetailCrowds() {
if (!this.courseDetail || !this.courseDetail.id) return;
apiCourse
.detail(this.courseDetail.id)
.then((res) => {
console.log('res1', res);
const result = res.result || {};
this.courseCrowds = Array.isArray(result.crowds) ? result.crowds : [];
})
.catch(() => {
this.courseCrowds = [];
});
},
// 添加报名按钮点击,根据 crowds 是否有值决定弹窗
handleAddSignupClick() {
if (this.hasCourseCrowds) {
this.audienceDialogVisible = true;
} else {
this.addSignupVisible = true;
}
},
handleSignupCreate(payload) {
console.log("signup payload", payload);
this.getSignupList();
},
handleDeleteSignup(row) {
this.$confirm(`<i class="el-icon-warning-outline"></i>确认删除${row.name || ''}的报名记录吗?`, '删除确认', {
confirmButtonText: '确定',
cancelButtonText: '取消',
dangerouslyUseHTMLString: true,
type: 'warning',
customClass: 'custom-confirm-dialog'
}).then(() => {
apicourseStudy.deleteSignUp(row.id, this.courseDetail.id)
.then((res) => {
if (res && res.status === 200) {
this.$showMessage("删除成功", 'success');
this.getSignupList();
} else if (res) {
this.$showMessage(res.message || "删除失败", 'error');
}
})
.catch((err) => {
this.$showMessage("删除失败", 'error');
});
})
.catch((err) => {
// this.$showMessage('已取消删除', 'info');
});
},
resetCommonResourceQuery() {
this.$refs.commonResourceStudyPeopleNameFilter.handleReset();
this.commonResourceStudyPeopleQuery = {
pageIndex: 1, //第几页
pageSize: 10, // 每页多少条
count: 0,
name: "",
status: "",
aid: [],
};
this.queryResourceStudyPeopleList();
},
resetExamCommonResourceQuery() {
this.$refs.examResourceStudyPeopleNameFilter.handleReset();
this.examResourceStudyPeopleQuery = {
pageIndex: 1, //第几页
pageSize: 10, // 每页多少条
count: 0,
name: "",
status: "",
aid: [],
};
this.queryExamStudyPeopleList();
},
handleShowResourdeDetailList(row) {
console.log(row);
console.log(7777);
this.commonResourceStudyPeopleQuery = {
pageIndex: 1, //第几页
pageSize: 10, // 每页多少条
count: 0,
name: "",
status: "",
aid: [],
};
this.rousourceRow = row;
if (row.contentType == "61") {
// 考试
this.queryExamStudyPeopleList();
this.examResourceStudyPeopleShow = true;
} else if (row.contentType == "62") {
// 评估
this.queryAssessStudyPeopleList();
this.commonResourceStudyPeopleShow = true;
} else {
// 通用接口
this.queryResourceStudyPeopleList();
this.commonResourceStudyPeopleShow = true;
}
},
queryExamStudyPeopleList() {
apicourseStudy
.contentsExam({
courseId: this.courseDetail.id,
contentId: this.rousourceRow.contentId,
pageIndex: this.examResourceStudyPeopleQuery.pageIndex,
pageSize: this.examResourceStudyPeopleQuery.pageSize,
name: "",
status: this.examResourceStudyPeopleQuery.status,
aid: this.examResourceStudyPeopleQuery.aid.join(","),
})
.then(async (res) => {
if (res.status === 200) {
let ids = [];
res.result.list.forEach((item) => {
item.code = "";
ids.push(item.aid);
});
await this.getQaUserData(res.result.list, ids);
this.examResourceStudyPeopleList = res.result.list;
this.examResourceStudyPeopleQuery.count = res.result.count;
} else {
this.$message.error(res.message);
}
});
},
queryAssessStudyPeopleList() {
apicourseStudy
.contentsAssess({
courseId: this.courseDetail.id,
contentId: this.rousourceRow.contentId,
pageIndex: this.commonResourceStudyPeopleQuery.pageIndex,
pageSize: this.commonResourceStudyPeopleQuery.pageSize,
name: "",
status: this.commonResourceStudyPeopleQuery.status,
aid: this.commonResourceStudyPeopleQuery.aid.join(","),
})
.then(async (res) => {
if (res.status === 200) {
let ids = [];
res.result.list.forEach((item) => {
item.code = "";
ids.push(item.aid);
});
await this.getQaUserData(res.result.list, ids);
this.commonResourceStudyPeopleList = res.result.list;
this.commonResourceStudyPeopleQuery.count = res.result.count;
} else {
this.$message.error(res.message);
}
});
},
queryResourceStudyPeopleList() {
console.log(this.rousourceRow);
console.log(888);
apicourseStudy
.studyContentRecords({
courseId: this.courseDetail.id,
contentId: this.rousourceRow.contentId,
pageIndex: this.commonResourceStudyPeopleQuery.pageIndex,
pageSize: this.commonResourceStudyPeopleQuery.pageSize,
name: "",
status: this.commonResourceStudyPeopleQuery.status,
aid: this.commonResourceStudyPeopleQuery.aid.join(","),
})
.then(async (res) => {
if (res.status === 200) {
let ids = [];
res.result.list.forEach((item) => {
item.code = "";
ids.push(item.aid);
});
await this.getQaUserData(res.result.list, ids);
this.commonResourceStudyPeopleList = res.result.list;
this.commonResourceStudyPeopleQuery.count = res.result.count;
} else {
this.$message.error(res.message);
}
});
},
handleExport(
res,
fileName,
type = "application/vnd.ms-excel;charset=UTF-8"
) {
const link = document.createElement("a"); // 创建a标签
let blob = new Blob([res], {
type: type,
}); // 设置文件类型
link.style.display = "none";
link.href = URL.createObjectURL(blob); // 创建URL
console.log(link.href);
link.setAttribute("download", fileName);
document.body.appendChild(link);
link.click();
URL.revokeObjectURL(link.href);
document.body.removeChild(link);
},
handleExportRecourseDetail(data) {
if (data.contentType == "60") {
// 作业导出
apicourseStudy
.exportHomework({
courseId: this.courseDetail.id,
contentId: data.contentId,
})
.then((res) => {
this.handleExport(
res,
`${this.courseDetail.name}的${data.contentName}.zip`,
"application/zip"
);
});
} else if (data.contentType == "61") {
// 考试导出
apicourseStudy
.exportExam({
courseId: this.courseDetail.id,
contentId: data.contentId,
})
.then((res) => {
this.handleExport(
res,
`${this.courseDetail.name}的${data.contentName}.xlsx`
);
});
}
},
handleExportStudyResource() {
apicourseStudy
.studyExport({
courseId: this.courseDetail.id,
})
.then((res) => {
this.handleExport(
res,
this.courseDetail.name + "的资源学习情况.xlsx"
);
});
},
handleExportStudyDetail() {
apicourseStudy
.studyExport({
courseId: this.courseDetail.id,
aname: this.learningRecords.name,
status: this.learningRecords.status,
queryStartTime: this.learningRecords.queryStartTime,
queryFinishTime: this.learningRecords.queryFinishTime,
})
.then((res) => {
this.handleExport(res, this.courseDetail.name + "的学习记录.xlsx");
});
},
handleExportSignup() {
apicourseStudy
.exportSignup({
courseId: this.courseDetail.id,
name: this.signup.name,
signType: this.signup.signType,
})
.then((res) => {
this.handleExport(res, this.courseDetail.name + "的报名记录.xlsx");
});
},
resetResourseList() {
this.recourseListQuery.contentName = "";
this.getResourseList();
},
resetStudyRecords() {
this.$refs.learningRecordsNameFilter.handleReset();
this.learningRecords.aid = [];
this.learningRecords.name = "";
this.learningRecords.status = "";
this.studyDateTime = [];
this.learningRecords.queryStartTime = "";
this.learningRecords.queryFinishTime = "";
this.getStudyRecords();
},
resetSignupList() {
this.$refs.signupNameFilter.handleReset();
this.signup = {
name: "",
signType: "",
aid: [],
};
this.getSignupList();
},
resOwnerName(code) {
if (code == "") {
return "";
}
return this.resOwnerMap.get(code);
},
sysTypeName(code) {
if (code == "") {
return "";
}
return this.sysTypeMap.get(code);
},
getResourseList() {
apiCoursePortal.pageListResource(this.recourseListQuery).then((rs) => {
if (rs.status == 200) {
this.recourseList = rs.result.list;
this.recourseListQuery.count = rs.result.count;
} else {
this.recourseList = [];
this.$message.error(rs.message);
}
});
},
studyContentRecordsSearch() {
this.learningSituation.pageIndex = 1;
this.studyContentRecords();
},
// 资源里的学习详情
studyContentRecords() {
let params = {
courseId: this.courseDetail.id, //课程的id
status: this.learningSituation.status, //状态
name: this.learningSituation.name, //学习人的姓名
contentId: this.contentId, //课程内容id
pageIndex: this.learningSituation.pageIndex,
pageSize: this.learningSituation.pageSize,
};
this.downParams = params;
apicourseStudy.studyContentRecords(params).then((res) => {
if (res.status === 200) {
this.learningSituation.list = res.result.list;
this.learningSituation.count = res.result.count;
} else {
this.$message.error(res.message);
}
});
},
downLoad() {
if (this.learningSituation.list.length == 0) {
this.$message.warning("暂无数据");
return;
}
this.isTrue = true;
let params = {
courseName: this.courseDetail.name,
courseId: this.courseDetail.id,
status: this.downParams.status || "",
name: this.downParams.name || "",
contentId: this.contentId,
};
// window.open(`/systemapi/xboe/m/course/portal/export?contentId=${params.contentId}&courseName=${params.courseName}&courseId=${params.courseId}&status=${params.status}&name=${params.name}`)
const url = `/systemapi/xboe/m/course/portal/export?contentId=${params.contentId}&courseName=${params.courseName}&courseId=${params.courseId}&status=${params.status}&name=${params.name}`;
axios({
method: "get",
url: url,
// responseType: 'blob',
headers: { "X-Access-Token": getToken() },
})
.then((res) => {
this.isTrue = false;
if (res.data.status == 200) {
if (res.data.result.includes("upload")) {
window.open("/upload" + res.data.result.split("upload")[1]);
} else {
this.$message.warning(res.data.result);
}
}
})
.catch((err) => {
this.isTrue = false;
this.$message.error(err.response.data.message);
});
},
handleSizeRecourseList(val) {
this.recourseListQuery.pageSize = val;
this.recourseListQuery.pageIndex = 1;
this.getResourseList();
},
handleCurrentChangeRecourseList(val) {
this.recourseListQuery.pageIndex = val;
this.getResourseList();
},
handleSizeChangeExamStudyPeople(val) {
this.examResourceStudyPeopleQuery.pageSize = val;
this.examResourceStudyPeopleQuery.pageIndex = 1;
this.queryExamStudyPeopleList();
},
handleCurrentChangeExamStudyPeople(val) {
this.examResourceStudyPeopleQuery.pageIndex = val;
//console.log('learningSituation.pageIndex',this.learningSituation.pageIndex);
this.queryExamStudyPeopleList();
},
handleSizeChangeStudyPeople(val) {
this.commonResourceStudyPeopleQuery.pageSize = val;
this.commonResourceStudyPeopleQuery.pageIndex = 1;
this.queryResourceStudyPeopleList();
},
handleCurrentChangeStudyPeople(val) {
this.commonResourceStudyPeopleQuery.pageIndex = val;
//console.log('learningSituation.pageIndex',this.learningSituation.pageIndex);
this.queryResourceStudyPeopleList();
},
handleSizeChangeSituation(val) {
this.learningSituation.pageSize = val;
this.learningSituation.pageIndex = 1;
this.studyContentRecords();
},
handleCurrentChangeSituation(val) {
this.learningSituation.pageIndex = val;
//console.log('learningSituation.pageIndex',this.learningSituation.pageIndex);
this.studyContentRecords();
},
handleSizeChangeStudyDetail(val) {
this.studyDetailQuery.pageSize = val;
this.studyDetailQuery.pageIndex = 1;
this.getStudyDetail();
},
handleCurrentStudyDetail(val) {
this.learningSituation.pageIndex = val;
//console.log('learningSituation.pageIndex',this.learningSituation.pageIndex);
this.getStudyDetail();
},
// 学习记录
getStudyRecords() {
let params = {
courseId: this.courseDetail.id, //课程的id
status: this.learningRecords.status, //状态
// courseType:this.learningRecords.type,//类型
aname: "", //学习人的姓名 learningRecords
pageIndex: this.learningRecords.pageIndex,
pageSize: this.learningRecords.pageSize,
queryStartTime:
this.studyDateTime.length > 0 ? this.studyDateTime[0] : "",
queryFinishTime:
this.studyDateTime.length > 1 ? this.studyDateTime[1] : "",
aid: this.learningRecords.aid.join(","),
};
apicourseStudy.studyRecords(params).then(async (res) => {
if (res.status === 200) {
let ids = [];
res.result.list.forEach((item) => {
item.code = "";
ids.push(item.aid);
});
await this.getQaUserData(res.result.list, ids);
this.learningRecords.list = res.result.list;
this.learningRecords.count = res.result.count;
} else {
this.$message.error(res.message);
}
});
},
getStudyDetail() {
apiCoursePortal.detailStudyPage(this.studyDetailQuery).then((res) => {
if (res.status == 200) {
if (res.result && res.result.length > 0) {
this.showStudyDetailPage = true;
this.courseStudyList = res.result.list;
this.getStudyDetail.count = res.result.count;
} else {
this.showStudyDetailPage = false;
this.courseStudyList = [
{
contentName: this.courseDetail.name,
status: this.studyDetailRow.status,
studyDuration: this.studyDetailRow.progress,
learningDuration: this.studyDetailRow.totalDuration,
},
];
}
} else {
this.courseStudyList = [];
}
});
},
handleSizeChangeRecords(val) {
this.learningRecords.pageSize = val;
this.learningRecords.pageIndex = 1;
this.getStudyRecords();
},
handleCurrentChangeRecords(val) {
this.learningRecords.pageIndex = val;
this.getStudyRecords();
},
handleAudienceConfirm(list) {
this.selectedAudiences = list;
this.getSignupList();
},
// 报名列表
getSignupList() {
let params = {
courseId: this.courseDetail.id, //课程的id
signType: this.signup.signType, //报名方式
name: "", //姓名
pageIndex: this.study.pageIndex,
pageSize: this.study.pageSize,
aid: this.signup.aid.join(","),
};
console.log(11111);
apicourseStudy.findSignup(params).then(async (res) => {
if (res.status === 200) {
let ids = [];
res.result.list.forEach((item) => {
item.code = "";
ids.push(item.aid);
});
await this.getQaUserData(res.result.list, ids);
console.log(22222);
this.study.list = res.result.list;
this.study.count = res.result.count;
} else {
this.$message.error(res.message);
}
});
},
getQaUserData(list, ids) {
return new Promise((resolve, reject) => {
const noReapetIds = [...new Set(ids)];
apiUser.getByIds(noReapetIds).then((res) => {
if (res.status == 200) {
list.forEach((item) => {
res.result.some((author) => {
if (author.aid == item.aid) {
item.code = author.code;
item.orgInfo = author.orgInfo;
}
});
console.log(11111);
// this.study.list = list;
});
resolve();
} else {
resolve();
this.$showMessage(res.message, "error");
}
});
});
},
handleSizeChange(val) {
this.study.pageSize = val;
this.study.pageIndex = 1;
this.getSignupList();
},
handleCurrentChange(val) {
this.study.pageIndex = val;
this.getSignupList();
},
handleTabClick(tab) {
if (tab.name === "second") {
this.getSignupList();
} else if (tab.name === "third") {
this.getStudyRecords();
} else {
// 资源
this.recourseListQuery.courseId = this.courseDetail.id;
this.getResourseList();
}
this.tabName = tab.name;
},
showStudyDetails(row) {
this.studyDetailQuery.courseId = row.courseId;
this.studyDetailQuery.aid = row.aid;
// this.study.detailType = row.courseType;
// this.study.examineId = row.courseId;
this.study.detailShow = true;
this.studyDetailRow = row;
this.getStudyDetail();
},
},
};
</script>
<style lang="scss">
.no-wrap {
overflow: hidden;
text-overflow: ellipsis;
-webkit-box-orient: vertical;
-webkit-line-clamp: 1;
word-break: break-all;
white-space: nowrap;
}
.delete-action-link--danger {
color: #E32E2E;
&:hover {
color: #E32E2E;
}
&:active {
color: #E32E2E;
}
&:focus {
color: #E32E2E;
}
}
#courseManage {
.option-code {
margin-left: 4px;
color: #999;
}
.noSplitDatePicker {
/* 隐藏范围选择器的分隔符和占位符 */
.el-range-separator,
.el-range__close-icon {
display: none !important;
}
}
.resetDatePicker {
.el-range-input {
text-align: left;
}
.el-date-editor {
width: 255px;
}
.el-input__icon {
line-height: 28px;
&.el-icon-date {
position: absolute;
right: 0;
line-height: 28px;
}
.el-input__inner {
height: 28px;
}
&.el-icon-close {
margin-right: 8px;
line-height: 28px;
}
}
}
.course-info {
display: flex;
align-items: center;
margin-bottom: 40px;
.course-desc-item {
margin-right: 40px;
.title {
font-weight: bold;
}
}
}
}
.ment-div {
padding: 20px 40px;
font-size: 20px;
.ment-box {
border-bottom: 1px solid #ccc;
margin-top: 10px;
.ment-title {
font-size: 24px;
margin-bottom: 10px;
}
}
.assess-info {
padding: 10px 0;
}
}
.content {
line-height: 30px;
}
.tab-content {
height: 400px;
overflow: auto;
}
.el-tabs__nav-wrap::after {
display: none; /* 隐藏滚动条轨道 */
}
.el-tabs__nav-scroll {
overflow: hidden; /* 隐藏滚动条滑块 */
}
/* 隐藏垂直滚动条 */
.el-table .el-table__body-wrapper::-webkit-scrollbar {
display: none; /* Chrome, Safari, Opera*/
}
</style>