<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>