Commit 7ee954cc authored by baixian's avatar baixian

推送和多学员删除功能

parent 5bf28b13
image/wx.png

536 Bytes

......@@ -12,11 +12,11 @@
<![endif]-->
<script charset="utf-8" src="https://map.qq.com/api/js?v=2.exp&key=XSZBZ-5LHCV-5I2P7-UQHPW-6456F-JBB3B"></script>
<script src="https://cdn.img.shangjiadao.cn/qingxiao/biz/js/console-polyfill.js?20191012222" charset="utf-8"></script><script src="https://cdn.img.shangjiadao.cn/qingxiao/biz/js/es6-shim.min.js?20191012222" charset="utf-8"></script><script src="https://cdn.img.shangjiadao.cn/qingxiao/biz/js/es5-shim.js?20191012222" charset="utf-8"></script><script src="https://cdn.img.shangjiadao.cn/qingxiao/biz/js/es5-sham.min.js?20191012222" charset="utf-8"></script><script src="https://cdn.img.shangjiadao.cn/qingxiao/biz/js/json3.min.js?20191012222" charset="utf-8"></script><script src="https://cdn.img.shangjiadao.cn/qingxiao/biz/js/html5shiv.min.js?20191012222" charset="utf-8"></script><script src="https://cdn.img.shangjiadao.cn/qingxiao/biz/js/polyfill.js?20191012222" charset="utf-8"></script><script src="https://cdn.img.shangjiadao.cn/qingxiao/biz/lib/vendor.dll.js?20191012222" charset="utf-8"></script>
<script src="js/console-polyfill.js?20191012222" charset="utf-8"></script><script src="js/es6-shim.min.js?20191012222" charset="utf-8"></script><script src="js/es5-shim.js?20191012222" charset="utf-8"></script><script src="js/es5-sham.min.js?20191012222" charset="utf-8"></script><script src="js/json3.min.js?20191012222" charset="utf-8"></script><script src="js/html5shiv.min.js?20191012222" charset="utf-8"></script><script src="js/polyfill.js?20191012222" charset="utf-8"></script><script src="lib/vendor.dll.js?20191012222" charset="utf-8"></script>
</head>
</head>
<body>
<div id="root"></div>
<script src="https://cdn.img.shangjiadao.cn/qingxiao/biz/dist/main.js?1571940439010" charset="utf-8"></script>
<script src="dist/main.js?1572332208185" charset="utf-8"></script>
</body>
</html>
\ No newline at end of file
......@@ -74,6 +74,7 @@ export default {
studentsLog: `${dakaapi}member/erp/student/logs`,
studentsUnBindWx: `${dakaapi}member/erp/student/wechat/remove`,
schoolUuid: `${dakaapi}member/school_uuid`,
studentHistory: `${dakaapi}member/erp/students/status`,
},
teachers: `${dakaapi}member/erp/teachers`,
choose_teacher: `${dakaapi}member/erp/teacher/distribution`,
......@@ -90,6 +91,7 @@ export default {
changeClassStatus: `${dakaapi}member/erp/class/status`,
addClassStudents: `${dakaapi}member/erp/class/student/add`,
plansAdd: `${dakaapi}member/erp/plans`,
wxConfig: `${dakaapi}member/erp/config`,
},
teacherMgt: {
teacherInvitations: `${dakaapi}member/erp/teacher/invitations`,
......
......@@ -55,6 +55,7 @@ export default {
page: 1,
perPage: 10,
class_id: 0,
status: 1,
},
queryToAddStudentListParams: {
school_id: 0,
......@@ -1358,6 +1359,7 @@ export default {
page: 1,
perPage: 10,
class_id: 0,
status: 1,
},
queryToAddStudentListParams: {
school_id: 0,
......@@ -1372,6 +1374,7 @@ export default {
page: 1,
perPage: 10,
schedule_id: 0,
status: 1,
},
scheduleStudentTotal: 0,
scheduleStudentList: [],
......
......@@ -16,6 +16,7 @@ import * as teachersAjax from '../services/teachers';
import * as classroommgtAjax from '../services/classroommgt';
import * as commonAjax from '../services/common';
import errorcode from '../common/errorcode';
import * as studentsAjax from '../services/students';
export default {
namespace: 'classmgt',
state: {
......@@ -119,6 +120,13 @@ export default {
classInviteqrcodeShow: false,
classInviteqrcodeUrl: '',
classInviteqrcodeUrl2: '',
wxVisible: false,
wxSubmitting: false,
wxConfig: {
schedule_remind_on_off: 1,
schedule_remind_student_before: 0,
schedule_remind_teacher_before: 0,
},
},
subscriptions: {
setup({ dispatch, history }) { // eslint-disable-line
......@@ -389,6 +397,82 @@ export default {
// message.error(classAddDate.msg, 1);
}
},
* saveWxConfig({ payload }, { call, put, select }) {
const { sid } = yield select(state => state.webapp);
const {
schedule_remind,
teacher_minutes,
parent_minutes,
type,
callBack,
} = payload;
const { wxSubmitting } = yield select(state => state.classmgt);
if (wxSubmitting) {
return;
}
yield put({
type: 'updateState',
payload: {
wxSubmitting: true,
},
});
const loadmessage = message.loading('保存中...', 0);
const data = yield call(classMgtAjax.wxConfig, {
school_id: sid,
schedule_remind,
teacher_minutes,
parent_minutes,
type,
});
yield put({
type: 'updateState',
payload: {
wxSubmitting: false,
},
});
setTimeout(loadmessage);
if (data.code === 200) {
message.success('保存成功', 1);
yield put({
type: 'updateState',
payload: {
wxVisible: false,
},
});
if (callBack && (typeof callBack == 'function')) {
callBack();
}
} else {
yield put({
type: 'webapp/errorrequestresolve',
payload: {
data,
},
});
}
},
* selectWxConfig({ payload }, { call, put, select }) {
const { sid } = yield select(state => state.webapp);
const data = yield call(classMgtAjax.GetWxConfig, {
school_id: sid,
type: 1,
});
if (data.code === 200) {
yield put({
type: 'updateState',
payload: {
wxConfig: data.data,
},
});
} else {
yield put({
type: 'webapp/errorrequestresolve',
payload: {
data,
},
});
}
},
* goback({ payload }, { call, put, select }) {
yield put(routerRedux.goBack());
},
......@@ -850,6 +934,13 @@ export default {
selectedClasskey: [],
selectedClass: [],
statusChangeSubmitting: false,
wxVisible: false,
wxSubmitting: false,
wxConfig: {
schedule_remind_on_off: 1,
schedule_remind_student_before: 0,
schedule_remind_teacher_before: 0,
},
},
});
},
......
......@@ -13,7 +13,6 @@ import * as teachersAjax from '../services/teachers';
import * as courseAjax from '../services/course';
import * as classMgtAjax from '../services/classmgt';
import * as commonAjax from '../services/common';
export default {
namespace: 'students',
state: {
......@@ -78,6 +77,7 @@ export default {
extra: 'time,recently_course',
birthday_start: '',
birthday_end: '',
status: 1,
},
searchstudentListQueryParams: {
school_id: 0,
......@@ -135,6 +135,8 @@ export default {
queryRepeatStudentsLoading: false,
studentAddParams: {},
repeatStudentList: [],
deleteVisible: false,
studentsId: 0, // 学生ID
},
subscriptions: {
setup({ dispatch, history }) { // eslint-disable-line
......@@ -323,10 +325,12 @@ export default {
const { params, action } = payload;
const { studentListQueryParams, studentListTotal, searching } = yield select(state => state.students);
if (action == 'search') {
if (studentListQueryParams.status === 2) {
return;
}
if (searching) {
return;
}
yield put({
type: 'updateState',
payload: {
......@@ -982,6 +986,108 @@ export default {
message.error('小程序码生成失败', 1);
}
},
* goHistoryStudent({ payload }, { call, put, select }) {
const { stat_time_status, status, callBack } = payload;
const { sid } = yield select(state => state.webapp);
const { studentsId, historyStudentLoading } = yield select(state => state.students);
if (historyStudentLoading) {
return;
}
yield put({
type: 'updateState',
payload: {
historyStudentLoading: true,
},
});
const studentDelete = yield call(studentsAjax.studentsHistory, {
ids: studentsId,
stat_time_status,
status,
});
yield put({
type: 'updateState',
payload: {
historyStudentLoading: false,
},
});
if (studentDelete.code === 200) {
message.success(status === 1 ? '转为在读学员成功' : '转为历史在读学员成功', 1);
yield put({
type: 'studentsList',
payload: {
params: {
},
},
});
yield put({
type: 'updateState',
payload: {
deleteVisible: false,
},
});
if (callBack && (typeof callBack == 'function')) {
callBack();
}
} else {
yield put({
type: 'webapp/errorrequestresolve',
payload: {
data: studentDelete,
},
});
}
},
* goDeleteStudent({ payload }, { call, put, select }) {
const { stat_time_status, status, callBack } = payload;
const { sid } = yield select(state => state.webapp);
const { studentsId, historyStudentLoading } = yield select(state => state.students);
if (historyStudentLoading) {
return;
}
yield put({
type: 'updateState',
payload: {
historyStudentLoading: true,
},
});
const studentDelete = yield call(studentsAjax.studentsDelete, {
ids: studentsId,
stat_time_status,
});
yield put({
type: 'updateState',
payload: {
historyStudentLoading: false,
},
});
if (studentDelete.code === 200) {
message.success('删除学员成功', 1);
yield put({
type: 'studentsList',
payload: {
params: {
},
},
});
yield put({
type: 'updateState',
payload: {
deleteVisible: false,
deleteOneVisible: false,
},
});
if (callBack && (typeof callBack == 'function')) {
callBack();
}
} else {
yield put({
type: 'webapp/errorrequestresolve',
payload: {
data: studentDelete,
},
});
}
},
* pageInit({ payload }, { call, put, select }) {
yield put({
type: 'updateState',
......@@ -1047,6 +1153,7 @@ export default {
extra: 'time,recently_course',
birthday_start: '',
birthday_end: '',
status: 1,
},
searchstudentListQueryParams: {
school_id: 0,
......@@ -1101,6 +1208,10 @@ export default {
inviteCodeShow: false,
inviteCode: '',
Inviteloading: false,
deleteVisible: false,
studentsId: 0,
historyStudentLoading: false,
deleteOneVisible: false,
},
});
},
......
import { connect } from 'dva';
import React from 'react';
import PropTypes from 'prop-types';
import { message, Row, Col, Input, Select, Modal, Form, InputNumber, Checkbox } from 'antd';
import { imagify, pageIn } from '../../utils/index';
import pageStyle from './WxPushTimeModal.less';
const FormItem = Form.Item;
class WxPushTimeModal extends React.Component {
componentWillMount() {
}
componentDidUpdate() {
}
componentWillUpdate() {
}
componentDidMount() { // 挂载
pageIn('班级管理');
}
componentWillUnmount() { // 卸载
}
componentWillReceiveProps(nextProps) {
}
save = () => {
const { form, save } = this.props;
form.validateFields((err, values) => {
if (!err) {
const {
schedule_remind,
teacher_minutes,
parent_minutes,
type,
} = values;
save({
schedule_remind: schedule_remind ? 1 : 2,
teacher_minutes,
parent_minutes,
type,
callBack: () => {
form.resetFields();
},
});
}
});
}
close = () => {
const { form, close } = this.props;
form.resetFields();
close();
}
render() {
const {
visible,
wxSubmitting,
form: { getFieldDecorator, getFieldValue },
wxConfig,
} = this.props;
const formItemModalLineLayout = {
labelCol: {
xs: { span: 24 },
sm: { span: 5 },
},
wrapperCol: {
xs: { span: 24 },
sm: { span: 19 },
},
};
return (
<Modal
visible={visible}
title="微信推送设置"
okText={!wxSubmitting ? '保存' : '保存中...'}
confirmLoading={wxSubmitting}
onCancel={this.close}
onOk={this.save}
className="modifyclassModal"
maskClosable={false}
zIndex={110}
>
<Form hideRequiredMark className={pageStyle.modalform} labelAlign="left">
<FormItem>
{getFieldDecorator('schedule_remind', {
valuePropName: 'checked',
initialValue: Number(wxConfig.schedule_remind_on_off) == 1,
})(<Checkbox><span className={pageStyle.tip}>微信服务推送通知</span></Checkbox>)}
</FormItem>
{getFieldDecorator('type', { initialValue: 1 })(<Input type="hidden" />)}
<FormItem className={pageStyle.firstItem} {...formItemModalLineLayout} label="家长:上课前">
{getFieldDecorator('parent_minutes', {
initialValue: wxConfig.schedule_remind_student_before,
rules: [
{
required: true,
message: '请输入正整数',
pattern: new RegExp(/^[1-9]\d*$/, 'g'),
},
],
})(<InputNumber min={0} />)}
<span className="ant-form-text"> 分钟推送上课提醒</span>
</FormItem>
<FormItem className={pageStyle.firstItem} {...formItemModalLineLayout} label="老师:上课前">
{getFieldDecorator('teacher_minutes', {
initialValue: wxConfig.schedule_remind_teacher_before,
rules: [
{
required: true,
message: '请输入正整数',
pattern: new RegExp(/^[1-9]\d*$/, 'g'),
},
],
})(<InputNumber min={0} />)}
<span className="ant-form-text"> 分钟推送上课提醒</span>
</FormItem>
</Form>
</Modal>
);
}
}
const WxPushTime = Form.create()(WxPushTimeModal);
export default WxPushTime;
.modalform {
.tip {
font-size:14px;
font-family:PingFangSC-Medium,PingFang SC;
font-weight:500;
color:rgba(0,0,0,0.65);
display: inline-block;
margin-left: 15px;
}
.firstItem {
margin-left: 40px;
}
:global {
.ant-form-item-label > label::after {
content: '';
}
}
}
......@@ -8,7 +8,7 @@ import EditClassModal from './EditClassModal';
import ClassRoomMgt from './classRoomMgt';
import ClassStatusChangeModal from './ClassStatusChangeModal';
import ClassrRgistration from './classrRgistration';
import WxPushTimeModal from './WxPushTimeModal';
const { Option } = Select;
const { TextArea } = Input;
class ClassMgtForm extends React.Component {
......@@ -410,6 +410,34 @@ class ClassMgtForm extends React.Component {
},
});
}
wxSwitch = () => {
const { dispatch } = this.props;
dispatch({
type: 'classmgt/selectWxConfig',
});
dispatch({
type: 'classmgt/updateState',
payload: {
wxVisible: true,
},
});
}
handleWxCancel = () => {
const { dispatch } = this.props;
dispatch({
type: 'classmgt/updateState',
payload: {
wxVisible: false,
},
});
}
handleSaveWx = (value) => {
const { dispatch } = this.props;
dispatch({
type: 'classmgt/saveWxConfig',
payload: value,
});
}
render() {
const { getFieldDecorator } = this.props.form;
const {
......@@ -431,6 +459,9 @@ class ClassMgtForm extends React.Component {
classInviteqrcodeUrl,
classInviteqrcodeUrl2,
inviteClassInfo,
wxVisible,
wxSubmitting,
wxConfig,
} = this.props;
const visible = false;
const columns = [
......@@ -539,6 +570,7 @@ class ClassMgtForm extends React.Component {
<div className={pageStyle.container}>
<div className={pageStyle.headerbox}>
{hasBtnPower('sjd/classmgt', 'addClass') && <Button icon="plus" className={pageStyle.headerbtn} type="primary" onClick={this.addClass}>添加班级</Button>}
{/* <Button className={pageStyle.headerbtn} onClick={this.wxSwitch} >微信推送设置</Button> */}
{hasBtnPower('sjd/classmgt', 'allWindingUp') && <Button className={pageStyle.headerbtn} onClick={this.operateClassStatus}>批量结业</Button>}
<Button icon="download" className={pageStyle.headerbtn} onClick={() => this.exportExcel(columns)} >导出</Button>
</div>
......@@ -674,6 +706,13 @@ class ClassMgtForm extends React.Component {
inviteClassInfo={inviteClassInfo}
codeImgClose={this.codeImgClose}
/>
<WxPushTimeModal
visible={wxVisible}
close={this.handleWxCancel}
save={this.handleSaveWx}
wxSubmitting={wxSubmitting}
wxConfig={wxConfig}
/>
</div>
);
}
......@@ -709,6 +748,9 @@ function mapStateToProps(state) {
classInviteqrcodeUrl,
classInviteqrcodeUrl2,
inviteClassInfo,
wxVisible,
wxSubmitting,
wxConfig,
} = state.classmgt;
return {
classList,
......@@ -735,6 +777,9 @@ function mapStateToProps(state) {
classInviteqrcodeUrl,
classInviteqrcodeUrl2,
inviteClassInfo,
wxVisible,
wxSubmitting,
wxConfig,
};
}
export default connect(mapStateToProps)(ClassMgt);
......
......@@ -13,7 +13,7 @@ class eliminateEdit extends React.Component {
currentCourse: {
course_mode: 1,
},
expendValue: 0,
expendValue: null,
};
}
componentDidMount() { // 挂载
......@@ -42,7 +42,7 @@ class eliminateEdit extends React.Component {
currentCourse: {
surplus: 0,
},
expendValue: 0,
expendValue: null,
});
}
});
......@@ -58,6 +58,7 @@ class eliminateEdit extends React.Component {
const { close, form, dispatch } = this.props;
form.resetFields();
this.setState({
expendValue: null,
currentCourse: {
surplus: 0,
},
......@@ -186,10 +187,10 @@ class eliminateEdit extends React.Component {
}}
>
{currentCourse.course_mode == 1 &&
<span>{expendValue || 0} 课时</span>
<span>{expendValue || currentCourse.surplus } 课时</span>
}
{currentCourse.course_mode == 2 &&
<span>{expendValue || 0} </span>
<span>{expendValue || currentCourse.surplus} </span>
}
</Form.Item>
) : (
......
import { connect } from 'dva';
import React from 'react';
import { Icon, Button, Row, Col, Input, Select, Checkbox, Form, InputNumber, Table, Modal, DatePicker, message, Pagination } from 'antd';
import { Icon, Button, Row, Tag, Col, Input, Select, Checkbox, Form, InputNumber, Table, Modal, Tabs, message, Pagination, Radio } from 'antd';
import pageStyle from './index.less';
import { pageIn, hasBtnPower, imagify } from '../../utils/index';
import RenewEdit from './RenewEdit';
......@@ -15,6 +15,7 @@ import InviteCodeDialog from '../../components/InviteCodeDialog';
import RepeatStudent from './RepeatStudent';
const { Option } = Select;
const { TextArea } = Input;
const { TabPane } = Tabs;
class StudentMgt extends React.Component {
state = {
cage: 0,
......@@ -44,6 +45,14 @@ class StudentMgt extends React.Component {
isExpendMore: false,
// Inviteloading: false,
};
constructor(props) {
super(props);
this.state = {
isChecked: false,
isShowQuestion: false,
verifyValue: '',
};
}
componentDidMount() { // 挂载
pageIn('学员管理');
// 初始化地图函数 自定义函数名init
......@@ -547,6 +556,131 @@ class StudentMgt extends React.Component {
type: 'students/sureAddRepeatStudent',
});
}
toDeleteModal = (record) => {
const { dispatch } = this.props;
dispatch({
type: 'students/updateState',
payload: {
deleteVisible: true,
studentsId: record.id,
},
});
}
closeDeleteModal = () => {
const { dispatch } = this.props;
dispatch({
type: 'students/updateState',
payload: {
deleteVisible: false,
deleteOneVisible: false,
studentsId: 0,
},
});
}
changeStatus= () => {
this.setState({
isChecked: !this.state.isChecked,
});
}
questionShow = () => {
this.setState({
isShowQuestion: !this.state.isShowQuestion,
});
}
changeTab = () => {
this.setState({
isChecked: false,
});
}
changeInputDelete = (e) => {
this.setState({
verifyValue: e.target.value,
});
}
changeStudentStatus = (status) => {
const { dispatch } = this.props;
dispatch({
type: 'students/studentsList',
payload: {
params: {
status,
page: 1,
},
},
});
}
goHistoryStudent = () => {
const { dispatch } = this.props;
const { isChecked } = this.state;
dispatch({
type: 'students/goHistoryStudent',
payload: {
status: 2,
stat_time_status: isChecked ? 2 : 1,
callBack: () => {
this.setState({
isChecked: false,
});
},
},
});
}
goDeleteStudent = () => {
const { dispatch } = this.props;
const { isChecked, verifyValue } = this.state;
if (verifyValue != '彻底删除') {
message.error('请先输入‘彻底删除’', 2);
return;
}
dispatch({
type: 'students/goDeleteStudent',
payload: {
stat_time_status: isChecked ? 2 : 1,
callBack: () => {
this.setState({
isChecked: false,
verifyValue: '',
});
},
},
});
}
toInSchoolStudent = (record) => {
const { dispatch, historyStudentLoading } = this.props;
dispatch({
type: 'students/updateState',
payload: {
studentsId: record.id,
},
});
Modal.confirm({
title: '确定转为在读学员吗?',
centered: false,
cancelText: '取消',
okText: '确定',
confirmLoading: historyStudentLoading,
onOk: () => {
dispatch({
type: 'students/goHistoryStudent',
payload: {
status: 1,
},
});
},
onCancel: () => {
},
});
}
toHistoryDeleteModal = (record) => {
const { dispatch } = this.props;
dispatch({
type: 'students/updateState',
payload: {
deleteOneVisible: true,
studentsId: record.id,
},
});
}
render() {
const { getFieldDecorator } = this.props.form;
const {
......@@ -597,8 +731,14 @@ class StudentMgt extends React.Component {
repeatStudentShow,
queryRepeatStudentsLoading,
repeatStudentList,
deleteVisible,
historyStudentLoading,
deleteOneVisible,
} = this.props;
const { qrCodeTitle, isExpendMore } = this.state;
const {
qrCodeTitle, isExpendMore, isChecked, isShowQuestion,
verifyValue,
} = this.state;
const columns = [
{
title: '学员姓名',
......@@ -619,7 +759,9 @@ class StudentMgt extends React.Component {
render: (text, record) => {
return (
<div>
{record.consumer_id == 0 ? <span className="hreflink" onClick={() => this.generateSingleBindQrcode(record)}>未绑定</span> : '已绑定'}
{/* eslint-disable-next-line jsx-a11y/alt-text */}
{record.consumer_id == 0 ? <img style={{ cursor: 'pointer' }} className="hreflink" onClick={() => this.generateSingleBindQrcode(record)} src={`${__IMGCDN__}wx.png`} /> : <img className="hreflink" src={`${__IMGCDN__}wx_active.png`} />
}
</div>
);
},
......@@ -676,19 +818,34 @@ class StudentMgt extends React.Component {
render: (text, record, index) => {
return (
<div className={pageStyle.tableoperatebox}>
{ hasBtnPower('sjd/student', 'addStudent') &&
{ hasBtnPower('sjd/student', 'addStudent') && record.status === 1 &&
<span>
<span className="hreflink" onClick={() => this.toChoiceClass(record)}>选班</span>
<span className={pageStyle.divideline}>|</span>
</span>
}
{hasBtnPower('sjd/student', 'addCourseHours') && <span className="hreflink" onClick={() => this.goRenewCourse(record)}>购课</span>}
{record.student_courses.filter(ele => ele.course_mode != 3).length != 0 && hasBtnPower('sjd/student', 'removeCourseHours') &&
{hasBtnPower('sjd/student', 'addCourseHours') && record.status === 1 && <span className="hreflink" onClick={() => this.goRenewCourse(record)}>购课</span>}
{record.student_courses.filter(ele => ele.course_mode != 3).length != 0 && hasBtnPower('sjd/student', 'removeCourseHours') && record.status === 1 &&
<span>
<span className={pageStyle.divideline}>|</span>
<span className="hreflink" onClick={() => this.EliminateEdit(record)}>消课</span>
</span>
}
{
record.status === 1 &&
<span>
<span className={pageStyle.divideline}>|</span>
<span className="hreflink" onClick={() => this.toDeleteModal(record)}>删除</span>
</span>
}
{
record.status === 2 &&
<span>
<span className="hreflink" onClick={() => this.toInSchoolStudent(record)}>转为在读学员</span>
<span className={pageStyle.divideline}>|</span>
<span className="hreflink" onClick={() => this.toHistoryDeleteModal(record)}>删除</span>
</span>
}
</div>
);
},
......@@ -805,6 +962,10 @@ class StudentMgt extends React.Component {
</div>
<div className={pageStyle.table}>
<div className={pageStyle.title}>学员管理</div>
<div className={pageStyle.tabFlex}>
<div className={studentListQueryParams.status == 1 ? pageStyle.tabActive : pageStyle.tabItem} style={{ marginRight: '50px' }} onClick={() => this.changeStudentStatus(1)}>在读学员</div>
<div className={studentListQueryParams.status == 2 ? pageStyle.tabActive : pageStyle.tabItem} onClick={() => this.changeStudentStatus(2)}>历史在读学员</div>
</div>
<div className={pageStyle.tablebox}>
<Table
dataSource={studentsinfo}
......@@ -841,6 +1002,116 @@ class StudentMgt extends React.Component {
previewQrcode={previewQrcode}
title={qrCodeTitle}
/>
<Modal
className={pageStyle.deleteModal}
maskClosable={false}
visible={deleteVisible}
closeIcon={<Icon type="close-circle" style={{ color: '#fff' }} />}
onCancel={this.closeDeleteModal}
footer={null}
width={400}
bodyStyle={{ padding: ' 0 24px 24px' }}
>
<div className={pageStyle.modalHead}>
<div>
<Tabs defaultActiveKey="1" onChange={this.changeTab}>
<TabPane
tab={
<div className={pageStyle.tabItem}>
<span>推荐使用</span>
<span className={pageStyle.tabTip}>转为历史在读</span>
</div>
}
key="1"
>
<div className={pageStyle.modalBody}>
<div className={pageStyle.commonTitle}>使用场景:</div>
<p>
1.上完一期,不续费了,他的作业学习数据保留以后可
以二次营销,有可能后续还报名的学员
</p>
<p>2.试听课上完之后,没有报名,转为历史学员后续营销</p>
<div className={pageStyle.commonTitle}>使用后有什么影响:</div>
<p>1.课时余额将清零</p>
<p>2.学员能查看自己的历史报读课程,自己交的作业</p>
<p>3.学员将自动退出当前班级</p>
<p>4.学员不会收到学校的各种通知</p>
<p>5.学员将从在读学员中移出,机构学员将不统计该学员</p>
<div className={pageStyle.commonTitle} onClick={this.questionShow}>常见问题 <span>{isShowQuestion ? '收起' : '展开'}</span></div>
{isShowQuestion &&
<div>
<p>Q:历史在读学员能转回在读学员吗?</p>
<p>A:可以,在历史在读人员点击转为正式学员即可</p>
</div>
}
<Radio className={pageStyle.radioOption} checked={isChecked} onClick={this.changeStatus}>
<div>删除学员之前在机构中产生的课时统计数据 <br />删除后课时统计总数将删除该学员数据
</div>
</Radio>
</div>
<div className={pageStyle.modalFooter}>
<Button type="primary" loading={historyStudentLoading} onClick={this.goHistoryStudent}>转为历史在读学员</Button>
</div>
</TabPane>
<TabPane
tab={
<div className={pageStyle.tabItem}>
<span>慎重选择</span>
<span className={pageStyle.tabTip1}>删除学员</span>
</div>
}
key="2"
>
<div className={pageStyle.modalBody}>
<div className={pageStyle.commonTitle}>删除后学员彻底从机构移出,该学员所有展示数 据都将删除</div>
<p>1.打卡作业数据将彻底删除</p>
<p>2.报课记录将彻底删除</p>
<div className={pageStyle.commonNotice}><span>注意</span>默认删除学员,学员之前在机构产生的
消数据统计不删除,若要清除历史课消数据勾选
下方按钮,保持课时数据统计准确性!
</div>
<Radio className={pageStyle.radioOption} checked={isChecked} onClick={this.changeStatus}>
<div>删除学员之前在机构中产生的课时统计数据 <br />删除后课时统计总数将删除该学员数据</div>
</Radio>
</div>
<div className={pageStyle.modalFooter}>
<Input className={pageStyle.commonInput} value={verifyValue} placeholder="请输入“彻底删除”" onChange={e => this.changeInputDelete(e)} />
<Button type="danger" loading={historyStudentLoading} onClick={this.goDeleteStudent}>确认删除</Button>
</div>
</TabPane>
</Tabs>
</div>
</div>
</Modal>
<Modal
title="慎重选择"
closable
maskClosable={false}
visible={deleteOneVisible}
onCancel={this.closeDeleteModal}
footer={null}
width={400}
bodyStyle={{ padding: ' 0 24px 24px' }}
>
<div className={pageStyle.modalHead}>
<div className={pageStyle.modalBody}>
<div className={pageStyle.commonTitle}>删除后学员彻底从机构移出,该学员所有展示数 据都将删除</div>
<p>1.打卡作业数据将彻底删除</p>
<p>2.报课记录将彻底删除</p>
<div className={pageStyle.commonNotice}><span>注意</span>默认删除学员,学员之前在机构产生的
消数据统计不删除,若要清除历史课消数据勾选
下方按钮,保持课时数据统计准确性!
</div>
<Radio className={pageStyle.radioOption} checked={isChecked} onClick={this.changeStatus}>
<div>删除学员之前在机构中产生的课时统计数据 <br />删除后课时统计总数将删除该学员数据</div>
</Radio>
</div>
<div className={pageStyle.modalFooter}>
<Input className={pageStyle.commonInput} value={verifyValue} placeholder="请输入“彻底删除”" onChange={e => this.changeInputDelete(e)} />
<Button type="danger" loading={historyStudentLoading} onClick={this.goDeleteStudent}>确认删除</Button>
</div>
</div>
</Modal>
{/*
<Modal
visible={previewBindQrcodeShow}
......@@ -1017,6 +1288,9 @@ function mapStateToProps(state) {
repeatStudentShow,
queryRepeatStudentsLoading,
repeatStudentList,
deleteVisible,
historyStudentLoading,
deleteOneVisible,
} = state.students;
const {
schoolUserInfo,
......@@ -1069,6 +1343,9 @@ function mapStateToProps(state) {
repeatStudentShow,
queryRepeatStudentsLoading,
repeatStudentList,
deleteVisible,
historyStudentLoading,
deleteOneVisible,
};
}
export default connect(mapStateToProps)(ForgotPassword);
......
......@@ -202,3 +202,147 @@
float: left;
}
}
.tabFlex {
display: flex;
align-items: center;
margin-left: 35px;
margin-top: 20px;
.tabItem {
font-size:16px;
font-family:PingFang SC;
font-weight:400;
color:rgba(128,128,128,1);
cursor: pointer;
height: 40px;
line-height: 40px;
}
.tabActive {
font-size:16px;
font-family:PingFang SC;
font-weight:400;
color:rgba(33,148,255,1);
position: relative;
cursor: pointer;
&:after {
position: absolute;
content: '';
display: block;
width: 70%;
height: 2px;
left: 10%;
bottom: -10px;
background-color: #4DA1FF;
}
}
}
.deleteModal {
:global {
.ant-modal-close {
right: -80px;
top: -25px;
.ant-modal-close-x {
font-size: 30px;
}
}
}
}
.modalHead {
.tabItem {
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
font-size: 16px;
}
.tabTip {
font-size: 12px;
color: rgba(0,0,0,0.5);
}
.tabTip1 {
font-size: 12px;
color: rgba(0,0,0,0.5);
}
:global {
.ant-tabs {
color: #000;
}
.ant-tabs-bar {
margin: 0;
}
.ant-tabs-nav{
//margin: 0 100px 0 0;
.ant-tabs-tab:first-child {
margin-right: 100px;
}
}
.ant-tabs-tab:nth-child(2):hover {
color: #FF4242;
}
.ant-tabs-tab:nth-child(2).ant-tabs-tab-active {
color: #FF4242;
}
}
}
.modalBody {
.commonTitle {
font-size:14px;
font-family:PingFang SC;
font-weight:500;
color:rgba(0,0,0,.85);
margin: 10px 0;
span {
color: #2194FF;
display: inline-block;
margin-left: 15px;
cursor: pointer;
}
}
p {
font-size:14px;
font-family:PingFang SC;
font-weight:500;
color:rgba(0,0,0,.5);
margin-bottom: 12px;
}
.radioOption {
display: flex;
align-items: flex-start;
margin: 20px 0 30px;
}
.commonNotice {
font-size:14px;
font-family:PingFang SC;
font-weight:500;
color:rgba(0,0,0,1);
margin: 60px 0;
span {
font-size: 12px;
color: #FF4242;
display: inline-block;
width: 35px;
height: 17px;
border: 1px solid #FF4242;
background-color: rgba(255,75,105,0.1);
line-height: 17px;
border-radius: 4px;
text-align: center;
margin-right: 10px;
}
}
}
.modalFooter {
text-align: center;
.commonInput {
margin: 0 auto;
margin-bottom: 20px;
border: 1px solid #FF4242;
width: 252px;
display: block;
}
:global {
.ant-input:focus {
border-color:#FF4242;
box-shadow: 0 0 0 2px rgba(255, 66, 66, .2);
}
}
}
......@@ -872,6 +872,10 @@ class StudentMgt extends React.Component {
return <div className={pageStyle.logitem}>{item.created_at} 老师:<span className={pageStyle.logTeacherName}>{item.data.teacher_name || '-'}</span> 为学员:<span className={pageStyle.logTeacherName}>{item.data.student_name || '-'}</span> <span className={pageStyle.logAction}>消除课时</span>:{item.data.expend || '-'}{item.data.mode_type == 2 && '天'} (<span className={pageStyle.logTeacherName}>{item.data.course_title || '-'}</span> )</div>;
case 10:
return <div className={pageStyle.logitem}>{item.created_at} 老师:<span className={pageStyle.logTeacherName}>{item.data.teacher_name || '-'}</span> <span className={pageStyle.logAction}>点名学员</span><span className={pageStyle.logTeacherName}>{item.data.student_name || '-'}</span> 状态: <span className={pageStyle.logAction}>{item.data.type == 1 && '到课'}{item.data.type == 3 && '请假'}{item.data.type == 2 && '迟到'}{item.data.type == 4 && '未到'}</span> {item.data.course_mode == 1 && `扣除课时${item.data.expend}课时`}</div>;
case 11:
return <div className={pageStyle.logitem}> {item.created_at} 老师:<span className={pageStyle.logTeacherName}>{item.data.teacher_name || '-'}</span> 为学员:<span className={pageStyle.logTeacherName}>{item.data.student_name || '-'}</span>转为<span className={pageStyle.logAction}>历史在读学员</span> &nbsp;并清除<span className={pageStyle.logTeacherName}>{item.data.student_name || '-'}</span>在机构中的历史课程数据</div>;
case 12:
return <div className={pageStyle.logitem}> {item.created_at} 老师:<span className={pageStyle.logTeacherName}>{item.data.teacher_name || '-'}</span> 为学员:<span className={pageStyle.logTeacherName}>{item.data.student_name || '-'}</span>转为<span className={pageStyle.logAction}>在读学员</span></div>;
default: return null;
}
})()}
......
......@@ -111,3 +111,19 @@ export function studentAdjust(params) {
data,
});
}
export function wxConfig(params) {
const data = qs.stringify(params);
return request({
url: `${api.classMgt.wxConfig}`,
method: 'POST',
data,
});
}
export function GetWxConfig(params) {
const data = qs.stringify(params);
return request({
url: `${api.classMgt.wxConfig}?${data}`,
method: 'GET',
data,
});
}
......@@ -80,3 +80,19 @@ export function createSchoolUuid(params) {
method: 'GET',
});
}
export function studentsDelete(parmas) {
const data = qs.stringify(parmas);
return request({
url: `${api.students.studentsinfo}?${data}`,
method: 'DELETE',
data,
});
}
export function studentsHistory(parmas) {
const data = qs.stringify(parmas);
return request({
url: `${api.students.studentHistory}?${data}`,
method: 'DELETE',
data,
});
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment