会员卡办理、预约基础内容完成

master
xiaoning 3 weeks ago
parent af73845fe9
commit f72f6ac234

@ -7,7 +7,15 @@ export function listTeacher(query) {
method: 'get', method: 'get',
params: query params: query
}) })
}export function getUserForTeacher(query) { }
export function teacherSelect(query) {
return request({
url: '/system/teacher/teacherSelect',
method: 'get',
params: query
})
}
export function getUserForTeacher(query) {
return request({ return request({
url: '/system/teacher/getUserForTeacher', url: '/system/teacher/getUserForTeacher',
method: 'get', method: 'get',

@ -1,6 +1,6 @@
import request from '@/utils/request' import request from '@/utils/request'
// 某课程 学到期日 // 某课程 学到期日
export function stuCourseDateAccountList(query) { export function stuCourseDateAccountList(query) {
return request({ return request({
url: '/api/sc/accountDate/list/stuCourseDateAccountList', url: '/api/sc/accountDate/list/stuCourseDateAccountList',
@ -27,7 +27,7 @@ export function renew(data) {
}) })
} }
// 获取各学每周期费用 // 获取各学每周期费用
export function claStudentChargeList(query) { export function claStudentChargeList(query) {
return request({ return request({
url: '/api/sc/accountDate/list/claStudentChargeList', url: '/api/sc/accountDate/list/claStudentChargeList',

@ -1,6 +1,6 @@
import request from '@/utils/request' import request from '@/utils/request'
// 某课程 学到期日 // 某课程 学到期日
export function stuCourseHourAccountList(query) { export function stuCourseHourAccountList(query) {
return request({ return request({
url: '/api/sc/accountHour/list/stuCourseHourAccountList', url: '/api/sc/accountHour/list/stuCourseHourAccountList',
@ -18,7 +18,7 @@ export function hourPay(data) {
}) })
} }
// 获取各学费用,剩余课时 // 获取各学费用,剩余课时
export function claStudentChargeList(query) { export function claStudentChargeList(query) {
return request({ return request({
url: '/api/sc/accountHour/list/claStudentChargeList', url: '/api/sc/accountHour/list/claStudentChargeList',

@ -1,6 +1,6 @@
import request from '@/utils/request' import request from '@/utils/request'
// 某课程 学到期日 // 某课程 学到期日
export function stuCourseDateAccountList(query) { export function stuCourseDateAccountList(query) {
return request({ return request({
url: '/api/sc/account/list/stuCourseDateAccountList', url: '/api/sc/account/list/stuCourseDateAccountList',

@ -1,54 +0,0 @@
import request from '@/utils/request'
// 新增班级学员
export function addClaStu(data) {
return request({
url: '/api/sc/course/cla/stu/add/addScCourseClaStu',
method: 'post',
data: data
})
}
// 新增学员班级
export function addStuCla(data) {
return request({
url: '/api/sc/course/cla/stu/add/addScCourseStuCla',
method: 'post',
data: data
})
}
// 删除班级学员
export function delClaStu(studentIds, claId) {
return request({
url: '/api/sc/course/cla/stu/delete/deleteById/' + studentIds + '/' + claId,
method: 'delete'
})
}
// 删除学员班级
export function delStuCla(claIds, studentId) {
return request({
url: '/api/sc/course/cla/stu/delete/deleteStuCla/' + claIds + '/' + studentId,
method: 'delete'
})
}
// 删除
export function claStuChargeInfo(query) {
return request({
url: '/api/sc/course/cla/stu/info/claStuChargeInfo',
method: 'get',
params: query
})
}
// 修改资费
export function updateClaStuCharge(data) {
return request({
url: '/apisc/course/cla/stu/update/claStuCharge',
method: 'put',
data: data
})
}

@ -9,6 +9,14 @@ export function searchListForCalendar(query) {
}) })
} }
export function searchListForCalendarByMemberId(query) {
return request({
url: '/api/sc/cla/time/list/searchListForCalendarByMemberId',
method: 'get',
params: query
})
}
// 获取最近几天的排课日程 // 获取最近几天的排课日程
export function searchRecentDayTimeList(query) { export function searchRecentDayTimeList(query) {
return request({ return request({
@ -61,19 +69,12 @@ export function delTime(courseTimeId) {
}) })
} }
// 变更 已记上课 信息 // 上课
export function changeHadClaTimeAttend(data) { export function confirmCla(data) {
return request({ return request({
url: '/api/sc/cla/time/update/changeHadClaTimeAttend', url: '/api/sc/cla/time/update/confirmCla',
method: 'post', method: 'post',
data: data data: data
}) })
} }
// 删除已上课
export function deleteHadClaTimeAttend(courseTimeId) {
return request({
url: '/api/sc/cla/time/delete/deleteHadClaTimeAttend/' + courseTimeId,
method: 'delete'
})
}

@ -51,37 +51,13 @@ export function delCla(claId) {
}) })
} }
// 导出
export function exportCla(query) {
return request({
url: '/api/sc/course/cla/export',
method: 'get',
params: query
})
}
// 班级学生信息 // 课程 预约学员列表
export function claStudentList(query) { export function searchCourseClaStudent(query) {
return request({ return request({
url: '/api/sc/course/cla/list/claStudentList', url: '/api/sc/course/cla/list/searchCourseClaStudent',
method: 'get', method: 'get',
params: query params: query
}) })
} }
// 学生班级信息
export function studentClaList(query) {
return request({
url: '/api/sc/course/cla/list/studentClaList',
method: 'get',
params: query
})
}
// 班级账户类型
export function claAccountType(claId) {
return request({
url: '/api/sc/course/cla/info/claAccountType/' + claId,
method: 'get'
})
}

@ -18,6 +18,21 @@ export function select(query) {
}) })
} }
export function selectForCheckbox() {
return request({
url: '/api/sc/course/type/list/selectForCheckbox',
method: 'get'
})
}
export function selectByTypeIds(query) {
return request({
url: '/api/sc/course/type/list/selectByTypeIds',
method: 'get',
params: query
})
}
// 查询详细 // 查询详细
export function getType(courseTypeId) { export function getType(courseTypeId) {
return request({ return request({
@ -60,3 +75,15 @@ export function exportType(query) {
params: query params: query
}) })
} }
// 是否开售
export function changeCourseTypeSale(courseTypeId, inUse) {
return request({
url: '/api/sc/course/type/changeCourseTypeSale',
method: 'put',
data: {
courseTypeId,
inUse
}
})
}

@ -9,14 +9,6 @@ export function listCourse(query) {
}) })
} }
// 查询列表 (含有学生报读状态)
export function selectCourseListWithStudentCourse(query) {
return request({
url: '/api/sc/course/list/selectCourseListWithStudentCourse',
method: 'get',
params: query
})
}
// select // select
export function select() { export function select() {
@ -60,14 +52,7 @@ export function delCourse(courseId) {
}) })
} }
// 导出
export function exportCourse(query) {
return request({
url: '/api/sc/course/export/exportCourse',
method: 'get',
params: query
})
}
// 是否开售 // 是否开售
export function changeCourseSale(courseId, sale) { export function changeCourseSale(courseId, sale) {
@ -81,20 +66,4 @@ export function changeCourseSale(courseId, sale) {
}) })
} }
// 报名 已选择课程详情
export function orderCourseDetail(query) {
return request({
url: '/api/sc/course/info/orderCourseDetail',
method: 'get',
params: query
})
}
// 学生是否可报读课程
export function studentCanSignUpCourse(query) {
return request({
url: '/api/sc/course/info/studentCanSignUpCourse',
method: 'get',
params: query
})
}

@ -0,0 +1,136 @@
import request from '@/utils/request'
/**
* 会员卡办理API
*/
export default {
// 办理新会员卡
createMemberCard(data) {
return request({
url: '/api/sc/memberCard/create',
method: 'post',
data
})
},
checkIn(data) {
return request({
url: `/api/sc/memberCard/checkIn`,
method: 'post',
data
})
},
// 根据ID查询会员卡
getCardById(id) {
return request({
url: `/api/sc/memberCard/${id}`,
method: 'get'
})
},
// 根据卡号查询会员卡
getCardByNo(cardNo) {
return request({
url: `/api/sc/memberCard/no/${cardNo}`,
method: 'get'
})
},
// 激活会员卡
activateCard(cardId) {
return request({
url: `/api/sc/memberCard/activate/${cardId}`,
method: 'post'
})
},
// 暂停会员卡
suspendCard(cardId) {
return request({
url: `/api/sc/memberCard/suspend/${cardId}`,
method: 'post'
})
},
// 续费会员卡
renewCard(data) {
return request({
url: '/api/sc/memberCard/renew',
method: 'post',
data
})
},
// 增加次数
addCardCount(cardId, count) {
return request({
url: '/api/sc/memberCard/add-count',
method: 'post',
params: { cardId, count }
})
},
// 扣减次数
deductCardCount(cardId, count) {
return request({
url: '/api/sc/memberCard/deduct-count',
method: 'post',
params: { cardId, count }
})
},
// 查询会员的会员卡列表
getMemberCards(memberId) {
return request({
url: `/api/sc/memberCard/member/${memberId}`,
method: 'get'
})
},
// 分页查询会员卡列表
getCardList(params) {
return request({
url: '/api/sc/memberCard/list',
method: 'post',
data: params
})
},
// 查询有效的会员卡
getValidMemberCards(memberId) {
return request({
url: `/api/sc/memberCard/valid/${memberId}`,
method: 'get'
})
},
// 检查会员卡状态
checkCardStatus(cardId) {
return request({
url: `/api/sc/memberCard/check-status/${cardId}`,
method: 'post'
})
},
// 删除会员卡
deleteCard(id) {
return request({
url: `/api/sc/memberCard/${id}`,
method: 'delete'
})
},
// 获取会员卡统计信息
getCardStatistics(memberId) {
return request({
url: `/api/sc/memberCard/statistics/${memberId}`,
method: 'get'
})
},
getTodayCardCount() {
return request({
url: `/api/sc/memberCard/todayCardCount`,
method: 'get'
})
},
}

@ -0,0 +1,70 @@
import request from '@/utils/request'
// 查询列表
export function listMemberCard(query) {
return request({
url: '/api/sc/memberCardTypes/list/searchList',
method: 'get',
params: query
})
}
// select
export function select(query) {
return request({
url: '/api/sc/memberCardTypes/list/select',
method: 'get',
params: query
})
}
// 查询详细
export function getMemberCard(cardId) {
return request({
url: '/api/sc/memberCardTypes/info/detailById/' + cardId,
method: 'get'
})
}
// 新增
export function addMemberCard(data) {
return request({
url: '/api/sc/memberCardTypes/add/memberCardTypes',
method: 'post',
data: data
})
}
// 修改
export function updateMemberCard(data) {
return request({
url: '/api/sc/memberCardTypes/update/updateMemberCardTypes',
method: 'put',
data: data
})
}export function editSale(data) {
return request({
url: '/api/sc/memberCardTypes/update/editSale',
method: 'put',
data: data
})
}
// 删除
export function delMemberCard(cardIds) {
return request({
url: '/api/sc/memberCardTypes/delete/deleteById/' + cardIds,
method: 'delete'
})
}
export function orderCardTypeDetail(query) {
return request({
url: '/api/sc/memberCardTypes/info/orderCardTypeDetail',
method: 'get',
params: query
})
}

@ -1,21 +1,7 @@
import request from '@/utils/request' import request from '@/utils/request'
// 查询列表
export function studentCourseInfo(studentId) {
return request({
url: '/api/sc/studentCourse/info/studentCourseInfo/' + studentId,
method: 'get'
})
}
// 班级课程 人员列表
export function searchCourseClaStudent(query) {
return request({
url: '/api/sc/studentCourse/list/searchCourseClaStudent',
method: 'get',
params: query
})
}
// 未选班 选班 // 未选班 选班
export function studentCourseChooseCla(data) { export function studentCourseChooseCla(data) {
@ -26,14 +12,6 @@ export function studentCourseChooseCla(data) {
}) })
} }
// 记上课
export function claTimeAttend(data) {
return request({
url: '/api/sc/studentCourse/update/claTimeAttend',
method: 'post',
data: data
})
}
// 停课 // 停课
export function stopStudentCourseStatus(studentCourseId) { export function stopStudentCourseStatus(studentCourseId) {
@ -51,7 +29,7 @@ export function atClaStudentCourseStatus(studentCourseId) {
}) })
} }
// 学报读课程列表 // 学报读课程列表
export function searchStudentCourse(query) { export function searchStudentCourse(query) {
return request({ return request({
url: '/api/sc/studentCourse/list/searchStudentCourse', url: '/api/sc/studentCourse/list/searchStudentCourse',

@ -4,99 +4,41 @@
diffNowDay: 排课记上课 可记间隔今天几天的排课 diffNowDay: 排课记上课 可记间隔今天几天的排课
appointClaTime: 选定排课 记上课 appointClaTime: 选定排课 记上课
appointCourseTimeId: 选定排课的 编号 appointCourseTimeId: 选定排课的 编号
needChooseCla: 是否需选择班级
--> -->
<template> <template>
<el-dialog :title="'记上课: ' + claInfo.claName + '(' + claInfo.deptName + ')'" :visible.sync="open" class="compact" width="850px"> <el-dialog title="记上课(记录实际上课信息)" :visible.sync="open" class="compact" width="850px">
<el-row v-loading="loadingClaDetail" class="cla-detail"> <el-row v-loading="loadingClaDetail" class="cla-detail">
<div v-if="needChooseCla" class="top-name" style="display: flex;justify-content: space-between;">
<div>
<label class="el-form-item__label required" style="width: 90px;">选择校区:</label>
<dept-select v-model="chooseDeptId" placeholder="选择校区" />
</div>
<div>
<label class="el-form-item__label required" style="width: 90px;">选择班级:</label>
<cla-select v-model="chooseClaId" :dept-id="chooseDeptId" @change="handleChooseCla" />
</div>
</div>
<div class="cla-base-info" style="border-bottom-width: 2px;"> <div class="cla-base-info" style="border-bottom-width: 2px;">
<div class="item" style="width: 100%;"> <div class="item">
<div class="item-name">上课方式:</div> <div class="item-name">校区:</div>
<div class="item-value"> <div class="item-value">{{ claInfo.deptName }}</div>
<el-radio-group v-model="form.attendType">
<el-radio
v-for="dict in claTimeAttendTypeOptions"
:key="dict.dictValue"
:disabled="appointClaTime"
:label="dict.dictValue"
>{{ dict.dictLabel }}</el-radio>
</el-radio-group>
</div>
</div> </div>
<div class="item"> <div class="item">
<div class="item-name">所属课程:</div> <div class="item-name">所属课程:</div>
<div class="item-value">{{ claCourseInfo.courseName }}</div> <div class="item-value">{{ claCourseInfo.courseName }}</div>
</div> </div>
<div v-if="form.attendType === 'rule'" class="item"> <div class="item">
<div class="item-name required">上课教师:</div> <div class="item-name">班级:</div>
<div class="item-value">{{ claTimeInfo.staffName }}</div> <div class="item-value">{{ claInfo.claName }}</div>
</div> </div>
<div v-else class="item">
<div class="item">
<div class="item-name required">上课教师:</div> <div class="item-name required">上课教师:</div>
<div class="item-value"> <div class="item-value">
<!-- <staff-select v-model="form.teacherId" teacher="1" placeholder="请选择上课教师" />--> <staff-select v-model="form.teacherId" :dept-id="claInfo.departId" placeholder="请选择上课教师" />
<el-select
v-model="form.teacherId"
filterable
allow-create
placeholder="选择上课教师"
clearable
default-first-option
>
<el-option
v-for="teacher in teacherOptions"
:key="teacher.userId"
:label="teacher.nickName"
:value="teacher.userId"
/>
</el-select>
</div> </div>
</div> </div>
<div v-if="form.attendType === 'rule'" class="item"> <div class="item">
<div class="item-name required">上课教室:</div> <div class="item-name required">上课教室:</div>
<div class="item-value">{{ claTimeInfo.roomName }}</div>
</div>
<div v-else class="item">
<div class="item-name">上课教室:</div>
<div class="item-value"> <div class="item-value">
<room-select v-model="form.roomId" :dept-id="claInfo.departId" placeholder="请选择上课教室" /> <room-select v-model="form.roomId" :dept-id="claInfo.departId" placeholder="请选择上课教室" />
</div> </div>
</div> </div>
<div v-if="form.attendType === 'rule'" class="item"> <div class="item">
<div class="item-name required">
<el-tooltip v-if="!appointClaTime" effect="dark" :content="'展示今天及前后'+(diffNowDay)+'天的计划排课日期'" placement="top">
<span>上课日期<svg-icon icon-class="question" />:</span>
</el-tooltip>
<span v-else>:</span>
</div>
<div class="item-value">
<cla-time-select
ref="claTimeSelect"
v-model="form.courseTimeId"
:cla-id="chooseClaId"
:diff-now-day="diffNowDay"
:appoint-cla-time="appointClaTime"
:appoint-course-time-id="appointCourseTimeId"
@change="handleClaDateChange"
@noPlan="handleNoPlanClaTime"
/>
</div>
</div>
<div v-else class="item">
<div class="item-name required">上课日期:</div> <div class="item-name required">上课日期:</div>
<div class="item-value"> <div class="item-value">
<el-date-picker <el-date-picker
v-model="form.claDate" v-model="form.realClaDate"
clearable clearable
size="small" size="small"
type="date" type="date"
@ -109,19 +51,16 @@
</div> </div>
<div class="item"> <div class="item">
<div class="item-name required"> <div class="item-name required">
<el-tooltip v-if="form.attendType === 'rule'" effect="dark" content="默认为计划上课时间,需填写实际上课时间" placement="top"> <span>上课时间:</span>
<span>上课时间<svg-icon icon-class="question" />:</span>
</el-tooltip>
<span v-else>:</span>
</div> </div>
<div class="item-value"> <div class="item-value">
<el-time-select <el-time-select
v-model="form.startTime" v-model="form.realStartTime"
size="small" size="small"
:picker-options="{ :picker-options="{
start: '08:00', start: '08:00',
step: '00:30', step: '00:01',
end: '19:00' end: '20:00'
}" }"
style="width: 135px;" style="width: 135px;"
placeholder="上课时间" placeholder="上课时间"
@ -130,18 +69,15 @@
</div> </div>
<div class="item"> <div class="item">
<div class="item-name required"> <div class="item-name required">
<el-tooltip v-if="form.attendType === 'rule'" effect="dark" content="默认为计划下课时间,需填写实际下课时间" placement="top"> <span>下课时间:</span>
<span>下课时间<svg-icon icon-class="question" />:</span>
</el-tooltip>
<span v-else>:</span>
</div> </div>
<div class="item-value"> <div class="item-value">
<el-time-select <el-time-select
v-model="form.endTime" v-model="form.realEndTime"
size="small" size="small"
:picker-options="{ :picker-options="{
start: '08:00', start: '08:00',
step: '00:30', step: '00:01',
end: '20:00' end: '20:00'
}" }"
style="width: 135px;" style="width: 135px;"
@ -150,107 +86,89 @@
</div> </div>
</div> </div>
<div class="item"> <div class="item">
<div class="item-name"> <div class="item-name required">上课主题:</div>
<span>备注:</span>
</div>
<div class="item-value">
<el-input v-model="form.memo" size="small" placeholder="备注" />
</div>
</div>
<div v-if="form.attendType === 'rule'" class="item">
<div class="item-name">上课主题:</div>
<div class="item-value"> <div class="item-value">
<el-input v-model="form.classTheme" size="small" placeholder="输入上课主题" /> <el-input v-model="form.classTheme" size="small" placeholder="输入上课主题" />
</div> </div>
</div> </div>
<div v-else class="item"> <div class="item">
<div class="item-name">上课主题:</div> <div class="item-name required">
<span>备注:</span>
</div>
<div class="item-value"> <div class="item-value">
<el-input v-model="form.classTheme" size="small" placeholder="输入上课主题" /> <el-input v-model="form.memo" size="small" placeholder="备注" />
</div> </div>
</div> </div>
<span style="color: #999; font-size: 12px; "> * 操作顺序 先为学员签到然后再上课上完的课程无法再为学员签到</span>
</div> </div>
</el-row> </el-row>
<el-row :gutter="10" class="mb8" style="margin-top: 10px;"> <el-row :gutter="10" class="mb8" style="margin-top: 10px;">
<el-col :span="1.5"> <el-col :span="1.5">
<el-button <el-button
type="info" type="primary"
icon="el-icon-collection" icon="el-icon-collection"
size="mini" size="mini"
@click="handleAutoDealStudentAttendStatusInfo('1')" @click="handleAutoDealStudentAttendStatusInfo()"
>全到课</el-button> >签到</el-button>
<el-button
type="info"
icon="el-icon-switch-button"
size="mini"
@click="handleAutoDealStudentAttendStatusInfo('3')"
>全缺勤</el-button>
</el-col> </el-col>
<span style="color: #999; font-size: 12px; "> * 说明会员签到的同时系统自动划扣会员卡内次数或金额 </span>
</el-row> </el-row>
<el-table ref="table" v-loading="loading" class="add-cla-time-attend-table" :data="dataList" @selection-change="handleSelectionChange">
<el-table ref="table" v-loading="loading" class="add-cla-time-attend-table" :height="500"
:data="claStudentList" >
<el-table-column type="selection" width="55" align="center" /> <el-table-column type="selection" width="55" align="center" />
<el-table-column align="center" prop="studentName" label="学生" fixed="left" /> <el-table-column align="center" prop="studentName" label="学员" fixed="left" />
<el-table-column align="center" prop="phone" label="是否到课" width="150" fixed="left"> <el-table-column align="center" prop="sex" label="性别" :formatter="sexFormatter" />
<el-table-column align="center" prop="phone" label="联系电话" width="120"/>
<el-table-column align="center" prop="bookStatus" label="预约状态" :formatter="bookStatusFormatter" width="100" />
<el-table-column align="center" prop="checkIn" label="是否签到" width="200" >
<template slot-scope="scope"> <template slot-scope="scope">
<el-radio-group v-model="studentAttendStatusForm[scope.row.studentCourseId].attendStatus" size="mini" @change="attendStatus => handleAttendStatusChange(attendStatus, scope.row)"> <el-radio-group v-model="scope.row.checkIn" >
<el-radio-button <el-radio :label="0">未签到</el-radio>
v-for="dict in attendStatusOptions" <el-radio :label="1">已签到</el-radio>
:key="dict.dictValue"
:label="dict.dictValue"
>{{ dict.dictLabel }}</el-radio-button>
</el-radio-group> </el-radio-group>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column align="center" label="扣减课时" width="100" fixed="left"> <el-table-column align="center" prop="cardNo" label="会员卡号" width="100" />
<template slot-scope="scope"> <el-table-column align="center" prop="cardTypeName" label="卡项名称" width="100" />
<el-input-number <el-table-column align="center" prop="remainingCount" label="会员卡余次" width="100" />
v-model="studentAttendStatusForm[scope.row.studentCourseId].stuLoseHour" <el-table-column align="center" prop="remainingTotalFee" label="会员卡余额" width="100" />
:disabled="studentAttendStatusForm[scope.row.studentCourseId].disable" <el-table-column align="center" prop="expiryDate" label="会员卡到期日" width="100" />
style="width: 80px" <el-table-column align="center" prop="chargeType" label="收费方式">
controls-position="right"
:min="0"
/>
</template>
</el-table-column>
<el-table-column align="center" prop="sex" label="性别" :formatter="sexFormatter" />
<el-table-column align="center" prop="phone" label="联系电话" width="120">
<template slot-scope="scope"> <template slot-scope="scope">
<el-tooltip effect="dark" :content="scope.row.contactInfo" placement="top"> <span>{{ chargeTypeFormatter(scope.row) }}</span>
<span>{{ scope.row.phone }}</span>
</el-tooltip>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column align="center" prop="status" label="状态" :formatter="studentCourseStatusFormatter" /> <el-table-column align="center" prop="deductCnt" label="划扣次数" width="100" />
<el-table-column align="center" prop="chargeType" label="收费方式"> <el-table-column align="center" prop="deductFee" label="划扣金额" width="100" />
<el-table-column align="center" prop="createTime" label="预约时间" width="100" />
<el-table-column align="center" prop="checkInTime" label="签到时间" width="100" />
<el-table-column align="center" prop="countBefore" label="划扣前次数" width="100" >
<template slot-scope="scope"> <template slot-scope="scope">
<span>{{ chargeTypeFormatter(scope.row) }}</span> <span>{{ scope.row.countBefore==null?'-':scope.row.countBefore}}</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column align="center" prop="chargeType" label="剩余课时/天" width="100"> <el-table-column align="center" prop="countAfter" label="划扣后次数" width="100" >
<template slot-scope="scope"> <template slot-scope="scope">
<span v-if="scope.row.chargeType === 'date'"> <span>{{ scope.row.countAfter==null?'-':scope.row.countAfter}}</span>
{{ scope.row.balanceDays }}
</span>
<span v-else>
<el-tooltip effect="dark" :content="'过期:' + scope.row.expireHour + '课时'" placement="top">
<span>{{ scope.row.balanceHour - scope.row.expireHour }}课时</span>
</el-tooltip>
</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column align="center" prop="status" label="最后续费时间" width="110"> <el-table-column align="center" prop="feeBefore" label="划扣前金额" width="100" >
<template slot-scope="scope"> <template slot-scope="scope">
<span>{{ parseTime(scope.row.lastSignTime, '{y}-{m}-{d}') }}</span> <span>{{ scope.row.feeBefore==null?'-':scope.row.feeBefore}}</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column align="center" label="备注" width="150"> <el-table-column align="center" prop="feeAfter" label="划扣后金额" width="100" >
<template slot-scope="scope"> <template slot-scope="scope">
<el-input v-model="studentAttendStatusForm[scope.row.studentCourseId].memo" size="small" placeholder="备注" /> <span>{{ scope.row.feeAfter==null?'-':scope.row.feeAfter}}</span>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
<div slot="footer" class="dialog-footer"> <div slot="footer" class="dialog-footer">
<el-button v-if="dataList.length > 0" :loading="loading" type="primary" @click="handleClaAttend"></el-button> <el-button v-if="claStudentList.length > 0" :loading="loading" type="primary" @click="handleClaAttend"></el-button>
<el-button @click="open = false"> </el-button> <el-button @click="open = false"> </el-button>
</div> </div>
</el-dialog> </el-dialog>
@ -264,9 +182,9 @@ import claSelect from '@/components/sc/course/cla/claSelect'
import deptSelect from '@/components/system/dept/deptSelect' import deptSelect from '@/components/system/dept/deptSelect'
import { allDetailInfoById } from '@/api/school/sc/cla' import { allDetailInfoById } from '@/api/school/sc/cla'
import moment from 'moment' import moment from 'moment'
import { searchCourseClaStudent } from '@/api/school/sc/student/course' import { searchCourseClaStudent } from '@/api/school/sc/cla/index'
import { claTimeAttend } from '@/api/school/sc/student/course' import {claTimeInfo as loadClaTimeInfo,confirmCla} from "@/api/school/sc/cla/claTime";
import {select as teacherSelect} from "@/api/school/system/staff"; import memberCardApi from "@/api/school/sc/memberCard";
export default { export default {
components: { components: {
staffSelect, staffSelect,
@ -296,11 +214,6 @@ export default {
type: String, type: String,
default: undefined default: undefined
}, },
//
needChooseCla: {
type: Boolean,
default: false
}
}, },
data() { data() {
return { return {
@ -315,25 +228,18 @@ export default {
// //
claTimeInfo: {}, claTimeInfo: {},
form: { form: {
attendType: 'rule',
deptId: undefined, deptId: undefined,
claId: undefined, claId: undefined,
claDate: '', realClaDate: '',
startTime: '', realStartTime: '',
endTime: '', realEndTime: '',
teacherId: undefined, teacherId: undefined,
roomId: undefined, roomId: undefined,
classTheme: undefined classTheme: undefined,
memo:""
}, },
teacherOptions:[],
//
claTimeAttendTypeOptions: [{
dictValue: 'rule',
dictLabel: '排课记上课'
}, {
dictValue: 'custom',
dictLabel: '自定义上课'
}],
// //
beginDatePickerOptions: { beginDatePickerOptions: {
disabledDate(time) { disabledDate(time) {
@ -341,105 +247,43 @@ export default {
} }
}, },
dataList: [], dataList: [],
queryParams: {
pageNum: 1,
pageSize: 200,
claId: this.chooseClaId,
effect: true
},
studentCourseStatusOptions: [],
chargeTypeOptions: [], chargeTypeOptions: [],
sexOptions: [], sexOptions: [],
// //
chooseStudentCourseIds: [], chooseStudentCourseIds: [],
// //
attendStatusOptions: [],
//
studentAttendStatusForm: {}, studentAttendStatusForm: {},
// //
chooseDeptId: undefined, chooseDeptId: undefined,
// chooseBookIds:[]
chooseClaId: undefined
} }
}, },
computed: { computed: {
}, },
watch: { watch: {
claId: {
handler(newValue) {
this.chooseClaId = newValue
},
immediate: true
},
chooseClaId: {
handler(newValue) {
this.queryParams.claId = newValue
},
immediate: true
},
open: { open: {
handler(newValue) { handler(newValue) {
if (newValue === true) { if (newValue === true) {
this.resetData() this.resetData()
if (this.appointClaTime === false && this.needChooseCla === false && this.claId) {
//
this.loadClaInfo() this.loadClaInfo()
} }
if (this.needChooseCla === false) {
//
this.$nextTick(() => {
this.$refs.claTimeSelect.loadRecentDayTime()
})
}
}
},
immediate: true
},
//
appointClaTime: {
handler(newValue) {
if (newValue === true) {
this.form.attendType = 'rule'
} else {
this.form.attendType = 'custom'
}
}, },
immediate: true immediate: true
}, },
//
needChooseCla: {
handler(newValue) {
if (newValue === true) {
this.form.attendType = 'custom'
} else {
this.form.attendType = 'rule'
}
},
immediate: true
}
}, },
created() { created() {
this.getDictListByDictType('student_course_status').then(response => {
this.studentCourseStatusOptions = response.data
})
this.getDictListByDictType('charge_type').then(response => { this.getDictListByDictType('charge_type').then(response => {
this.chargeTypeOptions = response.data this.chargeTypeOptions = response.data
}) })
this.getDictListByDictType('sys_user_sex').then(response => { this.getDictListByDictType('sys_user_sex').then(response => {
this.sexOptions = response.data this.sexOptions = response.data
}) })
this.getDictListByDictType('attend_status').then(response => { this.getDictListByDictType('book_status').then(response => {
this.attendStatusOptions = response.data this.bookStatusOptions = response.data
}) })
this.getTeacherOptions()
}, },
methods: { methods: {
getTeacherOptions() {
teacherSelect().then(response => {
this.teacherOptions = response.data
})
},
resetData() { resetData() {
this.claInfo = { this.claInfo = {
claName: '', claName: '',
@ -451,16 +295,16 @@ export default {
} }
this.dataList = [] this.dataList = []
if (this.needChooseCla) {
//
this.chooseDeptId = undefined
this.chooseClaId = undefined
}
}, },
loadClaInfo() { loadClaInfo() {
if (this.chooseClaId) { if (this.claId) {
this.loadingClaDetail = true this.loadingClaDetail = true
allDetailInfoById(this.chooseClaId).then(response => { loadClaTimeInfo(this.appointCourseTimeId).then(response => {
this.claTimeInfo = response.data
//
this.autoSetFormByClaTimeInfo()
return allDetailInfoById(this.claId)
}).then(response => {
this.loadingClaDetail = false this.loadingClaDetail = false
this.claInfo = response.data.courseCla this.claInfo = response.data.courseCla
this.claCourseInfo = response.data.course this.claCourseInfo = response.data.course
@ -470,11 +314,22 @@ export default {
}) })
} }
}, },
//
autoSetFormByClaTimeInfo() {
this.form.teacherId = this.claTimeInfo.teacherId
this.form.roomId = this.claTimeInfo.roomId
this.form.realClaDate = this.claTimeInfo.claDate
this.form.realStartTime = this.claTimeInfo.startTime.substr(0, 5)
this.form.realEndTime = this.claTimeInfo.endTime.substr(0, 5)
this.form.memo = this.claTimeInfo.memo
this.form.classTheme = this.claTimeInfo.classTheme
this.form.courseTimeId=this.appointCourseTimeId
},
// //
handleClaDateChange(claTimeInfo) { handleClaDateChange(claTimeInfo) {
this.claTimeInfo = claTimeInfo this.claTimeInfo = claTimeInfo
this.form.startTime = claTimeInfo.startTime.substr(0, 5) this.form.realStartTime = claTimeInfo.startTime.substr(0, 5)
this.form.endTime = claTimeInfo.endTime.substr(0, 5) this.form.realEndTime = claTimeInfo.endTime.substr(0, 5)
this.form.classTheme = claTimeInfo.classTheme this.form.classTheme = claTimeInfo.classTheme
// //
if (this.appointClaTime) { if (this.appointClaTime) {
@ -483,108 +338,118 @@ export default {
this.loadClaInfo() this.loadClaInfo()
} }
}, },
//
handleNoPlanClaTime() {
this.msgError('近日无计划排课,无法排课记上课')
},
sexFormatter(row, column) { sexFormatter(row, column) {
return selectDictLabel(this.sexOptions, row.sex) return selectDictLabel(this.sexOptions, row.sex)
}, },
chargeTypeFormatter(row, column) { chargeTypeFormatter(row, column) {
return selectDictLabel(this.chargeTypeOptions, row.chargeType) return selectDictLabel(this.chargeTypeOptions, row.chargeType)
}, },
studentCourseStatusFormatter(row, column) { bookStatusFormatter(row, column) {
return selectDictLabel(this.studentCourseStatusOptions, row.status) return selectDictLabel(this.bookStatusOptions, row.bookStatus)
}, },
getList() { getList() {
searchCourseClaStudent(this.queryParams).then(response => { this.loading = true
this.dataList = response.data.rows let claStudentList = []
searchCourseClaStudent({courseTimeId: this.appointCourseTimeId}).then(response => {
claStudentList = response.data
this.total = response.data.total this.total = response.data.total
this.claStudentList = claStudentList
this.loading = false this.loading = false
this.handleAutoDealStudentAttendStatusInfo('1')
}) })
}, },
//
handleAutoDealStudentAttendStatusInfo(attendStatus) { //
handleAutoDealStudentAttendStatusInfo() {
this.$nextTick(() => { this.$nextTick(() => {
this.chooseStudentCourseIds = [] this.claStudentList.forEach(row => {
this.dataList.forEach(row => { if ([0,1,2].includes(row.bookStatus)&&row.checkIn==0){
this.chooseStudentCourseIds.push(row.studentCourseId) //expiryDateb yyyy-MM-dd
if (row.expiryDate){
// 1. Dateyyyy-MM-ddUTC
const [year, month, day] = row.expiryDate.split('-').map(Number);
// 00=111=121
const expiryDate1 = new Date(year, month - 1, day);
// 2. 0
const today = new Date();
const todayStart = new Date(today.getFullYear(), today.getMonth(), today.getDate());
// 3.
if (expiryDate1.getTime() < todayStart.getTime()){
this.msgError('学员:'+row.studentName+'的会员卡已过期,无法使用!')
return ;
}
}
// remainingCount deductCnt remainingTotalFee deductFee
if (row.chargeType=='count'&&row.remainingCount<row.deductCnt){
this.msgError('学员:'+row.studentName+'的会员卡余次不足,无法使用!')
return ;
}
if (row.chargeType=='total_fee'&&row.remainingTotalFee<row.deductFee){
this.msgError('学员:'+row.studentName+'的会员卡余额不足,无法使用!')
return ;
}
this.chooseBookIds.push(row.bookId)
this.$refs.table.toggleRowSelection(row, true) this.$refs.table.toggleRowSelection(row, true)
}
}) })
}) if (this.chooseBookIds==null || this.chooseBookIds.length<1){
this.dataList.forEach(item => { this.msgError('没有可以满足签到条件的学员!')
this.$set(this.studentAttendStatusForm, item.studentCourseId, { this.$refs.table.clearSelection();
attendStatus: attendStatus, return ;
memo: '', }
stuLoseHour: item.chargeType === 'date' ? 0 : (this.form.attendType === 'rule' ? this.claTimeInfo.payHour : this.claInfo.everyStuLoseHour), // this.chooseBookIds
disable: item.chargeType === 'date' memberCardApi.checkIn({bookIds:this.chooseBookIds}).then(response => {
if (response.success){
this.msgSuccess('签到成功')
this.getList()
}else {
this.msgError(response.respMsg)
}
this.loading = false
}).catch(() => {
this.loading = false
}) })
}) })
}, },
// // /
handleClaAttend() { handleClaAttend() {
console.log('上课') console.log('上课')
if (this.form.attendType === 'custom') {
// //
if (this.form.teacherId === undefined || this.form.teacherId === '' || this.form.teacherId === null) { if (this.form.teacherId === undefined || this.form.teacherId === '' || this.form.teacherId === null) {
this.msgError('请选择上课教师') this.msgError('请选择上课教师')
return return
} else if (this.form.claDate === undefined || this.form.claDate === '' || this.form.claDate === null) { } else if (this.form.realClaDate === undefined || this.form.realClaDate === '' || this.form.realClaDate === null) {
this.msgError('请选择上课日期') this.msgError('请选择上课日期')
return return
} else if (this.form.startTime === undefined || this.form.startTime === '' || this.form.startTime === null) { } else if (this.form.realStartTime === undefined || this.form.realStartTime === '' || this.form.realStartTime === null) {
this.msgError('请选择上上课时间') this.msgError('请选择上课时间')
return return
} else if (this.form.endTime === undefined || this.form.endTime === '' || this.form.endTime === null) { } else if (this.form.realEndTime === undefined || this.form.realEndTime === '' || this.form.realEndTime === null) {
this.msgError('请选择下课时间') this.msgError('请选择下课时间')
return return
} }
} else if (this.form.attendType === 'rule') {
if (this.form.courseTimeId === undefined || this.form.courseTimeId === '' || this.form.courseTimeId === null) { if (this.form.courseTimeId === undefined || this.form.courseTimeId === '' || this.form.courseTimeId === null) {
this.msgError('请选择上课日期') this.msgError('页面数据错误,请刷新重试!')
return return
} }
}
let checkResult = true
const studentAttendList = [] const studentAttendList = []
try {
this.dataList.forEach(item => {
if (this.chooseStudentCourseIds.indexOf(item.studentCourseId) !== -1) {
if (item.chargeType !== 'date') {
const balanceHour = item.balanceHour - item.expireHour
if (balanceHour < this.studentAttendStatusForm[item.studentCourseId].stuLoseHour) {
this.msgError(item.studentName + ',课时不足,无法上课!')
checkResult = false
throw new Error('课时不足,无法上课!')
}
}
studentAttendList.push({
attendStatus: this.studentAttendStatusForm[item.studentCourseId].attendStatus,
studentCourseId: item.studentCourseId,
memo: this.studentAttendStatusForm[item.studentCourseId].memo,
stuLoseHour: this.studentAttendStatusForm[item.studentCourseId].stuLoseHour
})
}
})
} catch (e) {
console.log('balance hour error')
}
if (!checkResult) {
return this.form.claId = this.claId
}
this.form.studentAttendList = studentAttendList
this.form.claId = this.chooseClaId
this.loading = true this.loading = true
claTimeAttend(this.form).then(response => { confirmCla(this.form).then(response => {
this.loading = false this.loading = false
if (response.respCode === '0000') { if (response.respCode === '0000') {
this.$emit('success') this.$emit('success')
this.open = false this.open = false
this.msgSuccess('记上课成功') this.msgSuccess('记上课成功')
} else { } else {
this.msgError(response.respMsg) this.msgError(response.msgDetail)
} }
}).catch(() => { }).catch(() => {
this.loading = false this.loading = false
@ -604,12 +469,6 @@ export default {
} }
} }
}, },
//
handleChooseCla(claId) {
this.chooseClaId = claId
this.loadClaInfo()
this.getList()
}
} }
} }
</script> </script>

@ -1,16 +1,24 @@
<!-- 修改上课 --> <!-- 修改上课 -->
<template> <template>
<el-dialog :title="'修改上课记录: ' + claInfo.claName + '(' + claInfo.deptName + ')'" :visible.sync="open" class="compact" width="850px"> <el-dialog title='上课记录详情' :visible.sync="open" class="compact" width="1000px" >
<el-row v-loading="loadingClaDetail" class="cla-detail"> <el-row v-loading="loadingClaDetail" class="cla-detail">
<div class="cla-base-info" style="border-bottom-width: 2px;"> <div class="cla-base-info" style="border-bottom-width: 2px;">
<div class="item">
<div class="item-name">校区:</div>
<div class="item-value">{{ claInfo.deptName }}</div>
</div>
<div class="item"> <div class="item">
<div class="item-name">所属课程:</div> <div class="item-name">所属课程:</div>
<div class="item-value">{{ claCourseInfo.courseName }}</div> <div class="item-value">{{ claCourseInfo.courseName }}</div>
</div> </div>
<div class="item">
<div class="item-name">班级:</div>
<div class="item-value">{{ claInfo.claName }}</div>
</div>
<div class="item"> <div class="item">
<div class="item-name required">上课教师:</div> <div class="item-name required">上课教师:</div>
<div class="item-value"> <div class="item-value">
<staff-select v-model="form.teacherId" teacher="1" placeholder="请选择上课教师" /> <staff-select v-model="form.teacherId" :dept-id="claInfo.departId" placeholder="请选择上课教师" />
</div> </div>
</div> </div>
<div class="item"> <div class="item">
@ -44,8 +52,8 @@
size="small" size="small"
:picker-options="{ :picker-options="{
start: '08:00', start: '08:00',
step: '00:30', step: '00:01',
end: '19:00' end: '20:00'
}" }"
style="width: 135px;" style="width: 135px;"
placeholder="上课时间" placeholder="上课时间"
@ -62,7 +70,7 @@
size="small" size="small"
:picker-options="{ :picker-options="{
start: '08:00', start: '08:00',
step: '00:30', step: '00:01',
end: '20:00' end: '20:00'
}" }"
style="width: 135px;" style="width: 135px;"
@ -71,103 +79,75 @@
</div> </div>
</div> </div>
<div class="item"> <div class="item">
<div class="item-name required"> <div class="item-name required">上课主题:</div>
<span>备注:</span>
</div>
<div class="item-value"> <div class="item-value">
<el-input v-model="form.memo" size="small" placeholder="备注" /> <el-input v-model="form.classTheme" size="small" placeholder="输入上课主题" />
</div> </div>
</div> </div>
<div class="item"> <div class="item">
<div class="item-name required">上课主题:</div> <div class="item-name required">
<span>备注:</span>
</div>
<div class="item-value"> <div class="item-value">
<el-input v-model="form.classTheme" size="small" placeholder="输入上课主题" /> <el-input v-model="form.memo" size="small" placeholder="备注" />
</div> </div>
</div> </div>
</div> </div>
</el-row> </el-row>
<el-row :gutter="10" class="mb8" style="margin-top: 10px;"> <el-row :gutter="10" class="mb8" style="margin-top: 10px;">
<el-col :span="1.5"> <span style="color: #999; font-size: 12px; "> * 说明会员签到的同时系统自动划扣会员卡内次数或金额 先签到后上课</span>
<el-button
type="info"
icon="el-icon-collection"
size="mini"
@click="handleAutoDealStudentAttendStatusInfo('1')"
>全到课</el-button>
<el-button
type="info"
icon="el-icon-switch-button"
size="mini"
@click="handleAutoDealStudentAttendStatusInfo('3')"
>全缺勤</el-button>
</el-col>
</el-row> </el-row>
<el-table ref="table" v-loading="loading" class="add-cla-time-attend-table" :data="claStudentList" @selection-change="handleSelectionChange"> <el-table ref="table" v-loading="loading" class="add-cla-time-attend-table" :height="500"
:data="claStudentList" >
<el-table-column type="selection" width="55" align="center" /> <el-table-column type="selection" width="55" align="center" />
<el-table-column align="center" prop="studentName" label="学生" fixed="left" /> <el-table-column align="center" prop="studentName" label="学员" fixed="left" />
<el-table-column align="center" prop="phone" label="是否到课" width="150" fixed="left"> <el-table-column align="center" prop="sex" label="性别" :formatter="sexFormatter" />
<el-table-column align="center" prop="phone" label="联系电话" width="120"/>
<el-table-column align="center" prop="bookStatus" label="预约状态" :formatter="bookStatusFormatter" width="100" />
<el-table-column align="center" prop="checkIn" label="是否签到" width="200" >
<template slot-scope="scope"> <template slot-scope="scope">
<el-radio-group v-model="studentAttendStatusForm[scope.row.studentCourseId].attendStatus" size="mini" @change="attendStatus => handleAttendStatusChange(attendStatus, scope.row)"> <el-radio-group v-model="scope.row.checkIn" >
<el-radio-button <el-radio :label="0">未签到</el-radio>
v-for="dict in attendStatusOptions" <el-radio :label="1">已签到</el-radio>
:key="dict.dictValue"
:label="dict.dictValue"
>{{ dict.dictLabel }}</el-radio-button>
</el-radio-group> </el-radio-group>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column align="center" label="扣减课时" width="100" fixed="left"> <el-table-column align="center" prop="cardNo" label="会员卡号" width="100" />
<template slot-scope="scope"> <el-table-column align="center" prop="cardTypeName" label="卡项名称" width="100" />
<el-input-number <el-table-column align="center" prop="remainingCount" label="会员卡余次" width="100" />
v-model="studentAttendStatusForm[scope.row.studentCourseId].stuLoseHour" <el-table-column align="center" prop="remainingTotalFee" label="会员卡余额" width="100" />
:disabled="studentAttendStatusForm[scope.row.studentCourseId].disable" <el-table-column align="center" prop="expiryDate" label="会员卡到期日" width="100" />
style="width: 80px" <el-table-column align="center" prop="chargeType" label="收费方式">
controls-position="right"
:min="0"
/>
</template>
</el-table-column>
<el-table-column align="center" prop="sex" label="性别" :formatter="sexFormatter" />
<el-table-column align="center" prop="phone" label="联系电话" width="120">
<template slot-scope="scope"> <template slot-scope="scope">
<el-tooltip effect="dark" :content="scope.row.contactInfo" placement="top"> <span>{{ chargeTypeFormatter(scope.row) }}</span>
<span>{{ scope.row.phone }}</span>
</el-tooltip>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column align="center" prop="status" label="状态" :formatter="studentCourseStatusFormatter" /> <el-table-column align="center" prop="deductCnt" label="划扣次数" width="100" />
<el-table-column align="center" prop="chargeType" label="收费方式"> <el-table-column align="center" prop="deductFee" label="划扣金额" width="100" />
<el-table-column align="center" prop="createTime" label="预约时间" width="100" />
<el-table-column align="center" prop="checkInTime" label="签到时间" width="100" />
<el-table-column align="center" prop="countBefore" label="划扣前次数" width="100" >
<template slot-scope="scope"> <template slot-scope="scope">
<span>{{ chargeTypeFormatter(scope.row) }}</span> <span>{{ scope.row.countBefore==null?'-':scope.row.countBefore}}</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column align="center" prop="chargeType" label="剩余课时/天" width="100"> <el-table-column align="center" prop="countAfter" label="划扣后次数" width="100" >
<template slot-scope="scope"> <template slot-scope="scope">
<span v-if="scope.row.chargeType === 'date'"> <span>{{ scope.row.countAfter==null?'-':scope.row.countAfter}}</span>
{{ scope.row.balanceDays }}
</span>
<span v-else>
<el-tooltip effect="dark" :content="'过期:' + scope.row.expireHour + '课时'" placement="top">
<span>{{ scope.row.balanceHour - scope.row.expireHour }}课时</span>
</el-tooltip>
</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column align="center" prop="status" label="最后续费时间" width="110"> <el-table-column align="center" prop="feeBefore" label="划扣前金额" width="100" >
<template slot-scope="scope"> <template slot-scope="scope">
<span>{{ parseTime(scope.row.lastSignTime, '{y}-{m}-{d}') }}</span> <span>{{ scope.row.feeBefore==null?'-':scope.row.feeBefore}}</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column align="center" label="备注" width="150"> <el-table-column align="center" prop="feeAfter" label="划扣后金额" width="100" >
<template slot-scope="scope"> <template slot-scope="scope">
<el-input v-model="studentAttendStatusForm[scope.row.studentCourseId].memo" size="small" placeholder="备注" /> <span>{{ scope.row.feeAfter==null?'-':scope.row.feeAfter}}</span>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
<div slot="footer" class="dialog-footer">
<el-button v-if="claStudentList.length > 0" :loading="loading" type="primary" @click="handleClaAttend"></el-button>
<el-button @click="open = false"> </el-button>
</div>
</el-dialog> </el-dialog>
</template> </template>
<script> <script>
@ -175,10 +155,9 @@ import { selectDictLabel } from '@/utils/commonUtils'
import staffSelect from '@/components/system/staff/staffSelect' import staffSelect from '@/components/system/staff/staffSelect'
import roomSelect from '@/components/sc/base/roomSelect' import roomSelect from '@/components/sc/base/roomSelect'
import { allDetailInfoById } from '@/api/school/sc/cla' import { allDetailInfoById } from '@/api/school/sc/cla'
import { claTimeInfo as loadClaTimeInfo, changeHadClaTimeAttend } from '@/api/school/sc/cla/claTime' import { claTimeInfo as loadClaTimeInfo, } from '@/api/school/sc/cla/claTime'
import { hadClaTimeAttendDetail } from '@/api/school/sc/cla/claTimeAttend'
import moment from 'moment' import moment from 'moment'
import { searchCourseClaStudent } from '@/api/school/sc/student/course' import { searchCourseClaStudent } from '@/api/school/sc/cla/index'
export default { export default {
components: { components: {
staffSelect, staffSelect,
@ -226,20 +205,20 @@ export default {
queryParams: { queryParams: {
pageNum: 1, pageNum: 1,
pageSize: 200, pageSize: 200,
claId: this.claId, courseTimeId: this.courseTimeId,
effect: true effect: true
}, },
studentCourseStatusOptions: [],
chargeTypeOptions: [], chargeTypeOptions: [],
sexOptions: [], sexOptions: [],
// //
chooseStudentCourseIds: [], chooseStudentCourseIds: [],
// //
attendStatusOptions: [], attendStatusOptions: [],
// //
studentAttendStatusForm: {}, studentAttendStatusForm: {},
// //
chooseBookIds:[],
claTimeAttendList: [] claTimeAttendList: []
} }
}, },
@ -254,12 +233,6 @@ export default {
} }
}, },
watch: { watch: {
claId: {
handler(newValue) {
this.queryParams.claId = newValue
},
immediate: true
},
open: { open: {
handler(newValue) { handler(newValue) {
if (newValue === true) { if (newValue === true) {
@ -271,17 +244,14 @@ export default {
} }
}, },
created() { created() {
this.getDictListByDictType('student_course_status').then(response => {
this.studentCourseStatusOptions = response.data
})
this.getDictListByDictType('charge_type').then(response => { this.getDictListByDictType('charge_type').then(response => {
this.chargeTypeOptions = response.data this.chargeTypeOptions = response.data
}) })
this.getDictListByDictType('sys_user_sex').then(response => { this.getDictListByDictType('sys_user_sex').then(response => {
this.sexOptions = response.data this.sexOptions = response.data
}) })
this.getDictListByDictType('attend_status').then(response => { this.getDictListByDictType('book_status').then(response => {
this.attendStatusOptions = response.data this.bookStatusOptions = response.data
}) })
}, },
methods: { methods: {
@ -301,7 +271,7 @@ export default {
}, },
// //
loadClaAndClaTimeInfo() { loadClaAndClaTimeInfo() {
if (this.claId) { if (this.courseTimeId) {
this.loadingClaDetail = true this.loadingClaDetail = true
loadClaTimeInfo(this.courseTimeId).then(response => { loadClaTimeInfo(this.courseTimeId).then(response => {
this.claTimeInfo = response.data this.claTimeInfo = response.data
@ -341,143 +311,22 @@ export default {
chargeTypeFormatter(row, column) { chargeTypeFormatter(row, column) {
return selectDictLabel(this.chargeTypeOptions, row.chargeType) return selectDictLabel(this.chargeTypeOptions, row.chargeType)
}, },
studentCourseStatusFormatter(row, column) { bookStatusFormatter(row, column) {
return selectDictLabel(this.studentCourseStatusOptions, row.status) return selectDictLabel(this.bookStatusOptions, row.bookStatus)
}, },
// , // ,
loadCourseClaStudentAndAttendDetail() { loadCourseClaStudentAndAttendDetail() {
this.loading = true this.loading = true
let claStudentList = [] let claStudentList = []
searchCourseClaStudent(this.queryParams).then(response => { searchCourseClaStudent({courseTimeId: this.courseTimeId}).then(response => {
claStudentList = response.data.rows claStudentList = response.data
this.total = response.data.total this.total = response.data.total
return hadClaTimeAttendDetail(this.courseTimeId)
}).then(response => {
this.claTimeAttendList = response.data
// studentAttendStatusForm
claStudentList.forEach(item => {
const itemObj = {}
if (this.claTimeAttendMap.hasOwnProperty(item.studentCourseId)) {
itemObj.attendStatus = this.claTimeAttendMap[item.studentCourseId].attendStatus
itemObj.memo = this.claTimeAttendMap[item.studentCourseId].memo
itemObj.stuLoseHour = this.claTimeAttendMap[item.studentCourseId].payHour
itemObj.disable = item.chargeType === 'date'
} else {
itemObj.attendStatus = '1'
itemObj.memo = ''
itemObj.stuLoseHour = item.chargeType === 'date' ? 0 : this.claInfo.everyStuLoseHour
itemObj.disable = item.chargeType === 'date'
}
this.$set(this.studentAttendStatusForm, item.studentCourseId, itemObj)
})
this.claStudentList = claStudentList this.claStudentList = claStudentList
//
this.$nextTick(() => {
this.claStudentList.forEach(item => {
if (this.claTimeAttendMap.hasOwnProperty(item.studentCourseId)) {
this.$refs.table.toggleRowSelection(item, true)
}
})
})
this.loading = false this.loading = false
}) })
}, },
//
handleAutoDealStudentAttendStatusInfo(attendStatus) {
this.$nextTick(() => {
this.chooseStudentCourseIds = []
this.claStudentList.forEach(row => {
this.chooseStudentCourseIds.push(row.studentCourseId)
this.$refs.table.toggleRowSelection(row, true)
})
})
this.claStudentList.forEach(item => {
this.$set(this.studentAttendStatusForm, item.studentCourseId, {
attendStatus: attendStatus,
memo: '',
stuLoseHour: item.chargeType === 'date' ? 0 : this.claInfo.everyStuLoseHour,
disable: item.chargeType === 'date'
})
})
},
//
handleClaAttend() {
//
if (this.form.teacherId === undefined || this.form.teacherId === '' || this.form.teacherId === null) {
this.msgError('请选择上课教师')
return
} else if (this.form.claDate === undefined || this.form.claDate === '' || this.form.claDate === null) {
this.msgError('请选择上课日期')
return
} else if (this.form.startTime === undefined || this.form.startTime === '' || this.form.startTime === null) {
this.msgError('请选择上上课时间')
return
} else if (this.form.endTime === undefined || this.form.endTime === '' || this.form.endTime === null) {
this.msgError('请选择上下课时间')
return
}
let checkResult = true
const studentAttendList = []
try {
this.claStudentList.forEach(item => {
if (this.chooseStudentCourseIds.indexOf(item.studentCourseId) !== -1) {
if (item.chargeType !== 'date') {
const balanceHour = item.balanceHour - item.expireHour
if (balanceHour < this.studentAttendStatusForm[item.studentCourseId].stuLoseHour) {
this.msgError(item.studentName + ',课时不足,无法上课!')
checkResult = false
throw new Error('课时不足,无法上课!')
}
}
studentAttendList.push({
attendStatus: this.studentAttendStatusForm[item.studentCourseId].attendStatus,
studentCourseId: item.studentCourseId,
memo: this.studentAttendStatusForm[item.studentCourseId].memo,
stuLoseHour: this.studentAttendStatusForm[item.studentCourseId].stuLoseHour
})
}
})
} catch (e) {
console.log('balance hour error')
}
if (!checkResult) {
return
}
this.form.studentAttendList = studentAttendList
this.form.claId = this.claId
this.form.courseTimeId = this.courseTimeId
this.form.attendType = 'change'
this.loading = true
changeHadClaTimeAttend(this.form).then(response => {
this.loading = false
if (response.respCode === '0000') {
this.$emit('success')
this.open = false
this.msgSuccess('修改成功')
} else {
this.msgError(response.respMsg)
}
}).catch(() => {
this.loading = false
})
},
handleSelectionChange(selection) {
this.chooseStudentCourseIds = selection.map(item => item.studentCourseId)
},
handleAttendStatusChange(attendStatus, row) {
if (row.chargeType !== 'date') {
if (attendStatus === '2') {
this.studentAttendStatusForm[row.studentCourseId].stuLoseHour = 0
this.studentAttendStatusForm[row.studentCourseId].disable = true
} else {
this.studentAttendStatusForm[row.studentCourseId].stuLoseHour = this.claInfo.everyStuLoseHour
this.studentAttendStatusForm[row.studentCourseId].disable = false
}
}
}
} }
} }
</script> </script>

@ -60,8 +60,8 @@
size="small" size="small"
:picker-options="{ :picker-options="{
start: '08:00', start: '08:00',
step: '00:30', step: '00:01',
end: '19:00' end: '20:00'
}" }"
placeholder="选择上课时间" placeholder="选择上课时间"
/> />
@ -74,7 +74,7 @@
size="small" size="small"
:picker-options="{ :picker-options="{
start: '08:00', start: '08:00',
step: '00:30', step: '00:01',
end: '20:00' end: '20:00'
}" }"
placeholder="选择下课时间" placeholder="选择下课时间"
@ -83,21 +83,7 @@
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="任课教师:" prop="teacherId"> <el-form-item label="任课教师:" prop="teacherId">
<el-select <staff-select v-model="form.teacherId" placeholder="请选择上课教师" />
v-model="form.teacherId"
filterable
allow-create
placeholder="选择上课教师"
clearable
default-first-option
>
<el-option
v-for="teacher in teacherOptions"
:key="teacher.userId"
:label="teacher.nickName"
:value="teacher.userId"
/>
</el-select>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">

@ -1,6 +1,6 @@
<template> <template>
<el-dialog :title="title" :visible.sync="open" width="600px"> <el-dialog :title="title" :visible.sync="open" width="700px">
<el-form ref="form" v-loading="loadingChange" class="add-form auto-width" :model="form" :rules="rules" label-width="90px"> <el-form ref="form" v-loading="loadingChange" class="add-form auto-width" :model="form" :rules="rules" label-width="120px">
<el-row> <el-row>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="校区:" prop="deptId"> <el-form-item label="校区:" prop="deptId">
@ -70,17 +70,7 @@
</el-checkbox-group> </el-checkbox-group>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="24" style="text-align: left">
<el-form-item label="节假日:">
<el-radio-group v-model="form.filterHoliday">
<el-radio
v-for="dict in filterHolidayOptions"
:key="dict.dictValue"
:label="dict.dictValue"
>{{ dict.dictLabel }}</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
</div> </div>
<div v-if="form.ruleType !== '1'"> <div v-if="form.ruleType !== '1'">
<el-col :span="24" style="text-align: left"> <el-col :span="24" style="text-align: left">
@ -98,54 +88,65 @@
</div> </div>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="上课时间:" prop="startTime"> <el-form-item label="上课时间:" prop="startTime">
<el-input v-model="form.startTime" size="small" placeholder="请输入上课时间" /> <el-time-select
v-model="form.startTime"
<!-- <el-time-select--> size="small"
<!-- v-model="form.startTime"--> :picker-options="{
<!-- size="small"--> start: '08:00',
<!-- :picker-options="{--> step: '00:01',
<!-- start: '08:00',--> end: '20:00'
<!-- step: '00:30',--> }"
<!-- end: '19:00'--> @change="startTimeChange"
<!-- }"--> placeholder="选择上课时间"
<!-- placeholder="选择上课时间"--> />
<!-- />--> </el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="时长(分钟):" prop="claDuration">
<el-input-number v-model="form.claDuration" @change="startTimeChange" controls-position="right" :min="0" placeholder="请输入时长" />
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="下课时间:" prop="endTime"> <el-form-item label="下课时间:" prop="endTime">
<el-input v-model="form.endTime" size="small" placeholder="请输入下课时间" /> <el-time-select
<!-- <el-time-select--> v-model="form.endTime"
<!-- v-model="form.endTime"--> size="small"
<!-- size="small"--> disabled="true"
<!-- :picker-options="{--> placeholder="选择下课时间"
<!-- start: '08:00',--> />
<!-- step: '00:30',-->
<!-- end: '20:00'-->
<!-- }"-->
<!-- placeholder="选择下课时间"-->
<!-- />-->
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="任课教师:" prop="teacherId"> <el-form-item label="任课教师:" prop="teacherId">
<el-select <staff-select v-model="form.teacherId" :dept-id="form.deptId" placeholder="请选择上课教师" />
v-model="form.teacherId" <!-- <el-select-->
filterable <!-- v-model="form.teacherId"-->
allow-create <!-- filterable-->
placeholder="选择上课教师" <!-- allow-create-->
clearable <!-- placeholder="选择上课教师"-->
default-first-option <!-- clearable-->
> <!-- default-first-option-->
<el-option <!-- >-->
v-for="teacher in teacherOptions" <!-- <el-option-->
:key="teacher.userId" <!-- v-for="teacher in teacherOptions"-->
:label="teacher.nickName" <!-- :key="teacher.userId"-->
:value="teacher.userId" <!-- :label="teacher.nickName"-->
/> <!-- :value="teacher.userId"-->
</el-select> <!-- />-->
<!-- </el-select>-->
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12">
<el-form-item label="最多预约人数:" prop="atClassCnt">
<el-input-number v-model="form.atClassCnt" controls-position="right" placeholder="请输入人数" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="最少开课人数:" prop="lessCnt">
<el-input-number v-model="form.lessCnt" controls-position="right" :min="0" placeholder="请输入人数" />
</el-form-item>
</el-col>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="教室:" prop="roomId"> <el-form-item label="教室:" prop="roomId">
<room-select v-model="form.roomId" :dept-id="form.deptId" placeholder="请选择教师" /> <room-select v-model="form.roomId" :dept-id="form.deptId" placeholder="请选择教师" />
@ -157,6 +158,7 @@
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
<span style="color: #999; font-size: 12px;">{{form.ruleId?'* 说明:本操作会同时修改未上课且无学员预约/预约失败/取消预约的相关课表信息,已经上完的课程不会被修改;':''}}</span>
</el-form> </el-form>
<div slot="footer" class="dialog-footer"> <div slot="footer" class="dialog-footer">
<el-button :loading="loadingChange" type="primary" @click="submitForm"> </el-button> <el-button :loading="loadingChange" type="primary" @click="submitForm"> </el-button>
@ -205,6 +207,7 @@ export default {
}], }],
// //
form: { form: {
atClassCnt:20
}, },
teacherOptions:[], teacherOptions:[],
isIndeterminate: true, isIndeterminate: true,
@ -234,12 +237,6 @@ export default {
ruleType: [ ruleType: [
{ required: true, message: '规则类型不能为空', trigger: 'blur' } { required: true, message: '规则类型不能为空', trigger: 'blur' }
], ],
beginDate: [
],
endDate: [
],
chooseDate: [
],
repeatType: [ repeatType: [
{ required: true, message: '重复方式不能为空', trigger: 'blur' } { required: true, message: '重复方式不能为空', trigger: 'blur' }
], ],
@ -267,7 +264,13 @@ export default {
], ],
teacherId: [ teacherId: [
{ required: true, message: '任课教师不能为空', trigger: 'blur' } { required: true, message: '任课教师不能为空', trigger: 'blur' }
] ],
claDuration: [
{ required: true, message: '课程时长不能为空', trigger: ['blur','change'] }
],
atClassCnt: [
{ required: true, message: '最多预约人数不能为空', trigger: ['blur','change'] }
],
} }
if (this.form.ruleType === '1') { if (this.form.ruleType === '1') {
tempRules['beginDate'] = [ tempRules['beginDate'] = [
@ -290,7 +293,7 @@ export default {
if (newValue === '1') { if (newValue === '1') {
// //
this.form.repeatType = '1' this.form.repeatType = '1'
this.form.filterHoliday = true this.form.filterHoliday = false
} else { } else {
// //
this.form.repeatType = undefined this.form.repeatType = undefined
@ -347,12 +350,17 @@ export default {
endDate: undefined, endDate: undefined,
repeatType: '1', repeatType: '1',
weekDays: [], weekDays: [],
filterHoliday: true, filterHoliday: false,
startTime: '', startTime: '',
endTime: '', endTime: '',
teacherId: undefined, teacherId: undefined,
classTheme: undefined, classTheme: undefined,
chooseDate: undefined chooseDate: undefined,
roomId: '',
lessCnt:0,
atClassCnt:20,
claDuration:0,
} }
this.resetForm('form') this.resetForm('form')
this.canChangeCla = true this.canChangeCla = true
@ -423,6 +431,10 @@ export default {
this.form.endDate = undefined this.form.endDate = undefined
} }
}, },
//
startTimeChange() {
this.form.endTime = this.calculateEndTime(this.form.startTime, this.form.claDuration);
},
handleCheckAllChange(val) { handleCheckAllChange(val) {
this.form.weekDays = val ? this.weekDayOptions.map(item => { this.form.weekDays = val ? this.weekDayOptions.map(item => {
return item.dictValue return item.dictValue
@ -441,7 +453,34 @@ export default {
} else if (ruleType === '1') { } else if (ruleType === '1') {
// //
} }
} },
/**
* 计算结束时间时长单位分钟
* @param {String} startTime - 开始时间HH:mm
* @param {Number} duration - 时长分钟
* @returns {String} 计算后的结束时间
*/
calculateEndTime(startTime, duration) {
if (!startTime || !duration) return '';
//
const [startHour, startMinute] = startTime.split(':').map(Number);
//
const totalStartMinutes = startHour * 60 + startMinute;
// 使
let totalEndMinutes = totalStartMinutes + duration;
// 24
totalEndMinutes = totalEndMinutes % (24 * 60);
//
const endHour = Math.floor(totalEndMinutes / 60);
const endMinute = totalEndMinutes % 60;
// HH:mm
return `${endHour.toString().padStart(2, '0')}:${endMinute.toString().padStart(2, '0')}`;
},
} }
} }
</script> </script>

@ -2,7 +2,7 @@
<template> <template>
<div> <div>
<el-table v-loading="loading" :data="dataList"> <el-table v-loading="loading" :data="dataList">
<el-table-column align="center" prop="studentName" label="学" fixed="left" /> <el-table-column align="center" prop="studentName" label="学" fixed="left" />
<el-table-column align="center" prop="claName" label="班级" show-overflow-tooltip /> <el-table-column align="center" prop="claName" label="班级" show-overflow-tooltip />
<el-table-column align="center" prop="teacherName" label="教师" show-overflow-tooltip /> <el-table-column align="center" prop="teacherName" label="教师" show-overflow-tooltip />
<el-table-column align="center" prop="realClaDate" label="上课日期" width="120"> <el-table-column align="center" prop="realClaDate" label="上课日期" width="120">

@ -2,24 +2,24 @@
<div> <div>
<el-row style="margin-bottom: 15px;"> <el-row style="margin-bottom: 15px;">
<el-col v-if="!readonly" :span="6"> <el-col v-if="!readonly" :span="6">
<div style="height: 40px;align-items: center;display: flex;justify-content: start;"> <!-- <div style="height: 40px;align-items: center;display: flex;justify-content: start;">-->
<el-button <!-- <el-button-->
size="small" <!-- size="small"-->
type="info" <!-- type="info"-->
icon="el-icon-edit-outline" <!-- icon="el-icon-edit-outline"-->
@click="handleCalendarAddClaTime" <!-- @click="handleCalendarAddClaTime"-->
>课表排课</el-button> <!-- >课表排课</el-button>-->
<el-button <!-- <el-button-->
v-if="!readonly && addTimeRule" <!-- v-if="!readonly && addTimeRule"-->
v-hasPermi="['sc:claTimeRule:add']" <!-- v-hasPermi="['sc:claTimeRule:add']"-->
type="info" <!-- type="info"-->
icon="el-icon-document-copy" <!-- icon="el-icon-document-copy"-->
size="small" <!-- size="small"-->
@click="handleAddTimeRule" <!-- @click="handleAddTimeRule"-->
>规则排课</el-button> <!-- >规则排课</el-button>-->
</div> <!-- </div>-->
</el-col> </el-col>
<el-col v-if="!readonly" :span="12"> <el-col v-if="!readonly" :span="24" >
<div style="height: 40px;align-items: center;display: flex;justify-content: center;"> <div style="height: 40px;align-items: center;display: flex;justify-content: center;">
<div style="padding: 0 15px;cursor: pointer;" @click="calendarBeginDateClick(-7)"> <div style="padding: 0 15px;cursor: pointer;" @click="calendarBeginDateClick(-7)">
<el-icon class="el-icon-arrow-left" style="font-size: 30px;" /> <el-icon class="el-icon-arrow-left" style="font-size: 30px;" />
@ -106,16 +106,17 @@
</td> </td>
<td v-for="(claTimeArray, claTimeArrayIdx) in item.claTimeWeekDayMap" :key="claTimeArrayIdx" class="cell"> <td v-for="(claTimeArray, claTimeArrayIdx) in item.claTimeWeekDayMap" :key="claTimeArrayIdx" class="cell">
<div v-for="(claTime, claTimeIdx) in claTimeArray" :key="claTime.courseTimeId" class="cla-time-item-container"> <div v-for="(claTime, claTimeIdx) in claTimeArray" :key="claTime.courseTimeId" class="cla-time-item-container">
<div v-if="claTimeIdx < 2" class="cla-time-item success" :style="'background-color: ' + claTime.claColor + ';'"> <div v-if="claTimeIdx < 5" class="cla-time-item success" :style="'background-color: ' + claTime.claColor + ';'">
<div class="overflow-ellipsis">{{ claTime.claName }}</div> <div class="overflow-ellipsis">{{ claTime.startTime }} ~ {{ claTime.endTime }}</div>
<div class="overflow-ellipsis">{{ claTime.staffName }} {{ claTime.startTime }} ~ {{ claTime.endTime }}</div> <div class="overflow-ellipsis" >{{ claTime.claName }}{{ claTime.courseName }}</div>
<div class="overflow-ellipsis">{{ claTime.staffName }} </div>
<div class="right-top-tag"> <div class="right-top-tag">
<div v-if="claTime.claTimeStatus === '2'" class="claTimeStatus success"><span>已上课</span></div> <div v-if="claTime.claTimeStatus === '2'" class="claTimeStatus success"><span>已上课</span></div>
<div v-if="claTime.claTimeStatus === '1'" class="claTimeStatus"><span>未上课</span></div> <div v-if="claTime.claTimeStatus === '1'" class="claTimeStatus"><span>未上课</span></div>
</div> </div>
<div class="tooltip"> <div class="tooltip">
<div class="content"> <div class="content">
<div class="title">{{ claTime.claName }}</div> <div class="title">班级{{ claTime.claName }}</div>
<div class="item"><i class="el-icon-collection" /> {{ claTime.courseName }}</div> <div class="item"><i class="el-icon-collection" /> {{ claTime.courseName }}</div>
<div class="item"><i class="el-icon-notebook-1" /> {{ claTime.claDate }}</div> <div class="item"><i class="el-icon-notebook-1" /> {{ claTime.claDate }}</div>
<div class="item"><i class="el-icon-mouse" /> {{ claTime.weekDay }}</div> <div class="item"><i class="el-icon-mouse" /> {{ claTime.weekDay }}</div>
@ -134,7 +135,7 @@
</div> </div>
</div> </div>
</div> </div>
<div v-if="claTimeArray.length > 2" class="show-more" @click="showMore(claTimeArray)"> <div v-if="claTimeArray.length > 5" class="show-more" @click="showMore(claTimeArray)">
查看更多 查看更多
</div> </div>
</td> </td>
@ -186,7 +187,7 @@
</div> </div>
</template> </template>
<script> <script>
import { searchListForCalendar, delTime } from '@/api/school/sc/cla/claTime' import {searchListForCalendarByMemberId, searchListForCalendar, delTime } from '@/api/school/sc/cla/claTime'
import changeTime from '@/components/sc/claTime/changeTime' import changeTime from '@/components/sc/claTime/changeTime'
import changeTimeRule from '@/components/sc/claTime/changeTimeRule' import changeTimeRule from '@/components/sc/claTime/changeTimeRule'
import moment from 'moment' import moment from 'moment'
@ -238,7 +239,7 @@ export default {
type: Boolean, type: Boolean,
default: false default: false
}, },
// //
needStudentIdParam: { needStudentIdParam: {
type: Boolean, type: Boolean,
default: false default: false
@ -309,6 +310,26 @@ export default {
return return
} }
this.loading = true this.loading = true
if (this.studentId){
searchListForCalendarByMemberId({
beginDate: this.calendarBeginDate,
endDate: this.calendarEndDate,
claId: this.claId,
studentId: this.studentId,
teacherId: this.teacherId,
deptId: this.deptId
}).then(response => {
this.loading = false
if (response.respCode === '0000') {
if (response.data.columnTitles && response.data.claTimeContainer) {
this.columnTitles = response.data.columnTitles
this.claTimeContainer = response.data.claTimeContainer
}
}
}).catch(() => {
this.loading = false
})
}else {
searchListForCalendar({ searchListForCalendar({
beginDate: this.calendarBeginDate, beginDate: this.calendarBeginDate,
endDate: this.calendarEndDate, endDate: this.calendarEndDate,
@ -327,6 +348,8 @@ export default {
}).catch(() => { }).catch(() => {
this.loading = false this.loading = false
}) })
}
}, },
showMore(claTimeArray) { showMore(claTimeArray) {
this.showMoreData = true this.showMoreData = true
@ -416,11 +439,11 @@ export default {
</script> </script>
<style rel="stylesheet/scss" lang="scss" scoped> <style rel="stylesheet/scss" lang="scss" scoped>
$claTimeColumnWidth: 125px; $claTimeColumnWidth: 146px;
$claTimeColumnHeight: 46px; $claTimeColumnHeight: 60px;
$Padding8: 8px; $Padding8: 8px;
.cla-time-table { .cla-time-table {
font-size: 12px; font-size: 14px;
border: 1px solid #ebeef5; border: 1px solid #ebeef5;
border-right: none; border-right: none;
border-bottom: none; border-bottom: none;

@ -25,17 +25,6 @@
</el-form-item> </el-form-item>
</el-form> </el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="primary"
icon="el-icon-s-promotion"
size="mini"
@click="handleAddClaTime"
>记上课</el-button>
</el-col>
</el-row>
<el-table v-loading="loading" :data="dataList" @selection-change="handleSelectionChange"> <el-table v-loading="loading" :data="dataList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" /> <el-table-column type="selection" width="55" align="center" />
<el-table-column align="center" width="180" prop="realClaDate" label="上课时间" fixed="left"> <el-table-column align="center" width="180" prop="realClaDate" label="上课时间" fixed="left">
@ -44,15 +33,15 @@
<span v-else-if="scope.row.status === '1'">{{ scope.row.claDate }} {{ scope.row.startTime.substr(0,5) }}~{{ scope.row.endTime.substr(0,5) }}</span> <span v-else-if="scope.row.status === '1'">{{ scope.row.claDate }} {{ scope.row.startTime.substr(0,5) }}~{{ scope.row.endTime.substr(0,5) }}</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column align="center" prop="claName" label="上课班级" show-overflow-tooltip /> <el-table-column align="center" width="180" prop="claName" label="上课班级" show-overflow-tooltip />
<el-table-column align="center" prop="courseName" label="所属课程" show-overflow-tooltip /> <el-table-column align="center" width="180" prop="courseName" label="所属课程" show-overflow-tooltip />
<el-table-column align="center" width="180" prop="staffName" label="上课教师" />
<el-table-column align="center" prop="status" label="状态"> <el-table-column align="center" prop="status" label="状态">
<template slot-scope="scope"> <template slot-scope="scope">
<el-tag v-if="scope.row.status === '1'" type="danger"></el-tag> <el-tag v-if="scope.row.status === '1'" type="danger"></el-tag>
<el-tag v-else-if="scope.row.status === '2'">已上课</el-tag> <el-tag v-else-if="scope.row.status === '2'">已上课</el-tag>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column align="center" width="100" prop="staffName" label="上课教师" />
<el-table-column width="150" label="操作" align="center" class-name="small-padding fixed-width" fixed="right"> <el-table-column width="150" label="操作" align="center" class-name="small-padding fixed-width" fixed="right">
<template slot-scope="scope"> <template slot-scope="scope">
<el-button <el-button
@ -75,7 +64,7 @@
type="text" type="text"
icon="el-icon-edit-outline" icon="el-icon-edit-outline"
@click="handleUpdateWaitAttend(scope.row)" @click="handleUpdateWaitAttend(scope.row)"
>编辑</el-button> >详情</el-button>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
@ -91,6 +80,7 @@
<add-cla-time-attend <add-cla-time-attend
ref="addClaTimeAttend" ref="addClaTimeAttend"
:appoint-course-time-id="chooseCourseTimeId" :appoint-course-time-id="chooseCourseTimeId"
:cla-id="chooseClaId"
appoint-cla-time appoint-cla-time
:need-choose-cla="needChooseCla" :need-choose-cla="needChooseCla"
@success="getList" @success="getList"
@ -208,6 +198,7 @@ export default {
handleClaTimeAttend(claTime) { handleClaTimeAttend(claTime) {
this.needChooseCla = false this.needChooseCla = false
this.chooseCourseTimeId = claTime.courseTimeId this.chooseCourseTimeId = claTime.courseTimeId
this.chooseClaId = claTime.claId
this.$refs.addClaTimeAttend.open = true this.$refs.addClaTimeAttend.open = true
}, },
/** 已上课编辑 */ /** 已上课编辑 */
@ -223,12 +214,6 @@ export default {
this.$refs.changeTime.reset() this.$refs.changeTime.reset()
this.$refs.changeTime.openUpdateByOldInfo(claTime, claTime.courseTimeId) this.$refs.changeTime.openUpdateByOldInfo(claTime, claTime.courseTimeId)
}, },
/** 记上课 */
handleAddClaTime() {
this.needChooseCla = true
this.chooseCourseTimeId = undefined
this.$refs.addClaTimeAttend.open = true
}
} }
} }
</script> </script>

@ -32,46 +32,33 @@
<span>{{ scope.row.realClaDate }} {{ scope.row.realStartTime.substr(0,5) }}~{{ scope.row.realEndTime.substr(0,5) }}</span> <span>{{ scope.row.realClaDate }} {{ scope.row.realStartTime.substr(0,5) }}~{{ scope.row.realEndTime.substr(0,5) }}</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column align="center" prop="claName" label="上课班级" show-overflow-tooltip> <el-table-column align="center" width="180" prop="claName" label="上课班级" />
<template slot-scope="scope"> <el-table-column align="center" width="180" prop="courseName" label="所属课程" />
<router-link :to="'/edu/cla/detail/' + scope.row.claId" class="link-type"> <el-table-column align="center" width="180" prop="staffName" label="上课教师" />
<span>{{ scope.row.claName }}</span> <el-table-column align="center" width="180" prop="needAttendCnt" label="预约/实到">
</router-link>
</template>
</el-table-column>
<el-table-column align="center" prop="courseName" label="所属课程" show-overflow-tooltip />
<el-table-column align="center" width="100" prop="staffName" label="上课教师" />
<el-table-column align="center" width="80" prop="needAttendCnt" label="应到/实到">
<template slot-scope="scope"> <template slot-scope="scope">
<el-tooltip effect="dark" placement="top"> <el-tooltip effect="dark" placement="top">
<template slot="content"> <template slot="content">
<div> <div>
<div>到课: {{ scope.row.realAttendCnt }}</div> <div>到课: {{ scope.row.realAttendCnt }}</div>
<div>请假: {{ scope.row.leaveCnt }}</div> <div>预约: {{ scope.row.bookAttendCnt }}</div>
<div>缺勤: {{ scope.row.outCnt }}</div>
</div> </div>
</template> </template>
<span>{{ scope.row.realAttendCnt }}/{{ scope.row.needAttendCnt }}</span> <span>{{ scope.row.realAttendCnt }}/{{ scope.row.bookAttendCnt }}</span>
</el-tooltip> </el-tooltip>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column align="center" width="100" prop="" label="课时消耗"> <el-table-column align="center" width="180" prop="" label="课时消耗统计">
<template slot-scope="scope"> <template slot-scope="scope">
<span>{{ scope.row.payTotalHour }}</span> <span>{{ scope.row.payTotalHour }}</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column align="center" width="120" prop="" label="学费消耗(元)"> <el-table-column align="center" width="180" prop="" label="学费消耗统计(元)">
<template slot-scope="scope"> <template slot-scope="scope">
<span>{{ scope.row.payTotalFee }}</span> <span> {{ scope.row.payTotalFee }} </span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column align="center" prop="lastUpdateUserName" label="记录人" /> <el-table-column width="180" label="操作" align="center" class-name="small-padding fixed-width" fixed="right">
<el-table-column align="center" width="140" prop="lastUpdateTime" label="记录时间">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.lastUpdateTime, '{y}-{m}-{d} {h}:{i}') }}</span>
</template>
</el-table-column>
<el-table-column width="150" label="操作" align="center" class-name="small-padding fixed-width" fixed="right">
<template slot-scope="scope"> <template slot-scope="scope">
<el-button <el-button
v-hasPermi="['sc:claTime:update']" v-hasPermi="['sc:claTime:update']"
@ -79,14 +66,7 @@
type="text" type="text"
icon="el-icon-edit-outline" icon="el-icon-edit-outline"
@click="handleUpdate(scope.row)" @click="handleUpdate(scope.row)"
>修改</el-button> >详情</el-button>
<el-button
v-hasPermi="['sc:claTime:delete']"
size="mini"
type="text"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
>删除</el-button>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
@ -104,7 +84,7 @@
</template> </template>
<script> <script>
import { selectListForAttend, deleteHadClaTimeAttend } from '@/api/school/sc/cla/claTime' import { selectListForAttend } from '@/api/school/sc/cla/claTime'
import changeClaTimeAttend from '@/components/sc/claTime/changeClaTimeAttend' import changeClaTimeAttend from '@/components/sc/claTime/changeClaTimeAttend'
import deptSelect from '@/components/system/dept/deptSelect' import deptSelect from '@/components/system/dept/deptSelect'
import claSelect from '@/components/sc/course/cla/claSelect' import claSelect from '@/components/sc/course/cla/claSelect'
@ -199,23 +179,7 @@ export default {
this.chooseClaId = row.claId this.chooseClaId = row.claId
this.$refs.changeClaTimeAttend.open = true this.$refs.changeClaTimeAttend.open = true
}, },
/** 删除按钮操作 */
handleDelete(row) {
this.$confirm('是否确认删除上课记录?', '警告', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(function() {
return deleteHadClaTimeAttend(row.courseTimeId)
}).then((response) => {
if (response.respCode === '0000') {
this.getList()
this.msgSuccess('删除成功')
} else {
this.msgError(response.respMsg)
}
}).catch(function() {})
}
} }
} }
</script> </script>

@ -17,13 +17,8 @@
> >
<div> <div>
<div class="inline-block item"> <div class="inline-block item">
<!-- <span class="title">名称:</span>-->
<span class="option">{{ item.planName }}</span> <span class="option">{{ item.planName }}</span>
</div> </div>
<!-- <div class="inline-block item">-->
<!-- <span class="title">联系电话:</span>-->
<!-- <span class="option">{{ item.phonenumber }}</span>-->
<!-- </div>-->
</div> </div>
</el-option> </el-option>
</el-select> </el-select>
@ -45,7 +40,7 @@ export default {
default: '选择方案' default: '选择方案'
}, },
value: { value: {
type: Number, type: String,
default: undefined default: undefined
} }
}, },

@ -44,13 +44,14 @@
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="教练课时费:" prop="claFee"> <el-form-item label="课程价值:" prop="tuitionFee">
<el-input v-model="form.claFee" placeholder="请输入课时费金额(元/节)" /> <el-input v-model="form.tuitionFee" placeholder="请输入课程价值(元/节)" />
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
<el-row> <el-row>
<el-col :span="24"> <el-col :span="12">
<el-form-item label="上课校区:" prop="courseCampus" class="align-left"> <el-form-item label="上课校区:" prop="courseCampus" class="align-left">
<el-radio-group v-model="form.courseCampus"> <el-radio-group v-model="form.courseCampus">
<el-radio <el-radio
@ -62,8 +63,13 @@
</el-radio-group> </el-radio-group>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12">
<el-form-item label="教练课时费:" prop="claFee">
<el-input v-model="form.claFee" placeholder="请输入课时费金额(元/节)" />
</el-form-item>
</el-col>
</el-row> </el-row>
<el-row v-if="form.courseCampus === '部分校区'"> <el-row v-if="form.courseCampus ==='部分校区'">
<el-form-item label="选择校区:" prop="partCampus" class="align-left"> <el-form-item label="选择校区:" prop="partCampus" class="align-left">
<el-checkbox-group v-model="form.partCampus"> <el-checkbox-group v-model="form.partCampus">
<el-checkbox v-for="(item) in campusOptions" :key="item.id" :label="item.id" name="partCampus">{{ item.label }}</el-checkbox> <el-checkbox v-for="(item) in campusOptions" :key="item.id" :label="item.id" name="partCampus">{{ item.label }}</el-checkbox>
@ -77,14 +83,6 @@
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
<div class="title">
<div class="title-content">课程收费模式</div>
</div>
<div class="fee-mode-content">
<fee-mode-hour ref="feeModeHour" :campus-options="campusOptions" :had-choose-campus="form.partCampus" :course-campus="form.courseCampus" />
<fee-mode-date ref="feeModeDate" :campus-options="campusOptions" :had-choose-campus="form.partCampus" :course-campus="form.courseCampus" />
<fee-mode-cycle ref="feeModeCycle" :campus-options="campusOptions" :had-choose-campus="form.partCampus" :course-campus="form.courseCampus" />
</div>
</el-form> </el-form>
<div slot="footer" class="dialog-footer"> <div slot="footer" class="dialog-footer">
<el-button :loading="loadingChange" type="primary" @click="submitForm"> </el-button> <el-button :loading="loadingChange" type="primary" @click="submitForm"> </el-button>
@ -102,11 +100,10 @@ import feeModeHour from '@/components/sc/course/feeModeHour'
import feeModeDate from '@/components/sc/course/feeModeDate' import feeModeDate from '@/components/sc/course/feeModeDate'
import feeModeCycle from '@/components/sc/course/feeModeCycle' import feeModeCycle from '@/components/sc/course/feeModeCycle'
import addCourseType from '@/components/sc/course/type/addCourseType' import addCourseType from '@/components/sc/course/type/addCourseType'
import feeModePrepaid from '@/components/sc/course/feeModePrepaid1.vue'
export default { export default {
components: { components: {
feeModeHour,
feeModeDate,
feeModeCycle,
addCourseType addCourseType
}, },
data() { data() {
@ -118,6 +115,7 @@ export default {
form: { form: {
courseCampus: undefined, courseCampus: undefined,
claFee:0.0, claFee:0.0,
tuitionFee:0.00,
teachingMode: '1', teachingMode: '1',
partCampus: [], partCampus: [],
sale:'1', sale:'1',
@ -130,6 +128,13 @@ export default {
teachingMode: [ teachingMode: [
{ required: true, message: '请选择上课模式', trigger: 'blur' } { required: true, message: '请选择上课模式', trigger: 'blur' }
], ],
claFee: [
{
pattern: /^\d+(\.\d{1,2})?$/,
message: '请输入数字且最多保留2位小数',
trigger: 'blur'
},
],
courseCampus: [ courseCampus: [
{ required: true, message: '请选择上课校区', trigger: 'blur' } { required: true, message: '请选择上课校区', trigger: 'blur' }
] ]
@ -149,42 +154,15 @@ export default {
this.campusList() this.campusList()
this.campusSelect() this.campusSelect()
}, },
//
initFeeModeDate(data) {
this.$nextTick(() => {
this.$refs.feeModeHour.feeModeTableData = data.feeModeHourList
this.$refs.feeModeHour.feeModeHour = data.feeModeHour
this.$refs.feeModeDate.feeModeTableData = data.feeModeDateList
this.$refs.feeModeDate.feeModeDate = data.feeModeDate
this.$refs.feeModeCycle.feeModeTableData = data.feeModeCycleList
this.$refs.feeModeCycle.feeModeCycle = data.feeModeCycle
})
},
submitForm: function() { submitForm: function() {
this.$refs['form'].validate(valid => { this.$refs['form'].validate(valid => {
if (valid) { if (valid) {
this.loadingChange = true this.loadingChange = true
const feeModeHourList = this.$refs.feeModeHour.feeModeTableData
const feeModeHour = this.$refs.feeModeHour.feeModeHour
const feeModeDateList = this.$refs.feeModeDate.feeModeTableData
const feeModeDate = this.$refs.feeModeDate.feeModeDate
const feeModeCycleList = this.$refs.feeModeCycle.feeModeTableData
const feeModeCycle = this.$refs.feeModeCycle.feeModeCycle
this.form.feeModeHourList = feeModeHourList
this.form.feeModeHour = feeModeHour
this.form.feeModeDateList = feeModeDateList
this.form.feeModeDate = feeModeDate
this.form.feeModeCycleList = feeModeCycleList
this.form.feeModeCycle = feeModeCycle
this.form.sale='1' this.form.sale='1'
if (this.form.courseCampus=='全部校区' || this.form.partCampus.length<1){
this.form.partCampus=null
}
if (this.form.courseId !== undefined) { if (this.form.courseId !== undefined) {
updateCourse(this.form).then(response => { updateCourse(this.form).then(response => {
@ -242,32 +220,7 @@ export default {
partCampus: [] partCampus: []
} }
this.resetForm('form') this.resetForm('form')
this.$nextTick(() => {
this.$refs.feeModeHour.feeModeTableData = [{
campusId: -1,
campusName: '全部校区',
cnt: 1,
totalFee: 0
}]
this.$refs.feeModeHour.feeModeHour = true
this.$refs.feeModeDate.feeModeTableData = [{
campusId: -1,
campusName: '全部校区',
cnt: 1,
dateType: 'month',
totalFee: 0
}]
this.$refs.feeModeDate.feeModeDate = false
this.$refs.feeModeCycle.feeModeTableData = [{
campusId: -1,
campusName: '全部校区',
cnt: 1,
totalFee: 0
}]
this.$refs.feeModeCycle.feeModeCycle = false
})
}, },
// //
handleAddCourseType() { handleAddCourseType() {

@ -175,7 +175,7 @@ export default {
// //
chargeTypeOptions: [{ chargeTypeOptions: [{
chargeType: 'hour', chargeType: 'hour',
chargeTypeName: '按课时' chargeTypeName: '按次数'
}, { }, {
chargeType: 'date', chargeType: 'date',
chargeTypeName: '按时间' chargeTypeName: '按时间'
@ -229,7 +229,7 @@ export default {
const chargeNameArray = [] const chargeNameArray = []
chargeNames.split(',').forEach((value, index, array) => { chargeNames.split(',').forEach((value, index, array) => {
if (value === 'hour') { if (value === 'hour') {
chargeNameArray.push('按课时') chargeNameArray.push('按次数')
} else if (value === 'date') { } else if (value === 'date') {
chargeNameArray.push('按时间') chargeNameArray.push('按时间')
} else if (value === 'cycle') { } else if (value === 'cycle') {

@ -25,30 +25,10 @@
<el-row> <el-row>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="任课教师:" prop="staffId"> <el-form-item label="任课教师:" prop="staffId">
<el-select <staff-select v-model="form.staffId" :dept-id="chooseDepartId" placeholder="请选择上课教师" />
v-model="form.staffId"
filterable
allow-create
placeholder="选择上课教师"
clearable
default-first-option
>
<el-option
v-for="teacher in teacherOptions"
:key="teacher.userId"
:label="teacher.nickName"
:value="teacher.userId"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="满班人数:" prop="capacity">
<el-input-number v-model="form.capacity" controls-position="right" :min="0" placeholder="请输入满班人数" />
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row>
<el-row>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="招生状态:" prop="recruitStatus"> <el-form-item label="招生状态:" prop="recruitStatus">
<el-select <el-select
@ -68,13 +48,13 @@
</el-select> </el-select>
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row>
<el-row>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="每次上课:" prop="everyStuLoseHour"> <el-form-item label="满班人数:" prop="capacity">
学生扣除 <el-input-number v-model="form.everyStuLoseHour" class="auto-width" style="width: 100px" controls-position="right" :min="0" /> 课时 <el-input-number v-model="form.capacity" controls-position="right" :min="0" placeholder="请输入满班人数" />
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row>
<el-row>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="开班日期:" prop="openDate"> <el-form-item label="开班日期:" prop="openDate">
<el-date-picker <el-date-picker
@ -86,6 +66,13 @@
/> />
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="备注" prop="memo">
<el-input v-model="form.memo" type="textarea" placeholder="请输入备注内容" />
</el-form-item>
</el-col>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="结班日期:" prop="closeDate"> <el-form-item label="结班日期:" prop="closeDate">
<el-date-picker <el-date-picker
@ -99,13 +86,6 @@
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
<el-row>
<el-col :span="12">
<el-form-item label="备注" prop="memo">
<el-input v-model="form.memo" type="textarea" placeholder="请输入备注内容" />
</el-form-item>
</el-col>
</el-row>
</el-form> </el-form>
<div slot="footer" class="dialog-footer"> <div slot="footer" class="dialog-footer">
<el-button :loading="loadingChange" type="primary" @click="submitForm"> </el-button> <el-button :loading="loadingChange" type="primary" @click="submitForm"> </el-button>
@ -119,9 +99,11 @@
import chooseCourse from '@/components/sc/course/chooseCourse' import chooseCourse from '@/components/sc/course/chooseCourse'
import { addCla, updateCla } from '@/api/school/sc/cla' import { addCla, updateCla } from '@/api/school/sc/cla'
import { select as teacherSelect } from '@/api/school/system/staff' import { select as teacherSelect } from '@/api/school/system/staff'
import staffSelect from '@/components/system/staff/staffSelect'
import moment from 'moment' import moment from 'moment'
export default { export default {
components: { components: {
staffSelect,
chooseCourse chooseCourse
}, },
props: { props: {
@ -139,8 +121,9 @@ export default {
loadingSelect: false, loadingSelect: false,
form: { form: {
openDate: undefined, openDate: undefined,
everyStuLoseHour: 1, claColor: '#409EFF',
claColor: '#409EFF' capacity:20,
recruitStatus:'1'
}, },
rules: { rules: {
courseId: [ courseId: [
@ -149,21 +132,6 @@ export default {
claName: [ claName: [
{ required: true, message: '请输入班级名称', trigger: 'blur' } { required: true, message: '请输入班级名称', trigger: 'blur' }
], ],
staffId: [
{ required: true, message: '请选择任课教师', trigger: 'blur' }
],
capacity: [
{ required: true, message: '请填写满班人数', trigger: 'blur' }
],
recruitStatus: [
{ required: true, message: '请选择招生状态', trigger: 'blur' }
],
everyStuLoseHour: [
{ required: true, message: '请输入每次上课学生扣除课时', trigger: 'blur' }
],
openDate: [
{ required: true, message: '请输入开班日期', trigger: 'blur' }
]
}, },
recruitStatusOptions: [], recruitStatusOptions: [],
// //
@ -248,8 +216,9 @@ export default {
this.chooseDepartId = undefined this.chooseDepartId = undefined
this.form = { this.form = {
openDate: moment(new Date()).format('YYYY-MM-DD'), openDate: moment(new Date()).format('YYYY-MM-DD'),
everyStuLoseHour: 1, claColor: '#409EFF',
claColor: '#409EFF' capacity:20,
recruitStatus:'1'
} }
this.resetForm('form') this.resetForm('form')
} }

@ -22,10 +22,10 @@
<span class="title">班名:</span> <span class="title">班名:</span>
<span class="option">{{ item.claName }}({{ item.deptName }})</span> <span class="option">{{ item.claName }}({{ item.deptName }})</span>
</div> </div>
<div class="inline-block staffName"> <!-- <div class="inline-block staffName">-->
<span class="title">教师:</span> <!-- <span class="title">教师:</span>-->
<span class="option">{{ item.staffName }}</span> <!-- <span class="option">{{ item.staffName }}</span>-->
</div> <!-- </div>-->
<div class="inline-block recruitStatus"> <div class="inline-block recruitStatus">
<span class="title">状态:</span> <span class="title">状态:</span>
<span class="option">{{ recruitStatusFormatter(item.recruitStatus) }}({{ item.capacity }})</span> <span class="option">{{ recruitStatusFormatter(item.recruitStatus) }}({{ item.capacity }})</span>

@ -18,10 +18,10 @@
border border
class="fee-table" class="fee-table"
> >
<el-table-column <!-- <el-table-column-->
prop="campusName" <!-- prop="campusName"-->
label="开课校区" <!-- label="开课校区"-->
/> <!-- />-->
<el-table-column <el-table-column
prop="cnt" prop="cnt"
label="数量" label="数量"

@ -3,7 +3,7 @@
<el-col :span="12"> <el-col :span="12">
<el-form-item prop="feeModeDate" class="align-left none-margin-bottom margin-top-20"> <el-form-item prop="feeModeDate" class="align-left none-margin-bottom margin-top-20">
<template slot="label"> <template slot="label">
<div class="second-title">2. 时间收费:</div> <div class="second-title">2. 周期收费:</div>
</template> </template>
<el-switch v-model="feeModeDate" /> <el-switch v-model="feeModeDate" />
</el-form-item> </el-form-item>

@ -1,289 +1,228 @@
<template> <template>
<el-row> <el-row style="margin-bottom: 10px">
<el-col :span="24">
<el-form-item prop="feeModeHour" class="align-left none-margin-bottom">
<template slot="label">
<div class="second-title">1. 按课时收费:</div>
</template>
<el-switch v-model="feeModeHour" />
</el-form-item>
</el-col>
<el-col v-if="feeModeHour" :span="24"> <el-col v-if="feeModeHour" :span="24">
<label class="el-form-item__label" style="width: 100px;">定价标准:</label> <label class="el-form-item__label" style="width: 100px;">扣费标准:
</label>
<el-table <el-table
:data="feeModeTableData" :data="feeModeTableData"
:span-method="spanMethod"
border border
class="fee-table" class="fee-table"
> >
<el-table-column <el-table-column
prop="campusName" prop="courseType"
label="开课校区" label="课程类别"
width="200"
>
<template slot-scope="scope">
<div class="select-with-btn-container">
<el-select
v-model="scope.row.courseTypeId"
placeholder="请选择课程类别"
clearable
filterable
default-first-option
:loading="loadingSelect"
@change="handleCourseTypeChange(scope.row)"
>
<el-option
v-for="item in getAvailableCourseTypeOptions(scope.$index)"
:key="item.id"
:label="item.label"
:value="item.id"
/> />
</el-select>
</div>
</template>
</el-table-column>
<el-table-column <el-table-column
prop="cnt" prop="cnt"
label="数量(课时)" label="扣卡次数"
width="160" width="160"
> >
<template slot="header"><span class="header-need-input">数量(课时)</span></template> <template slot="header"><span class="header-need-input">扣卡次</span></template>
<template slot-scope="scope"> <template slot-scope="scope">
<el-input-number v-model="feeModeTableData[scope.$index].cnt" size="small" controls-position="right" :min="1" label="输入课时数量" /> <el-input-number v-model="scope.row.cnt" size="small" controls-position="right" :min="1" :precision="1" label="输入扣卡次数" />
</template> </template>
</el-table-column> </el-table-column>
<el-table-column <el-table-column
prop="totalFee" prop="totalFee"
label="总价(元)" label="或扣费金额(每节)"
width="160" width="160"
> >
<template slot="header"><span class="header-need-input">总价()</span></template> <template slot="header"><span class="header-need-input">或扣费金额(每节)</span></template>
<template slot-scope="scope"> <template slot-scope="scope">
<el-input-number v-model="feeModeTableData[scope.$index].totalFee" size="small" controls-position="right" :min="0" label="请输入金额" /> <el-input-number v-model="scope.row.totalFee" size="small" controls-position="right" :min="0" :precision="2" label="请输入金额" />
</template> </template>
</el-table-column> </el-table-column>
<el-table-column <el-table-column
label="操作" label="操作"
width="80" width="120"
align="center" align="center"
> >
<template slot-scope="scope"> <template slot-scope="scope">
<el-button v-if="lastCampus(scope)" style="padding: 3px 5px;" type="primary" icon="el-icon-plus" size="mini" @click="handleAddFeeMode(scope)" /> <!-- 关键修改1仅最后一行显示添加按钮 -->
<el-button v-if="canDel(scope)" style="padding: 3px 5px;margin-left: 5px;" type="danger" icon="el-icon-minus" size="mini" @click="handleDeleteFeeMode(scope)" /> <el-button
v-if="scope.$index === feeModeTableData.length - 1"
style="padding: 3px 5px;"
type="primary"
icon="el-icon-plus"
size="mini"
@click="handleAddFeeMode(scope)"
/>
<el-button
v-if="canDel(scope)"
style="padding: 3px 5px;margin-left: 5px;"
type="danger"
icon="el-icon-minus"
size="mini"
@click="handleDeleteFeeMode(scope)"
/>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
</el-col> </el-col>
</el-row> </el-row>
</template> </template>
<script> <script>
export default { export default {
props: { props: {
// //
campusOptions: { courseTypeOptions: {
type: Array, type: Array,
default: function() { default: () => []
return []
}
}, },
// //
hadChooseCampus: { hadChooseType: {
type: Array, type: Array,
default: function() { default: () => []
return []
}
}, },
// /
courseCampus: {
type: String,
default: 'all'
}
}, },
data() { data() {
return { return {
feeModeHour: true, feeModeHour: true,
// feeModeHourTableData index feeModeTableData: [],
spanData: {}, // key-value (courseTypeId => courseType)
feeModeTableData: [{ courseTypeOptionsMap: {},
campusId: -1, loadingSelect: false
campusName: '全部校区',
cnt: 1,
totalFee: 0
}],
// key value
campusOptionsMap: {}
} }
}, },
computed: {
},
watch: { watch: {
// key value //
campusOptions(newValue, oldValue) { courseTypeOptions: {
newValue.forEach((value, index, array) => { immediate: true,
this.campusOptionsMap[value.id] = value.label handler(newValue) {
}) // courseTypeIdcourseType
}, this.courseTypeOptionsMap = newValue.reduce((map, item) => {
// map[item.courseTypeId] = item.courseType;
courseCampus(newValue, oldValue) { return map;
if (!this.feeModeHour) { }, {});
this.feeModeTableData = []
return //
} this.initFeeModeTableData();
if (newValue === 'all') {
this.feeModeTableData = [{
campusId: -1,
campusName: '全部校区',
cnt: 1,
totalFee: 0
}]
} else if (newValue === 'part') {
const campusArray = []
this.campusOptions.forEach((value, index, array) => {
const id = value.id
const label = value.label
if (this.hadChooseCampus.indexOf(id) !== -1) {
campusArray.push({
campusId: id,
campusName: label,
cnt: 1,
totalFee: 10
})
}
})
this.feeModeTableData = campusArray
} }
}, },
// //
hadChooseCampus(newValue, oldValue) { hadChooseType: {
if (!this.feeModeHour) { immediate: true,
this.feeModeTableData = [] handler(newVal) {
return if (!this.feeModeHour) return;
this.initFeeModeTableData(newVal);
} }
const addCampusArray = [] },
const subCampusArray = [] //
// feeModeHour(newVal) {
if (newValue.length > oldValue.length) { if (newVal) {
// this.initFeeModeTableData();
newValue.forEach((value, index, array) => {
if (oldValue.indexOf(value) === -1) {
addCampusArray.push(value)
}
})
} else { } else {
// this.feeModeTableData = [];
oldValue.forEach((value, index, array) => {
if (newValue.indexOf(value) === -1) {
subCampusArray.push(value)
} }
})
} }
//
addCampusArray.forEach((value, index, array) => {
const campusName = this.campusOptionsMap[value]
this.feeModeTableData.push({
campusId: value,
campusName: campusName,
cnt: 1,
totalFee: 0
})
})
//
const tempArray = this.feeModeTableData
subCampusArray.forEach((value, index, array) => {
for (let i = tempArray.length - 1; i >= 0; i--) {
if (tempArray[i].campusId + '' === value) {
this.feeModeTableData.splice(i, 1)
}
}
})
}, },
// methods: {
feeModeHour(newValue, oldValue) { //
if (newValue && this.feeModeTableData.length === 0) { initFeeModeTableData(initIds = this.hadChooseType) {
if (this.courseCampus === 'all') { //
this.feeModeTableData = [{ if (this.feeModeTableData.length > 0) return;
campusId: -1,
campusName: '全部校区', let tableData = [];
if (initIds.length > 0) {
// IDID
tableData = initIds.map(id => ({
courseTypeId: id,
courseType: this.courseTypeOptionsMap[id] || '',
cnt: 1, cnt: 1,
totalFee: 0 totalFee: 0
}] }));
} else { } else {
this.hadChooseCampus.forEach((value, index, array) => { // ID
const campusName = this.campusOptionsMap[value] const firstOption = this.courseTypeOptions[0] || {};
this.feeModeTableData.push({ tableData = [{
campusId: value, courseTypeId: firstOption.id || '',
campusName: campusName, courseType: firstOption.label|| '',
cnt: 1, cnt: 1,
totalFee: 0 totalFee: 0
}) }];
})
}
} }
}
}, this.feeModeTableData = tableData;
methods: {
//
handleAddFeeMode(item) {
this.feeModeTableData.splice(item.$index + 1, 0, {
campusId: item.row.campusId,
campusName: item.row.campusName,
cnt: 1,
totalFee: 10
})
}, },
// // courseType
handleDeleteFeeMode(item) { handleCourseTypeChange(row) {
const index = item.$index row.courseType = this.courseTypeOptionsMap[row.courseTypeId] || '';
this.feeModeTableData.splice(index, 1)
}, },
spanMethod({ row, column, rowIndex, columnIndex }) { //
if (columnIndex !== 0) { getAvailableCourseTypeOptions(currentIndex) {
return // courseTypeId
} const selectedIds = this.feeModeTableData
// .filter((_, index) => index !== currentIndex)
let preEqual = true .map(item => item.courseTypeId)
// .filter(id => id);
let nextEqual = false
if (rowIndex > 0) { //
preEqual = this.feeModeTableData[rowIndex - 1].campusId === row.campusId const availableOptions = this.courseTypeOptions.filter(item => !selectedIds.includes(item.id));
} else { return availableOptions;
preEqual = false },
} // 2
if (this.feeModeTableData.length > rowIndex + 1) { handleAddFeeMode() {
// //
nextEqual = this.feeModeTableData[rowIndex + 1].campusId === row.campusId const availableOptions = this.getAvailableCourseTypeOptions(this.feeModeTableData.length);
} const firstOption = availableOptions[0] || {};
// this.feeModeTableData.push({
if (!preEqual && nextEqual) { courseTypeId: firstOption.id || '',
let rowspan = 1 courseType: firstOption.label || '',
for (let i = rowIndex + 1; i < this.feeModeTableData.length; i++) { cnt: 1,
if (row.campusId === this.feeModeTableData[i].campusId) { totalFee: 0
rowspan++ });
}
}
return {
rowspan: rowspan,
colspan: 1
}
} else if (preEqual) {
//
return {
rowspan: 0,
colspan: 0
}
}
}, },
// + //
lastCampus(item) { handleDeleteFeeMode(scope) {
const index = item.$index this.feeModeTableData.splice(scope.$index, 1);
const campusId = this.feeModeTableData[index].campusId
//
if (this.feeModeTableData.length === (index + 1)) {
return true
}
// +
return this.feeModeTableData[index + 1].campusId !== campusId
}, },
// //
canDel(item) { canDel() {
const index = item.$index return this.feeModeTableData.length > 1;
const campusId = this.feeModeTableData[index].campusId
//
if (this.feeModeTableData.length === 1) {
return false
}
//
if (this.feeModeTableData.length > 1 && index > 0) {
if (this.feeModeTableData[index - 1].campusId === campusId) {
return true
}
} }
//
if (this.feeModeTableData.length > index + 1) {
return this.feeModeTableData[index + 1].campusId === campusId
} }
} };
}
}
</script> </script>
<style scoped>
.fee-table {
margin-left: 10px;
width: calc(100% - 10px);
}
.select-with-btn-container {
width: 100%;
}
.header-need-input {
color: #606266;
}
</style>

@ -0,0 +1,184 @@
<template>
<el-row>
<el-col :span="12">
<el-form-item prop="feeModePrepaid" class="align-left none-margin-bottom margin-top-20">
<template slot="label">
<div class="second-title">4. 储值收费:</div>
</template>
<el-switch v-model="feeModePrepaid" />
<el-tooltip class="item" effect="dark" content="适合按储值收费课程" placement="right">
<svg-icon icon-class="question" style="height: 22px;width: 22px;top: 8px;position: absolute;left: 48px;" />
</el-tooltip>
</el-form-item>
</el-col>
<el-col v-if="feeModePrepaid" :span="24">
<label class="el-form-item__label" style="width: 100px;">定价标准:</label>
<el-table
:data="feeModeTableData"
border
class="fee-table"
>
<!-- <el-table-column-->
<!-- prop="campusName"-->
<!-- label="开课校区"-->
<!-- />-->
<el-table-column
prop="totalFee"
label="单次课金额(元)"
width="260"
>
<template slot="header"><span class="header-need-input">单次课金额()</span></template>
<template slot-scope="scope">
<el-input-number v-model="feeModeTableData[scope.$index].totalFee" size="small" controls-position="right" :min="0" label="请输入总金额" />
</template>
</el-table-column>
</el-table>
</el-col>
</el-row>
</template>
<script>
export default {
props: {
//
campusOptions: {
type: Array,
default: function() {
return []
}
},
//
hadChooseCampus: {
type: Array,
default: function() {
return []
}
},
// /
courseCampus: {
type: String,
default: 'all'
}
},
data() {
return {
feeModePrepaid: false,
feeModeTableData: [{
campusId: -1,
campusName: '全部校区',
cnt: 1,
totalFee: 10
}],
// key value
campusOptionsMap: {}
}
},
watch: {
// key value
campusOptions(newValue, oldValue) {
newValue.forEach((value, index, array) => {
this.campusOptionsMap[value.id] = value.label
})
},
//
courseCampus(newValue, oldValue) {
if (!this.feeModePrepaid) {
this.feeModeTableData = []
return
}
if (newValue === 'all') {
this.feeModeTableData = [{
campusId: -1,
campusName: '全部校区',
cnt: 1,
totalFee: 0
}]
} else if (newValue === 'part') {
const campusArray = []
this.campusOptions.forEach((value, index, array) => {
const id = value.id
const label = value.label
if (this.hadChooseCampus.indexOf(id) !== -1) {
campusArray.push({
campusId: id,
campusName: label,
cnt: 1,
totalFee: 0
})
}
})
this.feeModeTableData = campusArray
}
},
//
hadChooseCampus(newValue, oldValue) {
if (!this.feeModePrepaid) {
this.feeModeTableData = []
return
}
const addCampusArray = []
const subCampusArray = []
//
if (newValue.length > oldValue.length) {
//
newValue.forEach((value, index, array) => {
if (oldValue.indexOf(value) === -1) {
addCampusArray.push(value)
}
})
} else {
//
oldValue.forEach((value, index, array) => {
if (newValue.indexOf(value) === -1) {
subCampusArray.push(value)
}
})
}
//
addCampusArray.forEach((value, index, array) => {
const campusName = this.campusOptionsMap[value]
this.feeModeTableData.push({
campusId: value,
campusName: campusName,
cnt: 1,
totalFee: 0
})
})
//
const tempArray = this.feeModeTableData
subCampusArray.forEach((value, index, array) => {
for (let i = tempArray.length - 1; i >= 0; i--) {
if (tempArray[i].campusId + '' === value) {
this.feeModeTableData.splice(i, 1)
}
}
})
},
//
feeModePrepaid(newValue, oldValue) {
if (newValue && this.feeModeTableData.length === 0) {
if (this.courseCampus === 'all') {
this.feeModeTableData = [{
campusId: -1,
campusName: '全部校区',
cnt: 1,
totalFee: 0
}]
} else {
this.hadChooseCampus.forEach((value, index, array) => {
const campusName = this.campusOptionsMap[value]
this.feeModeTableData.push({
campusId: value,
campusName: campusName,
cnt: 1,
totalFee: 0
})
})
}
}
}
},
methods: {
}
}
</script>

@ -3,33 +3,6 @@
<div> <div>
<el-dialog title="选择课程" :visible.sync="open" width="700px" class="compact"> <el-dialog title="选择课程" :visible.sync="open" width="700px" class="compact">
<el-form ref="queryForm" :model="queryParams" :inline="true" label-width="75px" class="compact"> <el-form ref="queryForm" :model="queryParams" :inline="true" label-width="75px" class="compact">
<el-form-item label="课程名称:" prop="courseName">
<el-input
v-model="queryParams.courseName"
placeholder="请输入课程名称"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="上课校区:" prop="departId">
<el-select
v-model="queryParams.departId"
placeholder="请选择上课校区"
size="small"
filterable
default-first-option
:loading="loadingSelect"
@change="handleQuery()"
>
<el-option
v-for="item in campusOptions"
:key="item.id"
:label="item.label"
:value="item.id"
/>
</el-select>
</el-form-item>
<el-form-item label="课程类型:" prop="courseTypeId"> <el-form-item label="课程类型:" prop="courseTypeId">
<el-select <el-select
v-model="queryParams.courseTypeId" v-model="queryParams.courseTypeId"
@ -49,9 +22,9 @@
/> />
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="收费模式:" prop="chargeType"> <el-form-item label="收费模式:" prop="cardType">
<el-select <el-select
v-model="queryParams.chargeType" v-model="queryParams.cardType"
placeholder="请选择收费模式" placeholder="请选择收费模式"
clearable clearable
size="small" size="small"
@ -78,39 +51,45 @@
</el-form> </el-form>
<el-table ref="table" v-loading="loading" v-table-load-more="loadMore" :data="dataList" height="320" @select="handleSelect" @select-all="handleSelectAll"> <el-table ref="table" v-loading="loading" v-table-load-more="loadMore" :data="dataList" height="320" @select="handleSelect" @select-all="handleSelectAll">
<el-table-column type="selection" width="55" align="center" /> <el-table-column type="selection" width="55" align="center" />
<el-table-column prop="courseName" align="center" label="课程名称"> <el-table-column prop="courseName" align="center" label="卡项名称">
<template slot-scope="scope"> <template slot-scope="scope">
<span><el-tag v-if="scope.row.studentCourseId" size="mini" closable>续费</el-tag>{{ scope.row.courseName }}</span> <span>
<!-- <el-tag v-if="scope.row.studentCourseId" size="mini" closable>续费</el-tag>-->
{{ scope.row.cardName }}</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="courseTypeName" align="center" label="课程类型" /> <el-table-column prop="courseTypes" width="120" header-align="center" label="课程类别" >
<el-table-column prop="teachingMode" align="center" label="授课模式"> <template slot-scope="scope" >
<template slot-scope="scope"> {{scope.row.courseTypesName}}
<div v-if="scope.row.teachingMode === '1'"> </template>
<el-tooltip class="item" effect="dark" content="班课" placement="right"> </el-table-column>
<svg-icon icon-class="one-to-many" style="height: 25px;width: 25px;" /> <el-table-column prop="restrictedCourses" width="200" header-align="center" label="限制课程">
</el-tooltip> <template slot-scope="scope" >
<div v-if="scope.row.restrictedCourses=='1'">
全部允许<br>
</div>
<div v-if="scope.row.restrictedCourses=='2'">
<div>
<ul>
<li v-for="item in scope.row.courses" :key="item.id">
{{ item.courseType }} - {{item.courseNames}}
</li>
</ul>
</div> </div>
<div v-if="scope.row.teachingMode === '2'">
<el-tooltip class="item" effect="dark" content="一对一" placement="right">
<svg-icon icon-class="one-to-one" style="height: 25px;width: 25px;" />
</el-tooltip>
</div> </div>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="claCount" align="center" label="开班数" /> <el-table-column prop="restrictedTeacher" width="120" header-align="center" label="限制教练" >
<el-table-column prop="chargeNames" align="center" width="120" label="收费模式" :show-overflow-tooltip="true"> <template slot-scope="scope" >
<template slot-scope="scope"> {{scope.row.restrictedTeacher=='1'?'全部允许':scope.row.teachersName}}
{{ chargeNameByCodes(scope.row.chargeNames) }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="campusIds" align="center" label="开课校区"> <el-table-column prop="count" width="180" header-align="center" label="总天数/次数/时长" >
<template slot-scope="scope"> <template slot-scope="scope" >
<div v-if="scope.row.campusIds"> 总天数/有效期{{ scope.row.days?scope.row.days+'天':'未定义'}}<br>
<span v-if="scope.row.campusIds === '-1'"></span> 课程总次数{{ scope.row.count?scope.row.count+'次':'未定义'}}<br>
<span v-else>{{ scope.row.campusIds.split(',').length }}</span> 应付金额{{ scope.row.totalFee?scope.row.totalFee+'元':'未定义'}}
</div>
<div v-else> - </div>
</template> </template>
</el-table-column> </el-table-column>
<template slot="append"> <template slot="append">
@ -121,7 +100,7 @@
<div slot="footer" class="dialog-footer"> <div slot="footer" class="dialog-footer">
<div class="flex space-between"> <div class="flex space-between">
<div class="footer-left-txt"> <div class="footer-left-txt">
已选择 {{ chooseCourseIdList.length }} 门课程 <!-- 已选择 {{ chooseCourseIdList.length }} 门课程-->
</div> </div>
<div class="align-right"> <div class="align-right">
<el-button :loading="loading" type="primary" @click="chooseCourse"></el-button> <el-button :loading="loading" type="primary" @click="chooseCourse"></el-button>
@ -133,9 +112,8 @@
</div> </div>
</template> </template>
<script> <script>
import { selectCourseListWithStudentCourse } from '@/api/school/sc/course' import { listMemberCard } from '@/api/school/sc/memberCardType'
import { select as courseTypeSelect } from '@/api/school/sc/course/courseType' import { select as courseTypeSelect } from '@/api/school/sc/course/courseType'
import { campusList } from '@/api/school/system/dept'
export default { export default {
data() { data() {
@ -151,63 +129,41 @@ export default {
queryParams: { queryParams: {
pageNum: 1, pageNum: 1,
pageSize: 10, pageSize: 10,
courseName: undefined, cardType: undefined,
departId: undefined,
courseTypeId: undefined, courseTypeId: undefined,
teachingMode: undefined,
chargeType: undefined,
sale: '1' sale: '1'
}, },
// //
courseTypeOptions: [], courseTypeOptions: [],
//
teachingModeOptions: [{
teachingMode: '1',
teachingModeName: '班课'
}, {
teachingMode: '2',
teachingModeName: '一对一'
}],
//
campusOptions: [],
// //
chargeTypeOptions: [{ chargeTypeOptions: [{
chargeType: 'hour', chargeType: 'count',
chargeTypeName: '按课时' chargeTypeName: '按次数'
}, {
chargeType: 'date',
chargeTypeName: '按时间'
}, { }, {
chargeType: 'cycle', chargeType: 'days',
chargeTypeName: '按周期' chargeTypeName: '按周期'
}, {
chargeType: 'total_fee',
chargeTypeName: '按储值'
}], }],
chooseCourseIdList: [], chooseCardTypeId: [],
hasMore: false hasMore: false
} }
}, },
methods: { methods: {
initData() { initData() {
this.dataList = [] this.dataList = []
this.campusList() this.getList()
this.courseTypeList()
}, },
courseTypeList() { courseTypeList() {
courseTypeSelect({}).then(response => { courseTypeSelect({}).then(response => {
this.courseTypeOptions = response.data this.courseTypeOptions = response.data
}) })
}, },
async campusList() {
const response = await campusList()
this.campusOptions = response.data
if (this.campusOptions.length > 0) {
this.queryParams.departId = this.campusOptions[0].id
}
this.getList()
},
/** 查询列表 */ /** 查询列表 */
getList() { getList() {
this.loading = true this.loading = true
selectCourseListWithStudentCourse(this.queryParams).then(response => { listMemberCard(this.queryParams).then(response => {
this.dataList = [ this.dataList = [
...this.dataList, ...this.dataList,
...response.data.rows ...response.data.rows
@ -219,7 +175,7 @@ export default {
this.$nextTick(() => { this.$nextTick(() => {
this.dataList.forEach(row => { this.dataList.forEach(row => {
if (this.chooseCourseIdList.indexOf(row.courseId) !== -1) { if (this.chooseCardTypeId.indexOf(row.cardTypeId) !== -1) {
this.$refs.table.toggleRowSelection(row, true) this.$refs.table.toggleRowSelection(row, true)
} }
}) })
@ -243,38 +199,25 @@ export default {
this.resetForm('queryForm') this.resetForm('queryForm')
this.handleQuery() this.handleQuery()
}, },
chargeNameByCodes(chargeNames) {
if (chargeNames) {
const chargeNameArray = []
chargeNames.split(',').forEach((value, index, array) => {
if (value === 'hour') {
chargeNameArray.push('按课时')
} else if (value === 'date') {
chargeNameArray.push('按时间')
} else if (value === 'cycle') {
chargeNameArray.push('按周期')
}
})
return chargeNameArray.toString()
} else {
return '-'
}
},
handleSelect(selection, row) { handleSelect(selection, row) {
const idx = this.chooseCourseIdList.indexOf(row.courseId) const idx = this.chooseCardTypeId.indexOf(row.cardTypeId)
console.log('chooseCardTypeId',this.chooseCardTypeId)
if (idx !== -1) { if (idx !== -1) {
this.chooseCourseIdList.splice(idx, 1) this.chooseCardTypeId.splice(idx, 1)
} else { } else {
this.chooseCourseIdList.push(row.courseId) this.chooseCardTypeId.push(row.cardTypeId)
} }
}, },
handleSelectAll(selection) { handleSelectAll(selection) {
this.chooseCourseIdList = selection.map(item => item.courseId) this.chooseCardTypeId = selection.map(item => item.cardTypeId)
}, },
chooseCourse() { chooseCourse() {
if (this.chooseCardTypeId.length>1){
this.msgError('只能提交1项请确认选择数量')
return ;
}
this.$emit('chooseComplete', { this.$emit('chooseComplete', {
chooseCourseIdList: this.chooseCourseIdList, chooseCardTypeIdList: this.chooseCardTypeId,
departId: this.queryParams.departId
}) })
this.open = false this.open = false
} }

@ -154,7 +154,7 @@ export default {
// //
chargeTypeOptions: [{ chargeTypeOptions: [{
chargeType: 'hour', chargeType: 'hour',
chargeTypeName: '按课时' chargeTypeName: '按次数'
}, { }, {
chargeType: 'date', chargeType: 'date',
chargeTypeName: '按时间' chargeTypeName: '按时间'

@ -1,7 +1,7 @@
<!--新增课程类型--> <!--新增课程类型-->
<template> <template>
<el-dialog :title="title" :visible.sync="open" width="600px"> <el-dialog :title="title" :visible.sync="open" width="600px">
<el-form ref="form" v-loading="loadingChange" :model="form" :rules="rules" label-width="80px"> <el-form ref="form" v-loading="loadingChange" :model="form" :rules="rules" label-width="110px">
<el-row> <el-row>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="类型名称" prop="courseType"> <el-form-item label="类型名称" prop="courseType">
@ -9,6 +9,13 @@
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
<el-row>
<el-col :span="24">
<el-form-item label="课程类型说明:" prop="remark" >
<el-input v-model="form.remark" type="textarea" placeholder="请输入课程类型说明" />
</el-form-item>
</el-col>
</el-row>
</el-form> </el-form>
<div slot="footer" class="dialog-footer"> <div slot="footer" class="dialog-footer">
<el-button :loading="loadingChange" type="primary" @click="submitForm"> </el-button> <el-button :loading="loadingChange" type="primary" @click="submitForm"> </el-button>
@ -44,8 +51,8 @@ export default {
}, },
reset() { reset() {
this.form = { this.form = {
courseType: undefined, courseType: '',
sort: undefined remark: ''
} }
this.resetForm('form') this.resetForm('form')
}, },
@ -64,6 +71,7 @@ export default {
} else { } else {
this.msgError(response.respMsg) this.msgError(response.respMsg)
} }
this.reset()
}).catch(() => { }).catch(() => {
this.loadingChange = false this.loadingChange = false
}) })
@ -77,8 +85,10 @@ export default {
} else { } else {
this.msgError(response.respMsg) this.msgError(response.respMsg)
} }
this.reset()
}).catch(() => { }).catch(() => {
this.loadingChange = false this.loadingChange = false
}) })
} }
} }

@ -0,0 +1,555 @@
<template>
<div>
<el-dialog title="新设会员卡" :visible.sync="open" width="700px">
<el-form ref="form" v-loading="loadingChange" :model="form" :rules="rules" label-width="120px">
<div class="title top" >
<div class="title-content">会员卡基础信息</div>
<div style="padding-left: 10px;">
<span style="color: #999; font-size: 12px;">
* 说明卡项按充值/扣费方式可分为周期卡项次数卡项储值卡项三种方式可同时存在<br>
为会员办理会员卡左侧菜单办理入会->业务办理->报名需选择其中一项作为充值/扣费方式<br>
1.周期卡填写总天数/有效期可作为周期卡项使用<br>
2.周期卡填写总课程次数可作为次数卡项使用<br>
3.储值卡所有卡项均可作为储值卡项使用<br>
</span>
</div>
</div>
<el-row>
<el-col :span="12">
<el-form-item label="会员卡名称:" prop="cardName">
<el-input v-model="form.cardName" placeholder="请输入会员卡名称" />
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<el-form-item label="课程类别:" prop="courseTypes">
<el-checkbox-group v-model="form.courseTypes" @change="changecourseTypes">
<el-checkbox v-for="(item) in courseTypeOptions" :key="item.id" :label="item.id" name="courseTypes">{{ item.label }}</el-checkbox>
</el-checkbox-group>
</el-form-item>
</el-col>
</el-row>
<el-row >
<el-col :span="10" >
<el-form-item label="总天数/有效期:" prop="days">
<el-input v-model="form.days" placeholder="选填" />
</el-form-item>
</el-col>
<el-col :span="14" style="height: 35px;" >
<div style="margin-top: 10px;margin-left: 2px">
<span style="color: #999; font-size: 12px;">(填写后可作为周期卡项使用用于开周期卡时自动填写对应时长)</span>
</div>
</el-col>
</el-row>
<el-row >
<el-col :span="10" >
<el-form-item label="总课程次数:" prop="count">
<el-input v-model="form.count" placeholder="选填" />
</el-form-item>
</el-col>
<el-col :span="14" style="height: 35px;" >
<div style="margin-top: 10px;margin-left: 2px">
<span style="color: #999; font-size: 12px;">(填写后可作为次数卡项使用用于开次数卡时自动填写对应次数)</span>
</div>
</el-col>
</el-row>
<el-row >
<el-col :span="12" >
<el-form-item label="应付金额:" prop="totalFee">
<el-input v-model="form.totalFee" placeholder="选填" />
</el-form-item>
</el-col>
<el-col :span="12" style="height: 35px;" >
<div style="margin-top: 10px;margin-left: 2px">
<span style="color: #999; font-size: 12px;">开卡时会自动填写对应金额</span>
</div>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<el-form-item label="限制教练:" prop="restrictedTeacher" class="align-left">
<el-radio-group v-model="form.restrictedTeacher" @change="changeRestrictedTeacher">
<el-radio label="1">全部允许</el-radio>
<el-radio label="2">部分允许</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-row v-if="form.restrictedTeacher === '2'">
<el-col :span="24">
<el-form-item prop="teacherList">
<el-checkbox-group v-model="form.teacherList">
<el-checkbox v-for="(item) in teacherOptions" :key="item.id" :label="item.id" name="teacherList">{{ item.label }}</el-checkbox>
</el-checkbox-group>
</el-form-item>
</el-col>
</el-row>
<el-col :span="24">
<el-form-item label="限制课程:" prop="restrictedCourses" class="align-left">
<el-radio-group v-model="form.restrictedCourses" @change="changeRestrictedCourses">
<el-radio label="1">全部允许</el-radio>
<el-radio label="2">部分允许</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
</el-row>
<el-row v-if="form.restrictedCourses === '2'" >
<el-col :span="24" >
<el-form-item prop="courseListInType">
<!-- 按课程类型分块展示课程复选框 -->
<div class="course-group-container">
<div
v-for="group in chooseCourseTypes"
:key="group.id"
class="course-group-item"
>
<!-- 课程类型标题 -->
<div class="course-group-title">{{ group.label }}</div>
<!-- 该类型下的课程复选框 -->
<el-checkbox-group v-model="getCourseTypeItem(group.id).selectedCourses">
<el-checkbox v-for="(item) in group.courseList" :key="item.id" :label="item.id" name="courses">{{ item.label }}</el-checkbox>
</el-checkbox-group>
</div>
</div>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<el-form-item label="限制约课次数:" prop="restrictedNum" class="align-left">
<el-radio-group v-model="form.restrictedNum" >
<el-radio label="1">不限次数</el-radio>
<el-radio label="2">限制约课次数</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
</el-row>
<el-row v-if="form.restrictedNum === '2'">
<el-col :span="10">
<el-form-item prop="restrictedNum" >
<el-select v-model="form.bookTime" placeholder="" style="width: 100px">
<el-option
v-for="item in timeOptions"
:key="item.id"
:label="item.label"
:value="item.id"
/>
</el-select>
</el-form-item>
</el-col >
<el-col :span="14" >
<el-form-item prop="bookNum" label="内,只能使用:" >
<el-input v-model="form.bookNum" placeholder="" style="width: 80px" /> &nbsp;
</el-form-item>
<el-form-item></el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<el-form-item label="课程扣次或费用:" prop="chargeType" class="align-left">
<el-radio-group v-model="form.chargeType">
<el-radio
v-for="item in chargeTypeOptions"
:key="item.chargeType"
:label="item.chargeType"
:value="item.chargeType"
>{{ item.chargeTypeName }}</el-radio>
</el-radio-group>
<!-- <span style="color: #999; font-size: 12px; margin-left: 20px"> 默认扣1次或118元</span>-->
</el-form-item>
</el-col>
</el-row>
<el-row v-if="form.chargeType === 'default'">
<el-col :span="10" >
<el-form-item prop="defaultNum" >
扣卡次数
<el-input v-model="form.defaultNum" placeholder="" style="width: 60px" /> ,
</el-form-item>
</el-col>
<el-col :span="14" >
<el-form-item prop="defaultFee" label=" 或扣费金额(每节)">
<el-input v-model="form.defaultFee" placeholder="" style="width: 80px;" />
</el-form-item>
<el-form-item></el-form-item>
</el-col>
</el-row>
<el-row v-if="form.chargeType === 'customize'">
<fee-mode-hour ref="feeModeHour" :course-type-options="courseTypeOptions" :had-choose-type="form.courseTypes" />
</el-row>
<el-row>
<el-col :span="24">
<el-form-item label="会员卡简介:" prop="description">
<el-input v-model="form.description" type="textarea" placeholder="请输入会员卡简介" />
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<el-form-item label="会员卡条款:" prop="conditions">
<el-input v-model="form.conditions" type="textarea" placeholder="请输入会员卡条款" />
</el-form-item>
</el-col>
</el-row>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button :loading="loadingChange" type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { addMemberCard, updateMemberCard } from '@/api/school/sc/memberCardType'
import { selectForCheckbox,selectByTypeIds } from '@/api/school/sc/course/courseType'
import { teacherSelect} from "@/api/columns/teacher";
import feeModeHour from '@/components/sc/course/feeModeHour'
export default {
components: {
feeModeHour
},
data() {
return {
//
open: false,
loadingChange: false,
//
form: {
chargeType:'default',
defaultNum:1,
defaultFee:200,
courseTypes:[],
restrictedCourses:'1',
courseListInType:[],
partTypes:[],
sale:'1',
restrictedNum:'1',
bookTime:'每天',
bookNum:1,
restrictedTeacher:'1',
teacherList:[]
},
timeOptions:[{id:'每天',label:'每天'},
{id:'每周',label:'每周'},
{id:'每月',label:'每月'},
],
//
rules: {
cardName: [
{ required: true, message: '会员卡名称不能为空', trigger: 'blur' },
{ min: 2, max: 20, message: '长度在 2 到 20 个字符', trigger: 'blur' },
],
courseTypes: [
{ required: true, message: '请选择卡项包含的课程类别', trigger: 'change' },
],
days: [
{
pattern: /^[1-9]\d*$/,
message: '天数必须为正整数',
trigger: 'blur'
},
],
count: [
{
pattern: /^\d+(\.\d{1})?$/,
message: '请输入数字且最多保留1位小数',
trigger: 'blur'
},
],
totalFee: [
{
pattern: /^\d+(\.\d{1,2})?$/,
message: '请输入数字且最多保留2位小数',
trigger: 'blur'
},
],
teacherList: [
{
validator: (rule, value, callback) => {
if (this.form.restrictedTeacher === '2') {
if (!value || value.length<1) {
callback(new Error('请选择教练'));
} else {
callback();
}
} else {
callback(); //
}
},
trigger: ['change']// blur
},
],
courseListInType: [
{
validator: (rule, value, callback) => {
if (this.form.restrictedCourses === '2') {
value.forEach(item => {
if (!item.selectedCourses || item.selectedCourses.length<1) {
callback(new Error('请选择课程,'));
}
})
} else {
callback(); //
}
},
trigger: ['change']// blur
},
],
bookNum: [
{
pattern: /^[1-9]\d*$/,
message: '请输入正整数',//
trigger: 'blur'
},
],
defaultNum: [
{
pattern: /^\d+(\.\d{1})?$/,
message: '请输入数字且最多保留1位小数',
trigger: 'blur'
},
],
defaultFee: [
{
pattern: /^\d+(\.\d{1,2})?$/,
message: '请输入数字且最多保留2位小数',
trigger: 'blur'
},
],
},
//
chargeTypeOptions: [{
chargeType: 'default',
chargeTypeName: '所有课程默认'
}, {
chargeType: 'customize',
chargeTypeName: '自定义每节课扣次或费用'
}],
//
courseTypeOptions: [],
teacherOptions: [],
loadingSelect: false,
chooseCourseTypes:[],
}
},
created() {
},
methods: {
init: function() {
this.selectForCheckbox()
},
//
initFeeModeDate(data) {
this.$nextTick(() => {
this.$refs.feeModeHour.feeModeTableData = []
this.$refs.feeModeHour.feeModeTableData = data.feeModeHourList
})
this.changeRestrictedCourses(data.restrictedCourses)
},
/**
* 核心方法根据课程类型ID获取form.courseTypes中的对应项
* @param {Number} typeId 课程类型ID
* @returns {Object} {courseType: xx, selectedCourses: []}
*/
getCourseTypeItem(typeId) {
if (typeId){
let item = this.form.courseListInType.find(item => item.id === typeId);
// undefined
if (!item) {
item = { id: typeId, selectedCourses: [] };
this.form.courseListInType.push(item);
}
return item;
}
},
/**
* 课程类别下的课程
* @param data
*/
changeRestrictedCourses(data){
if (data==='2' && this.form.courseTypes.length>0){
// this.chooseCourseTypes=this.courseTypeOptions.filter(item => this.form.courseTypes.includes(item.id));
selectByTypeIds({typeIds:this.form.courseTypes}).then(response => {
this.loadingChange = false
this.chooseCourseTypes=response.data
}).catch(() => {
this.loadingChange = false
})
}else {
this.chooseCourseTypes=[]
this.form.courseListInType=[]
}
},
changecourseTypes(){
this.changeRestrictedCourses(this.form.restrictedCourses)
},
changeRestrictedTeacher(){
if (this.form.restrictedTeacher==='1'){
this.form.teacherList=[]
}
},
submitForm: function() {
this.$refs['form'].validate(valid => {
if (valid) {
this.loadingChange = true
if (this.form.chargeType=='customize'){
this.form.feeModeHourList = this.$refs.feeModeHour.feeModeTableData
if (this.form.courseTypes.length!==this.form.feeModeHourList.length){
this.$modal.msgError("课程扣次或费用设置的数据项,与所勾选的课程类别数量不一致!");
this.loadingChange =false;
return;
}
}
if (this.form.cardTypeId !== undefined) {
updateMemberCard(this.form).then(response => {
this.loadingChange = false
if (response.respCode === '0000') {
this.msgSuccess('修改成功')
this.open = false
this.$emit('success')
} else {
this.msgError(response.respMsg)
}
}).catch(() => {
this.loadingChange = false
})
} else {
addMemberCard(this.form).then(response => {
this.loadingChange = false
if (response.respCode === '0000') {
this.msgSuccess('新增成功')
this.open = false
this.$emit('success')
} else {
this.msgError(response.respMsg)
}
}).catch(() => {
this.loadingChange = false
})
}
}
})
},
selectForCheckbox() {
selectForCheckbox().then(response => {
this.courseTypeOptions = response.data
})
teacherSelect().then(response => {
this.teacherOptions = response.data.map(item => ({
label: item.nickName,
value: item.userId,
id: item.userId
}));
})
},
cancel() {
this.open = false
this.reset()
},
reset() {
this.form = {
chargeType:'default',
defaultNum:1,
defaultFee:200,
restrictedCourses:'1',
courseTypes:[],
courseListInType:[],
partTypes:[],
sale:'1',
restrictedNum:'1',
bookTime:'每天',
bookNum:1,
restrictedTeacher:'1',
teacherList:[]
}
this.resetForm('form')
},
//
handleAddCourseType() {
this.$refs.addCourseType.open = true
}
}
}
</script>
<style rel="stylesheet/scss" lang="scss">
.align-left {
text-align: left;
}
.second-title{
text-align: left;
padding-left: 15px;
}
.none-margin-bottom{
margin-bottom: 0px;
}
.margin-top-20{
margin-top: 20px;
}
.header-need-input:before{
content: '*';
color: #F56C6C;
margin-right: 4px;
}
.fee-table{
width: calc(100% - 25px);
margin-left: 25px;
}
</style>
<style rel="stylesheet/scss" lang="scss" scoped>
.title {
padding: 0px 0px;
color: rgba(0,0,0,.85);
font-weight: 500;
font-size: 16px;
display: flex;
&.top {
padding-top: 0px;
display: inline-block;
text-align: left;
}
.title-content{
border-left: 3px solid #409EFF;
padding-left: 10px;
}
}
</style>
<style>
/* 课程分组容器 */
.course-group-container {
display: flex;
flex-direction: column;
gap: 20px; /* 分组之间的间距 */
padding: 5px 0;
}
/* 单个课程分组项 */
.course-group-item {
padding: 10px;
background: #f8f9fa;
border-radius: 6px;
}
/* 课程类型标题 */
.course-group-title {
font-size: 14px;
font-weight: 600;
color: #303133;
margin-bottom: 10px;
padding-bottom: 5px;
border-bottom: 1px solid #e6e6e6;
}
</style>

@ -0,0 +1,227 @@
<template>
<div>
<el-form ref="queryForm" :model="queryParams" :inline="true" label-width="75px" class="compact">
<el-form-item label="课程类型:" prop="courseTypeId">
<el-select
v-model="queryParams.courseTypeId"
placeholder="请选择课程类别"
clearable
size="small"
filterable
default-first-option
:loading="loadingSelect"
@change="handleQuery()"
>
<el-option
v-for="item in courseTypeOptions"
:key="item.courseTypeId"
:label="item.courseType"
:value="item.courseTypeId"
/>
</el-select>
</el-form-item>
<el-form-item label="收费模式:" prop="cardType">
<el-select
v-model="queryParams.cardType"
placeholder="请选择收费模式"
size="small"
filterable
default-first-option
:loading="loadingSelect"
@change="handleQuery()"
>
<el-option
v-for="item in chargeTypeOptions"
:key="item.chargeType"
:label="item.chargeTypeName"
:value="item.chargeType"
/>
</el-select>
</el-form-item>
<el-row>
<el-col :span="24" class="text-right">
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery"></el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery"></el-button>
</el-form-item>
</el-col>
</el-row>
</el-form>
<el-table ref="table"
v-loading="loading"
v-table-load-more="loadMore"
:data="dataList"
height="320"
@select="handleSelect"
@row-click="handleRowClick">
<el-table-column type="selection" width="55" align="center" />
<el-table-column prop="courseName" width="300" align="center" label="卡项名称">
<template slot-scope="scope">
<span>
{{ scope.row.cardName }}</span>
</template>
</el-table-column>
<el-table-column prop="courseTypes" width="300" header-align="center" label="课程类别" >
<template slot-scope="scope" >
{{scope.row.courseTypesName}}
</template>
</el-table-column>
<el-table-column prop="restrictedCourses" width="300" header-align="center" label="限制课程">
<template slot-scope="scope" >
<div v-if="scope.row.restrictedCourses=='1'">
全部允许<br>
</div>
<div v-if="scope.row.restrictedCourses=='2'">
<div>
<ul>
<li v-for="item in scope.row.courses" :key="item.id">
{{ item.courseType }} - {{item.courseNames}}
</li>
</ul>
</div>
</div>
</template>
</el-table-column>
<el-table-column prop="restrictedTeacher" width="300" header-align="center" label="限制教练" >
<template slot-scope="scope" >
{{scope.row.restrictedTeacher=='1'?'全部允许':scope.row.teachersName}}
</template>
</el-table-column>
<el-table-column prop="count" width="300" header-align="center" label="总天数/次数/时长" >
<template slot-scope="scope" >
总天数/有效期{{ scope.row.days?scope.row.days+'天':'未定义'}}<br>
课程总次数{{ scope.row.count?scope.row.count+'次':'未定义'}}<br>
应付金额{{ scope.row.totalFee?scope.row.totalFee+'元':'未定义'}}
</template>
</el-table-column>
<template slot="append">
<div v-if="!hasMore" class="append-table-loading"></div>
<div v-else-if="loading" class="append-table-loading">加载中</div>
</template>
</el-table>
</div>
</template>
<script>
import { listMemberCard } from '@/api/school/sc/memberCardType'
import { select as courseTypeSelect } from '@/api/school/sc/course/courseType'
export default {
data() {
return {
open: false,
loading: true,
loadingSelect: false,
//
total: 0,
//
dataList: [],
//
queryParams: {
pageNum: 1,
pageSize: 10,
cardType: 'count',
courseTypeId: undefined,
sale: '1'
},
//
courseTypeOptions: [],
//
chargeTypeOptions: [{
chargeType: 'count',
chargeTypeName: '按次数'
}, {
chargeType: 'days',
chargeTypeName: '按周期'
}, {
chargeType: 'total_fee',
chargeTypeName: '按储值'
}],
chooseCardTypeId: [],
chooseCardTypes: [],
hasMore: false
}
},
created() {
this.initData()
this.courseTypeList()
},
methods: {
initData() {
this.dataList = []
this.getList()
},
courseTypeList() {
courseTypeSelect({}).then(response => {
this.courseTypeOptions = response.data
})
},
/** 查询列表 */
getList() {
this.loading = true
listMemberCard(this.queryParams).then(response => {
this.dataList = [
...this.dataList,
...response.data.rows
]
this.total = response.data.total
this.loading = false
this.hasMore = response.data.current < response.data.pages
this.chooseCardTypeId=[]
this.chooseCardTypes=[]
})
},
loadMore() {
if (this.hasMore) {
this.queryParams.pageNum = this.queryParams.pageNum + 1
this.getList()
}
},
/** 搜索按钮操作 */
handleQuery() {
if (this.queryParams.cardType==undefined ||this.queryParams.cardType==''){
this.msgError('请选择收费模式!')
return;
}
this.queryParams.pageNum = 1
this.dataList = []
this.getList()
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm('queryForm')
this.handleQuery()
},
handleSelect(selection, row) {
const idx = this.chooseCardTypeId.indexOf(row.cardTypeId)
if (idx !== -1) {
this.chooseCardTypeId.splice(idx, 1)
this.chooseCardTypes.splice(idx, 1)
} else {
this.chooseCardTypeId.push(row.cardTypeId)
this.chooseCardTypes.push(row)
}
},
handleRowClick(row) {
// toggleRowSelection
this.$refs.table.toggleRowSelection(row);
this.handleSelect('',row)
//
// const selectedRows = this.$refs.tableRef.selection;
// console.log('', selectedRows);
}
}
}
</script>
<style lang="scss" scoped>
.text-right {
text-align: right;
}
.append-table-loading {
text-align: center;
color: #848484;
padding: 5px;
font-size: 13px;
}
</style>

@ -18,18 +18,18 @@
<div class="item-name">经办校区:</div> <div class="item-name">经办校区:</div>
<div class="item-value">{{ orderInfo.handleDeptName }}</div> <div class="item-value">{{ orderInfo.handleDeptName }}</div>
</div> </div>
<div class="item">
<div class="item-name">经办人:</div>
<div class="item-value">{{ orderInfo.handleStaffName }}</div>
</div>
<div class="item"> <div class="item">
<div class="item-name">经办日期:</div> <div class="item-name">经办日期:</div>
<div class="item-value">{{ orderInfo.handleDate }}</div> <div class="item-value">{{ orderInfo.handleDate }}</div>
</div> </div>
<div class="item"> <div class="item">
<div class="item-name">:</div> <div class="item-name">:</div>
<div class="item-value">{{ orderInfo.studentName }}</div> <div class="item-value">{{ orderInfo.studentName }}</div>
</div> </div>
<div class="item">
<div class="item-name">学员电话:</div>
<div class="item-value">{{ orderInfo.phone }}</div>
</div>
<div class="item"> <div class="item">
<div class="item-name">订单类型:</div> <div class="item-name">订单类型:</div>
<div v-if="orderInfo.orderType === '1'" class="item-value"></div> <div v-if="orderInfo.orderType === '1'" class="item-value"></div>
@ -39,26 +39,14 @@
<div class="item-name">原价:</div> <div class="item-name">原价:</div>
<div class="item-value">¥{{ orderInfo.originalTotalFee }}</div> <div class="item-value">¥{{ orderInfo.originalTotalFee }}</div>
</div> </div>
<div class="item">
<div class="item-name">实际价格:</div>
<div class="item-value">¥{{ orderInfo.actualTotalFee }}</div>
</div>
<div class="item"> <div class="item">
<div class="item-name">实收:</div> <div class="item-name">实收:</div>
<div class="item-value">¥{{ orderInfo.receiptFee }}</div> <div class="item-value">¥{{ orderInfo.receiptFee }}</div>
</div> </div>
<div v-if="orderInfo.balanceFee !== 0" class="item">
<div class="item-name">余额支付:</div>
<div class="item-value">¥{{ orderInfo.balanceFee }}</div>
</div>
<div class="item"> <div class="item">
<div class="item-name">订单标签:</div> <div class="item-name">订单标签:</div>
<div class="item-value">{{ orderInfo.orderTag }}</div> <div class="item-value">{{ orderInfo.orderTag }}</div>
</div> </div>
<div class="item">
<div class="item-name">销售来源:</div>
<div class="item-value">{{ orderInfo.saleSourceTag }}</div>
</div>
<div class="item"> <div class="item">
<div class="item-name">销售员工:</div> <div class="item-name">销售员工:</div>
<div class="item-value">{{ orderInfo.saleStaffName }}</div> <div class="item-value">{{ orderInfo.saleStaffName }}</div>
@ -79,97 +67,54 @@
<div class="title"> <div class="title">
<div class="title-content">收款账户</div> <div class="title-content">收款账户</div>
</div> </div>
<div v-for="(item, index) in orderAccountArray" :key="index" class="cla-base-info">
<div class="item"> <div class="item">
<div class="item-name">收款账户:</div> <div class="item-name">收款账户:</div>
<div class="item-value">{{ item.accountName }}</div> <div class="item-value">{{ orderAccount.accountName }}</div>
</div>
<div class="item">
<div class="item-name">收款金额:</div>
<div class="item-value">{{ item.fee }}</div>
</div>
</div> </div>
<div v-for="item in orderDetailArray" :key="item.orderDetailId" class="top-border">
<div class="top-border">
<div class="title"> <div class="title">
<div class="title-content">报读课程({{ item.courseName }})</div> <div class="title-content">报读卡类({{ orderDetail.cardTypeName }})</div>
</div> </div>
<div class="cla-base-info"> <div class="cla-base-info">
<div class="item"> <div class="item">
<div class="item-name">课程:</div> <div class="item-name">扣费方式:</div>
<div class="item-value">{{ item.courseName }}</div>
</div>
<div class="item">
<div class="item-name">报读校区:</div>
<div class="item-value">{{ item.deptName }}</div>
</div>
<div class="item">
<div class="item-name">类型:</div>
<div class="item-value"> <div class="item-value">
<el-tag v-if="item.detailTag === '1'" size="medium" type="info"></el-tag> {{ orderDetail.chargeType=='count'?'按次数':orderDetail.chargeType=='total_fee'?'按储值':'按周期' }}
<el-tag v-else-if="item.detailTag === '2'" size="medium">续报</el-tag>
<el-tag v-else-if="item.detailTag === '3'" size="medium">扩科</el-tag>
<el-tag v-else size="medium">{{ item.detailTag }}</el-tag>
</div>
</div> </div>
<div v-if="item.claName" class="item">
<div class="item-name">班级:</div>
<div class="item-value">{{ item.claName }}</div>
</div> </div>
<div class="item"> <div class="item">
<div class="item-name">状态:</div> <div class="item-name">卡号: </div>
<div class="item-value"> <div class="item-value">
<el-tag v-if="item.orderDetailStatus === '1'" size="medium" type="info"></el-tag> {{ orderDetail.cardNo }}
<el-tag v-if="item.orderDetailStatus === '2'" size="medium"></el-tag>
<el-tag v-if="item.orderDetailStatus === '3'" size="medium" type="danger"></el-tag>
</div> </div>
</div> </div>
<div class="item"> <div v-if="orderDetail.chargeType=='count'" class="item">
<div class="item-name">收费方式:</div> <div class="item-name">总次数: </div>
<div class="item-value"> <div class="item-value">
<el-tooltip effect="dark" :content="item.chargeName" placement="top"> {{ orderDetail.totalCount }}
<span>{{ item.chargeName }}</span>
</el-tooltip>
</div> </div>
</div> </div>
<div v-if="item.chargeType === 'date'" class="item"> <div v-if="orderDetail.chargeType=='days'" class="item">
<div class="item-name">周期:</div> <div class="item-name">总天数: </div>
<div class="item-value"> <div class="item-value">
<el-tooltip effect="dark" :content="item.beginDate + '~' + item.endDate" placement="top"> {{ orderDetail.totalDays }}
<span>{{ item.beginDate }} ~ {{ item.endDate }}</span>
</el-tooltip>
</div>
</div> </div>
<div v-else-if="item.chargeType !== 'date' && item.expireDate" class="item">
<div class="item-name">过期时间:</div>
<div class="item-value">{{ item.expireDate }}</div>
</div>
<div class="item">
<div class="item-name">购买数量:</div>
<div class="item-value">{{ item.buyCount }}</div>
</div> </div>
<div class="item"> <div v-if="orderDetail.chargeType=='total_fee'" class="item">
<div class="item-name">原价:</div> <div class="item-name">储值金额: </div>
<div class="item-value">¥{{ item.originalFee }}</div> <div class="item-value">
</div> {{ orderDetail.totalFee }}
<div v-if="item.directDiscount !== 10" class="item">
<div class="item-name">折扣:</div>
<div class="item-value">{{ item.directDiscount }}</div>
</div>
<div v-if="item.directReduceFee" class="item">
<div class="item-name">减免:</div>
<div class="item-value">¥{{ item.directReduceFee }}</div>
</div> </div>
<div class="item">
<div class="item-name">实际价格:</div>
<div class="item-value">¥{{ item.actualFee }}</div>
</div> </div>
<div class="item"> <div class="item">
<div class="item-name">内部备注:</div> <div class="item-name">卡片状态:</div>
<div class="item-value">{{ item.insideMemo }}</div> <div class="item-value">{{ orderDetail.statusDesc }}</div>
</div> </div>
<div class="item"> <div class="item">
<div class="item-name">外部备注:</div> <div class="item-name">备注:</div>
<div class="item-value">{{ item.outsideMemo }}</div> <div class="item-value">{{ orderDetail.notes }}</div>
</div> </div>
</div> </div>
</div> </div>
@ -188,8 +133,8 @@ export default {
open: false, open: false,
loading: false, loading: false,
orderInfo: {}, orderInfo: {},
orderDetailArray: [], orderDetail: [],
orderAccountArray: [] orderAccount: []
} }
}, },
methods: { methods: {
@ -199,8 +144,8 @@ export default {
getOrder(orderId).then(response => { getOrder(orderId).then(response => {
this.loading = false this.loading = false
this.orderInfo = response.data.orderInfo this.orderInfo = response.data.orderInfo
this.orderDetailArray = response.data.orderDetail this.orderDetail = response.data.orderDetail
this.orderAccountArray = response.data.orderAccountList this.orderAccount = response.data.orderAccount
}).catch(() => { }).catch(() => {
this.loading = false this.loading = false
}) })

@ -1,7 +1,7 @@
<!--新增学员--> <!--新增学员-->
<template> <template>
<div> <div>
<el-dialog title="新增学员" :visible.sync="open" width="600px"> <el-dialog :title=title :visible.sync="open" width="600px">
<el-form ref="form" :model="form" :rules="rules" label-width="90px"> <el-form ref="form" :model="form" :rules="rules" label-width="90px">
<el-row> <el-row>
<el-col :span="12"> <el-col :span="12">
@ -35,7 +35,6 @@
/> />
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="入校时间:" prop="inTime"> <el-form-item label="入校时间:" prop="inTime">
<el-date-picker <el-date-picker
@ -48,14 +47,16 @@
/> />
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col v-for="(item, index) in contactArray" :key="index" :span="24" style="text-align: left;"> <el-col :span="12">
<el-form-item label="联系电话:"> <el-form-item label="联系电话:" prop="phone">
<el-input v-model="contactArray[index].contactPhone" style="width: 200px;" placeholder="联系电话" /> <el-input v-model="form.phone" placeholder="请输入联系电话" />
<!-- <el-button v-if="index === 0 && contactArray.length > 0" style="padding: 3px 5px;margin-left: 5px;" type="primary" icon="el-icon-plus" size="mini" @click="handleAddContactInfo()" />-->
<!-- <el-button v-if="index > 0" style="padding: 3px 5px;margin-left: 5px;" type="danger" icon="el-icon-minus" size="mini" @click="handleDeleteContactInfo(index)" />-->
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
<span style="color: #999; font-size: 12px; white-space: pre-line;">
* 说明本操作会自动关联相同手机号app用户<br>
如果手机号未在app注册本操作会自动注册一个新的app用户,<br>
登录账号默认为本手机号{{form.phone}}登录密码同为本手机号{{form.phone}}</span>
</el-form> </el-form>
<div slot="footer" class="dialog-footer"> <div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button> <el-button type="primary" @click="submitForm"> </el-button>
@ -74,9 +75,12 @@ export default {
data() { data() {
return { return {
open: false, open: false,
title:"",
remark:'',
// //
form: { form: {
sex: '2' sex: '0',
phone:''
}, },
// //
sexOptions: [], sexOptions: [],
@ -91,7 +95,12 @@ export default {
{ required: true, message: '性别不能为空', trigger: 'blur' } { required: true, message: '性别不能为空', trigger: 'blur' }
], ],
phone: [ phone: [
{ required: true, message: '联系电话不能为空', trigger: 'blur' } { required: true, message: '联系电话不能为空', trigger: 'blur' },
{
pattern: /^[1][3,4,5,6,7,8,9][0-9]{9}$/,
message: '请输入正确电话号码',
trigger: 'blur'
},
] ]
}, },
loadingSelect: false, loadingSelect: false,
@ -122,12 +131,10 @@ export default {
}, },
reset() { reset() {
this.form = { this.form = {
schoolId: undefined,
schoolName: undefined,
studentName: undefined, studentName: undefined,
birthDay: undefined, birthDay: undefined,
sex: '2', sex: '0',
phone: undefined, phone: '',
inTime: moment(new Date()).format('YYYY-MM-DD') inTime: moment(new Date()).format('YYYY-MM-DD')
} }
this.resetForm('form') this.resetForm('form')
@ -153,25 +160,26 @@ export default {
} }
this.open = true this.open = true
this.title = '修改学员基本信息' this.title = '修改学员基本信息'
this.remark=''
}) })
}, },
/** 提交按钮 */ /** 提交按钮 */
submitForm: function() { submitForm: function() {
this.$refs['form'].validate(valid => { this.$refs['form'].validate(valid => {
if (valid) { if (valid) {
this.contactArray.forEach(item => { // this.contactArray.forEach(item => {
if (item.contactRelation === undefined || item.contactRelation === null || item.contactRelation.trim() === '') { // if (item.contactRelation === undefined || item.contactRelation === null || item.contactRelation.trim() === '') {
this.msgError('请选择联系人与学员关系') // this.msgError('')
valid = false // valid = false
} else if (item.contactPhone === undefined || item.contactPhone === null || item.contactPhone.trim() === '') { // } else if (item.contactPhone === undefined || item.contactPhone === null || item.contactPhone.trim() === '') {
this.msgError('请填写联系人电话') // this.msgError('')
valid = false // valid = false
} // }
}) // })
if (!valid) { if (!valid) {
return return
} }
this.form.contactList = this.contactArray // this.form.contactList = this.contactArray
if (this.form.studentId !== undefined) { if (this.form.studentId !== undefined) {
updateStudent(this.form).then(response => { updateStudent(this.form).then(response => {
if (response.respCode === '0000') { if (response.respCode === '0000') {

@ -11,7 +11,7 @@
</div> </div>
<el-table v-else v-loading="loading" :data="dataList" @selection-change="handleSelectionChange"> <el-table v-else v-loading="loading" :data="dataList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" /> <el-table-column type="selection" width="55" align="center" />
<el-table-column align="center" prop="studentName" label="学" fixed="left" /> <el-table-column align="center" prop="studentName" label="学" fixed="left" />
<el-table-column align="center" prop="sex" label="性别" :formatter="sexFormatter" /> <el-table-column align="center" prop="sex" label="性别" :formatter="sexFormatter" />
<el-table-column align="center" prop="phone" label="联系电话" width="120"> <el-table-column align="center" prop="phone" label="联系电话" width="120">
<template slot-scope="scope"> <template slot-scope="scope">
@ -66,7 +66,7 @@
</template> </template>
<script> <script>
import { selectDictLabel } from '@/utils/commonUtils' import { selectDictLabel } from '@/utils/commonUtils'
import { searchCourseClaStudent, studentCourseChooseCla } from '@/api/school/sc/student/course' import { studentCourseChooseCla } from '@/api/school/sc/student/course'
export default { export default {
props: { props: {
// //

@ -12,7 +12,7 @@
</el-col> </el-col>
</el-row> </el-row>
<el-table v-loading="loading" :data="dataList"> <el-table v-loading="loading" :data="dataList">
<el-table-column align="center" prop="studentName" label="学" fixed="left"> <el-table-column align="center" prop="studentName" label="学" fixed="left">
<template slot-scope="scope"> <template slot-scope="scope">
<router-link :to="'/edu/student/detail/' + scope.row.studentId" class="link-type"> <router-link :to="'/edu/student/detail/' + scope.row.studentId" class="link-type">
<span>{{ scope.row.studentName }}</span> <span>{{ scope.row.studentName }}</span>
@ -102,7 +102,7 @@
</template> </template>
<script> <script>
import { selectDictLabel } from '@/utils/commonUtils' import { selectDictLabel } from '@/utils/commonUtils'
import { searchCourseClaStudent, stopStudentCourseStatus, atClaStudentCourseStatus, removeStuFromCla } from '@/api/school/sc/student/course' import { stopStudentCourseStatus, atClaStudentCourseStatus, removeStuFromCla } from '@/api/school/sc/student/course'
import courseStudentChooseCla from '@/components/sc/student/courseStudentChooseCla' import courseStudentChooseCla from '@/components/sc/student/courseStudentChooseCla'
import claTimeAttendDetailTable from '@/components/sc/claTime/claTimeAttendDetailTable' import claTimeAttendDetailTable from '@/components/sc/claTime/claTimeAttendDetailTable'
export default { export default {
@ -182,7 +182,7 @@ export default {
chargeTypeFormatter(row, column) { chargeTypeFormatter(row, column) {
if (row.chargeType === 'date' && row.effect === false && row.balanceDays > 0) { if (row.chargeType === 'date' && row.effect === false && row.balanceDays > 0) {
// > 0 // > 0
return '按课时(未生效)' return '按次数(未生效)'
} else { } else {
return selectDictLabel(this.chargeTypeOptions, row.chargeType) return selectDictLabel(this.chargeTypeOptions, row.chargeType)
} }

@ -23,7 +23,7 @@
</el-form-item> </el-form-item>
</el-form> </el-form>
<el-table v-loading="loading" :data="dataList"> <el-table v-loading="loading" :data="dataList">
<el-table-column align="center" prop="studentName" label="学" fixed="left"> <el-table-column align="center" prop="studentName" label="学" fixed="left">
<template slot-scope="scope"> <template slot-scope="scope">
<!-- <router-link :to="'/edu/student/detail/' + scope.row.studentId" class="link-type">--> <!-- <router-link :to="'/edu/student/detail/' + scope.row.studentId" class="link-type">-->
<span>{{ scope.row.studentName }}</span> <span>{{ scope.row.studentName }}</span>

@ -2,7 +2,7 @@
<el-select <el-select
v-model="studentId" v-model="studentId"
v-select-load-more="loadMoreStudent" v-select-load-more="loadMoreStudent"
placeholder="选择学查询相关信息" placeholder="选择学查询相关信息"
clearable clearable
filterable filterable
default-first-option default-first-option
@ -44,7 +44,7 @@ export default {
defaultStudentId(studentId){ defaultStudentId(studentId){
this.studentId=studentId; this.studentId=studentId;
}, },
// //
searchStudent(query) { searchStudent(query) {
// //
if (this.searchStudentParam.searchValue !== query) { if (this.searchStudentParam.searchValue !== query) {
@ -72,7 +72,7 @@ export default {
this.searchStudentParam.pageNum = this.searchStudentParam.pageNum + 1 this.searchStudentParam.pageNum = this.searchStudentParam.pageNum + 1
this.searchStudent(this.searchStudentParam.searchValue) this.searchStudent(this.searchStudentParam.searchValue)
} else { } else {
this.msgInfo('无更多学数据') this.msgInfo('无更多学数据')
} }
}, },
handleStudentChange(val) { handleStudentChange(val) {

@ -1,12 +1,12 @@
<!-- 列表 --> <!-- 列表 -->
<template> <template>
<div> <div>
<el-form ref="queryForm" :model="queryParams" :inline="true" label-width="80px"> <el-form ref="queryForm" :model="queryParams" :inline="true" label-width="80px">
<el-form-item label="学姓名:" prop="studentName"> <el-form-item label="学姓名:" prop="studentName">
<el-input <el-input
v-model="queryParams.studentName" v-model="queryParams.studentName"
placeholder="请输入学姓名" placeholder="请输入学姓名"
clearable clearable
size="small" size="small"
@keyup.enter.native="handleQuery" @keyup.enter.native="handleQuery"
@ -31,7 +31,7 @@
@keyup.enter.native="handleQuery" @keyup.enter.native="handleQuery"
/> />
</el-form-item> </el-form-item>
<el-form-item> <el-form-item style="float: right">
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery"></el-button> <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery"></el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery"></el-button> <el-button icon="el-icon-refresh" size="mini" @click="resetQuery"></el-button>
</el-form-item> </el-form-item>
@ -67,28 +67,15 @@
@click="handleDelete" @click="handleDelete"
>删除</el-button> >删除</el-button>
</el-col> </el-col>
<el-col :span="1.5">
<el-button
v-hasPermi="['sc:student:list']"
type="primary"
icon="el-icon-upload"
size="mini"
@click="handleImport"
>批量导入
</el-button>
</el-col>
</el-row> </el-row>
<el-table v-loading="loading" :data="dataList" @selection-change="handleSelectionChange"> <el-table v-loading="loading" :data="dataList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" /> <el-table-column type="selection" width="55" align="center" />
<el-table-column prop="studentName" label="学姓名"> <el-table-column prop="studentName" label="学员姓名">
<template slot-scope="scope"> <template slot-scope="scope">
<!-- <router-link :to="'/edu/student/detail/' + scope.row.studentId" class="link-type">-->
<span>{{ scope.row.studentName }}</span> <span>{{ scope.row.studentName }}</span>
<!-- </router-link>-->
</template> </template>
</el-table-column> </el-table-column>
<!-- <el-table-column prop="schoolName" label="所属学校" />-->
<el-table-column prop="birthDay" label="生日"> <el-table-column prop="birthDay" label="生日">
<template slot-scope="scope"> <template slot-scope="scope">
<span>{{ parseTime(scope.row.birthDay, '{y}-{m}-{d}') }}</span> <span>{{ parseTime(scope.row.birthDay, '{y}-{m}-{d}') }}</span>
@ -138,12 +125,12 @@
<change-student ref="changeStudent" @success="getList" /> <change-student ref="changeStudent" @success="getList" />
<upload-check-import-excel ref="uploadCheckImportExcel" title="学批量导入" import-template-name="import_student_order" download-template-name=""> <upload-check-import-excel ref="uploadCheckImportExcel" title="学批量导入" import-template-name="import_student_order" download-template-name="">
<template slot="successTable" slot-scope="scope"> <template slot="successTable" slot-scope="scope">
<el-table :data="scope.data"> <el-table :data="scope.data">
<el-table-column align="center" prop="studentName" label="学姓名" fixed="left" /> <el-table-column align="center" prop="studentName" label="学姓名" fixed="left" />
<el-table-column align="center" prop="contactRelation" label="主要联系人" show-overflow-tooltip /> <!-- <el-table-column align="center" prop="contactRelation" label="主要联系人" show-overflow-tooltip />-->
<el-table-column align="center" prop="contactPhone" label="联系电话" show-overflow-tooltip /> <el-table-column align="center" prop="phone" label="联系电话" show-overflow-tooltip />
<el-table-column align="center" prop="sex" label="性别" show-overflow-tooltip /> <el-table-column align="center" prop="sex" label="性别" show-overflow-tooltip />
<el-table-column align="center" prop="schoolName" label="学校" show-overflow-tooltip /> <el-table-column align="center" prop="schoolName" label="学校" show-overflow-tooltip />
<el-table-column align="center" prop="inTime" label="入校时间" show-overflow-tooltip /> <el-table-column align="center" prop="inTime" label="入校时间" show-overflow-tooltip />
@ -166,10 +153,10 @@
</template> </template>
<template slot="failTable" slot-scope="scope"> <template slot="failTable" slot-scope="scope">
<el-table :data="scope.data"> <el-table :data="scope.data">
<el-table-column align="center" prop="studentName" label="学姓名" fixed="left" /> <el-table-column align="center" prop="studentName" label="学姓名" fixed="left" />
<el-table-column align="center" prop="failMsg" label="失败原因" show-overflow-tooltip fixed="left" /> <el-table-column align="center" prop="failMsg" label="失败原因" show-overflow-tooltip fixed="left" />
<el-table-column align="center" prop="contactRelation" label="主要联系人" show-overflow-tooltip /> <!-- <el-table-column align="center" prop="contactRelation" label="主要联系人" show-overflow-tooltip />-->
<el-table-column align="center" prop="contactPhone" label="联系电话" show-overflow-tooltip /> <el-table-column align="center" prop="phone" label="联系电话" show-overflow-tooltip />
<el-table-column align="center" prop="sex" label="性别" show-overflow-tooltip /> <el-table-column align="center" prop="sex" label="性别" show-overflow-tooltip />
<el-table-column align="center" prop="schoolName" label="学校" show-overflow-tooltip /> <el-table-column align="center" prop="schoolName" label="学校" show-overflow-tooltip />
<el-table-column align="center" prop="inTime" label="入校时间" show-overflow-tooltip /> <el-table-column align="center" prop="inTime" label="入校时间" show-overflow-tooltip />

@ -189,7 +189,7 @@ export default {
title: '', title: '',
open: false, open: false,
loadingChange: false, loadingChange: false,
// M F //
sexOptions: [], sexOptions: [],
// //
personnelStatusOptions: [], personnelStatusOptions: [],
@ -215,7 +215,7 @@ export default {
{ required: true, message: '邮箱不能为空', trigger: 'blur' } { required: true, message: '邮箱不能为空', trigger: 'blur' }
], ],
sex: [ sex: [
{ required: true, message: '性别 M男 F女不能为空', trigger: 'blur' } { required: true, message: '性别 不能为空', trigger: 'blur' }
], ],
entryDate: [ entryDate: [
{ required: true, message: '入职日期不能为空', trigger: 'blur' } { required: true, message: '入职日期不能为空', trigger: 'blur' }

@ -1,6 +1,6 @@
<template> <template>
<el-select <el-select
v-model="staffId" v-model="userId"
v-select-load-more="loadStaff" v-select-load-more="loadStaff"
filterable filterable
:clearable="clearable" :clearable="clearable"
@ -11,27 +11,31 @@
> >
<el-option <el-option
v-for="item in staffList" v-for="item in staffList"
:key="item.staffId" :key="item.userId"
:label="item.staffName" :label="item.nickName"
:value="item.staffId" :value="item.userId"
> >
<div> <!-- <div>-->
<div class="inline-block item"> <!-- <div class="inline-block item">-->
<span class="title">姓名:</span> <!-- <span class="title">姓名:</span>-->
<span class="option">{{ item.staffName }}</span> <!-- <span class="option">{{ item.teacherName}}</span>-->
</div> <!-- </div>-->
<div class="inline-block item"> <!-- <div class="inline-block item">-->
<span class="title">联系电话:</span> <!-- <span class="title">联系电话:</span>-->
<span class="option">{{ item.phone }}</span> <!-- <span class="option">{{ item.phonenumber }}</span>-->
</div> <!-- </div>-->
</div> <!-- </div>-->
</el-option> </el-option>
</el-select> </el-select>
</template> </template>
<script> <script>
import { select } from '@/api/school/system/staff' import { teacherSelect } from '@/api/columns/teacher'
export default { export default {
props: { props: {
deptId: {
type: String,
default: undefined
},
clearable: { clearable: {
type: Boolean, type: Boolean,
default: false default: false
@ -51,7 +55,7 @@ export default {
}, },
data() { data() {
return { return {
staffId: this.value, userId: this.value,
staffList: [], staffList: [],
pageNum: 1, pageNum: 1,
hasMoreData: false hasMoreData: false
@ -60,7 +64,16 @@ export default {
watch: { watch: {
value: { value: {
handler(newValue, oldValue) { handler(newValue, oldValue) {
this.staffId = newValue this.userId = newValue
},
immediate: true
},
deptId: {
handler(newValue, oldValue) {
if (newValue === oldValue && newValue === undefined) {
return
}
this.loadStaff()
}, },
immediate: true immediate: true
} }
@ -70,32 +83,17 @@ export default {
}, },
methods: { methods: {
loadStaff: function() { loadStaff: function() {
if (this.pageNum === 1) {
select({ teacherSelect({
pageNum: this.pageNum, deptId: this.deptId
teacher: this.teacher
}).then(response => { }).then(response => {
if (response.respCode === '0000') { if (response.code === 200) {
this.staffList = response.data.rows this.staffList = response.data
this.hasMoreData = response.data.rows.length > 0
this.pageNum = this.pageNum + 1
} else { } else {
this.msgError(response.respMsg) this.msgError(response.msg)
} }
}) })
} else if (this.hasMoreData) {
select({
pageNum: this.pageNum
}).then(response => {
if (response.respCode === '0000') {
this.staffList = this.staffList.concat(response.data.rows)
this.hasMoreData = response.data.rows.length > 0
this.pageNum = this.pageNum + 1
} else {
this.msgError(response.respMsg)
}
})
}
}, },
handleSelect: function(val) { handleSelect: function(val) {
this.$emit('input', val) this.$emit('input', val)

@ -5,5 +5,5 @@ export const dict_types = ["sys_user_sex",
"pms_publish_status", 'sku_sort_list', "pms_publish_status", 'sku_sort_list',
'sys_show_status','oms_pay_type','oms_order_status','oms_aftersale_status','oms_aftersale_type',"pms_is_course", 'sys_show_status','oms_pay_type','oms_order_status','oms_aftersale_status','oms_aftersale_type',"pms_is_course",
'course_order_type', 'course_order_status','course_order_detail_tag' 'course_order_type', 'course_order_status','course_order_detail_tag'
,'charge_type','date_unit' ,'charge_type','date_unit','book_status'
]; ];

@ -112,7 +112,7 @@
padding: 8px 16px; padding: 8px 16px;
position: relative; position: relative;
height: 600px; height: 700px;
.calendar { .calendar {
position: absolute; position: absolute;

@ -1,7 +1,7 @@
<template> <template>
<div class="app-container"> <div class="app-container">
<!-- 搜索区域 --> <!-- 搜索区域 -->
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px"> <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="100px">
<el-form-item label="老师名称" prop="teacherName"> <el-form-item label="老师名称" prop="teacherName">
<el-input <el-input
v-model="queryParams.teacherName" v-model="queryParams.teacherName"
@ -21,7 +21,7 @@
<el-option label="展示" value="1"></el-option> <el-option label="展示" value="1"></el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item> <el-form-item style="float: right">
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery"></el-button> <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery"></el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery"></el-button> <el-button icon="el-icon-refresh" size="mini" @click="resetQuery"></el-button>
</el-form-item> </el-form-item>
@ -69,7 +69,7 @@
<el-table-column type="selection" width="55" align="center" /> <el-table-column type="selection" width="55" align="center" />
<el-table-column label="员工id" align="center" prop="userId" width="80" /> <el-table-column label="员工id" align="center" prop="userId" width="80" />
<el-table-column label="员工昵称" align="center" prop="nickName" width="80" /> <el-table-column label="员工昵称" align="center" prop="nickName" width="80" />
<el-table-column label="老师名称" align="center" prop="teacherName" /> <el-table-column label="老师名称app展示" align="center" prop="teacherName" />
<el-table-column label="头像" align="center" prop="avatarImg" width="100"> <el-table-column label="头像" align="center" prop="avatarImg" width="100">
<template slot-scope="scope"> <template slot-scope="scope">
<el-image <el-image

@ -82,25 +82,38 @@
<el-tag v-if="scope.row.orderStatus === '3'" size="medium" type="danger"></el-tag> <el-tag v-if="scope.row.orderStatus === '3'" size="medium" type="danger"></el-tag>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="studentName" align="center" label="学" /> <el-table-column prop="studentName" align="center" label="学" />
<el-table-column prop="phone" width="110" align="center" label="联系电话" /> <el-table-column prop="phone" width="110" align="center" label="联系电话" />
<el-table-column prop="orderDetail" width="200" align="center" label="销售内容"> <el-table-column prop="orderDetail" width="200" align="left" label="销售内容">
<template slot-scope="scope"> <template slot-scope="scope">
<el-tooltip effect="dark" placement="left"> {{ scope.row.cardType?'卡类:'+scope.row.cardType:'' }}<br>
<template slot="content"> 卡号 {{ scope.row.cardNo }}<br>
<div v-for="item in scope.row.orderDetail.split(';')" :key="item"> <span v-if="scope.row.chargeType=='count'">
<span>{{ item }}</span> 次数卡{{scope.row.totalCount}}
</div>
</template> </span>
<span style="display:inline-block;width: 180px;overflow: hidden;text-overflow: ellipsis;white-space: nowrap;"> {{ scope.row.orderDetail }} </span> <span v-if="scope.row.chargeType=='days'">
</el-tooltip> 周期卡{{scope.row.totalDays}}
</span>
<span v-if="scope.row.chargeType=='total_fee'">
储值卡{{scope.row.totalFee}}
</span>
{{ scope.row.memberCardStatus }}
<!-- <el-tooltip effect="dark" placement="left">-->
<!-- <template slot="content">-->
<!-- <div v-for="item in scope.row.orderDetail.split(';')" :key="item">-->
<!-- <span>{{ scope.row.chargeType }}</span>-->
<!-- </div>-->
<!-- </template>-->
<!-- <span style="display:inline-block;width: 180px;overflow: hidden;text-overflow: ellipsis;white-space: nowrap;">-->
<!-- {{ scope.row.cardNo }}-->
<!-- </span>-->
<!-- </el-tooltip>-->
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="actualTotalFee" align="center" label="应付(元)" /> <el-table-column prop="originalTotalFee" align="center" label="原价(元)" />
<el-table-column prop="receiptFee" align="center" label="实收(元)" /> <el-table-column prop="receiptFee" align="center" label="实收(元)" />
<el-table-column prop="balanceFee" width="120" align="center" label="余额支付(元)" />
<el-table-column prop="saleStaffName" align="center" label="销售员" /> <el-table-column prop="saleStaffName" align="center" label="销售员" />
<el-table-column prop="orderTag" align="center" label="订单标签" show-overflow-tooltip />
<el-table-column prop="handleDeptName" align="center" label="经办校区" show-overflow-tooltip /> <el-table-column prop="handleDeptName" align="center" label="经办校区" show-overflow-tooltip />
<el-table-column prop="handleDate" width="100" align="center" label="经办日期" /> <el-table-column prop="handleDate" width="100" align="center" label="经办日期" />
<el-table-column prop="createUserName" width="100" align="center" label="经办人" /> <el-table-column prop="createUserName" width="100" align="center" label="经办人" />
@ -114,7 +127,6 @@
<el-dropdown-menu slot="dropdown"> <el-dropdown-menu slot="dropdown">
<el-dropdown-item icon="el-icon-document" @click.native="handleOrderDetail(scope.row)">详情</el-dropdown-item> <el-dropdown-item icon="el-icon-document" @click.native="handleOrderDetail(scope.row)">详情</el-dropdown-item>
<el-dropdown-item icon="el-icon-delete" @click.native="invalidOrder(scope.row)">作废</el-dropdown-item> <el-dropdown-item icon="el-icon-delete" @click.native="invalidOrder(scope.row)">作废</el-dropdown-item>
<!-- <el-dropdown-item v-has-permi="['sc:order:print']" icon="el-icon-printer" @click.native="handlePrintOrder(scope.row)">打印</el-dropdown-item>-->
</el-dropdown-menu> </el-dropdown-menu>
</el-dropdown> </el-dropdown>
</template> </template>
@ -167,10 +179,6 @@ export default {
open: false, open: false,
// //
studentIdOptions: [], studentIdOptions: [],
// 1
orderTypeOptions: [],
//
orderStatusOptions: [],
handleDateArray: [], handleDateArray: [],
// //
queryParams: { queryParams: {
@ -197,12 +205,6 @@ export default {
this.handleDateArray = [startDate, endDate] this.handleDateArray = [startDate, endDate]
} }
this.getList() this.getList()
this.getDictListByDictType('order_type').then(response => {
this.orderTypeOptions = response.data
})
this.getDictListByDictType('order_status').then(response => {
this.orderStatusOptions = response.data
})
}, },
methods: { methods: {
getList() { getList() {
@ -252,7 +254,7 @@ export default {
}) })
}, },
orderTypeFormat(row, column) { orderTypeFormat(row, column) {
return this.selectDictLabel(this.orderTypeOptions, row.orderType) return this.selectDictLabel(this.dict.type.course_order_type, row.orderType)
}, },
// //
invalidOrder(row) { invalidOrder(row) {

File diff suppressed because it is too large Load Diff

@ -163,7 +163,7 @@
<router-link :to="{name: 'Student',params: {activeTab: 'studentSignUpList', minBalanceHour: 5}}"> <router-link :to="{name: 'Student',params: {activeTab: 'studentSignUpList', minBalanceHour: 5}}">
<div class="name">剩余课时小于5课时 <span class="cnt">{{ dashboardData.hourWillExpireCnt }}</span></div> <div class="name">剩余课时小于5课时 <span class="cnt">{{ dashboardData.hourWillExpireCnt }}</span></div>
</router-link> </router-link>
<div class="name">欠费学员 <span class="cnt">{{ dashboardData.arrearsStudentCnt }}</span></div> <div class="name">余额小于200元 <span class="cnt">{{ dashboardData.feeWillExpireCnt }}</span></div>
</div> </div>
</div> </div>
</div> </div>

@ -1,98 +0,0 @@
<template>
<div class="dashboard-editor-container">
<panel-group @handleSetLineChartData="handleSetLineChartData" />
<el-row style="background:#fff;padding:16px 16px 0;margin-bottom:32px;">
<line-chart :chart-data="lineChartData" />
</el-row>
<el-row :gutter="32">
<el-col :xs="24" :sm="24" :lg="8">
<div class="chart-wrapper">
<raddar-chart />
</div>
</el-col>
<el-col :xs="24" :sm="24" :lg="8">
<div class="chart-wrapper">
<pie-chart />
</div>
</el-col>
<el-col :xs="24" :sm="24" :lg="8">
<div class="chart-wrapper">
<bar-chart />
</div>
</el-col>
</el-row>
</div>
</template>
<script>
import PanelGroup from './dashboard/PanelGroup'
import LineChart from './dashboard/LineChart'
import RaddarChart from './dashboard/RaddarChart'
import PieChart from './dashboard/PieChart'
import BarChart from './dashboard/BarChart'
const lineChartData = {
newVisitis: {
expectedData: [100, 120, 161, 134, 105, 160, 165],
actualData: [120, 82, 91, 154, 162, 140, 145]
},
messages: {
expectedData: [200, 192, 120, 144, 160, 130, 140],
actualData: [180, 160, 151, 106, 145, 150, 130]
},
purchases: {
expectedData: [80, 100, 121, 104, 105, 90, 100],
actualData: [120, 90, 100, 138, 142, 130, 130]
},
shoppings: {
expectedData: [130, 140, 141, 142, 145, 150, 160],
actualData: [120, 82, 91, 154, 162, 140, 130]
}
}
export default {
name: 'Index',
components: {
PanelGroup,
LineChart,
RaddarChart,
PieChart,
BarChart
},
data() {
return {
lineChartData: lineChartData.newVisitis
}
},
methods: {
handleSetLineChartData(type) {
this.lineChartData = lineChartData[type]
}
}
}
</script>
<style lang="scss" scoped>
.dashboard-editor-container {
padding: 32px;
background-color: rgb(240, 242, 245);
position: relative;
.chart-wrapper {
background: #fff;
padding: 16px 16px 0;
margin-bottom: 32px;
}
}
@media (max-width:1024px) {
.chart-wrapper {
padding: 8px;
}
}
</style>

@ -77,6 +77,16 @@
:radioData="dict.type.pms_publish_status"/> :radioData="dict.type.pms_publish_status"/>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="8">
<el-form-item label="客服/顾问" prop="customerService">
<user-select v-model="form.customerService" @change="categoryChange"></user-select>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="教练" prop="instructor" v-if="form.isCourse==1">
<user-select v-model="form.instructor" @change="categoryChange"></user-select>
</el-form-item>
</el-col>
</el-row> </el-row>
</el-card> </el-card>
@ -172,13 +182,14 @@
<script> <script>
import {addPmsProduct, getPmsProduct, updatePmsProduct} from "@/api/pms/product"; import {addPmsProduct, getPmsProduct, updatePmsProduct} from "@/api/pms/product";
import userSelect from '@/components/system/user/userSelect'
import ProductCategorySelect from "@/views/components/ProductCategorySelect.vue"; import ProductCategorySelect from "@/views/components/ProductCategorySelect.vue";
import BrandSelect from "@/views/components/BrandSelect.vue"; import BrandSelect from "@/views/components/BrandSelect.vue";
import CourseSelect from "@/views/mall/product/courseSelect"; import CourseSelect from "@/views/mall/product/courseSelect";
export default { export default {
name: "AddProduct", name: "AddProduct",
dicts: ['pms_publish_status','pms_is_course'], dicts: ['pms_publish_status','pms_is_course'],
components: {BrandSelect, ProductCategorySelect,CourseSelect}, components: {BrandSelect, ProductCategorySelect,CourseSelect,userSelect},
data() { data() {
return { return {
@ -192,7 +203,9 @@ export default {
sort: 1000, sort: 1000,
isCourse:'0', isCourse:'0',
courseName:null, courseName:null,
courseId:null courseId:null,
customerService:null,
instructor:null
}, },
skuAttr:[], skuAttr:[],
albumPics:null, albumPics:null,
@ -225,6 +238,7 @@ export default {
}else { }else {
this.form.courseName =null this.form.courseName =null
this.form.courseId =null this.form.courseId =null
this.form.instructor =null
} }
}, },
refreshSku(){ refreshSku(){
@ -318,14 +332,21 @@ export default {
} }
if (this.form.id != null) { if (this.form.id != null) {
updatePmsProduct(this.form).then(response => { updatePmsProduct(this.form).then(response => {
if (response.code!=500){
this.cancel();
this.$modal.msgSuccess("修改成功"); this.$modal.msgSuccess("修改成功");
}
}); });
} else { } else {
addPmsProduct(this.form).then(response => { addPmsProduct(this.form).then(response => {
if (response.code!=500){
this.cancel();
this.$modal.msgSuccess("新增成功"); this.$modal.msgSuccess("新增成功");
}
}); });
} }
this.cancel();
}else{ }else{
if(this.form.name){ if(this.form.name){
this.$alert('请填写规格价格', '提示', { this.$alert('请填写规格价格', '提示', {

@ -25,15 +25,7 @@
</el-select> </el-select>
<!-- <staff-select v-model="queryParams.teacherId" teacher="1" clearable placeholder="选择任课教师" @change="handleChangeTeacher" />--> <!-- <staff-select v-model="queryParams.teacherId" teacher="1" clearable placeholder="选择任课教师" @change="handleChangeTeacher" />-->
</el-form-item> </el-form-item>
<el-form-item v-if="activeTab === 'table'" label="节假日:" prop="filterHoliday">
<el-radio-group v-model="queryParams.filterHoliday">
<el-radio
v-for="dict in filterHolidayOptions"
:key="dict.dictValue"
:label="dict.dictValue"
>{{ dict.dictLabel }}</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item v-if="activeTab === 'table'" label="上课时间:" prop="claDateArray"> <el-form-item v-if="activeTab === 'table'" label="上课时间:" prop="claDateArray">
<el-date-picker <el-date-picker
v-model="claDateArray" v-model="claDateArray"
@ -45,7 +37,7 @@
placeholder="选择开始日期" placeholder="选择开始日期"
/> />
</el-form-item> </el-form-item>
<el-form-item> <el-form-item style="float: right">
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery"></el-button> <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery"></el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery"></el-button> <el-button icon="el-icon-refresh" size="mini" @click="resetQuery"></el-button>
</el-form-item> </el-form-item>
@ -114,12 +106,6 @@
</template> </template>
</el-table-column> </el-table-column>
<el-table-column align="center" width="130" prop="weekDayName" label="上课星期" show-overflow-tooltip /> <el-table-column align="center" width="130" prop="weekDayName" label="上课星期" show-overflow-tooltip />
<el-table-column align="center" prop="filterHoliday" label="节假日">
<template slot-scope="scope">
<el-tag v-if="scope.row.filterHoliday" size="medium"></el-tag>
<el-tag v-else type="danger" size="medium">不过滤</el-tag>
</template>
</el-table-column>
<el-table-column prop="staffName" align="center" label="任课教师" show-overflow-tooltip /> <el-table-column prop="staffName" align="center" label="任课教师" show-overflow-tooltip />
<el-table-column prop="classTheme" align="center" label="上课主题" show-overflow-tooltip /> <el-table-column prop="classTheme" align="center" label="上课主题" show-overflow-tooltip />
<el-table-column width="150" label="操作" align="center" class-name="small-padding fixed-width" fixed="right"> <el-table-column width="150" label="操作" align="center" class-name="small-padding fixed-width" fixed="right">
@ -297,7 +283,7 @@ export default {
/** 删除按钮操作 */ /** 删除按钮操作 */
handleDelete(row) { handleDelete(row) {
const id = row.ruleId || this.ids const id = row.ruleId || this.ids
this.$confirm('是否确认删除?', '警告', { this.$confirm('本操作会将未上课且无学员预约/预约失败/取消预约的相关课表同时删除,已经上完的课程不会被删除,是否确认操作?', '警告', {
confirmButtonText: '确定', confirmButtonText: '确定',
cancelButtonText: '取消', cancelButtonText: '取消',
type: 'warning' type: 'warning'

@ -44,25 +44,7 @@
/> />
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="收费模式:" prop="chargeType"> <el-form-item style="float: right">
<el-select
v-model="queryParams.chargeType"
placeholder="请选择收费模式"
clearable
size="small"
filterable
default-first-option
:loading="loadingSelect"
>
<el-option
v-for="item in chargeTypeOptions"
:key="item.chargeType"
:label="item.chargeTypeName"
:value="item.chargeType"
/>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery"></el-button> <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery"></el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery"></el-button> <el-button icon="el-icon-refresh" size="mini" @click="resetQuery"></el-button>
</el-form-item> </el-form-item>
@ -98,16 +80,6 @@
@click="handleDelete" @click="handleDelete"
>取消班级</el-button> >取消班级</el-button>
</el-col> </el-col>
<!-- <el-col :span="1.5">-->
<!-- <el-button-->
<!-- v-hasPermi="['sc:course:list']"-->
<!-- type="primary"-->
<!-- icon="el-icon-upload"-->
<!-- size="mini"-->
<!-- @click="handleImport"-->
<!-- >批量导入-->
<!-- </el-button>-->
<!-- </el-col>-->
</el-row> </el-row>
<el-table v-loading="loading" :data="dataList" @selection-change="handleSelectionChange"> <el-table v-loading="loading" :data="dataList" @selection-change="handleSelectionChange">
@ -155,7 +127,7 @@
<el-dropdown-menu slot="dropdown"> <el-dropdown-menu slot="dropdown">
<el-dropdown-item v-hasPermi="['sc:cla:update']" icon="el-icon-document-add" @click.native="handleAddRule(scope.row)"></el-dropdown-item> <el-dropdown-item v-hasPermi="['sc:cla:update']" icon="el-icon-document-add" @click.native="handleAddRule(scope.row)"></el-dropdown-item>
<el-dropdown-item v-hasPermi="['sc:cla:update']" icon="el-icon-date" @click.native="handleShowClaCalendar(scope.row)"></el-dropdown-item> <el-dropdown-item v-hasPermi="['sc:cla:update']" icon="el-icon-date" @click.native="handleShowClaCalendar(scope.row)"></el-dropdown-item>
<el-dropdown-item v-hasPermi="['sc:cla:update']" icon="el-icon-data-line" @click.native="handleClaTimeAttend(scope.row)"></el-dropdown-item> <!-- <el-dropdown-item v-hasPermi="['sc:cla:update']" icon="el-icon-data-line" @click.native="handleClaTimeAttend(scope.row)"></el-dropdown-item>-->
<el-dropdown-item v-hasPermi="['sc:cla:update']" icon="el-icon-edit-outline" @click.native="handleUpdate(scope.row)"></el-dropdown-item> <el-dropdown-item v-hasPermi="['sc:cla:update']" icon="el-icon-edit-outline" @click.native="handleUpdate(scope.row)"></el-dropdown-item>
<el-dropdown-item v-hasPermi="['sc:cla:delete']" icon="el-icon-delete" @click.native="handleDelete(scope.row)"></el-dropdown-item> <el-dropdown-item v-hasPermi="['sc:cla:delete']" icon="el-icon-delete" @click.native="handleDelete(scope.row)"></el-dropdown-item>
</el-dropdown-menu> </el-dropdown-menu>
@ -284,17 +256,6 @@ export default {
courseOptions: [], courseOptions: [],
// //
teacherOptions: [], teacherOptions: [],
//
chargeTypeOptions: [{
chargeType: 'hour',
chargeTypeName: '按课时'
}, {
chargeType: 'date',
chargeTypeName: '按时间'
}, {
chargeType: 'cycle',
chargeTypeName: '按周期'
}],
// ,, // ,,
courseTimeOptions: [], courseTimeOptions: [],
// //
@ -303,7 +264,6 @@ export default {
pageSize: 10, pageSize: 10,
courseId: undefined, courseId: undefined,
teacherId: undefined, teacherId: undefined,
chargeId: '',
claName: undefined, claName: undefined,
courseTime: undefined courseTime: undefined
}, },
@ -318,9 +278,6 @@ export default {
teacherId: [ teacherId: [
{ required: true, message: '教师id不能为空', trigger: 'blur' } { required: true, message: '教师id不能为空', trigger: 'blur' }
], ],
chargeId: [
{ required: true, message: '收费方式id不能为空', trigger: 'blur' }
],
claName: [ claName: [
{ required: true, message: '班级名称不能为空', trigger: 'blur' } { required: true, message: '班级名称不能为空', trigger: 'blur' }
], ],
@ -481,9 +438,6 @@ export default {
return '-' return '-'
} }
}, },
handleImport() {
this.$refs.uploadCheckImportExcel.openImport()
}
} }
} }
</script> </script>

@ -64,24 +64,6 @@
/> />
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="收费模式:" prop="chargeType">
<el-select
v-model="queryParams.chargeType"
placeholder="请选择收费模式"
clearable
size="small"
filterable
default-first-option
:loading="loadingSelect"
>
<el-option
v-for="item in chargeTypeOptions"
:key="item.chargeType"
:label="item.chargeTypeName"
:value="item.chargeType"
/>
</el-select>
</el-form-item>
<el-form-item label="开售:" prop="sale"> <el-form-item label="开售:" prop="sale">
<el-switch <el-switch
v-model="queryParams.sale" v-model="queryParams.sale"
@ -129,26 +111,6 @@
>删除课程 >删除课程
</el-button> </el-button>
</el-col> </el-col>
<!-- <el-col :span="1.5">-->
<!-- <el-button-->
<!-- v-hasPermi="['sc:course:list']"-->
<!-- type="primary"-->
<!-- icon="el-icon-download"-->
<!-- size="mini"-->
<!-- @click="handleExport"-->
<!-- >导出当前结果-->
<!-- </el-button>-->
<!-- </el-col>-->
<!-- <el-col :span="1.5">-->
<!-- <el-button-->
<!-- v-hasPermi="['sc:course:list']"-->
<!-- type="primary"-->
<!-- icon="el-icon-upload"-->
<!-- size="mini"-->
<!-- @click="handleImport"-->
<!-- >批量导入-->
<!-- </el-button>-->
<!-- </el-col>-->
</el-row> </el-row>
<el-table v-loading="loading" :data="dataList" @selection-change="handleSelectionChange"> <el-table v-loading="loading" :data="dataList" @selection-change="handleSelectionChange">
@ -170,11 +132,6 @@
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="claCount" align="center" label="开班数" /> <el-table-column prop="claCount" align="center" label="开班数" />
<el-table-column prop="chargeNames" align="center" width="120" label="收费模式" :show-overflow-tooltip="true">
<template slot-scope="scope">
{{ chargeNameByCodes(scope.row.chargeNames) }}
</template>
</el-table-column>
<el-table-column prop="claFee" align="center" label="教练课时费/节" > <el-table-column prop="claFee" align="center" label="教练课时费/节" >
<template slot-scope="scope"> <template slot-scope="scope">
{{ scope.row.claFee }} {{ scope.row.claFee }}
@ -182,11 +139,10 @@
</el-table-column> </el-table-column>
<el-table-column prop="campusIds" align="center" label="开课校区"> <el-table-column prop="campusIds" align="center" label="开课校区">
<template slot-scope="scope"> <template slot-scope="scope">
<div v-if="scope.row.campusIds"> <div >
<span v-if="scope.row.campusIds === '-1'"></span> <span v-if="scope.row.campusIds==null"></span>
<span v-else>{{ scope.row.campusIds.split(',').length }}</span> <span v-else>{{ scope.row.campusIds.split(',').length }}</span>
</div> </div>
<div v-else> - </div>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="createTime" width="100" align="center" label="创建时间"> <el-table-column prop="createTime" width="100" align="center" label="创建时间">
@ -240,7 +196,7 @@
</template> </template>
<script> <script>
import {changeCourseSale, delCourse, exportCourse, getCourse, listCourse} from '@/api/school/sc/course' import {changeCourseSale, delCourse, getCourse, listCourse} from '@/api/school/sc/course'
import addCourseComponents from '@/components/sc/course/addCourse' import addCourseComponents from '@/components/sc/course/addCourse'
import uploadImportExcel from '@/components/tool/impt/uploadImportExcel' import uploadImportExcel from '@/components/tool/impt/uploadImportExcel'
import {select as courseTypeSelect} from '@/api/school/sc/course/courseType' import {select as courseTypeSelect} from '@/api/school/sc/course/courseType'
@ -294,7 +250,7 @@ export default {
// //
chargeTypeOptions: [{ chargeTypeOptions: [{
chargeType: 'hour', chargeType: 'hour',
chargeTypeName: '按课时' chargeTypeName: '按次数'
}, { }, {
chargeType: 'date', chargeType: 'date',
chargeTypeName: '按时间' chargeTypeName: '按时间'
@ -356,13 +312,12 @@ export default {
handleUpdate(row) { handleUpdate(row) {
getCourse(row.courseId || this.ids).then(response => { getCourse(row.courseId || this.ids).then(response => {
this.$refs.addCourseComponents.init() this.$refs.addCourseComponents.init()
response.data.partCampus=response.data.partCampus?.map(item => {
return parseInt(item)
})
this.$refs.addCourseComponents.form = response.data this.$refs.addCourseComponents.form = response.data
if (response.data.partCampus==null){
this.$refs.addCourseComponents.form.partCampus=[]
}
this.$refs.addCourseComponents.open = true this.$refs.addCourseComponents.open = true
this.$refs.addCourseComponents.title = '修改课程信息' this.$refs.addCourseComponents.title = '修改课程信息'
this.$refs.addCourseComponents.initFeeModeDate(response.data)
}) })
}, },
/** 删除按钮操作 */ /** 删除按钮操作 */
@ -388,33 +343,13 @@ export default {
that.loadingChange = false that.loadingChange = false
}) })
}, },
handleExport() {
const queryParams = this.queryParams
const that = this
this.$confirm('是否确认导出当前查询结果?', '警告', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(function() {
that.notifyInstance = that.$notify.info({
title: '提示',
message: '文件下载中,请稍后',
duration: 0
})
return exportCourse(queryParams)
}).then(response => {
this.downExportFile(response.data, '课程导出.xlsx', that.notifyInstance)
}).catch(function() {})
},
handleImport() {
this.$refs.uploadImportExcel.open = true
},
chargeNameByCodes(chargeNames) { chargeNameByCodes(chargeNames) {
if (chargeNames) { if (chargeNames) {
const chargeNameArray = [] const chargeNameArray = []
chargeNames.split(',').forEach((value, index, array) => { chargeNames.split(',').forEach((value, index, array) => {
if (value === 'hour') { if (value === 'hour') {
chargeNameArray.push('按课时') chargeNameArray.push('按次数')
} else if (value === 'date') { } else if (value === 'date') {
chargeNameArray.push('按时间') chargeNameArray.push('按时间')
} else if (value === 'cycle') { } else if (value === 'cycle') {
@ -426,7 +361,7 @@ export default {
return '-' return '-'
} }
}, },
// //
handleSaleChange(row) { handleSaleChange(row) {
const text = row.sale === '1' ? '开售' : '停售' const text = row.sale === '1' ? '开售' : '停售'
this.$confirm('确认要"' + text + '""' + row.courseName + '"课程吗?', '警告', { this.$confirm('确认要"' + text + '""' + row.courseName + '"课程吗?', '警告', {

@ -1,6 +1,6 @@
<template> <template>
<div class="app-container"> <div class="app-container">
<el-form ref="queryForm" :model="queryParams" :inline="true" label-width="68px"> <el-form ref="queryForm" :model="queryParams" :inline="true" label-width="100px">
<el-form-item label="课程类型名" prop="courseType"> <el-form-item label="课程类型名" prop="courseType">
<el-select v-model="queryParams.courseType" placeholder="请选择课程类型名" clearable size="small"> <el-select v-model="queryParams.courseType" placeholder="请选择课程类型名" clearable size="small">
<el-option <el-option
@ -47,22 +47,23 @@
@click="handleDelete" @click="handleDelete"
>删除</el-button> >删除</el-button>
</el-col> </el-col>
<el-col :span="1.5">
<el-button
v-hasPermi="['::export']"
type="primary"
icon="el-icon-download"
size="mini"
@click="handleExport"
>导出</el-button>
</el-col>
</el-row> </el-row>
<el-table v-loading="loading" :data="dataList" @selection-change="handleSelectionChange"> <el-table v-loading="loading" :data="dataList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" /> <el-table-column type="selection" width="55" align="center" />
<el-table-column prop="tenantId" label="所属租户" /> <el-table-column prop="courseType" width="170" label="课程类型名" />
<el-table-column prop="courseType" label="课程类型名" /> <el-table-column prop="sort" width="120" label="排序" />
<el-table-column prop="sort" label="排序" /> <el-table-column prop="inUse" width="120" align="center" label="开售">
<template slot-scope="scope">
<el-switch
v-model="scope.row.inUse"
active-value="1"
inactive-value="0"
@change="handleSaleChange(scope.row)"
/>
</template>
</el-table-column>
<el-table-column prop="remark" align="center" label="类型说明" />
<el-table-column width="150" label="操作" align="center" class-name="small-padding fixed-width"> <el-table-column width="150" label="操作" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope"> <template slot-scope="scope">
<el-button <el-button
@ -97,7 +98,7 @@
</template> </template>
<script> <script>
import { listType, getType, delType, select as courseTypeSelect } from '@/api//school/sc/course/courseType' import { listType, getType, delType, select as courseTypeSelect,changeCourseTypeSale } from '@/api//school/sc/course/courseType'
import addCourseType from '@/components/sc/course/type/addCourseType' import addCourseType from '@/components/sc/course/type/addCourseType'
export default { export default {
name: 'Type', name: 'Type',
@ -207,6 +208,21 @@ export default {
this.msgError(response.respMsg) this.msgError(response.respMsg)
} }
}).catch(function() {}) }).catch(function() {})
},
//
handleSaleChange(row) {
const text = row.inUse === '1' ? '开售' : '停售'
this.$confirm('确认要"' + text + '""' + row.courseType + '"课程类型吗?', '警告', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(function() {
return changeCourseTypeSale(row.courseTypeId, row.inUse)
}).then(() => {
this.msgSuccess(text + '成功')
}).catch(function() {
row.inUse = row.inUse === '0' ? '1' : '0'
})
} }
} }
} }

@ -0,0 +1,334 @@
<template>
<div class="app-container">
<el-form ref="queryForm" :model="queryParams" :inline="true" label-width="100px">
<el-form-item label="会员卡名称:" prop="cardName" >
<el-input
v-model="queryParams.cardName"
placeholder="请输入会员卡名称"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="开售:" prop="sale">
<el-switch
v-model="queryParams.sale"
active-value="1"
inactive-value="0"
/>
</el-form-item>
<el-form-item style="float: right">
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery"></el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery"></el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
v-hasPermi="['sc:course:add']"
type="primary"
icon="el-icon-plus"
size="mini"
@click="handleAdd"
>新设会员卡
</el-button>
</el-col>
<el-col :span="1.5">
<el-button
v-hasPermi="['sc:course:update']"
type="primary"
icon="el-icon-edit-outline"
size="mini"
:disabled="single"
@click="handleUpdate"
>修改会员卡
</el-button>
</el-col>
<el-col :span="1.5">
<el-button
v-hasPermi="['sc:course:delete']"
v-loading="loadingChange"
type="danger"
icon="el-icon-delete"
size="mini"
:disabled="multiple"
@click="handleDelete"
>删除会员卡
</el-button>
</el-col>
</el-row>
<el-table v-loading="loading" :data="dataList" :border="true" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column prop="cardName" width="120" align="center" label="会员卡名称" />
<el-table-column prop="courseTypes" width="100" header-align="center" label="课程类别" >
<template slot-scope="scope" >
{{scope.row.courseTypesName}}
</template>
</el-table-column>
<el-table-column prop="restrictedCourses" width="180" header-align="center" label="限制课程">
<template slot-scope="scope" >
<div v-if="scope.row.restrictedCourses=='1'">
全部允许<br>
</div>
<div v-if="scope.row.restrictedCourses=='2'">
<div>
<ul>
<li v-for="item in scope.row.courses" :key="item.id">
{{ item.courseType }} - {{item.courseNames}}
</li>
</ul>
</div>
</div>
</template>
</el-table-column>
<el-table-column prop="restrictedTeacher" width="100" header-align="center" label="限制教练" >
<template slot-scope="scope" >
{{scope.row.restrictedTeacher=='1'?'全部允许':scope.row.teachersName}}
</template>
</el-table-column>
<el-table-column prop="restrictedNum" align="center" width="120" label="次数限制" >
<template slot-scope="scope" >
{{ scope.row.restrictedNum=='1'?'不限次数':'限制次数'}}<br>
<div v-if="scope.row.restrictedNum=='2'">
{{scope.row.bookTime}}内只能使用{{scope.row.bookNum}}
</div>
</template>
</el-table-column>
<el-table-column prop="totalFee" width="150" header-align="center" label="每节课扣次或费用">
<template slot-scope="scope" >
<div v-if="scope.row.chargeType=='default'">
默认<br>
{{scope.row.defaultNum}}或扣{{scope.row.defaultFee}}
</div>
<div v-if="scope.row.chargeType=='customize'">
<div>
<ul>
<li v-for="item in scope.row.feeModeHourList" :key="item.courseTypeId">
{{ item.courseType }} - {{item.cnt}}{{item.totalFee}}
</li>
</ul>
</div>
</div>
</template>
</el-table-column>
<el-table-column prop="count" width="180" header-align="center" label="总天数/次数/时长" >
<template slot-scope="scope" >
总天数/有效期{{ scope.row.days?scope.row.days+'天':'未定义'}}<br>
课程总次数{{ scope.row.count?scope.row.count+'次':'未定义'}}<br>
应付金额{{ scope.row.totalFee?scope.row.totalFee+'元':'未定义'}}
</template>
</el-table-column>
<!-- :show-overflow-tooltip="true"-->
<el-table-column prop="description" width="180" header-align="center" label="会员卡简介" />
<el-table-column prop="conditions" width="180" header-align="center" label="会员卡条款" />
<el-table-column prop="createTime" width="100" align="center" label="创建时间">
<template slot-scope="scope">{{ parseTime(scope.row.createTime, '{y}-{m}-{d}') }}</template>
</el-table-column>
<el-table-column prop="sale" align="center" label="开售">
<template slot-scope="scope">
<el-switch
v-model="scope.row.sale"
active-value="1"
inactive-value="0"
@change="handleSaleChange(scope.row)"
/>
</template>
</el-table-column>
<el-table-column width="100" label="操作" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-button
v-hasPermi="['sc:course:update']"
size="mini"
type="text"
icon="el-icon-edit-outline"
@click="handleUpdate(scope.row)"
>变更信息
</el-button>
<el-button
v-hasPermi="['sc:course:delete']"
v-loading="loadingChange"
size="mini"
type="text"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
>删除会员卡
</el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
<add-member-cart-types ref="addCourseComponents" @success="getList" />
</div>
</template>
<script>
import {
listMemberCard,
getMemberCard,
delMemberCard,
editSale
} from '@/api/school/sc/memberCardType'
import addMemberCartTypes from '@/components/sc/memberCardTypes/addMemberCardTypes.vue'
export default {
name: 'Course',
components: {
addMemberCartTypes
},
data() {
return {
//
loading: true,
loadingChange: false,
loadingSelect: false,
//
ids: [],
//
single: true,
//
multiple: true,
//
total: 0,
//
dataList: [],
//
queryParams: {
pageNum: 1,
pageSize: 10,
cardName: undefined,
sale: '1'
},
//
courseTypeOptions: [],
//
campusOptions: [],
//
chargeTypeOptions: [{
chargeType: 'hour',
chargeTypeName: '按次数'
}, {
chargeType: 'date',
chargeTypeName: '按时间'
}, {
chargeType: 'cycle',
chargeTypeName: '按周期'
}],
notifyInstance: null
}
},
created() {
this.getList()
},
methods: {
/** 查询列表 */
getList() {
this.loading = true
listMemberCard(this.queryParams).then(response => {
this.dataList = response.data.rows
this.total = response.data.total
this.loading = false
})
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1
this.getList()
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm('queryForm')
this.handleQuery()
},
/** 新增按钮操作 */
handleAdd(row) {
this.$refs.addCourseComponents.init()
this.$refs.addCourseComponents.reset()
this.$refs.addCourseComponents.open = true
},
//
handleSelectionChange(selection) {
this.ids = selection.map(item => item.cardTypeId)
this.single = selection.length !== 1
this.multiple = !selection.length
},
/** 修改按钮操作 */
handleUpdate(row) {
getMemberCard(row.cardTypeId || this.ids).then(response => {
this.$refs.addCourseComponents.init()
this.$refs.addCourseComponents.form = response.data
this.$refs.addCourseComponents.open = true
this.$refs.addCourseComponents.title = '修改会员卡信息'
this.$refs.addCourseComponents.initFeeModeDate(response.data)
})
},
/** 删除按钮操作 */
handleDelete(row) {
const that = this
const id = row.cardTypeId || this.ids
this.$confirm('是否确认删除?', '警告', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(function() {
that.loadingChange = true
return delMemberCard(id)
}).then((response) => {
that.loadingChange = false
if (response.respCode === '0000') {
this.getList()
this.msgSuccess('删除成功')
} else {
this.msgError(response.respMsg)
}
}).catch(function() {
that.loadingChange = false
})
},
chargeNameByCodes(chargeNames) {
if (chargeNames) {
const chargeNameArray = []
chargeNames.split(',').forEach((value, index, array) => {
if (value === 'hour') {
chargeNameArray.push('按次数')
} else if (value === 'date') {
chargeNameArray.push('按时间')
} else if (value === 'cycle') {
chargeNameArray.push('按周期')
}
})
return chargeNameArray.toString()
} else {
return '-'
}
},
//
handleSaleChange(row) {
const text = row.sale === '1' ? '开售' : '停售'
this.$confirm('确认要"' + text + '""' + row.cardName + '"会员卡吗?', '警告', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(function() {
return editSale({cardTypeId:row.cardTypeId, sale:row.sale})
}).then(() => {
this.msgSuccess(text + '成功')
}).catch(function() {
row.sale = row.sale === '0' ? '1' : '0'
})
}
}
}
</script>

@ -1,309 +0,0 @@
<template>
<div class="app-container">
<el-form ref="queryForm" :model="queryParams" :inline="true" label-width="68px">
<el-form-item label="订单类型" prop="orderType">
<el-select v-model="queryParams.orderType" placeholder="请选择订单类型" clearable size="small">
<el-option
v-for="dict in orderTypeOptions"
:key="dict.dictValue"
:label="dict.dictLabel"
:value="dict.dictValue"
/>
</el-select>
</el-form-item>
<el-form-item label="校区:" prop="deptId">
<dept-select v-model="queryParams.deptId" />
</el-form-item>
<el-form-item label="课程:" prop="courseId">
<course-select v-model="queryParams.courseId" :dept-id="queryParams.deptId" clearable mounted-load-all />
</el-form-item>
<el-form-item label="订单状态" prop="orderStatus">
<el-select v-model="queryParams.orderStatus" placeholder="请选择订单状态" clearable size="small">
<el-option
v-for="dict in orderStatusOptions"
:key="dict.dictValue"
:label="dict.dictLabel"
:value="dict.dictValue"
/>
</el-select>
</el-form-item>
<el-form-item label="经办日期" prop="handleDateArray">
<el-date-picker
v-model="handleDateArray"
clearable
size="small"
style="width: 230px"
type="daterange"
value-format="yyyy-MM-dd"
placeholder="选择经办日期"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery"></el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery"></el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-dropdown>
<el-button type="primary" size="mini">
业务办理 <i class="el-icon-arrow-down el-icon--right" />
</el-button>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item v-has-permi="['sc:order:handleSignUp']" icon="el-icon-plus" @click.native="signUp">报名</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</el-col>
<el-col :span="1.5">
<el-button
v-hasPermi="['sc:order:batchInvalid']"
v-loading="loadingChange"
type="danger"
icon="el-icon-delete"
size="mini"
:disabled="multiple"
@click="batchInvalidOrder"
>批量作废订单
</el-button>
</el-col>
</el-row>
<el-table v-loading="loading" :data="dataList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column prop="orderId" width="170" align="center" label="订单编号" fixed="left">
<template slot-scope="scope">
<span style="text-decoration: underline;cursor: pointer;" @click="handleOrderDetail(scope.row)">{{ scope.row.orderId }}</span>
</template>
</el-table-column>
<el-table-column prop="orderType" align="center" label="订单类型" :formatter="orderTypeFormat" fixed="left" />
<el-table-column prop="orderStatus" align="center" label="订单状态" fixed="left">
<template slot-scope="scope">
<el-tag v-if="scope.row.orderStatus === '1'" size="medium" type="info"></el-tag>
<el-tag v-if="scope.row.orderStatus === '2'" size="medium"></el-tag>
<el-tag v-if="scope.row.orderStatus === '3'" size="medium" type="danger"></el-tag>
</template>
</el-table-column>
<el-table-column prop="studentName" align="center" label="学生" />
<el-table-column prop="phone" width="110" align="center" label="联系电话" />
<el-table-column prop="orderDetail" width="200" align="center" label="销售内容">
<template slot-scope="scope">
<el-tooltip effect="dark" placement="left">
<template slot="content">
<div v-for="item in scope.row.orderDetail.split(';')" :key="item">
<span>{{ item }}</span>
</div>
</template>
<span style="display:inline-block;width: 180px;overflow: hidden;text-overflow: ellipsis;white-space: nowrap;"> {{ scope.row.orderDetail }} </span>
</el-tooltip>
</template>
</el-table-column>
<el-table-column prop="actualTotalFee" align="center" label="应付(元)" />
<el-table-column prop="receiptFee" align="center" label="实收(元)" />
<el-table-column prop="balanceFee" width="120" align="center" label="余额支付(元)" />
<el-table-column prop="saleStaffName" align="center" label="销售员" />
<el-table-column prop="orderTag" align="center" label="订单标签" show-overflow-tooltip />
<el-table-column prop="handleDeptName" align="center" label="经办校区" show-overflow-tooltip />
<el-table-column prop="handleDate" width="100" align="center" label="经办日期" />
<el-table-column prop="createUserName" width="100" align="center" label="经办人" />
<el-table-column prop="memo" align="center" label="办理备注" show-overflow-tooltip />
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" fixed="right">
<template slot-scope="scope">
<el-dropdown trigger="click">
<span style="cursor: pointer;color: #409EFF;outline: none;">
操作<i class="el-icon-arrow-down el-icon--right" style="font-size: 12px;" />
</span>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item icon="el-icon-document" @click.native="handleOrderDetail(scope.row)">详情</el-dropdown-item>
<el-dropdown-item icon="el-icon-delete" @click.native="invalidOrder(scope.row)">作废</el-dropdown-item>
<el-dropdown-item v-has-permi="['sc:order:print']" icon="el-icon-printer" @click.native="handlePrintOrder(scope.row)">打印</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
<order-detail ref="orderDetail" />
</div>
</template>
<script>
import { selectDictLabel } from '@/utils/commonUtils'
import { listOrder, invalidById } from '@/api/school/sc/order'
import orderDetail from '@/components/sc/order/orderDetail'
import deptSelect from '@/components/system/dept/deptSelect'
import courseSelect from '@/components/sc/course/courseSelect'
import moment from 'moment'
export default {
name: 'Order',
components: {
orderDetail,
deptSelect,
courseSelect
},
data() {
return {
//
loading: true,
loadingChange: false,
//
ids: [],
//
single: true,
//
multiple: true,
//
total: 0,
//
dataList: [],
//
open: false,
//
studentIdOptions: [],
// 1
orderTypeOptions: [],
//
orderStatusOptions: [],
handleDateArray: [],
//
queryParams: {
pageNum: 1,
pageSize: 10,
studentId: undefined,
orderType: undefined,
handleDate: undefined
},
//
form: {},
//
rules: {
}
}
},
created() {
const handleDate = this.$route.query.handleDate
if (handleDate !== undefined && handleDate === 'thisMonth') {
//
const startDate = moment().month(moment().month()).startOf('month').format('YYYY-MM-DD')
const endDate = moment().month(moment().month()).endOf('month').format('YYYY-MM-DD')
this.handleDateArray = [startDate, endDate]
}
this.getList()
this.getDictListByDictType('course_order_type').then(response => {
this.orderTypeOptions = response.data
})
this.getDictListByDictType('course_order_status').then(response => {
this.orderStatusOptions = response.data
})
},
methods: {
getList() {
this.loading = true
listOrder(this.queryParams).then(response => {
this.dataList = response.data.rows
this.total = response.data.total
this.loading = false
})
},
//
cancel() {
this.open = false
this.reset()
},
//
reset() {
this.form = {
}
this.resetForm('form')
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1
if (this.handleDateArray !== undefined && this.handleDateArray !== null && this.handleDateArray.length === 2) {
this.queryParams.handleDate = this.handleDateArray.toString()
} else {
this.queryParams.handleDate = undefined
}
this.getList()
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm('queryForm')
this.handleQuery()
},
//
handleSelectionChange(selection) {
this.ids = selection.map(item => item.orderId)
this.single = selection.length !== 1
this.multiple = !selection.length
},
//
signUp() {
this.$router.push({
path: '/order/handle/signUp'
})
},
orderTypeFormat(row, column) {
return selectDictLabel(this.orderTypeOptions, row.orderType)
},
//
invalidOrder(row) {
const that = this
this.confirm('确定作废本订单?', function() {
that.loading = true
invalidById(row.orderId).then(response => {
that.loading = false
if (response.respCode === '0000') {
that.msgSuccess('作废成功')
that.getList()
} else {
that.msgError(response.respMsg)
}
}).catch(() => {
that.loading = false
})
})
},
//
batchInvalidOrder(row) {
const that = this
const id = this.ids
this.confirm('确定作废已选择订单?', function() {
that.loading = true
invalidById(id).then(response => {
that.loading = false
if (response.respCode === '0000') {
that.msgSuccess('作废成功')
that.getList()
} else {
that.msgError(response.respMsg)
}
}).catch(() => {
that.loading = false
that.getList()
})
})
},
//
handleOrderDetail(row) {
this.$refs.orderDetail.loadOrderDetail(row.orderId)
},
//
handlePrintOrder(row) {
this.$router.push({
path: '/order/handle/print/' + row.orderId
})
}
}
}
</script>
<style rel="stylesheet/scss" lang="scss" scoped>
</style>

@ -1,280 +0,0 @@
<template>
<div ref="print" class="print-container">
<div class="print-title">
<span>{{ tenantInfo.tenantName }}</span>
<span>业务凭证</span>
</div>
<div class="header-info">
<div class="left-info">
<div class="header-item">学员姓名: {{ orderInfo.studentName }}</div>
<div class="header-item">经办日期: {{ orderInfo.handleDate }}</div>
<div v-if="orderInfo.orderType === '1'" class="header-item">: </div>
<div v-else class="header-item">类型: {{ orderInfo.orderType }}</div>
</div>
<div class="right-info">订单: {{ orderInfo.orderId }}</div>
</div>
<div class="print-content">
<div v-for="item in orderDetailArray" :key="item.orderDetailId">
<div class="header">
<div class="top-title w150">课程信息</div>
<div class="top-title w150">班级</div>
<div class="top-title w150">收费方式</div>
<div class="top-title w50">数量</div>
<div class="top-title w80">原价</div>
<div class="top-title w150">折扣/减免</div>
<div class="top-title w80">实际价格</div>
<div class="top-title flex1">备注</div>
</div>
<div class="content">
<div class="value w150">{{ item.courseName }}({{ item.deptName }})</div>
<div class="value w150">{{ item.claName||'' }}</div>
<div class="value w150">{{ item.chargeName }}</div>
<div class="value w50">{{ item.buyCount }}</div>
<div class="value w80">¥{{ item.originalFee }}</div>
<div class="value w150">
<span v-if="item.directDiscount && item.directDiscount !== 10">{{ item.directDiscount }} </span>
<span v-if="item.directReduceFee && item.directReduceFee !== 0"> :¥{{ item.directReduceFee }}</span>
</div>
<div class="value w80">¥{{ item.actualFee }}</div>
<div class="value flex1">{{ item.outsideMemo }}</div>
</div>
</div>
<div class="content">
<div class="value flex1">备注: {{ orderInfo.memo||'' }}</div>
</div>
<div class="content">
<div class="value flex1">
<span class="span-title">原价总计:</span>
<span>¥{{ orderInfo.originalTotalFee }}</span>
</div>
<div class="value flex1">
<span class="span-title">实际价格:</span>
<span>¥{{ orderInfo.actualTotalFee }}</span>
</div>
<div class="value flex1">
<span class="span-title">实收:</span>
<span>¥{{ orderInfo.receiptFee }}</span>
</div>
<div class="value flex1">
<span class="span-title">余额支付:</span>
<span>¥{{ orderInfo.balanceFee }}</span>
</div>
</div>
<div class="content">
<div class="value flex1">
<span class="span-title">收款方式:</span>
<span v-for="(item, index) in orderAccountArray" :key="index">
<span style="margin-right: 15px;">{{ item.accountName }}: {{ item.fee }}</span>
</span>
</div>
</div>
<div class="content">
<div class="value flex1">
<div>地址:</div>
<div>{{ tenantInfo.contactAddress }}</div>
</div>
<div class="value flex1">
<div>联系电话:</div>
<div>{{ tenantInfo.contactPhone }}</div>
</div>
<div class="value flex1">
<div>经办人:</div>
<div>{{ orderInfo.handleStaffName }}</div>
</div>
<div class="value flex1">
<div>打印时间:</div>
<div>{{ now }}</div>
</div>
<div class="value flex1">
<div>经办签名:</div>
<div>&nbsp;</div>
</div>
<div class="value flex1">
<div>客户签名:</div>
<div>&nbsp;</div>
</div>
</div>
</div>
<div class="bottom-memo">开课后不予办理退费请妥善保管您的收据,丢失不予补办</div>
<div class="no-print bottom-btn-container">
<el-button v-if="canPrint" type="primary" @click="handlePrint"> </el-button>
<el-button v-else type="info">订单已作废,无法打印</el-button>
</div>
</div>
</template>
<script>
import { getOrder } from '@/api/school/sc/order'
import { nowTenantInfo } from '@/api/school/system/tenant'
import moment from 'moment'
export default {
data() {
return {
orderId: undefined,
loading: false,
orderInfo: {},
orderDetailArray: [],
orderAccountArray: [],
tenantInfo: {}
}
},
computed: {
now() {
return moment(new Date()).format('YYYY-MM-DD HH:mm:ss')
},
//
canPrint() {
//
return this.orderInfo.orderStatus && this.orderInfo.orderStatus !== '3'
}
},
watch: {
orderId: {
handler(newValue) {
if (newValue) {
this.loadOrderDetail(newValue)
this.loadTenantInfo()
}
},
immediate: true
}
},
created(param) {
const orderId = this.$route.params && this.$route.params.orderId
if (orderId) {
this.orderId = orderId
}
},
methods: {
loadOrderDetail(orderId) {
this.loading = true
getOrder(orderId).then(response => {
this.loading = false
this.orderInfo = response.data.orderInfo
this.orderDetailArray = response.data.orderDetail
this.orderAccountArray = response.data.orderAccountList
}).catch(() => {
this.loading = false
})
},
loadTenantInfo() {
nowTenantInfo().then(response => {
this.tenantInfo = response.data
}).catch(() => {
this.loading = false
})
},
handlePrint() {
this.$print(this.$refs.print)
}
}
}
</script>
<style rel="stylesheet/scss" lang="scss" scoped>
.main-container.print {
.print-container {
zoom: 0.7;
}
}
.print-container {
width: 900px;
margin: auto;
.print-title {
margin-top: 25px;
font-size: 16px;
color: #000;
font-weight: 800;
text-align: center;
}
.header-info {
padding: 10px 0;
font-size: 12px;
display: flex;
justify-content: space-between;
align-items: center;
.left-info {
display: flex;
justify-content: flex-start;
align-items: center;
.header-item {
margin-right: 15px;
}
}
}
.print-content {
border-top: 1px solid #737373;
border-left: 1px solid #737373;
font-size: 14px;
text-align: left;
.flex1 {
flex: 1;
}
.w150 {
width: 150px;
}
.w180 {
width: 180px;
}
.w50 {
width: 50px;
}
.w100 {
width: 100px;
}
.w80 {
width: 80px;
}
.header {
display: flex;
justify-content: flex-start;
align-items: inherit;
.top-title {
border-right: 1px solid #737373;
border-bottom: 1px solid #737373;
font-weight: 600;
color: #000;
padding: 5px;
}
}
.content {
display: flex;
justify-content: flex-start;
align-items: inherit;
.value {
border-right: 1px solid #737373;
border-bottom: 1px solid #737373;
font-weight: normal;
color: #000;
padding: 5px;
.span-title {
font-weight: 600;
color: #000;
}
}
}
}
.bottom-memo {
margin-top: 5px;
font-size: 12px;
}
/*底部按钮*/
.bottom-btn-container {
padding: 15px 20px;
text-align: center;
}
}
</style>

File diff suppressed because it is too large Load Diff

@ -119,6 +119,11 @@
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
<span style="color: #999; font-size: 12px;">
* 说明场地费为xx元每小时
<br>实际计算中未满半小时按0.5小时计算收费已满半小时,按1小时计算收费
<br>例如教室使用40分钟按1小时计算收费使用70分钟按1.5小时计算收费
</span>
</el-form> </el-form>
<div slot="footer" class="dialog-footer"> <div slot="footer" class="dialog-footer">
<el-button :loading="loadingChange" type="primary" @click="submitForm"> </el-button> <el-button :loading="loadingChange" type="primary" @click="submitForm"> </el-button>

@ -57,14 +57,14 @@ export default {
handleAdd() { handleAdd() {
this.reset() this.reset()
this.open = true this.open = true
this.title = '添加学基本信息' this.title = '添加学基本信息'
}, },
handleUpdate(row) { handleUpdate(row) {
this.reset() this.reset()
const data=JSON.parse(JSON.stringify(row)) const data=JSON.parse(JSON.stringify(row))
this.form=data this.form=data
this.open = true this.open = true
this.title = '修改学基本信息' this.title = '修改学基本信息'
}, },
/** 提交按钮 */ /** 提交按钮 */
submitForm: function() { submitForm: function() {

@ -60,14 +60,14 @@ export default {
handleAdd() { handleAdd() {
this.reset() this.reset()
this.open = true this.open = true
this.title = '添加学基本信息' this.title = '添加学基本信息'
}, },
handleUpdate(row) { handleUpdate(row) {
this.reset() this.reset()
const data=JSON.parse(JSON.stringify(row)) const data=JSON.parse(JSON.stringify(row))
this.form=data this.form=data
this.open = true this.open = true
this.title = '修改学基本信息' this.title = '修改学基本信息'
}, },
/** 提交按钮 */ /** 提交按钮 */
submitForm: function() { submitForm: function() {

@ -7,7 +7,7 @@
</template> </template>
</el-table-column> </el-table-column>
<el-table-column align="center" prop="claName" label="班级" show-overflow-tooltip /> <el-table-column align="center" prop="claName" label="班级" show-overflow-tooltip />
<el-table-column align="center" prop="studentName" label="学" show-overflow-tooltip /> <el-table-column align="center" prop="studentName" label="学" show-overflow-tooltip />
<el-table-column align="center" prop="chargeType" width="120" label="收费方式"> <el-table-column align="center" prop="chargeType" width="120" label="收费方式">
<template slot-scope="scope"> <template slot-scope="scope">
<span>{{ chargeTypeFormatter(scope.row) }}</span> <span>{{ chargeTypeFormatter(scope.row) }}</span>

@ -20,7 +20,7 @@
</el-form-item> </el-form-item>
</el-form> </el-form>
<el-table v-loading="loading" :data="dataList"> <el-table v-loading="loading" :data="dataList">
<el-table-column prop="studentName" align="center" label="学" fixed="left" /> <el-table-column prop="studentName" align="center" label="学" fixed="left" />
<el-table-column prop="logType" align="center" label="日志类型" fixed="left"> <el-table-column prop="logType" align="center" label="日志类型" fixed="left">
<template slot-scope="scope"> <template slot-scope="scope">
<el-tag v-if="scope.row.logType === '1'"></el-tag> <el-tag v-if="scope.row.logType === '1'"></el-tag>

@ -0,0 +1,427 @@
<template>
<div >
<el-table :data="tableData" v-loading="loading" >
<el-table-column type="selection" width="65" align="center" />
<el-table-column prop="cardNo" label="卡号" width="180" fixed>
</el-table-column>
<el-table-column prop="memberName" label="会员" width="180">
<template slot-scope="scope">
<div class="member-cell">
<div class="member-name">{{ scope.row.memberName }}</div>
<div class="member-phone">{{ scope.row.memberPhone }}</div>
</div>
</template>
</el-table-column>
<el-table-column prop="cardTypeName" label="卡类型" width="160" />
<el-table-column prop="statusDesc" label="状态" width="160">
<template slot-scope="scope">
<el-tag :type="getStatusTagType(scope.row.status)" size="small">
{{ scope.row.statusDesc }}
</el-tag>
</template>
</el-table-column>
<el-table-column prop="chargeType" label="扣费方式" width="250">
<template slot-scope="scope">
<div v-if="scope.row.chargeType=='count'" class="item">
<div class="item-name">次数卡</div>
<div class="item-name">总次数: {{ scope.row.totalCount }} </div>
<div class="item-name">剩余次数: {{ scope.row.remainingCount }} </div>
</div>
<div v-if="scope.row.chargeType=='days'" class="item">
<div class="item-name">周期卡</div>
<div class="item-name">总天数: {{ scope.row.totalDays }} </div>
<div class="item-name">剩余天数: {{ scope.row.remainingDays }} </div>
</div>
<div v-if="scope.row.chargeType=='total_fee'" class="item">
<div class="item-name">储值卡 </div>
<div class="item-name">储值金额: {{ scope.row.totalFee }} </div>
<div class="item-name">剩余金额: {{ scope.row.remainingTotalFee }} </div>
</div>
</template>
</el-table-column>
<el-table-column prop="activationDate" label="激活日期" width="160">
<template slot-scope="scope">
<span >
{{ scope.row.activationDate || '-' }}
</span>
</template>
</el-table-column>
<el-table-column prop="expiryDate" label="到期时间" width="160">
<template slot-scope="scope">
<span :class="{'expiring': isExpiring(scope.row.expiryDate)}">
{{ scope.row.expiryDate || '-' }}
</span>
</template>
</el-table-column>
<el-table-column prop="price" label="实付价格" width="160">
<template slot-scope="scope">
¥{{ scope.row.price }}
</template>
</el-table-column>
<el-table-column prop="purchaseDate" label="办理时间" width="180">
<template slot-scope="scope">
{{ formatDateTime(scope.row.purchaseDate) }}
</template>
</el-table-column>
</el-table>
</div>
</template>
<script>
import memberCardApi from '@/api/school/sc/memberCard'
import {select as selectCardType} from '@/api/school/sc/memberCardType'
export default {
name: 'MemberCardList',
props: {
studentId: {
type: String,
default: undefined
}
},
data() {
return {
//
searchForm: {
memberId: null,
},
//
tableData: [],
loading: false,
//
pagination: {
current: 1,
size: 10,
total: 0
},
//
memberOptions: [],
cardTypeOptions: [],
//
selectedCard: null,
selectedCardId: null,
//
detailDialogVisible: false,
activateDialogVisible: false,
renewDialogVisible: false,
countDialogVisible: false,
countDialogType: 'add' // add deduct
}
},
watch: {
studentId: {
handler(newValue) {
this.searchForm.memberId = newValue
},
immediate: true
}
},
created() {
this.loadCardTypeOptions()
},
methods: {
//
async loadData(studentId) {
this.searchForm.memberId=studentId
this.loading = true
try {
const params = {
...this.searchForm,
pageNum: this.pagination.current,
pageSize: this.pagination.size
}
//
if (this.searchForm.dateRange && this.searchForm.dateRange.length === 2) {
params.startDate = this.searchForm.dateRange[0]
params.endDate = this.searchForm.dateRange[1]
}
const response = await memberCardApi.getCardList(params)
if (response.respCode === '0000') {
this.tableData = response.data.rows || []
this.pagination.total = response.data.total || 0
} else {
this.$message.error(response.message || '加载失败')
}
} catch (error) {
console.error('加载数据失败:', error)
this.$message.error('加载失败')
} finally {
this.loading = false
}
},
//
// async loadMemberOptions() {
// try {
// const response = await getStudent('')
// this.memberOptions = response.data || []
// } catch (error) {
// console.error(':', error)
// }
// },
//
async loadCardTypeOptions() {
try {
const response = await selectCardType('')
this.cardTypeOptions = response.data || []
} catch (error) {
console.error('加载卡类型选项失败:', error)
}
},
//
handleSearch() {
this.pagination.current = 1
this.loadData()
},
//
resetSearch() {
this.$refs.searchForm.resetFields()
this.pagination.current = 1
this.loadData()
},
//
handleSizeChange(size) {
this.pagination.size = size
this.pagination.current = 1
this.loadData()
},
//
handleCurrentChange(current) {
this.pagination.current = current
this.loadData()
},
//
viewDetail(row) {
this.selectedCardId = row.id
this.detailDialogVisible = true
},
//
handleCommand(command, row) {
this.selectedCard = row
switch (command) {
case 'activate':
this.activateCard()
break
case 'suspend':
this.suspendCard()
break
case 'renew':
this.renewCard()
break
case 'addCount':
this.showCountDialog('add')
break
case 'deductCount':
this.showCountDialog('deduct')
break
case 'checkStatus':
this.checkCardStatus()
break
case 'delete':
this.deleteCard()
break
}
},
//
async activateCard() {
try {
const confirm = await this.$confirm('确定要激活这张会员卡吗?', '提示', {
type: 'warning'
})
if (confirm) {
const response = await memberCardApi.activateCard(this.selectedCard.id)
if (response.code === 200) {
this.$message.success('激活成功')
this.loadData()
} else {
this.$message.error(response.message || '激活失败')
}
}
} catch (error) {
console.error('激活失败:', error)
}
},
//
async suspendCard() {
try {
const confirm = await this.$confirm('确定要暂停这张会员卡吗?', '提示', {
type: 'warning'
})
if (confirm) {
const response = await memberCardApi.suspendCard(this.selectedCard.id)
if (response.code === 200) {
this.$message.success('暂停成功')
this.loadData()
} else {
this.$message.error(response.message || '暂停失败')
}
}
} catch (error) {
console.error('暂停失败:', error)
}
},
// /
showCountDialog(type) {
this.countDialogType = type
this.countDialogVisible = true
},
//
async checkCardStatus() {
try {
const response = await memberCardApi.checkCardStatus(this.selectedCard.id)
if (response.code === 200) {
this.$message.success(response.message || '卡片状态正常')
this.loadData()
} else {
this.$message.warning(response.message || '卡片状态异常')
}
} catch (error) {
console.error('检查状态失败:', error)
}
},
//
getStatusTagType(status) {
const typeMap = {
'ACTIVE': 'success',
'INACTIVE': 'info',
'EXPIRED': 'warning',
'SUSPENDED': 'danger',
'DEPLETED': 'danger'
}
return typeMap[status] || 'info'
},
//
formatDateTime(dateTime) {
if (!dateTime) return '-'
return dateTime.replace('T', ' ')
},
// 7
isExpiring(expiryDate) {
if (!expiryDate) return false
const today = new Date()
const expiry = new Date(expiryDate)
const daysDiff = Math.floor((expiry - today) / (1000 * 60 * 60 * 24))
return daysDiff >= 0 && daysDiff <= 7
},
}
}
</script>
<style scoped lang="scss">
.member-card-list {
padding: 20px;
.page-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20px;
h2 {
margin: 0;
color: #333;
}
.header-actions {
display: flex;
gap: 10px;
}
}
.search-card {
margin-bottom: 20px;
.el-form-item {
margin-bottom: 10px;
}
}
.table-card {
.card-no-cell {
display: flex;
align-items: center;
.card-no {
margin-right: 8px;
}
.available-icon {
color: #67c23a;
}
.unavailable-icon {
color: #f56c6c;
}
}
.member-cell {
.member-name {
font-weight: 500;
margin-bottom: 2px;
}
.member-phone {
font-size: 12px;
color: #666;
}
}
.expiring {
color: #e6a23c;
font-weight: 500;
}
.pagination {
margin-top: 20px;
text-align: right;
}
}
}
</style>

@ -1,6 +1,7 @@
<template> <template>
<div> <div>
<el-table v-loading="loading" :data="dataList"> <el-table v-loading="loading" :data="dataList">
<el-table-column type="selection" width="55" align="center" />
<el-table-column prop="orderId" width="170" align="center" label="订单编号" fixed="left"> <el-table-column prop="orderId" width="170" align="center" label="订单编号" fixed="left">
<template slot-scope="scope"> <template slot-scope="scope">
<span style="text-decoration: underline;cursor: pointer;" @click="handleOrderDetail(scope.row)">{{ scope.row.orderId }}</span> <span style="text-decoration: underline;cursor: pointer;" @click="handleOrderDetail(scope.row)">{{ scope.row.orderId }}</span>
@ -14,25 +15,38 @@
<el-tag v-if="scope.row.orderStatus === '3'" size="medium" type="danger"></el-tag> <el-tag v-if="scope.row.orderStatus === '3'" size="medium" type="danger"></el-tag>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="studentName" align="center" label="学生" fixed="left" /> <el-table-column prop="studentName" align="center" label="学" />
<el-table-column prop="phone" width="110" align="center" label="联系电话" /> <el-table-column prop="phone" width="110" align="center" label="联系电话" />
<el-table-column prop="orderDetail" width="200" align="center" label="销售内容"> <el-table-column prop="orderDetail" width="200" align="left" label="销售内容">
<template slot-scope="scope"> <template slot-scope="scope">
<el-tooltip effect="dark" placement="left"> {{ scope.row.cardType?'卡类:'+scope.row.cardType:'' }}<br>
<template slot="content"> 卡号 {{ scope.row.cardNo }}<br>
<div v-for="item in scope.row.orderDetail.split(';')" :key="item"> <span v-if="scope.row.chargeType=='count'">
<span>{{ item }}</span> 次数卡{{scope.row.totalCount}}
</div>
</template> </span>
<span style="display:inline-block;width: 180px;overflow: hidden;text-overflow: ellipsis;white-space: nowrap;"> {{ scope.row.orderDetail }} </span> <span v-if="scope.row.chargeType=='days'">
</el-tooltip> 周期卡{{scope.row.totalDays}}
</span>
<span v-if="scope.row.chargeType=='total_fee'">
储值卡{{scope.row.totalFee}}
</span>
{{ scope.row.memberCardStatus }}
<!-- <el-tooltip effect="dark" placement="left">-->
<!-- <template slot="content">-->
<!-- <div v-for="item in scope.row.orderDetail.split(';')" :key="item">-->
<!-- <span>{{ scope.row.chargeType }}</span>-->
<!-- </div>-->
<!-- </template>-->
<!-- <span style="display:inline-block;width: 180px;overflow: hidden;text-overflow: ellipsis;white-space: nowrap;">-->
<!-- {{ scope.row.cardNo }}-->
<!-- </span>-->
<!-- </el-tooltip>-->
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="actualTotalFee" align="center" label="应付(元)" /> <el-table-column prop="originalTotalFee" align="center" label="原价(元)" />
<el-table-column prop="receiptFee" align="center" label="实收(元)" /> <el-table-column prop="receiptFee" align="center" label="实收(元)" />
<el-table-column prop="balanceFee" width="120" align="center" label="余额支付(元)" />
<el-table-column prop="saleStaffName" align="center" label="销售员" /> <el-table-column prop="saleStaffName" align="center" label="销售员" />
<el-table-column prop="orderTag" align="center" label="订单标签" show-overflow-tooltip />
<el-table-column prop="handleDeptName" align="center" label="经办校区" show-overflow-tooltip /> <el-table-column prop="handleDeptName" align="center" label="经办校区" show-overflow-tooltip />
<el-table-column prop="handleDate" width="100" align="center" label="经办日期" /> <el-table-column prop="handleDate" width="100" align="center" label="经办日期" />
<el-table-column prop="createUserName" width="100" align="center" label="经办人" /> <el-table-column prop="createUserName" width="100" align="center" label="经办人" />

@ -1,15 +1,6 @@
<template> <template>
<div class="app-container"> <div class="app-container">
<el-tabs v-model="activeTab" tab-position="top" @tab-click="handleTabChange">
<el-tab-pane name="studentList" label="学生列表">
<span slot="label" style="font-size: 16px;"><i class="el-icon-s-order" /> 学生列表</span>
<student-table ref="studentTable" /> <student-table ref="studentTable" />
</el-tab-pane>
<el-tab-pane name="studentSignUpList" label="报读列表">
<span slot="label" style="font-size: 16px;"><i class="el-icon-s-promotion" /> 报读列表</span>
<student-course-sign-up-table ref="studentCourseSignUpTable" />
</el-tab-pane>
</el-tabs>
</div> </div>
</template> </template>
@ -39,7 +30,7 @@ export default {
methods: { methods: {
handleTabChange(tab) { handleTabChange(tab) {
if (tab.name === 'studentList') { if (tab.name === 'studentList') {
// //
} else if (tab.name === 'studentSignUpList') { } else if (tab.name === 'studentSignUpList') {
// //
this.$refs.studentCourseSignUpTable.getList() this.$refs.studentCourseSignUpTable.getList()

@ -1,10 +1,10 @@
<!-- 视图 --> <!-- 视图 -->
<template> <template>
<div class="container"> <div class="container">
<el-row v-loading="loading" class="cla-detail"> <el-row v-loading="loading" class="cla-detail">
<div class="top-name" style="display: flex;justify-content: space-between;"> <div class="top-name" style="display: flex;justify-content: space-between;">
<div v-if="canSearchStudent"> <div v-if="canSearchStudent">
<label class="el-form-item__label" style="width: 80px;">选择学:</label> <label class="el-form-item__label" style="width: 80px;">选择学:</label>
<student-select @change="handleStudentChange" /> <student-select @change="handleStudentChange" />
</div> </div>
<div v-if="studentId !== undefined"> <div v-if="studentId !== undefined">
@ -12,18 +12,14 @@
</div> </div>
</div> </div>
<div class="cla-base-info"> <div class="cla-base-info">
<div class="item">
<div class="item-name">学校:</div>
<div class="item-value">{{ studentInfo.schoolName }}</div>
</div>
<div class="item"> <div class="item">
<div class="item-name">年龄:</div> <div class="item-name">年龄:</div>
<div class="item-value">{{ studentInfo.age }}</div> <div class="item-value">{{ studentInfo.age }}</div>
</div> </div>
<div class="item"> <div class="item">
<div class="item-name">性别:</div> <div class="item-name">性别:</div>
<div v-if="studentInfo.sex === 'M'" class="item-value"></div> <div v-if="studentInfo.sex === '1'" class="item-value"></div>
<div v-else-if="studentInfo.sex === 'F'" class="item-value"></div> <div v-else-if="studentInfo.sex === '2'" class="item-value"></div>
<div v-else class="item-value">未知</div> <div v-else class="item-value">未知</div>
</div> </div>
<div class="item"> <div class="item">
@ -42,8 +38,8 @@
</el-row> </el-row>
<div class="tab-container"> <div class="tab-container">
<el-tabs v-model="activeTab" tab-position="top" @tab-click="handleTabChange"> <el-tabs v-model="activeTab" tab-position="top" @tab-click="handleTabChange">
<el-tab-pane name="studentCourse" label="课程"> <el-tab-pane name="studentCourse" label="会员卡">
<span slot="label" style="font-size: 16px;"><i class="el-icon-notebook-2" /> 课程</span> <span slot="label" style="font-size: 16px;"><i class="el-icon-notebook-2" /> 会员卡</span>
<student-course-table ref="studentCourseTable" :student-id="studentId" /> <student-course-table ref="studentCourseTable" :student-id="studentId" />
</el-tab-pane> </el-tab-pane>
<el-tab-pane name="studentOrder" label="订单"> <el-tab-pane name="studentOrder" label="订单">
@ -58,10 +54,6 @@
<span slot="label" style="font-size: 16px;"><i class="el-icon-document-copy" /> 上课记录</span> <span slot="label" style="font-size: 16px;"><i class="el-icon-document-copy" /> 上课记录</span>
<cla-time-attend-detail-table ref="claTimeAttendDetailTable" :student-id="studentId" /> <cla-time-attend-detail-table ref="claTimeAttendDetailTable" :student-id="studentId" />
</el-tab-pane> </el-tab-pane>
<el-tab-pane name="courseLog" label="日志">
<span slot="label" style="font-size: 16px;"><i class="el-icon-document" /> 日志</span>
<student-log-table ref="studentLogTable" :student-id="studentId" />
</el-tab-pane>
</el-tabs> </el-tabs>
</div> </div>
</div> </div>
@ -72,7 +64,7 @@ import studentOrderTable from '@/views/school/student/components/studentOrderTab
import studentLogTable from '@/views/school/student/components/studentLogTable' import studentLogTable from '@/views/school/student/components/studentLogTable'
import claTimeAttendDetailTable from '@/components/sc/claTime/claTimeAttendDetailTable' import claTimeAttendDetailTable from '@/components/sc/claTime/claTimeAttendDetailTable'
import claTimeCalendar from '@/components/sc/claTime/claTimeCalendar' import claTimeCalendar from '@/components/sc/claTime/claTimeCalendar'
import studentCourseTable from '@/views/school/student/components/studentCourseTable' import studentCourseTable from '@/views/school/student/components/studentMemberCard.vue'
import studentSelect from '@/components/sc/student/studentSelect' import studentSelect from '@/components/sc/student/studentSelect'
export default { export default {
components: { components: {
@ -92,7 +84,7 @@ export default {
studentInfo: { studentInfo: {
}, },
studentId: undefined, studentId: undefined,
// //
canSearchStudent: true canSearchStudent: true
} }
}, },
@ -120,7 +112,7 @@ export default {
} }
}, },
methods: { methods: {
// //
handleStudentChange(studentId) { handleStudentChange(studentId) {
if (!studentId) { if (!studentId) {
return return
@ -133,7 +125,7 @@ export default {
if (this.canSearchStudent === false) { if (this.canSearchStudent === false) {
this.$store.dispatch('tagsView/updateVisitedViewName', { this.$store.dispatch('tagsView/updateVisitedViewName', {
view: this.$route, view: this.$route,
name: '学:' + this.studentInfo.studentName name: '学:' + this.studentInfo.studentName
}) })
} }
}).catch(() => { }).catch(() => {
@ -149,7 +141,7 @@ export default {
} }
this.$nextTick(() => { this.$nextTick(() => {
if (tab.name === 'studentCourse') { if (tab.name === 'studentCourse') {
this.$refs.studentCourseTable.getList(this.studentId) this.$refs.studentCourseTable.loadData(this.studentId)
} else if (tab.name === 'studentOrder') { } else if (tab.name === 'studentOrder') {
this.$refs.studentOrderTable.getList() this.$refs.studentOrderTable.getList()
} else if (tab.name === 'claTimeAttend') { } else if (tab.name === 'claTimeAttend') {

@ -1,6 +1,7 @@
<template> <template>
<div class="app-container"> <div class="app-container">
<el-row :gutter="20"> <el-row :gutter="20">
<!--部门数据--> <!--部门数据-->
<el-col :span="4" :xs="24"> <el-col :span="4" :xs="24">
<div class="head-container"> <div class="head-container">
@ -229,19 +230,6 @@
</el-col> </el-col>
</el-row> </el-row>
<el-row> <el-row>
<!-- <el-col :span="12">-->
<!-- <el-form-item label="岗位">-->
<!-- <el-select v-model="form.postIds" multiple placeholder="请选择岗位">-->
<!-- <el-option-->
<!-- v-for="item in postOptions"-->
<!-- :key="item.postId"-->
<!-- :label="item.postName"-->
<!-- :value="item.postId"-->
<!-- :disabled="item.status == 1"-->
<!-- ></el-option>-->
<!-- </el-select>-->
<!-- </el-form-item>-->
<!-- </el-col>-->
<el-col :span="12"> <el-col :span="12">
<el-form-item label="角色"> <el-form-item label="角色">
<el-select v-model="form.roleIds" multiple placeholder="请选择角色"> <el-select v-model="form.roleIds" multiple placeholder="请选择角色">
@ -263,6 +251,11 @@
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
<span v-if="form.userId == undefined" style="color: #999; font-size: 12px;padding-top: 1px">
* 操作说明本操作会自动关联角色关联相同手机号的app用户<br>
如果手机号未在app注册本操作会自动注册一个新的app用户,<br>
登录账号默认为本手机号{{form.phonenumber}}登录密码与本账号密码相同{{form.password}}
</span>
</el-form> </el-form>
<div slot="footer" class="dialog-footer"> <div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button> <el-button type="primary" @click="submitForm"> </el-button>
@ -492,8 +485,8 @@ export default {
deptId: undefined, deptId: undefined,
userName: undefined, userName: undefined,
nickName: undefined, nickName: undefined,
password: undefined, password: '',
phonenumber: undefined, phonenumber: '',
email: undefined, email: undefined,
sex: undefined, sex: undefined,
status: "0", status: "0",

@ -11,8 +11,8 @@
</el-form-item> </el-form-item>
<el-form-item label="性别"> <el-form-item label="性别">
<el-radio-group v-model="user.sex"> <el-radio-group v-model="user.sex">
<el-radio label="0"></el-radio>
<el-radio label="1"></el-radio> <el-radio label="1"></el-radio>
<el-radio label="2"></el-radio>
</el-radio-group> </el-radio-group>
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>

Loading…
Cancel
Save