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

master
xiaoning 3 weeks ago
parent af73845fe9
commit f72f6ac234

@ -7,7 +7,15 @@ export function listTeacher(query) {
method: 'get',
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({
url: '/system/teacher/getUserForTeacher',
method: 'get',

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

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

@ -1,6 +1,6 @@
import request from '@/utils/request'
// 某课程 学到期日
// 某课程 学到期日
export function stuCourseDateAccountList(query) {
return request({
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) {
return request({
@ -61,19 +69,12 @@ export function delTime(courseTimeId) {
})
}
// 变更 已记上课 信息
export function changeHadClaTimeAttend(data) {
// 上课
export function confirmCla(data) {
return request({
url: '/api/sc/cla/time/update/changeHadClaTimeAttend',
url: '/api/sc/cla/time/update/confirmCla',
method: 'post',
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({
url: '/api/sc/course/cla/list/claStudentList',
url: '/api/sc/course/cla/list/searchCourseClaStudent',
method: 'get',
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) {
return request({
@ -60,3 +75,15 @@ export function exportType(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
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) {
@ -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'
// 查询列表
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) {
@ -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) {
@ -51,7 +29,7 @@ export function atClaStudentCourseStatus(studentCourseId) {
})
}
// 学报读课程列表
// 学报读课程列表
export function searchStudentCourse(query) {
return request({
url: '/api/sc/studentCourse/list/searchStudentCourse',

@ -4,99 +4,41 @@
diffNowDay: 排课记上课 可记间隔今天几天的排课
appointClaTime: 选定排课 记上课
appointCourseTimeId: 选定排课的 编号
needChooseCla: 是否需选择班级
-->
<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">
<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="item" style="width: 100%;">
<div class="item-name">上课方式:</div>
<div class="item-value">
<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 class="item">
<div class="item-name">校区:</div>
<div class="item-value">{{ claInfo.deptName }}</div>
</div>
<div class="item">
<div class="item-name">所属课程:</div>
<div class="item-value">{{ claCourseInfo.courseName }}</div>
</div>
<div v-if="form.attendType === 'rule'" class="item">
<div class="item-name required">上课教师:</div>
<div class="item-value">{{ claTimeInfo.staffName }}</div>
<div class="item">
<div class="item-name">班级:</div>
<div class="item-value">{{ claInfo.claName }}</div>
</div>
<div v-else class="item">
<div class="item">
<div class="item-name required">上课教师:</div>
<div class="item-value">
<!-- <staff-select v-model="form.teacherId" teacher="1" 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>
<staff-select v-model="form.teacherId" :dept-id="claInfo.departId" placeholder="请选择上课教师" />
</div>
</div>
<div v-if="form.attendType === 'rule'" class="item">
<div class="item">
<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">
<room-select v-model="form.roomId" :dept-id="claInfo.departId" placeholder="请选择上课教室" />
</div>
</div>
<div v-if="form.attendType === 'rule'" 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">
<div class="item-name required">上课日期:</div>
<div class="item-value">
<el-date-picker
v-model="form.claDate"
v-model="form.realClaDate"
clearable
size="small"
type="date"
@ -109,19 +51,16 @@
</div>
<div class="item">
<div class="item-name required">
<el-tooltip v-if="form.attendType === 'rule'" effect="dark" content="默认为计划上课时间,需填写实际上课时间" placement="top">
<span>上课时间<svg-icon icon-class="question" />:</span>
</el-tooltip>
<span v-else>:</span>
<span>上课时间:</span>
</div>
<div class="item-value">
<el-time-select
v-model="form.startTime"
v-model="form.realStartTime"
size="small"
:picker-options="{
start: '08:00',
step: '00:30',
end: '19:00'
step: '00:01',
end: '20:00'
}"
style="width: 135px;"
placeholder="上课时间"
@ -130,18 +69,15 @@
</div>
<div class="item">
<div class="item-name required">
<el-tooltip v-if="form.attendType === 'rule'" effect="dark" content="默认为计划下课时间,需填写实际下课时间" placement="top">
<span>下课时间<svg-icon icon-class="question" />:</span>
</el-tooltip>
<span v-else>:</span>
<span>下课时间:</span>
</div>
<div class="item-value">
<el-time-select
v-model="form.endTime"
v-model="form.realEndTime"
size="small"
:picker-options="{
start: '08:00',
step: '00:30',
start: '08:00',
step: '00:01',
end: '20:00'
}"
style="width: 135px;"
@ -150,107 +86,89 @@
</div>
</div>
<div class="item">
<div class="item-name">
<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-name required">上课主题:</div>
<div class="item-value">
<el-input v-model="form.classTheme" size="small" placeholder="输入上课主题" />
</div>
</div>
<div v-else class="item">
<div class="item-name">上课主题:</div>
<div class="item">
<div class="item-name required">
<span>备注:</span>
</div>
<div class="item-value">
<el-input v-model="form.classTheme" size="small" placeholder="输入上课主题" />
<el-input v-model="form.memo" size="small" placeholder="备注" />
</div>
</div>
<span style="color: #999; font-size: 12px; "> * 操作顺序 先为学员签到然后再上课上完的课程无法再为学员签到</span>
</div>
</el-row>
<el-row :gutter="10" class="mb8" style="margin-top: 10px;">
<el-col :span="1.5">
<el-button
type="info"
type="primary"
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>
@click="handleAutoDealStudentAttendStatusInfo()"
>签到</el-button>
</el-col>
<span style="color: #999; font-size: 12px; "> * 说明会员签到的同时系统自动划扣会员卡内次数或金额 </span>
</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 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="studentName" label="学员" 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">
<el-radio-group v-model="studentAttendStatusForm[scope.row.studentCourseId].attendStatus" size="mini" @change="attendStatus => handleAttendStatusChange(attendStatus, scope.row)">
<el-radio-button
v-for="dict in attendStatusOptions"
:key="dict.dictValue"
:label="dict.dictValue"
>{{ dict.dictLabel }}</el-radio-button>
<el-radio-group v-model="scope.row.checkIn" >
<el-radio :label="0">未签到</el-radio>
<el-radio :label="1">已签到</el-radio>
</el-radio-group>
</template>
</el-table-column>
<el-table-column align="center" label="扣减课时" width="100" fixed="left">
<template slot-scope="scope">
<el-input-number
v-model="studentAttendStatusForm[scope.row.studentCourseId].stuLoseHour"
:disabled="studentAttendStatusForm[scope.row.studentCourseId].disable"
style="width: 80px"
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">
<el-table-column align="center" prop="cardNo" label="会员卡号" width="100" />
<el-table-column align="center" prop="cardTypeName" label="卡项名称" width="100" />
<el-table-column align="center" prop="remainingCount" label="会员卡余次" width="100" />
<el-table-column align="center" prop="remainingTotalFee" label="会员卡余额" width="100" />
<el-table-column align="center" prop="expiryDate" label="会员卡到期日" width="100" />
<el-table-column align="center" prop="chargeType" label="收费方式">
<template slot-scope="scope">
<el-tooltip effect="dark" :content="scope.row.contactInfo" placement="top">
<span>{{ scope.row.phone }}</span>
</el-tooltip>
<span>{{ chargeTypeFormatter(scope.row) }}</span>
</template>
</el-table-column>
<el-table-column align="center" prop="status" label="状态" :formatter="studentCourseStatusFormatter" />
<el-table-column align="center" prop="chargeType" label="收费方式">
<el-table-column align="center" prop="deductCnt" label="划扣次数" width="100" />
<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">
<span>{{ chargeTypeFormatter(scope.row) }}</span>
<span>{{ scope.row.countBefore==null?'-':scope.row.countBefore}}</span>
</template>
</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">
<span v-if="scope.row.chargeType === 'date'">
{{ 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>
<span>{{ scope.row.countAfter==null?'-':scope.row.countAfter}}</span>
</template>
</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">
<span>{{ parseTime(scope.row.lastSignTime, '{y}-{m}-{d}') }}</span>
<span>{{ scope.row.feeBefore==null?'-':scope.row.feeBefore}}</span>
</template>
</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">
<el-input v-model="studentAttendStatusForm[scope.row.studentCourseId].memo" size="small" placeholder="备注" />
<span>{{ scope.row.feeAfter==null?'-':scope.row.feeAfter}}</span>
</template>
</el-table-column>
</el-table>
<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>
</div>
</el-dialog>
@ -264,9 +182,9 @@ import claSelect from '@/components/sc/course/cla/claSelect'
import deptSelect from '@/components/system/dept/deptSelect'
import { allDetailInfoById } from '@/api/school/sc/cla'
import moment from 'moment'
import { searchCourseClaStudent } from '@/api/school/sc/student/course'
import { claTimeAttend } from '@/api/school/sc/student/course'
import {select as teacherSelect} from "@/api/school/system/staff";
import { searchCourseClaStudent } from '@/api/school/sc/cla/index'
import {claTimeInfo as loadClaTimeInfo,confirmCla} from "@/api/school/sc/cla/claTime";
import memberCardApi from "@/api/school/sc/memberCard";
export default {
components: {
staffSelect,
@ -296,11 +214,6 @@ export default {
type: String,
default: undefined
},
//
needChooseCla: {
type: Boolean,
default: false
}
},
data() {
return {
@ -315,25 +228,18 @@ export default {
//
claTimeInfo: {},
form: {
attendType: 'rule',
deptId: undefined,
claId: undefined,
claDate: '',
startTime: '',
endTime: '',
realClaDate: '',
realStartTime: '',
realEndTime: '',
teacherId: undefined,
roomId: undefined,
classTheme: undefined
classTheme: undefined,
memo:""
},
teacherOptions:[],
//
claTimeAttendTypeOptions: [{
dictValue: 'rule',
dictLabel: '排课记上课'
}, {
dictValue: 'custom',
dictLabel: '自定义上课'
}],
//
beginDatePickerOptions: {
disabledDate(time) {
@ -341,105 +247,43 @@ export default {
}
},
dataList: [],
queryParams: {
pageNum: 1,
pageSize: 200,
claId: this.chooseClaId,
effect: true
},
studentCourseStatusOptions: [],
chargeTypeOptions: [],
sexOptions: [],
//
//
chooseStudentCourseIds: [],
//
attendStatusOptions: [],
//
//
studentAttendStatusForm: {},
//
chooseDeptId: undefined,
//
chooseClaId: undefined
chooseBookIds:[]
}
},
computed: {
},
watch: {
claId: {
handler(newValue) {
this.chooseClaId = newValue
},
immediate: true
},
chooseClaId: {
handler(newValue) {
this.queryParams.claId = newValue
},
immediate: true
},
open: {
handler(newValue) {
if (newValue === true) {
this.resetData()
if (this.appointClaTime === false && this.needChooseCla === false && this.claId) {
//
this.loadClaInfo()
}
if (this.needChooseCla === false) {
//
this.$nextTick(() => {
this.$refs.claTimeSelect.loadRecentDayTime()
})
}
this.loadClaInfo()
}
},
immediate: true
},
//
appointClaTime: {
handler(newValue) {
if (newValue === true) {
this.form.attendType = 'rule'
} else {
this.form.attendType = 'custom'
}
},
immediate: true
},
//
needChooseCla: {
handler(newValue) {
if (newValue === true) {
this.form.attendType = 'custom'
} else {
this.form.attendType = 'rule'
}
},
immediate: true
}
},
created() {
this.getDictListByDictType('student_course_status').then(response => {
this.studentCourseStatusOptions = response.data
})
this.getDictListByDictType('charge_type').then(response => {
this.chargeTypeOptions = response.data
})
this.getDictListByDictType('sys_user_sex').then(response => {
this.sexOptions = response.data
})
this.getDictListByDictType('attend_status').then(response => {
this.attendStatusOptions = response.data
this.getDictListByDictType('book_status').then(response => {
this.bookStatusOptions = response.data
})
this.getTeacherOptions()
},
methods: {
getTeacherOptions() {
teacherSelect().then(response => {
this.teacherOptions = response.data
})
},
resetData() {
this.claInfo = {
claName: '',
@ -451,16 +295,16 @@ export default {
}
this.dataList = []
if (this.needChooseCla) {
//
this.chooseDeptId = undefined
this.chooseClaId = undefined
}
},
loadClaInfo() {
if (this.chooseClaId) {
if (this.claId) {
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.claInfo = response.data.courseCla
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) {
this.claTimeInfo = claTimeInfo
this.form.startTime = claTimeInfo.startTime.substr(0, 5)
this.form.endTime = claTimeInfo.endTime.substr(0, 5)
this.form.realStartTime = claTimeInfo.startTime.substr(0, 5)
this.form.realEndTime = claTimeInfo.endTime.substr(0, 5)
this.form.classTheme = claTimeInfo.classTheme
//
if (this.appointClaTime) {
@ -483,108 +338,118 @@ export default {
this.loadClaInfo()
}
},
//
handleNoPlanClaTime() {
this.msgError('近日无计划排课,无法排课记上课')
},
sexFormatter(row, column) {
return selectDictLabel(this.sexOptions, row.sex)
},
chargeTypeFormatter(row, column) {
return selectDictLabel(this.chargeTypeOptions, row.chargeType)
},
studentCourseStatusFormatter(row, column) {
return selectDictLabel(this.studentCourseStatusOptions, row.status)
bookStatusFormatter(row, column) {
return selectDictLabel(this.bookStatusOptions, row.bookStatus)
},
getList() {
searchCourseClaStudent(this.queryParams).then(response => {
this.dataList = response.data.rows
this.loading = true
let claStudentList = []
searchCourseClaStudent({courseTimeId: this.appointCourseTimeId}).then(response => {
claStudentList = response.data
this.total = response.data.total
this.claStudentList = claStudentList
this.loading = false
this.handleAutoDealStudentAttendStatusInfo('1')
})
},
//
handleAutoDealStudentAttendStatusInfo(attendStatus) {
//
handleAutoDealStudentAttendStatusInfo() {
this.$nextTick(() => {
this.chooseStudentCourseIds = []
this.dataList.forEach(row => {
this.chooseStudentCourseIds.push(row.studentCourseId)
this.$refs.table.toggleRowSelection(row, true)
this.claStudentList.forEach(row => {
if ([0,1,2].includes(row.bookStatus)&&row.checkIn==0){
//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.dataList.forEach(item => {
this.$set(this.studentAttendStatusForm, item.studentCourseId, {
attendStatus: attendStatus,
memo: '',
stuLoseHour: item.chargeType === 'date' ? 0 : (this.form.attendType === 'rule' ? this.claTimeInfo.payHour : this.claInfo.everyStuLoseHour),
disable: item.chargeType === 'date'
if (this.chooseBookIds==null || this.chooseBookIds.length<1){
this.msgError('没有可以满足签到条件的学员!')
this.$refs.table.clearSelection();
return ;
}
// this.chooseBookIds
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() {
console.log('上课')
if (this.form.attendType === 'custom') {
//
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) {
} else if (this.form.realClaDate === undefined || this.form.realClaDate === '' || this.form.realClaDate === null) {
this.msgError('请选择上课日期')
return
} else if (this.form.startTime === undefined || this.form.startTime === '' || this.form.startTime === null) {
this.msgError('请选择上上课时间')
} else if (this.form.realStartTime === undefined || this.form.realStartTime === '' || this.form.realStartTime === null) {
this.msgError('请选择上课时间')
return
} else if (this.form.endTime === undefined || this.form.endTime === '' || this.form.endTime === null) {
this.msgError('请选择上下课时间')
} else if (this.form.realEndTime === undefined || this.form.realEndTime === '' || this.form.realEndTime === null) {
this.msgError('请选择下课时间')
return
}
} else if (this.form.attendType === 'rule') {
if (this.form.courseTimeId === undefined || this.form.courseTimeId === '' || this.form.courseTimeId === null) {
this.msgError('请选择上课日期')
this.msgError('页面数据错误,请刷新重试!')
return
}
}
let checkResult = true
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.studentAttendList = studentAttendList
this.form.claId = this.chooseClaId
this.form.claId = this.claId
this.loading = true
claTimeAttend(this.form).then(response => {
confirmCla(this.form).then(response => {
this.loading = false
if (response.respCode === '0000') {
this.$emit('success')
this.open = false
this.msgSuccess('记上课成功')
} else {
this.msgError(response.respMsg)
this.msgError(response.msgDetail)
}
}).catch(() => {
this.loading = false
@ -604,12 +469,6 @@ export default {
}
}
},
//
handleChooseCla(claId) {
this.chooseClaId = claId
this.loadClaInfo()
this.getList()
}
}
}
</script>

@ -1,16 +1,24 @@
<!-- 修改上课 -->
<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">
<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-name">所属课程:</div>
<div class="item-value">{{ claCourseInfo.courseName }}</div>
</div>
<div class="item">
<div class="item-name">班级:</div>
<div class="item-value">{{ claInfo.claName }}</div>
</div>
<div class="item">
<div class="item-name required">上课教师:</div>
<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 class="item">
@ -44,8 +52,8 @@
size="small"
:picker-options="{
start: '08:00',
step: '00:30',
end: '19:00'
step: '00:01',
end: '20:00'
}"
style="width: 135px;"
placeholder="上课时间"
@ -61,8 +69,8 @@
v-model="form.endTime"
size="small"
:picker-options="{
start: '08:00',
step: '00:30',
start: '08:00',
step: '00:01',
end: '20:00'
}"
style="width: 135px;"
@ -71,103 +79,75 @@
</div>
</div>
<div class="item">
<div class="item-name required">
<span>备注:</span>
</div>
<div class="item-name required">上课主题:</div>
<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 class="item">
<div class="item-name required">上课主题:</div>
<div class="item-name required">
<span>备注:</span>
</div>
<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>
</el-row>
<el-row :gutter="10" class="mb8" style="margin-top: 10px;">
<el-col :span="1.5">
<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>
<span style="color: #999; font-size: 12px; "> * 说明会员签到的同时系统自动划扣会员卡内次数或金额 先签到后上课</span>
</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 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="studentName" label="学员" 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">
<el-radio-group v-model="studentAttendStatusForm[scope.row.studentCourseId].attendStatus" size="mini" @change="attendStatus => handleAttendStatusChange(attendStatus, scope.row)">
<el-radio-button
v-for="dict in attendStatusOptions"
:key="dict.dictValue"
:label="dict.dictValue"
>{{ dict.dictLabel }}</el-radio-button>
<el-radio-group v-model="scope.row.checkIn" >
<el-radio :label="0">未签到</el-radio>
<el-radio :label="1">已签到</el-radio>
</el-radio-group>
</template>
</el-table-column>
<el-table-column align="center" label="扣减课时" width="100" fixed="left">
<template slot-scope="scope">
<el-input-number
v-model="studentAttendStatusForm[scope.row.studentCourseId].stuLoseHour"
:disabled="studentAttendStatusForm[scope.row.studentCourseId].disable"
style="width: 80px"
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">
<el-table-column align="center" prop="cardNo" label="会员卡号" width="100" />
<el-table-column align="center" prop="cardTypeName" label="卡项名称" width="100" />
<el-table-column align="center" prop="remainingCount" label="会员卡余次" width="100" />
<el-table-column align="center" prop="remainingTotalFee" label="会员卡余额" width="100" />
<el-table-column align="center" prop="expiryDate" label="会员卡到期日" width="100" />
<el-table-column align="center" prop="chargeType" label="收费方式">
<template slot-scope="scope">
<el-tooltip effect="dark" :content="scope.row.contactInfo" placement="top">
<span>{{ scope.row.phone }}</span>
</el-tooltip>
<span>{{ chargeTypeFormatter(scope.row) }}</span>
</template>
</el-table-column>
<el-table-column align="center" prop="status" label="状态" :formatter="studentCourseStatusFormatter" />
<el-table-column align="center" prop="chargeType" label="收费方式">
<el-table-column align="center" prop="deductCnt" label="划扣次数" width="100" />
<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">
<span>{{ chargeTypeFormatter(scope.row) }}</span>
<span>{{ scope.row.countBefore==null?'-':scope.row.countBefore}}</span>
</template>
</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">
<span v-if="scope.row.chargeType === 'date'">
{{ 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>
<span>{{ scope.row.countAfter==null?'-':scope.row.countAfter}}</span>
</template>
</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">
<span>{{ parseTime(scope.row.lastSignTime, '{y}-{m}-{d}') }}</span>
<span>{{ scope.row.feeBefore==null?'-':scope.row.feeBefore}}</span>
</template>
</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">
<el-input v-model="studentAttendStatusForm[scope.row.studentCourseId].memo" size="small" placeholder="备注" />
<span>{{ scope.row.feeAfter==null?'-':scope.row.feeAfter}}</span>
</template>
</el-table-column>
</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>
</template>
<script>
@ -175,10 +155,9 @@ import { selectDictLabel } from '@/utils/commonUtils'
import staffSelect from '@/components/system/staff/staffSelect'
import roomSelect from '@/components/sc/base/roomSelect'
import { allDetailInfoById } from '@/api/school/sc/cla'
import { claTimeInfo as loadClaTimeInfo, changeHadClaTimeAttend } from '@/api/school/sc/cla/claTime'
import { hadClaTimeAttendDetail } from '@/api/school/sc/cla/claTimeAttend'
import { claTimeInfo as loadClaTimeInfo, } from '@/api/school/sc/cla/claTime'
import moment from 'moment'
import { searchCourseClaStudent } from '@/api/school/sc/student/course'
import { searchCourseClaStudent } from '@/api/school/sc/cla/index'
export default {
components: {
staffSelect,
@ -226,20 +205,20 @@ export default {
queryParams: {
pageNum: 1,
pageSize: 200,
claId: this.claId,
courseTimeId: this.courseTimeId,
effect: true
},
studentCourseStatusOptions: [],
chargeTypeOptions: [],
sexOptions: [],
//
//
chooseStudentCourseIds: [],
//
attendStatusOptions: [],
//
//
studentAttendStatusForm: {},
//
chooseBookIds:[],
claTimeAttendList: []
}
},
@ -254,12 +233,6 @@ export default {
}
},
watch: {
claId: {
handler(newValue) {
this.queryParams.claId = newValue
},
immediate: true
},
open: {
handler(newValue) {
if (newValue === true) {
@ -271,17 +244,14 @@ export default {
}
},
created() {
this.getDictListByDictType('student_course_status').then(response => {
this.studentCourseStatusOptions = response.data
})
this.getDictListByDictType('charge_type').then(response => {
this.chargeTypeOptions = response.data
})
this.getDictListByDictType('sys_user_sex').then(response => {
this.sexOptions = response.data
})
this.getDictListByDictType('attend_status').then(response => {
this.attendStatusOptions = response.data
this.getDictListByDictType('book_status').then(response => {
this.bookStatusOptions = response.data
})
},
methods: {
@ -301,7 +271,7 @@ export default {
},
//
loadClaAndClaTimeInfo() {
if (this.claId) {
if (this.courseTimeId) {
this.loadingClaDetail = true
loadClaTimeInfo(this.courseTimeId).then(response => {
this.claTimeInfo = response.data
@ -341,143 +311,22 @@ export default {
chargeTypeFormatter(row, column) {
return selectDictLabel(this.chargeTypeOptions, row.chargeType)
},
studentCourseStatusFormatter(row, column) {
return selectDictLabel(this.studentCourseStatusOptions, row.status)
bookStatusFormatter(row, column) {
return selectDictLabel(this.bookStatusOptions, row.bookStatus)
},
// ,
loadCourseClaStudentAndAttendDetail() {
this.loading = true
let claStudentList = []
searchCourseClaStudent(this.queryParams).then(response => {
claStudentList = response.data.rows
searchCourseClaStudent({courseTimeId: this.courseTimeId}).then(response => {
claStudentList = response.data
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.$nextTick(() => {
this.claStudentList.forEach(item => {
if (this.claTimeAttendMap.hasOwnProperty(item.studentCourseId)) {
this.$refs.table.toggleRowSelection(item, true)
}
})
})
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>

@ -60,8 +60,8 @@
size="small"
:picker-options="{
start: '08:00',
step: '00:30',
end: '19:00'
step: '00:01',
end: '20:00'
}"
placeholder="选择上课时间"
/>
@ -74,7 +74,7 @@
size="small"
:picker-options="{
start: '08:00',
step: '00:30',
step: '00:01',
end: '20:00'
}"
placeholder="选择下课时间"
@ -83,21 +83,7 @@
</el-col>
<el-col :span="12">
<el-form-item label="任课教师:" prop="teacherId">
<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>
<staff-select v-model="form.teacherId" placeholder="请选择上课教师" />
</el-form-item>
</el-col>
<el-col :span="12">

@ -1,6 +1,6 @@
<template>
<el-dialog :title="title" :visible.sync="open" width="600px">
<el-form ref="form" v-loading="loadingChange" class="add-form auto-width" :model="form" :rules="rules" label-width="90px">
<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="120px">
<el-row>
<el-col :span="12">
<el-form-item label="校区:" prop="deptId">
@ -70,17 +70,7 @@
</el-checkbox-group>
</el-form-item>
</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 v-if="form.ruleType !== '1'">
<el-col :span="24" style="text-align: left">
@ -98,54 +88,65 @@
</div>
<el-col :span="12">
<el-form-item label="上课时间:" prop="startTime">
<el-input v-model="form.startTime" size="small" placeholder="请输入上课时间" />
<!-- <el-time-select-->
<!-- v-model="form.startTime"-->
<!-- size="small"-->
<!-- :picker-options="{-->
<!-- start: '08:00',-->
<!-- step: '00:30',-->
<!-- end: '19:00'-->
<!-- }"-->
<!-- placeholder="选择上课时间"-->
<!-- />-->
<el-time-select
v-model="form.startTime"
size="small"
:picker-options="{
start: '08:00',
step: '00:01',
end: '20:00'
}"
@change="startTimeChange"
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-col>
<el-col :span="12">
<el-form-item label="下课时间:" prop="endTime">
<el-input v-model="form.endTime" size="small" placeholder="请输入下课时间" />
<!-- <el-time-select-->
<!-- v-model="form.endTime"-->
<!-- size="small"-->
<!-- :picker-options="{-->
<!-- start: '08:00',-->
<!-- step: '00:30',-->
<!-- end: '20:00'-->
<!-- }"-->
<!-- placeholder="选择下课时间"-->
<!-- />-->
<el-time-select
v-model="form.endTime"
size="small"
disabled="true"
placeholder="选择下课时间"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="任课教师:" prop="teacherId">
<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>
<staff-select v-model="form.teacherId" :dept-id="form.deptId" 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>-->
</el-form-item>
</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-form-item label="教室:" prop="roomId">
<room-select v-model="form.roomId" :dept-id="form.deptId" placeholder="请选择教师" />
@ -157,6 +158,7 @@
</el-form-item>
</el-col>
</el-row>
<span style="color: #999; font-size: 12px;">{{form.ruleId?'* 说明:本操作会同时修改未上课且无学员预约/预约失败/取消预约的相关课表信息,已经上完的课程不会被修改;':''}}</span>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button :loading="loadingChange" type="primary" @click="submitForm"> </el-button>
@ -205,6 +207,7 @@ export default {
}],
//
form: {
atClassCnt:20
},
teacherOptions:[],
isIndeterminate: true,
@ -234,12 +237,6 @@ export default {
ruleType: [
{ required: true, message: '规则类型不能为空', trigger: 'blur' }
],
beginDate: [
],
endDate: [
],
chooseDate: [
],
repeatType: [
{ required: true, message: '重复方式不能为空', trigger: 'blur' }
],
@ -267,7 +264,13 @@ export default {
],
teacherId: [
{ required: true, message: '任课教师不能为空', trigger: 'blur' }
]
],
claDuration: [
{ required: true, message: '课程时长不能为空', trigger: ['blur','change'] }
],
atClassCnt: [
{ required: true, message: '最多预约人数不能为空', trigger: ['blur','change'] }
],
}
if (this.form.ruleType === '1') {
tempRules['beginDate'] = [
@ -290,7 +293,7 @@ export default {
if (newValue === '1') {
//
this.form.repeatType = '1'
this.form.filterHoliday = true
this.form.filterHoliday = false
} else {
//
this.form.repeatType = undefined
@ -347,12 +350,17 @@ export default {
endDate: undefined,
repeatType: '1',
weekDays: [],
filterHoliday: true,
filterHoliday: false,
startTime: '',
endTime: '',
teacherId: undefined,
classTheme: undefined,
chooseDate: undefined
chooseDate: undefined,
roomId: '',
lessCnt:0,
atClassCnt:20,
claDuration:0,
}
this.resetForm('form')
this.canChangeCla = true
@ -423,6 +431,10 @@ export default {
this.form.endDate = undefined
}
},
//
startTimeChange() {
this.form.endTime = this.calculateEndTime(this.form.startTime, this.form.claDuration);
},
handleCheckAllChange(val) {
this.form.weekDays = val ? this.weekDayOptions.map(item => {
return item.dictValue
@ -441,7 +453,34 @@ export default {
} 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>

@ -2,7 +2,7 @@
<template>
<div>
<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="teacherName" label="教师" show-overflow-tooltip />
<el-table-column align="center" prop="realClaDate" label="上课日期" width="120">

@ -2,24 +2,24 @@
<div>
<el-row style="margin-bottom: 15px;">
<el-col v-if="!readonly" :span="6">
<div style="height: 40px;align-items: center;display: flex;justify-content: start;">
<el-button
size="small"
type="info"
icon="el-icon-edit-outline"
@click="handleCalendarAddClaTime"
>课表排课</el-button>
<el-button
v-if="!readonly && addTimeRule"
v-hasPermi="['sc:claTimeRule:add']"
type="info"
icon="el-icon-document-copy"
size="small"
@click="handleAddTimeRule"
>规则排课</el-button>
</div>
<!-- <div style="height: 40px;align-items: center;display: flex;justify-content: start;">-->
<!-- <el-button-->
<!-- size="small"-->
<!-- type="info"-->
<!-- icon="el-icon-edit-outline"-->
<!-- @click="handleCalendarAddClaTime"-->
<!-- >课表排课</el-button>-->
<!-- <el-button-->
<!-- v-if="!readonly && addTimeRule"-->
<!-- v-hasPermi="['sc:claTimeRule:add']"-->
<!-- type="info"-->
<!-- icon="el-icon-document-copy"-->
<!-- size="small"-->
<!-- @click="handleAddTimeRule"-->
<!-- >规则排课</el-button>-->
<!-- </div>-->
</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="padding: 0 15px;cursor: pointer;" @click="calendarBeginDateClick(-7)">
<el-icon class="el-icon-arrow-left" style="font-size: 30px;" />
@ -106,16 +106,17 @@
</td>
<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-if="claTimeIdx < 2" class="cla-time-item success" :style="'background-color: ' + claTime.claColor + ';'">
<div class="overflow-ellipsis">{{ claTime.claName }}</div>
<div class="overflow-ellipsis">{{ claTime.staffName }} {{ claTime.startTime }} ~ {{ claTime.endTime }}</div>
<div v-if="claTimeIdx < 5" class="cla-time-item success" :style="'background-color: ' + claTime.claColor + ';'">
<div class="overflow-ellipsis">{{ 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 v-if="claTime.claTimeStatus === '2'" class="claTimeStatus success"><span>已上课</span></div>
<div v-if="claTime.claTimeStatus === '1'" class="claTimeStatus"><span>未上课</span></div>
</div>
<div class="tooltip">
<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-notebook-1" /> {{ claTime.claDate }}</div>
<div class="item"><i class="el-icon-mouse" /> {{ claTime.weekDay }}</div>
@ -134,7 +135,7 @@
</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>
</td>
@ -186,7 +187,7 @@
</div>
</template>
<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 changeTimeRule from '@/components/sc/claTime/changeTimeRule'
import moment from 'moment'
@ -238,7 +239,7 @@ export default {
type: Boolean,
default: false
},
//
//
needStudentIdParam: {
type: Boolean,
default: false
@ -309,24 +310,46 @@ export default {
return
}
this.loading = true
searchListForCalendar({
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
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
})
}).catch(() => {
this.loading = false
})
}else {
searchListForCalendar({
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
})
}
},
showMore(claTimeArray) {
this.showMoreData = true
@ -416,11 +439,11 @@ export default {
</script>
<style rel="stylesheet/scss" lang="scss" scoped>
$claTimeColumnWidth: 125px;
$claTimeColumnHeight: 46px;
$claTimeColumnWidth: 146px;
$claTimeColumnHeight: 60px;
$Padding8: 8px;
.cla-time-table {
font-size: 12px;
font-size: 14px;
border: 1px solid #ebeef5;
border-right: none;
border-bottom: none;

@ -25,17 +25,6 @@
</el-form-item>
</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-column type="selection" width="55" align="center" />
<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>
</template>
</el-table-column>
<el-table-column align="center" prop="claName" label="上课班级" show-overflow-tooltip />
<el-table-column align="center" prop="courseName" label="所属课程" show-overflow-tooltip />
<el-table-column align="center" prop="status" label="状态">
<el-table-column align="center" width="180" prop="claName" 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="状态">
<template slot-scope="scope">
<el-tag v-if="scope.row.status === '1'" type="danger"></el-tag>
<el-tag v-else-if="scope.row.status === '2'">已上课</el-tag>
</template>
</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">
<template slot-scope="scope">
<el-button
@ -75,7 +64,7 @@
type="text"
icon="el-icon-edit-outline"
@click="handleUpdateWaitAttend(scope.row)"
>编辑</el-button>
>详情</el-button>
</template>
</el-table-column>
</el-table>
@ -91,6 +80,7 @@
<add-cla-time-attend
ref="addClaTimeAttend"
:appoint-course-time-id="chooseCourseTimeId"
:cla-id="chooseClaId"
appoint-cla-time
:need-choose-cla="needChooseCla"
@success="getList"
@ -208,6 +198,7 @@ export default {
handleClaTimeAttend(claTime) {
this.needChooseCla = false
this.chooseCourseTimeId = claTime.courseTimeId
this.chooseClaId = claTime.claId
this.$refs.addClaTimeAttend.open = true
},
/** 已上课编辑 */
@ -223,12 +214,6 @@ export default {
this.$refs.changeTime.reset()
this.$refs.changeTime.openUpdateByOldInfo(claTime, claTime.courseTimeId)
},
/** 记上课 */
handleAddClaTime() {
this.needChooseCla = true
this.chooseCourseTimeId = undefined
this.$refs.addClaTimeAttend.open = true
}
}
}
</script>

@ -32,46 +32,33 @@
<span>{{ scope.row.realClaDate }} {{ scope.row.realStartTime.substr(0,5) }}~{{ scope.row.realEndTime.substr(0,5) }}</span>
</template>
</el-table-column>
<el-table-column align="center" prop="claName" label="上课班级" show-overflow-tooltip>
<template slot-scope="scope">
<router-link :to="'/edu/cla/detail/' + scope.row.claId" class="link-type">
<span>{{ scope.row.claName }}</span>
</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="应到/实到">
<el-table-column align="center" width="180" prop="claName" label="上课班级" />
<el-table-column align="center" width="180" prop="courseName" label="所属课程" />
<el-table-column align="center" width="180" prop="staffName" label="上课教师" />
<el-table-column align="center" width="180" prop="needAttendCnt" label="预约/实到">
<template slot-scope="scope">
<el-tooltip effect="dark" placement="top">
<template slot="content">
<div>
<div>到课: {{ scope.row.realAttendCnt }}</div>
<div>请假: {{ scope.row.leaveCnt }}</div>
<div>缺勤: {{ scope.row.outCnt }}</div>
<div>预约: {{ scope.row.bookAttendCnt }}</div>
</div>
</template>
<span>{{ scope.row.realAttendCnt }}/{{ scope.row.needAttendCnt }}</span>
<span>{{ scope.row.realAttendCnt }}/{{ scope.row.bookAttendCnt }}</span>
</el-tooltip>
</template>
</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">
<span>{{ scope.row.payTotalHour }}</span>
</template>
</el-table-column>
<el-table-column align="center" width="120" prop="" label="学费消耗(元)">
<template slot-scope="scope">
<span>{{ scope.row.payTotalFee }}</span>
</template>
</el-table-column>
<el-table-column align="center" prop="lastUpdateUserName" label="记录人" />
<el-table-column align="center" width="140" prop="lastUpdateTime" label="记录时间">
<el-table-column align="center" width="180" prop="" label="学费消耗统计(元)">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.lastUpdateTime, '{y}-{m}-{d} {h}:{i}') }}</span>
<span> {{ scope.row.payTotalFee }} </span>
</template>
</el-table-column>
<el-table-column width="150" label="操作" align="center" class-name="small-padding fixed-width" fixed="right">
<el-table-column width="180" label="操作" align="center" class-name="small-padding fixed-width" fixed="right">
<template slot-scope="scope">
<el-button
v-hasPermi="['sc:claTime:update']"
@ -79,14 +66,7 @@
type="text"
icon="el-icon-edit-outline"
@click="handleUpdate(scope.row)"
>修改</el-button>
<el-button
v-hasPermi="['sc:claTime:delete']"
size="mini"
type="text"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
>删除</el-button>
>详情</el-button>
</template>
</el-table-column>
</el-table>
@ -104,7 +84,7 @@
</template>
<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 deptSelect from '@/components/system/dept/deptSelect'
import claSelect from '@/components/sc/course/cla/claSelect'
@ -199,23 +179,7 @@ export default {
this.chooseClaId = row.claId
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>

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

@ -44,13 +44,14 @@
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="教练课时费:" prop="claFee">
<el-input v-model="form.claFee" placeholder="请输入课时费金额(元/节)" />
<el-form-item label="课程价值:" prop="tuitionFee">
<el-input v-model="form.tuitionFee" placeholder="请输入课程价值(元/节)" />
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<el-col :span="12">
<el-form-item label="上课校区:" prop="courseCampus" class="align-left">
<el-radio-group v-model="form.courseCampus">
<el-radio
@ -62,8 +63,13 @@
</el-radio-group>
</el-form-item>
</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 v-if="form.courseCampus === '部分校区'">
<el-row v-if="form.courseCampus ==='部分校区'">
<el-form-item label="选择校区:" prop="partCampus" class="align-left">
<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>
@ -77,14 +83,6 @@
</el-form-item>
</el-col>
</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>
<div slot="footer" class="dialog-footer">
<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 feeModeCycle from '@/components/sc/course/feeModeCycle'
import addCourseType from '@/components/sc/course/type/addCourseType'
import feeModePrepaid from '@/components/sc/course/feeModePrepaid1.vue'
export default {
components: {
feeModeHour,
feeModeDate,
feeModeCycle,
addCourseType
},
data() {
@ -118,6 +115,7 @@ export default {
form: {
courseCampus: undefined,
claFee:0.0,
tuitionFee:0.00,
teachingMode: '1',
partCampus: [],
sale:'1',
@ -130,6 +128,13 @@ export default {
teachingMode: [
{ required: true, message: '请选择上课模式', trigger: 'blur' }
],
claFee: [
{
pattern: /^\d+(\.\d{1,2})?$/,
message: '请输入数字且最多保留2位小数',
trigger: 'blur'
},
],
courseCampus: [
{ required: true, message: '请选择上课校区', trigger: 'blur' }
]
@ -149,42 +154,15 @@ export default {
this.campusList()
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() {
this.$refs['form'].validate(valid => {
if (valid) {
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'
if (this.form.courseCampus=='全部校区' || this.form.partCampus.length<1){
this.form.partCampus=null
}
if (this.form.courseId !== undefined) {
updateCourse(this.form).then(response => {
@ -242,32 +220,7 @@ export default {
partCampus: []
}
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() {

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

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

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

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

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

@ -1,289 +1,228 @@
<template>
<el-row>
<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-row style="margin-bottom: 10px">
<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
:data="feeModeTableData"
:span-method="spanMethod"
border
class="fee-table"
>
<el-table-column
prop="campusName"
label="开课校区"
/>
prop="courseType"
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
prop="cnt"
label="数量(课时)"
label="扣卡次数"
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">
<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>
</el-table-column>
<el-table-column
prop="totalFee"
label="总价(元)"
label="或扣费金额(每节)"
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">
<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>
</el-table-column>
<el-table-column
label="操作"
width="80"
width="120"
align="center"
>
<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)" />
<el-button v-if="canDel(scope)" style="padding: 3px 5px;margin-left: 5px;" type="danger" icon="el-icon-minus" size="mini" @click="handleDeleteFeeMode(scope)" />
<!-- 关键修改1仅最后一行显示添加按钮 -->
<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>
</el-table-column>
</el-table>
</el-col>
</el-row>
</template>
<script>
export default {
props: {
//
campusOptions: {
//
courseTypeOptions: {
type: Array,
default: function() {
return []
}
default: () => []
},
//
hadChooseCampus: {
//
hadChooseType: {
type: Array,
default: function() {
return []
}
default: () => []
},
// /
courseCampus: {
type: String,
default: 'all'
}
},
data() {
return {
feeModeHour: true,
// feeModeHourTableData index
spanData: {},
feeModeTableData: [{
campusId: -1,
campusName: '全部校区',
cnt: 1,
totalFee: 0
}],
// key value
campusOptionsMap: {}
feeModeTableData: [],
// key-value (courseTypeId => courseType)
courseTypeOptionsMap: {},
loadingSelect: false
}
},
computed: {
},
watch: {
// key value
campusOptions(newValue, oldValue) {
newValue.forEach((value, index, array) => {
this.campusOptionsMap[value.id] = value.label
})
},
//
courseCampus(newValue, oldValue) {
if (!this.feeModeHour) {
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: 10
})
}
})
this.feeModeTableData = campusArray
//
courseTypeOptions: {
immediate: true,
handler(newValue) {
// courseTypeIdcourseType
this.courseTypeOptionsMap = newValue.reduce((map, item) => {
map[item.courseTypeId] = item.courseType;
return map;
}, {});
//
this.initFeeModeTableData();
}
},
//
hadChooseCampus(newValue, oldValue) {
if (!this.feeModeHour) {
this.feeModeTableData = []
return
//
hadChooseType: {
immediate: true,
handler(newVal) {
if (!this.feeModeHour) return;
this.initFeeModeTableData(newVal);
}
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)
}
}
})
},
//
feeModeHour(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
})
})
}
//
feeModeHour(newVal) {
if (newVal) {
this.initFeeModeTableData();
} else {
this.feeModeTableData = [];
}
}
},
methods: {
//
handleAddFeeMode(item) {
this.feeModeTableData.splice(item.$index + 1, 0, {
campusId: item.row.campusId,
campusName: item.row.campusName,
cnt: 1,
totalFee: 10
})
},
//
handleDeleteFeeMode(item) {
const index = item.$index
this.feeModeTableData.splice(index, 1)
},
spanMethod({ row, column, rowIndex, columnIndex }) {
if (columnIndex !== 0) {
return
}
//
let preEqual = true
//
let nextEqual = false
//
initFeeModeTableData(initIds = this.hadChooseType) {
//
if (this.feeModeTableData.length > 0) return;
let tableData = [];
if (rowIndex > 0) {
preEqual = this.feeModeTableData[rowIndex - 1].campusId === row.campusId
if (initIds.length > 0) {
// IDID
tableData = initIds.map(id => ({
courseTypeId: id,
courseType: this.courseTypeOptionsMap[id] || '',
cnt: 1,
totalFee: 0
}));
} else {
preEqual = false
}
if (this.feeModeTableData.length > rowIndex + 1) {
//
nextEqual = this.feeModeTableData[rowIndex + 1].campusId === row.campusId
// ID
const firstOption = this.courseTypeOptions[0] || {};
tableData = [{
courseTypeId: firstOption.id || '',
courseType: firstOption.label|| '',
cnt: 1,
totalFee: 0
}];
}
//
if (!preEqual && nextEqual) {
let rowspan = 1
for (let i = rowIndex + 1; i < this.feeModeTableData.length; i++) {
if (row.campusId === this.feeModeTableData[i].campusId) {
rowspan++
}
}
return {
rowspan: rowspan,
colspan: 1
}
} else if (preEqual) {
//
return {
rowspan: 0,
colspan: 0
}
}
this.feeModeTableData = tableData;
},
// +
lastCampus(item) {
const index = item.$index
const campusId = this.feeModeTableData[index].campusId
//
if (this.feeModeTableData.length === (index + 1)) {
return true
}
// +
return this.feeModeTableData[index + 1].campusId !== campusId
// courseType
handleCourseTypeChange(row) {
row.courseType = this.courseTypeOptionsMap[row.courseTypeId] || '';
},
//
canDel(item) {
const index = item.$index
const campusId = this.feeModeTableData[index].campusId
//
if (this.feeModeTableData.length === 1) {
return false
}
//
getAvailableCourseTypeOptions(currentIndex) {
// courseTypeId
const selectedIds = this.feeModeTableData
.filter((_, index) => index !== currentIndex)
.map(item => item.courseTypeId)
.filter(id => id);
//
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
}
//
const availableOptions = this.courseTypeOptions.filter(item => !selectedIds.includes(item.id));
return availableOptions;
},
// 2
handleAddFeeMode() {
//
const availableOptions = this.getAvailableCourseTypeOptions(this.feeModeTableData.length);
const firstOption = availableOptions[0] || {};
this.feeModeTableData.push({
courseTypeId: firstOption.id || '',
courseType: firstOption.label || '',
cnt: 1,
totalFee: 0
});
},
//
handleDeleteFeeMode(scope) {
this.feeModeTableData.splice(scope.$index, 1);
},
//
canDel() {
return this.feeModeTableData.length > 1;
}
}
}
};
</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>
<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-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-select
v-model="queryParams.courseTypeId"
@ -49,9 +22,9 @@
/>
</el-select>
</el-form-item>
<el-form-item label="收费模式:" prop="chargeType">
<el-form-item label="收费模式:" prop="cardType">
<el-select
v-model="queryParams.chargeType"
v-model="queryParams.cardType"
placeholder="请选择收费模式"
clearable
size="small"
@ -78,39 +51,45 @@
</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-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">
<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>
</el-table-column>
<el-table-column prop="courseTypeName" align="center" label="课程类型" />
<el-table-column prop="teachingMode" align="center" label="授课模式">
<template slot-scope="scope">
<div v-if="scope.row.teachingMode === '1'">
<el-tooltip class="item" effect="dark" content="班课" placement="right">
<svg-icon icon-class="one-to-many" style="height: 25px;width: 25px;" />
</el-tooltip>
<el-table-column prop="courseTypes" width="120" header-align="center" label="课程类别" >
<template slot-scope="scope" >
{{scope.row.courseTypesName}}
</template>
</el-table-column>
<el-table-column prop="restrictedCourses" width="200" header-align="center" label="限制课程">
<template slot-scope="scope" >
<div v-if="scope.row.restrictedCourses=='1'">
全部允许<br>
</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 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="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) }}
<el-table-column prop="restrictedTeacher" width="120" header-align="center" label="限制教练" >
<template slot-scope="scope" >
{{scope.row.restrictedTeacher=='1'?'全部允许':scope.row.teachersName}}
</template>
</el-table-column>
<el-table-column prop="campusIds" align="center" label="开课校区">
<template slot-scope="scope">
<div v-if="scope.row.campusIds">
<span v-if="scope.row.campusIds === '-1'"></span>
<span v-else>{{ scope.row.campusIds.split(',').length }}</span>
</div>
<div v-else> - </div>
<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>
<template slot="append">
@ -121,7 +100,7 @@
<div slot="footer" class="dialog-footer">
<div class="flex space-between">
<div class="footer-left-txt">
已选择 {{ chooseCourseIdList.length }} 门课程
<!-- 已选择 {{ chooseCourseIdList.length }} 门课程-->
</div>
<div class="align-right">
<el-button :loading="loading" type="primary" @click="chooseCourse"></el-button>
@ -133,9 +112,8 @@
</div>
</template>
<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 { campusList } from '@/api/school/system/dept'
export default {
data() {
@ -151,63 +129,41 @@ export default {
queryParams: {
pageNum: 1,
pageSize: 10,
courseName: undefined,
departId: undefined,
cardType: undefined,
courseTypeId: undefined,
teachingMode: undefined,
chargeType: undefined,
sale: '1'
},
//
courseTypeOptions: [],
//
teachingModeOptions: [{
teachingMode: '1',
teachingModeName: '班课'
}, {
teachingMode: '2',
teachingModeName: '一对一'
}],
//
campusOptions: [],
//
chargeTypeOptions: [{
chargeType: 'hour',
chargeTypeName: '按课时'
}, {
chargeType: 'date',
chargeTypeName: '按时间'
chargeType: 'count',
chargeTypeName: '按次数'
}, {
chargeType: 'cycle',
chargeType: 'days',
chargeTypeName: '按周期'
}, {
chargeType: 'total_fee',
chargeTypeName: '按储值'
}],
chooseCourseIdList: [],
chooseCardTypeId: [],
hasMore: false
}
},
methods: {
initData() {
this.dataList = []
this.campusList()
this.courseTypeList()
this.getList()
},
courseTypeList() {
courseTypeSelect({}).then(response => {
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() {
this.loading = true
selectCourseListWithStudentCourse(this.queryParams).then(response => {
listMemberCard(this.queryParams).then(response => {
this.dataList = [
...this.dataList,
...response.data.rows
@ -219,7 +175,7 @@ export default {
this.$nextTick(() => {
this.dataList.forEach(row => {
if (this.chooseCourseIdList.indexOf(row.courseId) !== -1) {
if (this.chooseCardTypeId.indexOf(row.cardTypeId) !== -1) {
this.$refs.table.toggleRowSelection(row, true)
}
})
@ -243,38 +199,25 @@ export default {
this.resetForm('queryForm')
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) {
const idx = this.chooseCourseIdList.indexOf(row.courseId)
const idx = this.chooseCardTypeId.indexOf(row.cardTypeId)
console.log('chooseCardTypeId',this.chooseCardTypeId)
if (idx !== -1) {
this.chooseCourseIdList.splice(idx, 1)
this.chooseCardTypeId.splice(idx, 1)
} else {
this.chooseCourseIdList.push(row.courseId)
this.chooseCardTypeId.push(row.cardTypeId)
}
},
handleSelectAll(selection) {
this.chooseCourseIdList = selection.map(item => item.courseId)
this.chooseCardTypeId = selection.map(item => item.cardTypeId)
},
chooseCourse() {
if (this.chooseCardTypeId.length>1){
this.msgError('只能提交1项请确认选择数量')
return ;
}
this.$emit('chooseComplete', {
chooseCourseIdList: this.chooseCourseIdList,
departId: this.queryParams.departId
chooseCardTypeIdList: this.chooseCardTypeId,
})
this.open = false
}

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

@ -1,7 +1,7 @@
<!--新增课程类型-->
<template>
<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-col :span="12">
<el-form-item label="类型名称" prop="courseType">
@ -9,6 +9,13 @@
</el-form-item>
</el-col>
</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>
<div slot="footer" class="dialog-footer">
<el-button :loading="loadingChange" type="primary" @click="submitForm"> </el-button>
@ -44,8 +51,8 @@ export default {
},
reset() {
this.form = {
courseType: undefined,
sort: undefined
courseType: '',
remark: ''
}
this.resetForm('form')
},
@ -64,6 +71,7 @@ export default {
} else {
this.msgError(response.respMsg)
}
this.reset()
}).catch(() => {
this.loadingChange = false
})
@ -77,8 +85,10 @@ export default {
} else {
this.msgError(response.respMsg)
}
this.reset()
}).catch(() => {
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-value">{{ orderInfo.handleDeptName }}</div>
</div>
<div class="item">
<div class="item-name">经办人:</div>
<div class="item-value">{{ orderInfo.handleStaffName }}</div>
</div>
<div class="item">
<div class="item-name">经办日期:</div>
<div class="item-value">{{ orderInfo.handleDate }}</div>
</div>
<div class="item">
<div class="item-name">:</div>
<div class="item-name">:</div>
<div class="item-value">{{ orderInfo.studentName }}</div>
</div>
<div class="item">
<div class="item-name">学员电话:</div>
<div class="item-value">{{ orderInfo.phone }}</div>
</div>
<div class="item">
<div class="item-name">订单类型:</div>
<div v-if="orderInfo.orderType === '1'" class="item-value"></div>
@ -39,26 +39,14 @@
<div class="item-name">原价:</div>
<div class="item-value">¥{{ orderInfo.originalTotalFee }}</div>
</div>
<div class="item">
<div class="item-name">实际价格:</div>
<div class="item-value">¥{{ orderInfo.actualTotalFee }}</div>
</div>
<div class="item">
<div class="item-name">实收:</div>
<div class="item-value">¥{{ orderInfo.receiptFee }}</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-name">订单标签:</div>
<div class="item-value">{{ orderInfo.orderTag }}</div>
</div>
<div class="item">
<div class="item-name">销售来源:</div>
<div class="item-value">{{ orderInfo.saleSourceTag }}</div>
</div>
<div class="item">
<div class="item-name">销售员工:</div>
<div class="item-value">{{ orderInfo.saleStaffName }}</div>
@ -79,97 +67,54 @@
<div class="title">
<div class="title-content">收款账户</div>
</div>
<div v-for="(item, index) in orderAccountArray" :key="index" class="cla-base-info">
<div class="item">
<div class="item-name">收款账户:</div>
<div class="item-value">{{ item.accountName }}</div>
</div>
<div class="item">
<div class="item-name">收款金额:</div>
<div class="item-value">{{ item.fee }}</div>
</div>
<div class="item">
<div class="item-name">收款账户:</div>
<div class="item-value">{{ orderAccount.accountName }}</div>
</div>
<div v-for="item in orderDetailArray" :key="item.orderDetailId" class="top-border">
<div class="top-border">
<div class="title">
<div class="title-content">报读课程({{ item.courseName }})</div>
<div class="title-content">报读卡类({{ orderDetail.cardTypeName }})</div>
</div>
<div class="cla-base-info">
<div class="item">
<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-name">扣费方式:</div>
<div class="item-value">
<el-tag v-if="item.detailTag === '1'" size="medium" type="info"></el-tag>
<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>
{{ orderDetail.chargeType=='count'?'按次数':orderDetail.chargeType=='total_fee'?'按储值':'按周期' }}
</div>
</div>
<div v-if="item.claName" class="item">
<div class="item-name">班级:</div>
<div class="item-value">{{ item.claName }}</div>
</div>
<div class="item">
<div class="item-name">状态:</div>
<div class="item-name">卡号: </div>
<div class="item-value">
<el-tag v-if="item.orderDetailStatus === '1'" size="medium" type="info"></el-tag>
<el-tag v-if="item.orderDetailStatus === '2'" size="medium"></el-tag>
<el-tag v-if="item.orderDetailStatus === '3'" size="medium" type="danger"></el-tag>
{{ orderDetail.cardNo }}
</div>
</div>
<div class="item">
<div class="item-name">收费方式:</div>
<div v-if="orderDetail.chargeType=='count'" class="item">
<div class="item-name">总次数: </div>
<div class="item-value">
<el-tooltip effect="dark" :content="item.chargeName" placement="top">
<span>{{ item.chargeName }}</span>
</el-tooltip>
{{ orderDetail.totalCount }}
</div>
</div>
<div v-if="item.chargeType === 'date'" class="item">
<div class="item-name">周期:</div>
<div v-if="orderDetail.chargeType=='days'" class="item">
<div class="item-name">总天数: </div>
<div class="item-value">
<el-tooltip effect="dark" :content="item.beginDate + '~' + item.endDate" placement="top">
<span>{{ item.beginDate }} ~ {{ item.endDate }}</span>
</el-tooltip>
{{ orderDetail.totalDays }}
</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 class="item">
<div class="item-name">原价:</div>
<div class="item-value">¥{{ item.originalFee }}</div>
</div>
<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 class="item">
<div class="item-name">实际价格:</div>
<div class="item-value">¥{{ item.actualFee }}</div>
<div v-if="orderDetail.chargeType=='total_fee'" class="item">
<div class="item-name">储值金额: </div>
<div class="item-value">
{{ orderDetail.totalFee }}
</div>
</div>
<div class="item">
<div class="item-name">内部备注:</div>
<div class="item-value">{{ item.insideMemo }}</div>
<div class="item-name">卡片状态:</div>
<div class="item-value">{{ orderDetail.statusDesc }}</div>
</div>
<div class="item">
<div class="item-name">外部备注:</div>
<div class="item-value">{{ item.outsideMemo }}</div>
<div class="item-name">备注:</div>
<div class="item-value">{{ orderDetail.notes }}</div>
</div>
</div>
</div>
@ -188,8 +133,8 @@ export default {
open: false,
loading: false,
orderInfo: {},
orderDetailArray: [],
orderAccountArray: []
orderDetail: [],
orderAccount: []
}
},
methods: {
@ -199,8 +144,8 @@ export default {
getOrder(orderId).then(response => {
this.loading = false
this.orderInfo = response.data.orderInfo
this.orderDetailArray = response.data.orderDetail
this.orderAccountArray = response.data.orderAccountList
this.orderDetail = response.data.orderDetail
this.orderAccount = response.data.orderAccount
}).catch(() => {
this.loading = false
})

@ -1,7 +1,7 @@
<!--新增学员-->
<template>
<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-row>
<el-col :span="12">
@ -35,7 +35,6 @@
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="入校时间:" prop="inTime">
<el-date-picker
@ -48,14 +47,16 @@
/>
</el-form-item>
</el-col>
<el-col v-for="(item, index) in contactArray" :key="index" :span="24" style="text-align: left;">
<el-form-item label="联系电话:">
<el-input v-model="contactArray[index].contactPhone" style="width: 200px;" 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-col :span="12">
<el-form-item label="联系电话:" prop="phone">
<el-input v-model="form.phone" placeholder="请输入联系电话" />
</el-form-item>
</el-col>
</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>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button>
@ -74,9 +75,12 @@ export default {
data() {
return {
open: false,
title:"",
remark:'',
//
form: {
sex: '2'
sex: '0',
phone:''
},
//
sexOptions: [],
@ -91,7 +95,12 @@ export default {
{ required: true, message: '性别不能为空', trigger: 'blur' }
],
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,
@ -122,12 +131,10 @@ export default {
},
reset() {
this.form = {
schoolId: undefined,
schoolName: undefined,
studentName: undefined,
birthDay: undefined,
sex: '2',
phone: undefined,
sex: '0',
phone: '',
inTime: moment(new Date()).format('YYYY-MM-DD')
}
this.resetForm('form')
@ -153,25 +160,26 @@ export default {
}
this.open = true
this.title = '修改学员基本信息'
this.remark=''
})
},
/** 提交按钮 */
submitForm: function() {
this.$refs['form'].validate(valid => {
if (valid) {
this.contactArray.forEach(item => {
if (item.contactRelation === undefined || item.contactRelation === null || item.contactRelation.trim() === '') {
this.msgError('请选择联系人与学员关系')
valid = false
} else if (item.contactPhone === undefined || item.contactPhone === null || item.contactPhone.trim() === '') {
this.msgError('请填写联系人电话')
valid = false
}
})
// this.contactArray.forEach(item => {
// if (item.contactRelation === undefined || item.contactRelation === null || item.contactRelation.trim() === '') {
// this.msgError('')
// valid = false
// } else if (item.contactPhone === undefined || item.contactPhone === null || item.contactPhone.trim() === '') {
// this.msgError('')
// valid = false
// }
// })
if (!valid) {
return
}
this.form.contactList = this.contactArray
// this.form.contactList = this.contactArray
if (this.form.studentId !== undefined) {
updateStudent(this.form).then(response => {
if (response.respCode === '0000') {

@ -11,7 +11,7 @@
</div>
<el-table v-else v-loading="loading" :data="dataList" @selection-change="handleSelectionChange">
<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="phone" label="联系电话" width="120">
<template slot-scope="scope">
@ -66,7 +66,7 @@
</template>
<script>
import { selectDictLabel } from '@/utils/commonUtils'
import { searchCourseClaStudent, studentCourseChooseCla } from '@/api/school/sc/student/course'
import { studentCourseChooseCla } from '@/api/school/sc/student/course'
export default {
props: {
//

@ -12,7 +12,7 @@
</el-col>
</el-row>
<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">
<router-link :to="'/edu/student/detail/' + scope.row.studentId" class="link-type">
<span>{{ scope.row.studentName }}</span>
@ -102,7 +102,7 @@
</template>
<script>
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 claTimeAttendDetailTable from '@/components/sc/claTime/claTimeAttendDetailTable'
export default {
@ -182,7 +182,7 @@ export default {
chargeTypeFormatter(row, column) {
if (row.chargeType === 'date' && row.effect === false && row.balanceDays > 0) {
// > 0
return '按课时(未生效)'
return '按次数(未生效)'
} else {
return selectDictLabel(this.chargeTypeOptions, row.chargeType)
}

@ -23,7 +23,7 @@
</el-form-item>
</el-form>
<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">
<!-- <router-link :to="'/edu/student/detail/' + scope.row.studentId" class="link-type">-->
<span>{{ scope.row.studentName }}</span>

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

@ -1,12 +1,12 @@
<!-- 列表 -->
<!-- 列表 -->
<template>
<div>
<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
v-model="queryParams.studentName"
placeholder="请输入学姓名"
placeholder="请输入学姓名"
clearable
size="small"
@keyup.enter.native="handleQuery"
@ -31,7 +31,7 @@
@keyup.enter.native="handleQuery"
/>
</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 icon="el-icon-refresh" size="mini" @click="resetQuery"></el-button>
</el-form-item>
@ -67,28 +67,15 @@
@click="handleDelete"
>删除</el-button>
</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-table v-loading="loading" :data="dataList" @selection-change="handleSelectionChange">
<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">
<!-- <router-link :to="'/edu/student/detail/' + scope.row.studentId" class="link-type">-->
<span>{{ scope.row.studentName }}</span>
<!-- </router-link>-->
</template>
</el-table-column>
<!-- <el-table-column prop="schoolName" label="所属学校" />-->
<el-table-column prop="birthDay" label="生日">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.birthDay, '{y}-{m}-{d}') }}</span>
@ -138,12 +125,12 @@
<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">
<el-table :data="scope.data">
<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="contactPhone" label="联系电话" show-overflow-tooltip />
<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="phone" 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="inTime" label="入校时间" show-overflow-tooltip />
@ -166,10 +153,10 @@
</template>
<template slot="failTable" slot-scope="scope">
<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="contactRelation" label="主要联系人" show-overflow-tooltip />
<el-table-column align="center" prop="contactPhone" label="联系电话" show-overflow-tooltip />
<!-- <el-table-column align="center" prop="contactRelation" 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="schoolName" label="学校" show-overflow-tooltip />
<el-table-column align="center" prop="inTime" label="入校时间" show-overflow-tooltip />

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

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

@ -5,5 +5,5 @@ export const dict_types = ["sys_user_sex",
"pms_publish_status", 'sku_sort_list',
'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'
,'charge_type','date_unit'
,'charge_type','date_unit','book_status'
];

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

@ -1,7 +1,7 @@
<template>
<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-input
v-model="queryParams.teacherName"
@ -21,7 +21,7 @@
<el-option label="展示" value="1"></el-option>
</el-select>
</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 icon="el-icon-refresh" size="mini" @click="resetQuery"></el-button>
</el-form-item>
@ -69,7 +69,7 @@
<el-table-column type="selection" width="55" align="center" />
<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="teacherName" />
<el-table-column label="老师名称app展示" align="center" prop="teacherName" />
<el-table-column label="头像" align="center" prop="avatarImg" width="100">
<template slot-scope="scope">
<el-image

@ -82,25 +82,38 @@
<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="studentName" 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">
<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>
{{ scope.row.cardType?'卡类:'+scope.row.cardType:'' }}<br>
卡号 {{ scope.row.cardNo }}<br>
<span v-if="scope.row.chargeType=='count'">
次数卡{{scope.row.totalCount}}
</span>
<span v-if="scope.row.chargeType=='days'">
周期卡{{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>
</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="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="经办人" />
@ -114,8 +127,7 @@
<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-menu>
</el-dropdown>
</template>
</el-table-column>
@ -167,10 +179,6 @@ export default {
open: false,
//
studentIdOptions: [],
// 1
orderTypeOptions: [],
//
orderStatusOptions: [],
handleDateArray: [],
//
queryParams: {
@ -197,12 +205,6 @@ export default {
this.handleDateArray = [startDate, endDate]
}
this.getList()
this.getDictListByDictType('order_type').then(response => {
this.orderTypeOptions = response.data
})
this.getDictListByDictType('order_status').then(response => {
this.orderStatusOptions = response.data
})
},
methods: {
getList() {
@ -252,7 +254,7 @@ export default {
})
},
orderTypeFormat(row, column) {
return this.selectDictLabel(this.orderTypeOptions, row.orderType)
return this.selectDictLabel(this.dict.type.course_order_type, row.orderType)
},
//
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}}">
<div class="name">剩余课时小于5课时 <span class="cnt">{{ dashboardData.hourWillExpireCnt }}</span></div>
</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>

@ -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"/>
</el-form-item>
</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-card>
@ -172,13 +182,14 @@
<script>
import {addPmsProduct, getPmsProduct, updatePmsProduct} from "@/api/pms/product";
import userSelect from '@/components/system/user/userSelect'
import ProductCategorySelect from "@/views/components/ProductCategorySelect.vue";
import BrandSelect from "@/views/components/BrandSelect.vue";
import CourseSelect from "@/views/mall/product/courseSelect";
export default {
name: "AddProduct",
dicts: ['pms_publish_status','pms_is_course'],
components: {BrandSelect, ProductCategorySelect,CourseSelect},
components: {BrandSelect, ProductCategorySelect,CourseSelect,userSelect},
data() {
return {
@ -192,7 +203,9 @@ export default {
sort: 1000,
isCourse:'0',
courseName:null,
courseId:null
courseId:null,
customerService:null,
instructor:null
},
skuAttr:[],
albumPics:null,
@ -225,6 +238,7 @@ export default {
}else {
this.form.courseName =null
this.form.courseId =null
this.form.instructor =null
}
},
refreshSku(){
@ -318,14 +332,21 @@ export default {
}
if (this.form.id != null) {
updatePmsProduct(this.form).then(response => {
this.$modal.msgSuccess("修改成功");
if (response.code!=500){
this.cancel();
this.$modal.msgSuccess("修改成功");
}
});
} else {
addPmsProduct(this.form).then(response => {
this.$modal.msgSuccess("新增成功");
if (response.code!=500){
this.cancel();
this.$modal.msgSuccess("新增成功");
}
});
}
this.cancel();
}else{
if(this.form.name){
this.$alert('请填写规格价格', '提示', {

@ -25,15 +25,7 @@
</el-select>
<!-- <staff-select v-model="queryParams.teacherId" teacher="1" clearable placeholder="选择任课教师" @change="handleChangeTeacher" />-->
</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-date-picker
v-model="claDateArray"
@ -45,7 +37,7 @@
placeholder="选择开始日期"
/>
</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 icon="el-icon-refresh" size="mini" @click="resetQuery"></el-button>
</el-form-item>
@ -114,12 +106,6 @@
</template>
</el-table-column>
<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="classTheme" align="center" label="上课主题" show-overflow-tooltip />
<el-table-column width="150" label="操作" align="center" class-name="small-padding fixed-width" fixed="right">
@ -297,7 +283,7 @@ export default {
/** 删除按钮操作 */
handleDelete(row) {
const id = row.ruleId || this.ids
this.$confirm('是否确认删除?', '警告', {
this.$confirm('本操作会将未上课且无学员预约/预约失败/取消预约的相关课表同时删除,已经上完的课程不会被删除,是否确认操作?', '警告', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'

@ -44,25 +44,7 @@
/>
</el-select>
</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>
<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>
@ -98,16 +80,6 @@
@click="handleDelete"
>取消班级</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-table v-loading="loading" :data="dataList" @selection-change="handleSelectionChange">
@ -155,7 +127,7 @@
<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-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:delete']" icon="el-icon-delete" @click.native="handleDelete(scope.row)"></el-dropdown-item>
</el-dropdown-menu>
@ -284,17 +256,6 @@ export default {
courseOptions: [],
//
teacherOptions: [],
//
chargeTypeOptions: [{
chargeType: 'hour',
chargeTypeName: '按课时'
}, {
chargeType: 'date',
chargeTypeName: '按时间'
}, {
chargeType: 'cycle',
chargeTypeName: '按周期'
}],
// ,,
courseTimeOptions: [],
//
@ -303,7 +264,6 @@ export default {
pageSize: 10,
courseId: undefined,
teacherId: undefined,
chargeId: '',
claName: undefined,
courseTime: undefined
},
@ -318,9 +278,6 @@ export default {
teacherId: [
{ required: true, message: '教师id不能为空', trigger: 'blur' }
],
chargeId: [
{ required: true, message: '收费方式id不能为空', trigger: 'blur' }
],
claName: [
{ required: true, message: '班级名称不能为空', trigger: 'blur' }
],
@ -481,9 +438,6 @@ export default {
return '-'
}
},
handleImport() {
this.$refs.uploadCheckImportExcel.openImport()
}
}
}
</script>

@ -64,24 +64,6 @@
/>
</el-select>
</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-switch
v-model="queryParams.sale"
@ -129,26 +111,6 @@
>删除课程
</el-button>
</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-table v-loading="loading" :data="dataList" @selection-change="handleSelectionChange">
@ -170,11 +132,6 @@
</template>
</el-table-column>
<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="教练课时费/节" >
<template slot-scope="scope">
{{ scope.row.claFee }}
@ -182,11 +139,10 @@
</el-table-column>
<el-table-column prop="campusIds" align="center" label="开课校区">
<template slot-scope="scope">
<div v-if="scope.row.campusIds">
<span v-if="scope.row.campusIds === '-1'"></span>
<div >
<span v-if="scope.row.campusIds==null"></span>
<span v-else>{{ scope.row.campusIds.split(',').length }}</span>
</div>
<div v-else> - </div>
</template>
</el-table-column>
<el-table-column prop="createTime" width="100" align="center" label="创建时间">
@ -240,7 +196,7 @@
</template>
<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 uploadImportExcel from '@/components/tool/impt/uploadImportExcel'
import {select as courseTypeSelect} from '@/api/school/sc/course/courseType'
@ -294,7 +250,7 @@ export default {
//
chargeTypeOptions: [{
chargeType: 'hour',
chargeTypeName: '按课时'
chargeTypeName: '按次数'
}, {
chargeType: 'date',
chargeTypeName: '按时间'
@ -356,13 +312,12 @@ export default {
handleUpdate(row) {
getCourse(row.courseId || this.ids).then(response => {
this.$refs.addCourseComponents.init()
response.data.partCampus=response.data.partCampus?.map(item => {
return parseInt(item)
})
this.$refs.addCourseComponents.form = response.data
if (response.data.partCampus==null){
this.$refs.addCourseComponents.form.partCampus=[]
}
this.$refs.addCourseComponents.open = true
this.$refs.addCourseComponents.title = '修改课程信息'
this.$refs.addCourseComponents.initFeeModeDate(response.data)
})
},
/** 删除按钮操作 */
@ -388,33 +343,13 @@ export default {
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) {
if (chargeNames) {
const chargeNameArray = []
chargeNames.split(',').forEach((value, index, array) => {
if (value === 'hour') {
chargeNameArray.push('按课时')
chargeNameArray.push('按次数')
} else if (value === 'date') {
chargeNameArray.push('按时间')
} else if (value === 'cycle') {
@ -426,7 +361,7 @@ export default {
return '-'
}
},
//
//
handleSaleChange(row) {
const text = row.sale === '1' ? '开售' : '停售'
this.$confirm('确认要"' + text + '""' + row.courseName + '"课程吗?', '警告', {

@ -1,6 +1,6 @@
<template>
<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-select v-model="queryParams.courseType" placeholder="请选择课程类型名" clearable size="small">
<el-option
@ -47,22 +47,23 @@
@click="handleDelete"
>删除</el-button>
</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-table v-loading="loading" :data="dataList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column prop="tenantId" label="所属租户" />
<el-table-column prop="courseType" label="课程类型名" />
<el-table-column prop="sort" label="排序" />
<el-table-column prop="courseType" width="170" label="课程类型名" />
<el-table-column prop="sort" width="120" 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">
<template slot-scope="scope">
<el-button
@ -97,7 +98,7 @@
</template>
<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'
export default {
name: 'Type',
@ -207,6 +208,21 @@ export default {
this.msgError(response.respMsg)
}
}).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-col>
</el-row>
<span style="color: #999; font-size: 12px;">
* 说明场地费为xx元每小时
<br>实际计算中未满半小时按0.5小时计算收费已满半小时,按1小时计算收费
<br>例如教室使用40分钟按1小时计算收费使用70分钟按1.5小时计算收费
</span>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button :loading="loadingChange" type="primary" @click="submitForm"> </el-button>

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

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

@ -7,7 +7,7 @@
</template>
</el-table-column>
<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="收费方式">
<template slot-scope="scope">
<span>{{ chargeTypeFormatter(scope.row) }}</span>

@ -20,7 +20,7 @@
</el-form-item>
</el-form>
<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">
<template slot-scope="scope">
<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>
<div>
<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">
<template slot-scope="scope">
<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>
</template>
</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="orderDetail" width="200" align="center" label="销售内容">
<el-table-column prop="orderDetail" width="200" align="left" 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>
{{ scope.row.cardType?'卡类:'+scope.row.cardType:'' }}<br>
卡号 {{ scope.row.cardNo }}<br>
<span v-if="scope.row.chargeType=='count'">
次数卡{{scope.row.totalCount}}
</span>
<span v-if="scope.row.chargeType=='days'">
周期卡{{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>
</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="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="经办人" />

@ -1,15 +1,6 @@
<template>
<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" />
</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>
<student-table ref="studentTable" />
</div>
</template>
@ -39,7 +30,7 @@ export default {
methods: {
handleTabChange(tab) {
if (tab.name === 'studentList') {
//
//
} else if (tab.name === 'studentSignUpList') {
//
this.$refs.studentCourseSignUpTable.getList()

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

@ -1,6 +1,7 @@
<template>
<div class="app-container">
<el-row :gutter="20">
<!--部门数据-->
<el-col :span="4" :xs="24">
<div class="head-container">
@ -229,19 +230,6 @@
</el-col>
</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-form-item label="角色">
<el-select v-model="form.roleIds" multiple placeholder="请选择角色">
@ -263,6 +251,11 @@
</el-form-item>
</el-col>
</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>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button>
@ -492,8 +485,8 @@ export default {
deptId: undefined,
userName: undefined,
nickName: undefined,
password: undefined,
phonenumber: undefined,
password: '',
phonenumber: '',
email: undefined,
sex: undefined,
status: "0",

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

Loading…
Cancel
Save