<template> <div class="class admin-refresh"> <div class="form-block section-search search-single"> <el-form label-width="90px" inline size="small"> <el-form-item> <el-cascader :popper-class="'refresh-cascader-multi width-560'" placeholder="请选择期数" style="width: 560px" filterable :options="goodsList" :props="{value:'id',label:'name'}" @active-item-change="handleItemChange" @change="changePeriods" v-model="selectedGoods"></el-cascader> </el-form-item> <el-form-item> <el-select style="width: 160px;" filterable v-model="teacher_id" @change="getClassList" placeholder="请选择老师" clearable> <el-option v-for="(data,index) in teacherList" :key="index" :label="data.teacher_name" :value="data.teacher_id"></el-option> </el-select> </el-form-item> <el-form-item label> <el-button type="primary" @click="getClassList">搜索</el-button> </el-form-item> <el-form-item style="float: right"> <div class="search-btn-wrapper"> <el-button @click="onExport" type="primary" v-if="$store.state.exportFinish" plain>导出完课用户</el-button> <el-button @click="onAdd" type="success" v-if="!$store.state.readonly">添加班级</el-button> <el-button type="success" @click="sendMsg">发送活动通知</el-button> </div> </el-form-item> </el-form> </div> <div v-if="title && title.title " class="intro"> <el-table border size="mini" :data="[title]" style="display: block;margin: 10px auto;background: transparent"> <el-table-column label="期数名称" width="280px"> <template slot-scope="scope"> <span style="white-space: normal">{{periodName}}</span> </template> </el-table-column> <el-table-column label="可看课包数" prop="watch_num"></el-table-column> <el-table-column label="已看课包数" prop="has_watch_num"></el-table-column> <el-table-column label="开始时间" prop="start_at"></el-table-column> <el-table-column label="老师数量" prop="count_teacher_num"></el-table-column> <el-table-column label="预计学员总数" prop="count_max_join_num"></el-table-column> <el-table-column label="学员总数" prop="count_join_num"></el-table-column> <el-table-column label="结束时间" prop="over_at"></el-table-column> </el-table> </div> <div v-if="!title || !title.title"> <el-form label-width="300px" inline> <el-form-item label="暂无期数信息,请先选择期数"></el-form-item> </el-form> </div> <div> <el-table @expand-change="changeRow" :data="classList"> <el-table-column type="expand"> <template slot-scope="scope"> <el-table :data="[scope.row]" style="width: 100%"> <el-table-column label="到课率" :render-header="rendertip"> <template slot-scope="scope2"> <span>{{ scope2.row.arrive_course_rate | percent}}</span> </template> </el-table-column> <el-table-column label="看课率" :render-header="rendertip"> <template slot-scope="scope2"> <span>{{ scope2.row.watch_course_rate | percent}}</span> </template> </el-table-column> <el-table-column label="完课率" :render-header="rendertip"> <template slot-scope="scope2"> <span>{{ scope2.row.over_course_rate | percent}}</span> </template> </el-table-column> <el-table-column label="打卡率" :render-header="rendertip"> <template slot-scope="scope2"> <span>{{ scope2.row.clock_rate | percent}}</span> </template> </el-table-column> <el-table-column label="全勤打卡率" :render-header="rendertip"> <template slot-scope="scope2"> <span>{{ scope2.row.over_clock_rate | percent}}</span> </template> </el-table-column> <el-table-column label="转化率" :render-header="rendertip"> <template slot-scope="scope2"> <span>{{ scope2.row.transform_rate | percent}}</span> </template> </el-table-column> </el-table> </template> </el-table-column> <el-table-column label="班级名称" width="200px"> <template slot-scope="scope">{{scope.row.class_name}}</template> </el-table-column> <!--<el-table-column prop="qr" label="班级二维码"> <template slot-scope="scope"> <a :href="scope.row.qr" v-if="scope.row.qr" target="_blank"> <img class="avatar" :src="scope.row.qr" alt="二维码"/> </a> <p v-if="!scope.row.qr">--</p> </template> </el-table-column>--> <el-table-column prop="teacher_name" label="班主任" width="120px"></el-table-column> <el-table-column label="老师状态" width="80px"> <template slot-scope="scope">{{scope.row.teacher_status === 0 ? '带班' : '不带班'}}</template> </el-table-column> <el-table-column label="班级类型" width="80px"> <template slot-scope="scope">{{scope.row.type | classTypeFilter}}</template> </el-table-column> <el-table-column prop="max_join_num" label="最大人数" width="100px"></el-table-column> <el-table-column prop="join_num" label="现有人数" width="100px"></el-table-column> <el-table-column prop="source" label="活动方案"> <template slot-scope="scope">{{scope.row.source | classSourceFilter}}</template> </el-table-column> <el-table-column label="操作" width="246"> <template slot-scope="scope"> <el-button @click="showUser(scope.row)" size="mini" type="primary">班级成员</el-button> <el-button @click="editClass(scope.row)" size="mini" v-if="!$store.state.readonly" type="warning">编辑</el-button> <el-button @click="delClass(scope.row)" size="mini" v-if="$store.state.deletePermission && !$store.state.readonly" type="danger">删除</el-button> </template> </el-table-column> </el-table> </div> <page :nowPage="nowPage" :total="total" :limit="limit" @pageChange="onPageChange" @sizeChange="onSizeChange" /> <class-dialog :dialogObj="dialogObj" @reflash="onReflash"></class-dialog> <user-list :userObj="userObj" @reflash="getClassList" /> </div> </template> <script> import { getGoodsListApi, getPeriodsApi, getClassListApi, getPeriodsTeacherApi, delClassApi, getClassStatisticsApi, getDefaultPeriodsApi, postActiveNoticeApi, getConfigListApi, getSourceStudentApi, exportExcelApi } from "../../service/api"; import classDialog from "./dialog"; import { GOODSTYPE, CLASSSOURCE } from "../../util/wordbook"; import UserList from "./userList"; import page from "../framework/page"; import { tipArr } from "../../util/tipArr"; let studentSource = {} export default { data() { return { noticeDialog: false, nowPage: 1, total: 0, limit: 10, periodsId: null, goods_id: null, goodsList: [], teacher_id: "", classList: [], title: "", countObj: "", teacherList: [], userObj: { classId: "", title: "", show: false, goods_id: null }, dialogObj: { show: false, title: "添加班级", periodsId: "", type: 0, id: 0 }, selectedGoods: [], secGoods: [] }; }, components: { UserList, classDialog, page }, filters: { classTypeFilter(val) { let _val = parseInt(val); if (_val === 1) { return "带班班级"; } else if (_val === 2) { return "观摩班级"; } else { return ""; } }, classSourceFilter(val) { // return CLASSSOURCE[val]; return studentSource[val]; }, percent(val) { return (val * 100).toFixed(2) + "%"; }, }, computed: { periodName: function () { if (this.selectedGoods.length) { return `【${this.selectedGoods[0]}】${this.title.title}${this.title.watch_num}课时(${this.title.start_at.slice(5).replace('-', '')})-d${this.title.has_watch_num}` } else { return '' } }, }, mounted() { this.initPage(); }, methods: { rendertip(h, { column }) { // common.tipFilter(h,column,tipArr2) return h("span", [ h("span", column.label), h( "el-tooltip", { props: { effect: "dark", content: tipArr[column.label], placement: "top" } }, [ h("i", { class: "el-icon-question", style: "color:#409eff;display:block;" }) ] ) ]); }, sendMsg() { if (this.title && this.title.title) { this.$confirm("你将发送给" + this.title.title + "用户", "提示", { confirmButtonText: "确定", cancelButtonText: "取消", type: "warning" }).then(() => { // console.log(this.selectedGoods) postActiveNoticeApi(this.periods.id).then(res => { this.noticeDialog = false; this.$message({ type: "success", message: "发送成功" + res.num + "个" }); }); }); } else { this.$message({ message: "请选择期数" }); } }, changeRow(data, b) { if (b.indexOf(data) > -1) { getClassStatisticsApi(data.periods_id, data.id).then(res => { data.arrive_course_rate = res.arrive_course_rate; data.watch_course_rate = res.watch_course_rate; data.over_course_rate = res.over_course_rate; data.work_rate = res.work_rate; data.over_work_rate = res.over_work_rate; data.clock_rate = res.clock_rate; data.over_clock_rate = res.over_clock_rate; data.transform_rate = res.transform_rate; }); } }, initQuery() { let _query = this.$route.query; if (_query && _query.goods_id && _query.periods_id) { this.goods_id = _query.goods_id; this.selectedGoods = [ parseInt(_query.goods_id), parseInt(_query.periods_id) ]; getPeriodsApi({ goods_id: this.selectedGoods[0], limit: 100 }).then( res => { res.list.forEach(i => { i.name = i.title; }); this.goodsList.find(i => { return i.id === this.selectedGoods[0]; }).children = res.list; let nowGoods = this.goodsList.find(i => { return i.id === this.selectedGoods[0]; }); this.periods = nowGoods.children.find(i => { return i.id === this.selectedGoods[1]; }); console.log(this.periods); this.teacher_id = ""; this.getClassList(); } ); } else { getDefaultPeriodsApi().then(res => { console.log(res); // if (res) { this.goods_id = res.goods_id; this.selectedGoods = [parseInt(res.goods_id), parseInt(res.id)]; getPeriodsApi({ goods_id: this.selectedGoods[0], limit: 100 }).then( res => { res.list.forEach(i => { i.name = i.title; }); this.goodsList.find(i => { return i.id === this.selectedGoods[0]; }).children = res.list; let nowGoods = this.goodsList.find(i => { return i.id === this.selectedGoods[0]; }); this.periods = nowGoods.children.find(i => { return i.id === this.selectedGoods[1]; }); this.teacher_id = ""; console.log(this.periods); this.getClassList(); } ); } }); } console.log(this.goodsList); }, initPage() { let json = { page: 1, limit: 100, goods_type: "1,2" }; getSourceStudentApi().then(res=>{ let obj = {} res.forEach((item,index)=>{ obj[item.type]=item.name }) studentSource = obj console.log(obj) }); getGoodsListApi(json).then(res => { console.log(res); res.list.forEach(i => { //i.name = `【${i.id}】` i.name = "[" + i.id + "]" + "[" + GOODSTYPE[i.goods_type] + "]" + "[" + i.current_price / 100 + "元]" + i.name; i.children = []; }); this.goodsList = res.list; this.initQuery(); }); }, showUser(data) { let classType = data.type == 1 ? "(带班班级)" : "(观摩班级)"; console.log(data); // debugger this.userObj = { classId: data.id, periods_id: data.periods_id, show: true, goods_id: this.goods_id, title: `${data.teacher_name}班级用户列表${classType}`, teacherId: data.teacher_id, class_name: data.class_name, type: data.type, watch_num: this.title.watch_num }; console.log(this.userObj); }, getTeacher() { if (!this.periods) return; getPeriodsTeacherApi(this.periods.id).then(res => { let obj = {}; //班级老师去重 res = res.reduce(function(item, next) { obj[next.teacher_id] ? "" : (obj[next.teacher_id] = true && item.push(next)); return item; }, []); this.teacherList = res; }); }, changePeriods(data) { if (data.length > 1) { this.goods_id = data[0]; let nowGoods = this.goodsList.find(i => { return i.id === data[0]; }); this.periods = nowGoods.children.find(i => { return i.id === data[1]; }); console.log(this.goodsList); console.log(this.periods); // debugger this.teacher_id = ""; this.getTeacher(); this.getClassList(); } }, onPageChange(val) { this.nowPage = val; this.getClassList(); }, onSizeChange(val) { this.limit = val; this.nowPage = 1; this.getClassList(); }, onReflash(periods) { this.periods = periods; this.selectedGoods = [periods.goods_id, periods.id]; this.getClassList(); }, getClassList() { if (!this.periods) return; this.getTeacher(); let json = { limit: this.limit, page: this.nowPage }; if (this.teacher_id) { json.teacher_id = this.teacher_id; } console.log(this.periods); getClassListApi(this.periods.id, json).then(res => { // debugger res.list.forEach(data => { data.arrive_course_rate = 0; data.watch_course_rate = 0; data.over_course_rate = 0; data.work_rate = 0; data.over_work_rate = 0; data.clock_rate = 0; data.over_clock_rate = 0; data.transform_rate = 0; }); this.title = res.periods; this.title.count_join_num = res.count.count_join_num ? res.count.count_join_num : "暂无"; this.title.count_max_join_num = res.count.count_max_join_num ? res.count.count_max_join_num : "暂无"; this.title.count_teacher_num = res.count.count_teacher_num ? res.count.count_teacher_num : "暂无"; this.countObj = res.count ? res.count : ""; this.classList = res.list; this.total = res.total; }); }, handleItemChange(val) { getPeriodsApi({ goods_id: val[0], limit: 100 }).then(res => { res.list.forEach(i => { i.name = i.title; }); this.goodsList.find(i => { return i.id === val[0]; }).children = res.list; }); }, delClass(data) { this.$confirm("此操作将删除该班级?", "提示", { confirmButtonText: "确定", cancelButtonText: "取消", type: "warning" }).then(() => { delClassApi(data.id).then(res => { this.$message({ type: "success", message: "删除成功!" }); this.getClassList(); }); }); }, onExport() { let json = { periods_id: this.selectedGoods[1] }; exportExcelApi("/api/admin/periods/finish/user/export", json); }, onAdd() { this.dialogObj = { show: true, title: "添加班级", type: 0, teacherList: this.teacherList ? this.teacherList : [] }; if (this.periods) { this.dialogObj.periods = this.periods; this.dialogObj.periodsId = this.periods.id; } }, editClass(data) { this.dialogObj = { show: true, title: "编辑班级", type: 1, id: data.id, teacherList: this.teacherList ? this.teacherList : [] }; if (this.periods) { this.dialogObj.periods = this.periods; this.dialogObj.periodsId = this.periods.id; } } } }; </script> <style scoped lang="less"> .class { /*padding: 20px 0;*/ } .intro .el-form-item { margin-bottom: 0; } .avatar { width: 70px; } </style> <style> .demo-table-expand { font-size: 0; } .demo-table-expand label { width: 90px; color: #99a9bf; } .demo-table-expand .el-form-item { margin-right: 0; margin-bottom: 0; width: 50%; } </style>