Browse Source

Merge branch 'dev' into ymorder

organize
刘嘉炜 4 years ago
parent
commit
6dc1ae832d
  1. 11
      src/components/order_list/club_rental/club_rental.vue
  2. 6
      src/components/order_list/device/device.vue
  3. 4
      src/components/order_list/locker/locker.vue
  4. 20
      src/components/order_list/mall/mall.vue
  5. 2
      src/components/order_list/spectacular_monent/spectacular_monent.vue
  6. 4
      src/components/organize_order/organize_order.vue
  7. 2
      src/components/site/order_modal/order_modal.vue
  8. 78
      src/pages.json
  9. 6
      src/pages/index/index.vue
  10. 71
      src/pages/order_list/order_list.vue
  11. 25
      src/pages/order_search/order_search.vue
  12. BIN
      src/static/images/icon/index/tab_10.png
  13. BIN
      src/static/images/icon/index/tab_8.png
  14. BIN
      src/static/images/icon/index/tab_9.png
  15. BIN
      src/static/images/order_null.png
  16. 1
      src/store/index.js
  17. 147
      src/subpackage/course/components/cancel_class_modal/cancel_class_modal.vue
  18. 175
      src/subpackage/course/components/class_reset_modal/class_reset_modal.vue
  19. 143
      src/subpackage/course/components/manage/bclass_reserve_item/bclass_reserve_item.vue
  20. 93
      src/subpackage/course/components/manage/class_manage_item/class_manage_item.vue
  21. 125
      src/subpackage/course/components/manage/private_reserve_item/private_reserve_item.vue
  22. 86
      src/subpackage/course/components/manage/student_course_item/student_course_item.vue
  23. 114
      src/subpackage/course/components/sclass_record_section/sclass_record_section.vue
  24. 95
      src/subpackage/course/components/store_name/store_name.vue
  25. 117
      src/subpackage/course/components/tab_bar/tab_bar.vue
  26. 192
      src/subpackage/course/components/task_section/task_section.vue
  27. 33
      src/subpackage/course/js/course_api.js
  28. 10
      src/subpackage/course/js/course_server.js
  29. 409
      src/subpackage/course/pages/arrange_class/arrange_class.vue
  30. 226
      src/subpackage/course/pages/class_add_student/class_add_student.vue
  31. 242
      src/subpackage/course/pages/class_student_detail/class_student_detail.vue
  32. 250
      src/subpackage/course/pages/class_time_change/class_time_change.vue
  33. 242
      src/subpackage/course/pages/index/index.vue
  34. 396
      src/subpackage/course/pages/manage_detail/bclass_reserve_detail/bclass_reserve_detail.vue
  35. 540
      src/subpackage/course/pages/manage_detail/class_manage_detail/class_manage_detail.vue
  36. 236
      src/subpackage/course/pages/manage_detail/private_reserve_detail/private_reserve_detail.vue
  37. 323
      src/subpackage/course/pages/manage_detail/student_course_detail/student_course_detail.vue
  38. 352
      src/subpackage/course/pages/manage_list/manage_list.vue
  39. 138
      src/subpackage/course/pages/task_detail/task_detail.vue
  40. 146
      src/subpackage/course/pages/task_finish_list/task_finish_list.vue
  41. BIN
      src/subpackage/course/static/images/icon/arrow_b2.png
  42. BIN
      src/subpackage/course/static/images/icon/arrow_black.png
  43. BIN
      src/subpackage/course/static/images/icon/arrow_green.png
  44. BIN
      src/subpackage/course/static/images/icon/arrow_white.png
  45. BIN
      src/subpackage/course/static/images/icon/calendar.png
  46. BIN
      src/subpackage/course/static/images/icon/close_gray.png
  47. BIN
      src/subpackage/course/static/images/icon/phone.png
  48. BIN
      src/subpackage/course/static/images/icon/triangle.png
  49. BIN
      src/subpackage/course/static/images/no_order.png
  50. BIN
      src/subpackage/course/static/images/tab/tab_0_0.png
  51. BIN
      src/subpackage/course/static/images/tab/tab_0_1.png
  52. BIN
      src/subpackage/course/static/images/tab/tab_0_2.png
  53. BIN
      src/subpackage/course/static/images/tab/tab_0_3.png
  54. 6
      src/subpackage/device/components/order/organize_detail/organize_detail.vue
  55. 2
      src/subpackage/order/js/api.js
  56. 12
      src/subpackage/order/pages/club_rental/detail/detail.vue
  57. 10
      src/subpackage/order/pages/devices/detail/detail.vue
  58. 8
      src/subpackage/order/pages/mall/detail/detail.vue
  59. 25
      src/subpackage/order/pages/mall/refund_operate/refund_operate.vue
  60. 12
      src/subpackage/order/pages/mall/send_out/send_out.vue
  61. 6
      src/subpackage/order/pages/rent_and_sale/detail/detail.vue
  62. 2
      src/subpackage/order/pages/spectacular_monent/detail/detail.vue

11
src/components/order_list/club_rental/club_rental.vue

@ -1,6 +1,7 @@
<template> <template>
<!-- 租球机 -->
<view class="club-rental-container" @click="toInfo"> <view class="club-rental-container" @click="toInfo">
<a-header :source="orderInfo.source || '-'" :status="getStatusTxt(orderInfo.pay_status)">
<a-header :source="orderInfo.source || '-'" :status="orderInfo.extension.status_text || '-'">
<view slot="line" class="crc-line"> <view slot="line" class="crc-line">
<image class="cl-img" mode="aspectFit" src="/static/images/icon/location.png"></image> <image class="cl-img" mode="aspectFit" src="/static/images/icon/location.png"></image>
<view class="cl-view">{{ orderInfo.hardware_name || '-' }}</view> <view class="cl-view">{{ orderInfo.hardware_name || '-' }}</view>
@ -47,7 +48,9 @@ export default {
}, },
props: { props: {
orderInfo: { orderInfo: {
default: {},
default: {
extension: {}
},
type: Object type: Object
} }
}, },
@ -58,9 +61,9 @@ export default {
let { orderInfo } = this; let { orderInfo } = this;
util.routeTo(`/subpackage/order/pages/club_rental/detail/detail?order_no=${orderInfo.order_no}`, 'nT'); util.routeTo(`/subpackage/order/pages/club_rental/detail/detail?order_no=${orderInfo.order_no}`, 'nT');
}, },
getStatusTxt(status = 0){
getStatusTxt(status = -1){
let _obj = { let _obj = {
1: '寄存中',
0: '租用中',
2: '已完成', 2: '已完成',
4: '已退款', 4: '已退款',
} }

6
src/components/order_list/device/device.vue

@ -1,10 +1,10 @@
<template> <template>
<!-- 售货柜/浴室/咖啡/储物柜订单 -->
<!-- 售货柜/浴室/咖啡/ -->
<view class="device-container" @click="toInfo"> <view class="device-container" @click="toInfo">
<a-header :source="orderInfo.source" :status="status_txt(orderInfo.pay_status)">
<a-header :source="orderInfo.stadium_name" :status="status_txt(orderInfo.pay_status)">
<view slot="line" class="dc-line"> <view slot="line" class="dc-line">
<image class="dl-img" mode="aspectFit" src="/static/images/icon/location.png"></image> <image class="dl-img" mode="aspectFit" src="/static/images/icon/location.png"></image>
<view class="dl-view">{{ orderInfo.extension.hardware_name || '-' }}</view>
<view class="dl-view">{{ orderInfo.hardware_name || '-' }}</view>
</view> </view>
</a-header> </a-header>
<view class="dc-info"> <view class="dc-info">

4
src/components/order_list/locker/locker.vue

@ -1,9 +1,9 @@
<template> <template>
<view class="locker-container" @click="toInfo"> <view class="locker-container" @click="toInfo">
<a-header :source="orderInfo.source" :status="status_txt(orderInfo.pay_status)">
<a-header :source="orderInfo.stadium_name" :status="status_txt(orderInfo.pay_status)">
<view slot="line" class="lc-line"> <view slot="line" class="lc-line">
<image class="ll-img" mode="aspectFit" src="/static/images/icon/location.png"></image> <image class="ll-img" mode="aspectFit" src="/static/images/icon/location.png"></image>
<view class="ll-view">{{ orderInfo.extension.hardware_name || '-' }}</view>
<view class="ll-view">{{ orderInfo.hardware_name || '-' }}</view>
</view> </view>
</a-header> </a-header>
<view class="lc-info"> <view class="lc-info">

20
src/components/order_list/mall/mall.vue

@ -4,6 +4,7 @@
<view class="mn-view">订单号{{ orderInfo.order_no || '-' }}</view> <view class="mn-view">订单号{{ orderInfo.order_no || '-' }}</view>
<view class="mn-view">{{ orderInfo.status_text || '-' }}</view> <view class="mn-view">{{ orderInfo.status_text || '-' }}</view>
</view> </view>
<view class="mo-after-sale-tip" v-if="orderInfo.after_sale_status == 1">{{ orderInfo.after_sale_status_text || '-' }}</view>
<view class="mo-goods-ls"> <view class="mo-goods-ls">
<view class="rgi-single" v-if="orderInfo.goods_nums == 1"> <view class="rgi-single" v-if="orderInfo.goods_nums == 1">
<image class="rs-img" mode="aspectFill" :src="orderInfo.goods[0].product_imgs"></image> <image class="rs-img" mode="aspectFill" :src="orderInfo.goods[0].product_imgs"></image>
@ -22,16 +23,24 @@
</view> </view>
<view class="mo-total"><text class="mt-txt">商品金额合计</text>¥{{ orderInfo.pay_amount || 0 }}</view> <view class="mo-total"><text class="mt-txt">商品金额合计</text>¥{{ orderInfo.pay_amount || 0 }}</view>
<view class="mo-bot"> <view class="mo-bot">
<view class="mb-express">配送方式{{ orderInfo.product_order_self_pickup == 1 ? '自提' : '快递' }}</view>
<view class="mb-btn" @click.stop="toSendOut">发货</view>
<view class="mb-express" v-if="orderInfo.status == 2">配送方式{{ orderInfo.product_order_self_pickup == 1 ? '自提' : '快递' }}</view>
<view class="mb-btn" v-if="orderInfo.status == 1&&orderInfo.after_sale_status == 0" @click.stop="toSendOut">发货</view>
</view> </view>
</view> </view>
</template> </template>
<script> <script>
// 0/1/2/3/4/5/6 - /////退/退 1,2,3,6
import util from '../../../utils/util'; import util from '../../../utils/util';
export default { export default {
computed: {
isShowSendMethods(){
let { orderInfo } = this;
return orderInfo.status == 2 || orderInfo.status == 3 || orderInfo.status == 5 || orderInfo.status == 6
},
},
props: { props: {
orderInfo: { orderInfo: {
default: { default: {
extension: {} extension: {}
@ -79,6 +88,13 @@ export default {
} }
} }
} }
.mo-after-sale-tip{
margin-bottom: 12upx;
text-align: right;
font-size: 24upx;
line-height: 30upx;
color: #EA5061;
}
.mo-goods-ls{ .mo-goods-ls{
margin-bottom: 30upx; margin-bottom: 30upx;
@include centerFlex(space-between); @include centerFlex(space-between);

2
src/components/order_list/spectacular_monent/spectacular_monent.vue

@ -11,7 +11,7 @@
<a-line :value="orderInfo.price_type_text || '-'"> <a-line :value="orderInfo.price_type_text || '-'">
<block slot="name">类型</block> <block slot="name">类型</block>
</a-line> </a-line>
<block v-if="orderInfo.order_type == 0">
<block v-if="orderInfo.order_type == 0 || orderInfo.order_type == 2">
<a-line :value="orderInfo.venue_name || '-'"> <a-line :value="orderInfo.venue_name || '-'">
<block slot="name">场地</block> <block slot="name">场地</block>
</a-line> </a-line>

4
src/components/organize_order/organize_order.vue

@ -30,12 +30,12 @@
<view class="rv-view">{{orderInfo.label.Date+" "+ orderInfo.label.StartTime+" "+orderInfo.label.EndTime || '-'}}</view> <view class="rv-view">{{orderInfo.label.Date+" "+ orderInfo.label.StartTime+" "+orderInfo.label.EndTime || '-'}}</view>
</view> </view>
</view> </view>
<view class="rs-line" v-if="orderInfo.status=='End'">
<!-- <view class="rs-line" v-if="orderInfo.status=='End'">
<view class="rl-view">未发放</view> <view class="rl-view">未发放</view>
<view class="rl-view"> <view class="rl-view">
<view class="rv-view">{{orderInfo.un_amount_already_amount || '-'}}</view> <view class="rv-view">{{orderInfo.un_amount_already_amount || '-'}}</view>
</view> </view>
</view>
</view> -->
</view> </view>
<view class="ro-bot" v-if="orderInfo.original_order&&orderInfo.original_order.pay_status != 0"> <view class="ro-bot" v-if="orderInfo.original_order&&orderInfo.original_order.pay_status != 0">

2
src/components/site/order_modal/order_modal.vue

@ -69,7 +69,7 @@
<view class="om-info-line"> <view class="om-info-line">
<view class="oil-view">预订项目</view> <view class="oil-view">预订项目</view>
<view class="oil-view"> <view class="oil-view">
<view class="ov-view">{{ orderInfo.stadium_name || ' ' }}</view>
<view class="ov-view">{{ orderInfo.project || ' ' }}</view>
</view> </view>
</view> </view>
<view class="om-info-line"> <view class="om-info-line">

78
src/pages.json

@ -498,6 +498,84 @@
} }
} }
] ]
},
{
"root": "subpackage/course",
"pages": [
{
"path": "pages/index/index",
"style" : {
"navigationBarTitleText": "课程管理"
}
},
{
"path": "pages/manage_list/manage_list",
"style" : {
"navigationBarTitleText": "课程管理列表"
}
},
{
"path": "pages/manage_detail/student_course_detail/student_course_detail",
"style" : {
"navigationBarTitleText": "学员课程详情"
}
},
{
"path": "pages/manage_detail/private_reserve_detail/private_reserve_detail",
"style" : {
"navigationBarTitleText": "私教约课记录详情"
}
},
{
"path": "pages/manage_detail/bclass_reserve_detail/bclass_reserve_detail",
"style" : {
"navigationBarTitleText": "大班约课记录详情"
}
},
{
"path": "pages/manage_detail/class_manage_detail/class_manage_detail",
"style" : {
"navigationBarTitleText": "班级管理详情"
}
},
{
"path": "pages/task_detail/task_detail",
"style" : {
"navigationBarTitleText": "作业详情"
}
},
{
"path": "pages/arrange_class/arrange_class",
"style" : {
"navigationBarTitleText": "安排上课"
}
},
{
"path": "pages/class_add_student/class_add_student",
"style" : {
"navigationBarTitleText": "添加学员"
}
},
{
"path": "pages/class_student_detail/class_student_detail",
"style" : {
"navigationBarTitleText": "学员详情"
}
},
{
"path": "pages/class_time_change/class_time_change",
"style" : {
"navigationBarTitleText": "更改上课时间"
}
},
{
"path": "pages/task_finish_list/task_finish_list",
"style" : {
"navigationBarTitleText": "作业完成列表"
}
}
]
} }
], ],
"globalStyle": { "globalStyle": {

6
src/pages/index/index.vue

@ -125,6 +125,12 @@
name: '商品零售', name: '商品零售',
path: '/subpackage/retail/pages/index/index', path: '/subpackage/retail/pages/index/index',
serverKey: 1011 // serverKey: 1011 //
},
{
id: 8,
name: '课程管理',
path: '/subpackage/course/pages/index/index',
serverKey: 1013 // 1013
} }
]; ];

71
src/pages/order_list/order_list.vue

@ -45,7 +45,7 @@
</view> </view>
</view> </view>
</view> </view>
<view class="ol-order-list">
<view class="ol-order-list" v-if="orderList&&orderList.length">
<view class="ool-item" v-for="(e,i) in orderList" :key="i" > <view class="ool-item" v-for="(e,i) in orderList" :key="i" >
<reservation-order :order-info="e" v-if="orderType == 3"></reservation-order> <reservation-order :order-info="e" v-if="orderType == 3"></reservation-order>
<membership-order :order-info="e" v-if="orderType == 4"></membership-order> <membership-order :order-info="e" v-if="orderType == 4"></membership-order>
@ -69,6 +69,10 @@
</view> </view>
</view> </view>
<view class="ol-order-null" v-else>
<image mode="aspectFit" src="/static/images/order_null.png"></image>
<view>暂无内容</view>
</view>
<!-- 分类tab --> <!-- 分类tab -->
<view class="ox-dark-mask" v-if="isShowClassify" @click="hideClassify"> <view class="ox-dark-mask" v-if="isShowClassify" @click="hideClassify">
<view class="ol-classify" @click.stop="()=>false"> <view class="ol-classify" @click.stop="()=>false">
@ -93,7 +97,7 @@
<view class="op-time"> <view class="op-time">
<text>开始时间</text> <text>开始时间</text>
<view> <view>
<input placeholder="选择时间" disabled :value="tempTimer.start" />
<input placeholder="选择时间" disabled :value="tempTimer.start || periodInfo.start" />
<image mode="aspectFit" src="/static/images/icon/arrow_b2.png"></image> <image mode="aspectFit" src="/static/images/icon/arrow_b2.png"></image>
</view> </view>
</view> </view>
@ -102,7 +106,7 @@
<view class="op-time"> <view class="op-time">
<text>截止时间</text> <text>截止时间</text>
<view> <view>
<input placeholder="选择时间" disabled :value="tempTimer.end" />
<input placeholder="选择时间" disabled :value="tempTimer.end || periodInfo.end" />
<image mode="aspectFit" src="/static/images/icon/arrow_b2.png"></image> <image mode="aspectFit" src="/static/images/icon/arrow_b2.png"></image>
</view> </view>
</view> </view>
@ -161,12 +165,14 @@
isStoreInfo(){ isStoreInfo(){
let { orderType } = this; let { orderType } = this;
return ( return (
orderType == 3 || orderType == 4 ||
orderType == 1 || orderType == 10 ||
orderType == 3 || orderType == 4 ||
orderType == 1 || orderType == 10 ||
orderType == 18 || orderType == 12 || orderType == 18 || orderType == 12 ||
orderType == 18 || orderType == 12 || orderType == 18 || orderType == 12 ||
orderType == 15 || orderType == 16 || orderType == 15 || orderType == 16 ||
orderType == 8
orderType == 8 || orderType == 7 ||
orderType == 11 || orderType == 6 ||
orderType == 9
) )
}, },
// //
@ -304,8 +310,8 @@
let _obj = { start: '', end: '' }; let _obj = { start: '', end: '' };
if(type == 3 ){ if(type == 3 ){
_obj['start']=util.formatDate({});
_obj['end'] = util.formatDate({date: _afterSeven});
_obj['start']=util.formatDate({date: _beforeSeven});
_obj['end'] = util.formatDate({});
} }
if(type == 4 || type == 1){ if(type == 4 || type == 1){
@ -338,13 +344,20 @@
}, },
confirmPeriod(){ confirmPeriod(){
let { start, end } = this.tempTimer; let { start, end } = this.tempTimer;
let { tempTimer, periodInfo } = this;
let _start = tempTimer.start || periodInfo.start || '';
let _end = tempTimer.end || periodInfo.end || '';
this.periodInfo = {
start: _start,
end: _end,
};
if( if(
!start || !end ||
new Date(start.replace(/\-/g,'/')).getTime()>=new Date(end.replace(/\-/g,'/')).getTime()
// !start || !end ||
new Date(start.replace(/\-/g,'/')).getTime()> new Date(end.replace(/\-/g,'/')).getTime()
)return util.showNone('请选择合理时间!'); )return util.showNone('请选择合理时间!');
this.periodInfo = { ...this.tempTimer };
this.hidePeriodModal(); this.hidePeriodModal();
this.$nextTick(this.refreshList); this.$nextTick(this.refreshList);
}, },
@ -426,9 +439,10 @@
let { brandInfo, curTabID, periodInfo, orderType, curSelectedStore, appointOrderType, selectedOrderType } = this; let { brandInfo, curTabID, periodInfo, orderType, curSelectedStore, appointOrderType, selectedOrderType } = this;
let _curSelectedStore = curSelectedStore || {}; let _curSelectedStore = curSelectedStore || {};
let _startTime = periodInfo.start ? periodInfo.start + ' ' + '00:00:00' : '', _endTime = periodInfo.end ? periodInfo.end + ' ' + '23:59:59' : ''; // 20211026
let _obj = { let _obj = {
begin: periodInfo.start || '',
end: periodInfo.end || '',
begin: _startTime,
end: _endTime,
status: curTabID, status: curTabID,
brand_id: brandInfo.brand.id, brand_id: brandInfo.brand.id,
stadium_id: _curSelectedStore.id || '' stadium_id: _curSelectedStore.id || ''
@ -444,8 +458,8 @@
// , 0430.0507() // , 0430.0507()
if(orderType == "10"){ if(orderType == "10"){
_obj['type'] = selectedOrderType; _obj['type'] = selectedOrderType;
_obj['filter_start_time'] = periodInfo.start;
_obj['filter_end_time'] = periodInfo.end;
_obj['filter_start_time'] = _startTime;
_obj['filter_end_time'] = _endTime;
_obj['pay_status'] = curTabID; _obj['pay_status'] = curTabID;
}; };
@ -557,13 +571,13 @@
case 9: // status 1,4 1 退 4 case 9: // status 1,4 1 退 4
return [ {id: '1,4', name: '全部'}, {id: 1, name: '交易成功'}, {id: 4, name: '退款完成 '}]; return [ {id: '1,4', name: '全部'}, {id: 1, name: '交易成功'}, {id: 4, name: '退款完成 '}];
case 7: // status 1,2,4 1 2 退 4 case 7: // status 1,2,4 1 2 退 4
return [ {id: '1,2,4', name: '全部'}, {id: 1, name: '寄存中'}, {id: 2, name: '已完成'}, {id: 4, name: '退款完成 '}];
return [ {id: '1,2,4', name: '全部'}, {id: 1, name: '寄存中'}, {id: 2, name: '已完成'}, {id: 4, name: '退款完成'}];
case 14: // 1,2,4 1= 4=退 2= case 14: // 1,2,4 1= 4=退 2=
return [ {id: '1,2,4', name: '全部'}, {id: 1, name: '进行中'}, {id: 2, name: '已完成'}, {id: 4, name: '已退款 '}];
case 2: // 0/1/2/3/4/5/6 - /////退/退 1,2,3,6
return [ {id: '1,2,3,6', name: '全部'}, {id: 0, name: '待支付'}, {id: 1, name: '待发货'}, {id: 2, name: '已发货'}, {id: 3, name: '已完成 '}, {id: 4, name: '已关闭 '}, {id: 5, name: '退款中 '}, {id: 6, name: '已退款 '}];
return [ {id: '1,2,4', name: '全部'}, {id: 1, name: '进行中'}, {id: 2, name: '已完成'}, {id: 4, name: '已退款'}];
case 2: // 0/1/2/3/4/5/6 - /////退/退 1,2,3,6 //
return [ {id: 'assistant_all', name: '全部'}, {id: 1, name: '待发货'}, {id: 2, name: '已发货'}, {id: 3, name: '交易完成'}, {id: 'after_sale', name: '申请售后中'}, {id: 6, name: '退款完成'}];
case 8: // status 1,2,4 1 2 退4 5 case 8: // status 1,2,4 1 2 退4 5
return [ {id: '1,2,4', name: '全部'}, {id: 1, name: '租用中'}, {id: 2, name: '已完成 '}, {id: 4, name: '已退款 '},{id: 5, name: '已购买 '}];
return [ {id: '1,2,4', name: '全部'}, {id: 1, name: '租用中'}, {id: 2, name: '已完成'}, {id: 4, name: '已退款'},{id: 5, name: '已购买'}];
default: default:
return [] return []
} }
@ -665,6 +679,23 @@
margin-bottom: 24upx; margin-bottom: 24upx;
} }
} }
.ol-order-null{
padding-top: 114upx;
>image{
margin: 0 auto 70upx;
display: block;
width: 380upx;
height: 380upx;
}
>view{
text-align: center;
line-height: 44upx;
font-size: 32upx;
color: #9A9A9D;
}
}
.ol-classify{ .ol-classify{
position: absolute; position: absolute;
right: 0; right: 0;

25
src/pages/order_search/order_search.vue

@ -156,18 +156,20 @@ export default {
}){ }){
let { brandInfo } = this; let { brandInfo } = this;
util.showLoad(); util.showLoad();
let _data = {
key,
begin: '',
end: '',
status: '',
brand_id: brandInfo.brand.id,
stadium_id: '',
page,
page_size,
}
if(orderType in deviceTypeObj())_data['type'] = deviceTypeObj()[orderType];
servers.get({ servers.get({
url: this.getApiUrl(orderType), url: this.getApiUrl(orderType),
data: {
key,
begin: '',
end: '',
status: '',
brand_id: brandInfo.brand.id,
stadium_id: '',
page,
page_size,
},
data: _data,
failMsg: '加载失败!' failMsg: '加载失败!'
}) })
.then(res=>{ .then(res=>{
@ -184,6 +186,9 @@ export default {
}) })
.catch(util.hideLoad) .catch(util.hideLoad)
}, },
getReqQuery(){
}
} }
} }

BIN
src/static/images/icon/index/tab_10.png

Before

Width: 52  |  Height: 52  |  Size: 402 B

BIN
src/static/images/icon/index/tab_8.png

Before

Width: 52  |  Height: 52  |  Size: 477 B

After

Width: 52  |  Height: 52  |  Size: 2.4 KiB

BIN
src/static/images/icon/index/tab_9.png

Before

Width: 52  |  Height: 52  |  Size: 696 B

BIN
src/static/images/order_null.png

After

Width: 380  |  Height: 380  |  Size: 8.5 KiB

1
src/store/index.js

@ -29,6 +29,7 @@ export default new Vuex.Store({
'1010': '设备管理', '1010': '设备管理',
'1011': '商品零售', '1011': '商品零售',
'1012': '订单管理', '1012': '订单管理',
'1013': '课程管理',
}, },
// 场地占用提交页面信息 // 场地占用提交页面信息

147
src/subpackage/course/components/cancel_class_modal/cancel_class_modal.vue

@ -0,0 +1,147 @@
<template>
<!--弹框 取消上课 -->
<view class="cancel-class-modal" @click.stop="">
<view class="ox-dark-mask fixed-mask " @touchmove.stop.prevent="moveHandle">
<view class="mask-modal" @click.stop="">
<view class="mm-close">
<image src="/subpackage/course/static/images/icon/close_gray.png" @click="closeChange"></image>
</view>
<view class="mm-tit">取消上课</view>
<view class="mm-cause">
<textarea class="mc-textarea" @blur="bindTextAreaBlur" placeholder="请输入取消上课的原因(选填)" maxlength="25" v-model="causeTxt"></textarea>
<view class="mc-num">{{causeTxt.length || 0}}/25</view>
</view>
<view class="mm-btn">
<view class="mb-btn1" hover-class="hover-active" @click="confirmChange">确认</view>
<view class="mb-btn2" hover-class="hover-active" @click="closeChange">取消</view>
</view>
</view>
</view>
</view>
</template>
<script>
import util from '@/utils/util';
export default {
props:{
orderInfo: {
type: Object,
default: ()=>({})
}
},
computed: {
},
data(){
return {
causeTxt: "",
}
},
methods: {
moveHandle(){},
//
bindTextAreaBlur: function(e) {
// console.log( ": " + e.detail.value)
this.causeTxt = e.detail.value
this.$emit('bindTextAreaBlur', this.causeTxt)
},
closeChange(){
this.$emit('reasonClose')
},
confirmChange(){
this.$emit('reasonConfirm', this.causeTxt)
},
},
}
</script>
<style lang="scss">
@import '~style/public.scss';
.cancel-class-modal{
}
//
.fixed-mask{
// position: fixed;
// left: 0;
// top: 0;
// right: 0;
// bottom: 0;
// background-color: rgba(0, 0, 0, .5);
z-index: 999;
}
.mask-modal{
position: absolute;
left: 50%;
top: 46%;
transform: translate(-50%, -50%);
width: 620rpx;
padding: 30rpx 0 82rpx;
border-radius: 10rpx;
background-color: #FFFFFF;
.mm-close{
@include centerFlex(flex-end);
>image{
margin-right: 30rpx;
width: 34rpx;
height: 34rpx;
}
}
.mm-tit{
margin: 16rpx auto 38rpx;
color: #333333;
font-size: 32rpx;
line-height: 44rpx;
text-align: center;
font-weight: 700;
}
.mm-cause{
margin: auto;
position: relative;
width: 538rpx;
height: 150rpx;
border-radius: 10rpx;
border: 2rpx solid #D8D8D8;
.mc-textarea{
margin: 24rpx 20rpx;
width: 498rpx;
height: 102rpx;
color: #333;
font-size: 28rpx;
line-height: 40rpx;
}
.mc-num{
position: absolute;
right: 20rpx;
bottom: 20rpx;
color: #9A9A9D;
font-size: 28rpx;
}
}
.mm-btn{
margin-top: 80rpx;
@include centerFlex(center);
>view{
margin: 0 10rpx;
padding: 22rpx 0;
width: 240rpx;
border-radius: 10rpx;
border: 2rpx solid #009874;
font-size: 32rpx;
line-height: 44rpx;
text-align: center;
}
.mb-btn1{
color: #FFFFFF;
background-color: #009874;
}
.mb-btn2{
color: #009874;
}
}
}
</style>

175
src/subpackage/course/components/class_reset_modal/class_reset_modal.vue

@ -0,0 +1,175 @@
<template>
<!-- 转班弹框 -->
<view class="class-reset-modal" @click.stop="">
<view class="ox-dark-mask fixed-mask" @touchmove.stop.prevent="moveHandle" v-if="isShowClass" @click="closeReset">
<view class="mask-modal" @click.stop="">
<view class="mm-close">
<image src="/subpackage/course/static/images/icon/close_gray.png" @click="closeReset"></image>
</view>
<view class="mm-tit">选择班级</view>
<view class="mm-line">课程名称{{info.course_name || '-'}}</view>
<scroll-view class="mm-scroll" scroll-y>
<view class="ms-list" v-for="(e,i) in classList" :key="i">
<view class="ml-item" @click="selectClass(e)">
<image :class="[resetInfo.new_id==e.id?'mi-img':'mi-icon']" :src="resetInfo.new_id==e.id?'/static/images/icon/selected_987.png':''"></image>
<view class="mi-info">
<view>班级名称{{e.name || '-'}}</view>
<view>班级人数{{e.nums || 0}}</view>
<view>上课教练{{e.coach || '-'}}</view>
</view>
</view>
</view>
</scroll-view>
<view class="mm-btn" hover-class="hover-active" @click="confirmReset">确定</view>
</view>
</view>
</view>
</template>
<script>
import util from '@/utils/util';
export default {
props:{
info: {
type: Object,
default: ()=>({})
},
canlist: {
type: Array,
default() {
return [];
}
},
isShowClass: {
type: Boolean,
default: false
}
},
computed: {
// userInfo(){
// return uni.getStorageSync('loginInfo') || {};
// },
classList(){
let { info, canlist } = this
let _list = []
if(canlist.length > 0)_list = canlist.filter(e=>e.id != info.sclass_id);
return _list || [];
},
},
data() {
return {
resetInfo:{
new_id: "", //ID
// user_id: "",
// user_order_no: "",
},
}
},
methods: {
moveHandle(){},
selectClass(item){
this.resetInfo.new_id = item.id
},
closeReset(){
this.$emit('closeReset')
},
confirmReset(){
let { resetInfo, classList } = this
if(classList.length == 0)return util.showNone('无可选班级!');
if(resetInfo.new_id == '')return util.showNone('请选择!');
this.$emit('confirmReset',resetInfo)
},
},
}
</script>
<style lang="scss">
@import '~style/public.scss';
.class-reset-modal{
.fixed-mask{
z-index: 999;
}
.mask-modal{
position: absolute;
left: 50%;
top: 45%;
transform: translate(-50%, -50%);
width: 558rpx;
padding: 20rpx 0;
border-radius: 10rpx;
background-color: #FFFFFF;
.mm-close{
@include centerFlex(flex-end);
>image{
margin-right: 22rpx;
width: 36rpx;
height: 36rpx;
}
}
.mm-tit{
margin: 6rpx auto 40rpx;
color: #1A1A1A;
font-size: 36rpx;
font-weight: 700;
text-align: center;
}
.mm-line{
flex-grow: 1;
margin: 0 38rpx;
color: #1A1A1A;
font-size: 32rpx;
padding-bottom: 20rpx;
border-bottom: 2rpx solid #E5E5E5;
}
.mm-scroll{
margin-left: 42rpx;
height: 368rpx;
.ms-list{
.ml-item{
padding-top: 28rpx;
display: flex;
align-items: center;
justify-content: flex-start;
>image{
flex-shrink: 0;
margin-right: 24rpx;
margin-top: 14rpx;
}
.mi-icon{
width: 36rpx;
height: 36rpx;
border-radius: 50%;
border: 2rpx solid #9C9C9F;
}
.mi-img{
width: 40rpx;
height: 40rpx;
}
.mi-info{
>view{
color: #1A1A1A;
font-size: 28rpx;
line-height: 52rpx;
}
}
}
}
}
.mm-btn{
margin: 60rpx auto;
padding: 18rpx 0;
width: 240rpx;
border-radius: 6rpx;
background-color: #009874;
color: #FFFFFF;
font-size: 32rpx;
text-align: center;
}
}
}
</style>

143
src/subpackage/course/components/manage/bclass_reserve_item/bclass_reserve_item.vue

@ -0,0 +1,143 @@
<template>
<!-- 大班约课记录 -->
<view class="bclass-reserve-item" @click="toDetail">
<view class="bri-line">
<view class="bl-store">{{orderInfo.brand_name ||''}}({{orderInfo.stadium_name||'-'}})</view>
<view class="bl-status" :class="[orderInfo.status_text=='已上课'?'status-gray':orderInfo.status_text=='已取消'?'status-red':'']">{{orderInfo.status_text||'-'}}</view>
</view>
<view class="bri-view">已预约人数<text>{{orderInfo.bclass_nums||0}}上课区间{{orderInfo.bclass_nums_min||0}}-{{orderInfo.bclass_nums_max||0}}</text></view>
<view class="bri-view">上课时间<text>{{ formatDate({date: orderInfo.date, partition: '.'}) || ''}}{{orderInfo.week||'-'}} {{orderInfo.start_duration||''}}-{{orderInfo.end_duration||''}}</text></view>
<view class="bri-view">上课地点<text>{{orderInfo.addr||''}}</text></view>
<view class="bri-view">上课教练<text>{{orderInfo.coach_name||''}}</text></view>
<view class="bri-view">课程名称<text>{{orderInfo.course_name||''}}</text></view>
<block v-if="orderInfo.status_text=='已取消'">
<view class="bri-view">取消时间<text>{{orderInfo.cancel_time||''}}</text></view>
<view class="bri-view">取消原因<text>{{orderInfo.cancel_reason||''}}</text></view>
</block>
<view class="bri-btn" v-if="orderInfo.status_text=='待确认'||orderInfo.status_text=='待上课'">
<view class="bb-btn1" hover-class="hover-active" @click.stop="isCancelClass=true">取消上课</view>
<view class="bb-btn2" hover-class="hover-active" @click.stop="confirmClass" v-if="orderInfo.status_text=='待确认'">确认上课</view>
</view>
<!-- 弹框 取消上课 -->
<cancel-class-modal
v-if="isCancelClass"
@reasonConfirm="reasonConfirm"
@reasonClose="isCancelClass=false"
></cancel-class-modal>
</view>
</template>
<script>
import util from '@/utils/util';
import cancel_class_modal from '../../cancel_class_modal/cancel_class_modal.vue';
export default {
components: {
'cancel-class-modal': cancel_class_modal,
},
props:{
orderInfo: {
type: Object,
default: ()=>({})
},
},
computed: {
},
data(){
return {
isCancelClass: false,
}
},
methods: {
formatDate: util.formatDate,
toDetail(){
let { orderInfo } = this
util.routeTo(`/subpackage/course/pages/manage_detail/bclass_reserve_detail/bclass_reserve_detail?id=${orderInfo.id}`,'nT');
},
//
reasonConfirm(e){
this.isCancelClass = false
let { orderInfo } = this
let _info = {
id: orderInfo.id,
reason: e,
course_kind: orderInfo.course_kind,
}
this.$emit('bclassCancel', _info)
},
//
confirmClass(){
let { orderInfo } = this
this.$emit('bclassConfirm', orderInfo.subscribe_no)
},
},
}
</script>
<style lang="scss">
@import '~style/public.scss';
.bclass-reserve-item{
padding: 26rpx 44rpx 34rpx;
background-color: #FFFFFF;
.bri-line{
margin-bottom: 20rpx;
padding: 0 0 32rpx 2rpx;
border-bottom: 2rpx solid #E5E5E5;
@include centerFlex(space-between);
.bl-store{
color: #1A1A1A;
font-size: 28rpx;
line-height: 40rpx;
font-weight: 700;
@include textHide(1);
}
.bl-status{
flex-shrink: 0;
color: #009874;
font-size: 28rpx;
line-height: 40rpx;
}
.status-gray{
color: #9C9C9F;
}
.status-red{
color: #EA5061;
}
}
.bri-view{
color: #9C9C9F;
font-size: 28rpx;
line-height: 52rpx;
>text{
color: #1A1A1A;
}
}
.bri-btn{
margin-top: 18rpx;
@include centerFlex(flex-end);
>view{
margin-left: 20rpx;
padding: 20rpx 0;
width: 192rpx;
border-radius: 6rpx;
font-size: 28rpx;
line-height: 40rpx;
font-weight: 700;
text-align: center;
}
.bb-btn1{
color: #EA5061;
border: 2rpx solid #EA5061;
background-color: #FFFFFF;
}
.bb-btn2{
color: #FFFFFF;
border: 2rpx solid #009874;
background-color: #009874;
}
}
}
</style>

93
src/subpackage/course/components/manage/class_manage_item/class_manage_item.vue

@ -0,0 +1,93 @@
<template>
<!-- 班级管理 -->
<view class="class-manage-item" @click="toDetail">
<view class="cmi-line">
<view class="cl-store">{{orderInfo.barnd_name||''}}({{orderInfo.stadium_name||'-'}})</view>
<view class="cl-status" :class="[orderInfo.sclass_status_text=='已结束'?'status-gray':orderInfo.sclass_status_text=='成班失败'?'status-red':'']">{{orderInfo.sclass_status_text||'-'}}</view>
</view>
<block v-if="orderInfo.sclass_status_text=='成班中'||orderInfo.sclass_status_text=='成班失败'">
<view class="cmi-view">课程名称<text>{{orderInfo.course_name||''}}</text></view>
<view class="cmi-view">班级id<text>{{orderInfo.sclass_no||''}}</text></view>
<view class="cmi-view">成班人数区间<text>{{orderInfo.sclass_min_nums||0}}-{{orderInfo.sclass_max_nums||0}}</text></view>
<view class="cmi-view">已报名人数<text>{{orderInfo.sclass_nums||0}}</text></view>
<view class="cmi-view">报名截止时间<text>{{orderInfo.sclass_join_deadline||''}}</text></view>
</block>
<block v-if="orderInfo.sclass_status_text=='进行中'||orderInfo.sclass_status_text=='已结束'">
<view class="cmi-view">班级名称<text>{{orderInfo.sclass_name||''}}</text></view>
<view class="cmi-view">班级人数<text>{{orderInfo.sclass_nums||0}}</text></view>
<view class="cmi-view">上课教练<text>{{orderInfo.sclass_coach||''}}</text></view>
<view class="cmi-view">上课地点<text>{{orderInfo.sclass_addr||''}}</text></view>
<view class="cmi-view">课程日期<text>{{orderInfo.sclass_stime||''}}-{{orderInfo.sclass_etime||''}}</text></view>
<view class="cmi-view">课程名称<text>{{orderInfo.course_name||''}}</text></view>
</block>
</view>
</template>
<script>
import util from '@/utils/util';
export default {
props:{
orderInfo: {
type: Object,
default: ()=>({})
},
},
computed: {
},
data(){
return {
}
},
methods: {
toDetail(){
let { orderInfo } = this
util.routeTo(`/subpackage/course/pages/manage_detail/class_manage_detail/class_manage_detail?id=${orderInfo.id}`,'nT');
},
},
}
</script>
<style lang="scss">
@import '~style/public.scss';
.class-manage-item{
padding: 26rpx 44rpx 30rpx;
background-color: #FFFFFF;
.cmi-line{
margin-bottom: 20rpx;
padding: 0 0 32rpx 2rpx;
border-bottom: 2rpx solid #E5E5E5;
@include centerFlex(space-between);
.cl-store{
color: #1A1A1A;
font-size: 28rpx;
line-height: 40rpx;
font-weight: 700;
@include textHide(1);
}
.cl-status{
flex-shrink: 0;
color: #009874;
font-size: 28rpx;
line-height: 40rpx;
}
.status-gray{
color: #9C9C9F;
}
.status-red{
color: #EA5061;
}
}
.cmi-view{
color: #9C9C9F;
font-size: 28rpx;
line-height: 52rpx;
>text{
color: #1A1A1A;
}
}
}
</style>

125
src/subpackage/course/components/manage/private_reserve_item/private_reserve_item.vue

@ -0,0 +1,125 @@
<template>
<!-- 私教约课记录 -->
<view class="private-reserve-item" @click="toDetail">
<view class="pri-line">
<view class="pl-store">{{orderInfo.brand_name||''}}({{orderInfo.stadium_name||'-'}})</view>
<view class="pl-status" :class="[orderInfo.status_text=='已上课'?'status-gray':orderInfo.status_text=='已取消'?'status-red':'']">{{orderInfo.status_text||'-'}}</view>
</view>
<view class="pri-view">学员信息<text>{{orderInfo.student_name||'-'}}{{orderInfo.student_gender||'-'}} {{orderInfo.student_phone||''}}</text></view>
<view class="pri-view">上课时间<text>{{ formatDate({date: orderInfo.date, partition: '.'}) || ''}}{{orderInfo.week||'-'}} {{orderInfo.start_duration||''}}-{{orderInfo.end_duration||''}}</text></view>
<view class="pri-view">上课地点<text>{{orderInfo.addr||''}}</text></view>
<view class="pri-view">上课教练<text>{{orderInfo.coach_name||''}}</text></view>
<view class="pri-view">课程名称<text>{{orderInfo.course_name||''}}</text></view>
<block v-if="orderInfo.status_text=='已取消'">
<view class="pri-view">取消时间<text>{{orderInfo.cancel_time||''}}</text></view>
<view class="pri-view">取消原因<text>{{orderInfo.cancel_reason||''}}</text></view>
</block>
<view class="pri-btn" v-if="orderInfo.status_text=='待上课'">
<view hover-class="hover-active" @click.stop="isCancelClass=true">取消上课</view>
</view>
<cancel-class-modal
v-if="isCancelClass"
@reasonConfirm="reasonConfirm"
@reasonClose="isCancelClass=false"
></cancel-class-modal>
</view>
</template>
<script>
import util from '@/utils/util';
import cancel_class_modal from '../../cancel_class_modal/cancel_class_modal.vue';
export default {
components: {
'cancel-class-modal': cancel_class_modal,
},
props:{
orderInfo: {
type: Object,
default: ()=>({})
},
},
computed: {
},
data(){
return {
isCancelClass: false,
}
},
methods: {
formatDate: util.formatDate,
toDetail(){
let { orderInfo } = this
util.routeTo(`/subpackage/course/pages/manage_detail/private_reserve_detail/private_reserve_detail?id=${orderInfo.id}`,'nT');
},
reasonConfirm(e){
this.isCancelClass = false
let { orderInfo } = this
let _info = {
subscribe_no: orderInfo.subscribe_no,
reason: e,
course_kind: orderInfo.course_kind,
}
this.$emit('priclassCancel', _info)
},
},
}
</script>
<style lang="scss">
@import '~style/public.scss';
.private-reserve-item{
padding: 26rpx 44rpx 30rpx;
background-color: #FFFFFF;
.pri-line{
margin-bottom: 20rpx;
padding: 0 0 32rpx 2rpx;
border-bottom: 2rpx solid #E5E5E5;
@include centerFlex(space-between);
.pl-store{
color: #1A1A1A;
font-size: 28rpx;
line-height: 40rpx;
font-weight: 700;
@include textHide(1);
}
.pl-status{
flex-shrink: 0;
color: #009874;
font-size: 28rpx;
line-height: 40rpx;
}
.status-gray{
color: #9C9C9F;
}
.status-red{
color: #EA5061;
}
}
.pri-view{
color: #9C9C9F;
font-size: 28rpx;
line-height: 52rpx;
>text{
color: #1A1A1A;
}
}
.pri-btn{
margin-top: 6rpx;
@include centerFlex(flex-end);
>view{
padding: 20rpx 0;
width: 192rpx;
border-radius: 6rpx;
border: 2rpx solid #EA5061;
color: #EA5061;
font-size: 28rpx;
line-height: 40rpx;
font-weight: 700;
text-align: center;
}
}
}
</style>

86
src/subpackage/course/components/manage/student_course_item/student_course_item.vue

@ -0,0 +1,86 @@
<template>
<!-- 学员课程 -->
<view class="student-course-item" @click="toDetail">
<view class="sci-status" :class="[orderInfo.order_status==2?'status-gray':orderInfo.order_status==3?'status-red':'']">{{zh_order_status()}}</view>
<view class="sci-view">学员信息<text>{{orderInfo.student_name || '-'}}{{orderInfo.student_gender||'-'}} {{orderInfo.student_phone||''}}</text></view>
<view class="sci-view">剩余课时<text>{{orderInfo.period_nums_surplus||0}}课时 {{orderInfo.period_nums_use||0}}/{{orderInfo.period_nums||0}})</text></view>
<view class="sci-view">课程名称<text>{{orderInfo.course_name||''}}</text></view>
<view class="sci-view">有效期至<text>{{ formatDate({date: orderInfo.course_end, partition: '.'}) || ''}}</text></view>
<view class="sci-view">课程类型<text>{{orderInfo.course_kind||''}}</text></view>
<view class="sci-view" v-if="orderInfo.course_kind!='成班课'">上课教练<text>{{orderInfo.course_coach||''}}</text></view>
</view>
</template>
<script>
import util from '@/utils/util';
export default {
props:{
orderInfo: {
type: Object,
default: ()=>({})
},
},
computed: {
},
data(){
return {
}
},
methods: {
formatDate: util.formatDate,
zh_order_status(){
let { orderInfo } = this
if(orderInfo.order_status==2)return "已结束";
if(orderInfo.order_status==3)return "已退款";
if(orderInfo.sclass_status){
if(orderInfo.sclass_status==0)return "成班中";
if(orderInfo.sclass_status==1)return "进行中";
if(orderInfo.sclass_status==2)return "已结束";
if(orderInfo.sclass_status==3)return "成班失败";
if(orderInfo.sclass_status==4)return "已退款";
}
return "进行中";
},
toDetail(){
// this.$emit('closeChange')
let { orderInfo } = this
util.routeTo(`/subpackage/course/pages/manage_detail/student_course_detail/student_course_detail?order_no=${orderInfo.order_no}`,'nT');
},
},
}
</script>
<style lang="scss">
@import '~style/public.scss';
.student-course-item{
position: relative;
padding: 30rpx 44rpx;
background-color: #FFFFFF;
.sci-status{
position: absolute;
top: 30rpx;
right: 44rpx;
font-size: 28rpx;
line-height: 40rpx;
color: #009874;
}
.status-gray{
color: #9A9A9D;
}
.status-red{
color: #EA5061;
}
.sci-view{
// flex-shrink: 0;
margin-right: 84rpx;
color: #9C9C9F;
font-size: 28rpx;
line-height: 52rpx;
>text{
color: #1A1A1A;
}
}
}
</style>

114
src/subpackage/course/components/sclass_record_section/sclass_record_section.vue

@ -0,0 +1,114 @@
<template>
<view class="sclass-record-section">
<view class="cds-tab">
<view>课时编号</view>
<view>上课时间</view>
<view>考勤状态</view>
</view>
<view class="cds-list" v-for="(e,i) in recordInfo" :key="i">
<view class="cl-item">
<view>{{ e.user_lesson|| '-'}}</view>
<view>{{e.period_date!=''?formatDate({date: e.period_date, partition: '.'}) :'-'}}{{`${' '+e.period_start_time || ''}-${e.period_end_time || ''}` ||''}}</view>
<view
:class="[e.user_status==0?'ci-txt-green':
e.user_status==4?'ci-txt-red':'']"
>{{ zh_status(e.user_status)}}</view>
</view>
</view>
</view>
</template>
<script>
import util from '@/utils/util';
export default {
props:{
recordInfo: {
type: Array,
default() {
return [];
}
},
},
computed: {
},
data() {
return {
}
},
methods: {
formatDate: util.formatDate,
zh_status(status){
let arr = ["待上课","已上课","申请请假中","已请假","缺勤"]
return arr[status] || '';
},
}
}
</script>
<style lang="scss">
@import '~style/public.scss';
.sclass-record-section{
.cds-tab{
margin: 0 24rpx;
border: 2rpx solid #E8E8E8;
background-color: #F6F8F8;
@include centerFlex(flex-start);
>view{
height: 110rpx;
color: #1A1A1A;
font-size: 28rpx;
text-align: center;
@include centerFlex(center);
&:first-child {
width: 166rpx;
}
&:nth-child(2){
width: 338rpx;
border-left: 2rpx solid #E8E8E8;
border-right: 2rpx solid #E8E8E8;
}
&:nth-child(3){
width: 194rpx;
// border-right: 2rpx solid #E8E8E8;
}
}
}
.cds-list{
.cl-item{
margin: 0 24rpx;
border-left: 2rpx solid #E8E8E8;
border-right: 2rpx solid #E8E8E8;
border-bottom: 2rpx solid #E8E8E8;
background-color: #FFFFFF;
@include centerFlex(flex-start);
>view{
height: 110rpx;
color: #1A1A1A;
font-size: 28rpx;
text-align: center;
@include centerFlex(center);
&:first-child {
width: 166rpx;
}
&:nth-child(2){
width: 338rpx;
border-left: 2rpx solid #E8E8E8;
border-right: 2rpx solid #E8E8E8;
}
&:nth-child(3){
width: 194rpx;
}
}
.ci-txt-green{
color: #009874;
}
.ci-txt-red{
color: #EA5061;
}
}
}
}
</style>

95
src/subpackage/course/components/store_name/store_name.vue

@ -0,0 +1,95 @@
<template>
<picker class="store-name-picker" :range="storeList" range-key="name" @change="storeChange">
<view class="store-name" :style="{background:getThemeBg()}">
<image mode="aspectFit" :src="curStoreInfo.logo || ''" :class="[theme=='light'?'sn-logo':'sn-logo2']"></image>
<view class="sn-txt" :style="{color:getThemeColor()}">{{curStoreInfo.name || '-'}}</view>
<image :class="[theme=='light'?'sn-arrow':'sn-arrow2']" mode="aspectFit" :src="getThemeIcon()"></image>
</view>
</picker>
</template>
<script>
import { mapState } from 'vuex'
export default {
computed: {
...mapState({
storeList: state => state.device.storeList,
curStoreInfo: state => state.device.curStoreInfo,
}),
getThemeIcon(){
return ()=> {return (this.theme=='light')?'/subpackage/course/static/images/icon/arrow_white.png':'/subpackage/course/static/images/icon/arrow_black.png';}
},
getThemeColor(){
return ()=> {return (this.theme=='light')?'#FFFFFF':'#333333';}
},
getThemeBg(){
return ()=> {return (this.theme=='light')?'none':'none';} //
},
},
props: ["theme"],//, "light":
created() {
// console.log("store_name theme: ", this.theme);
},
methods: {
storeChange(e){
let { storeList, curStoreInfo } = this;
let _curSelect = storeList[e.detail.value];
if(_curSelect.id!==curStoreInfo.id)this.$store.commit('setStoreInfo', _curSelect);
console.log(e)
}
}
}
</script>
<style>
.store-name-picker{
width: 100%;
z-index: 5;
}
.store-name{
display: flex;
flex-direction: row;
align-items: center;
justify-content: flex-start;
padding: 0 40upx;
height: 100upx;
/* background-color: #fff; */
}
.sn-logo{
flex-grow: 0;
flex-shrink: 0;
margin-right: 20upx;
width: 52upx;
height: 52upx;
}
.sn-logo2{
flex-grow: 0;
flex-shrink: 0;
margin-right: 10upx;
width: 30upx;
height: 30upx;
}
.sn-txt{
/* flex-grow: 1; */
line-height: 40upx;
font-size: 28upx;
color: #1a1a1a;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.sn-arrow{
flex-shrink: 0;
flex-grow: 0;
margin-left: 20upx;
width: 28upx;
height: 28upx;
}
.sn-arrow2{
flex-shrink: 0;
flex-grow: 0;
margin-left: 20upx;
width: 20upx;
height: 20upx;
}
</style>

117
src/subpackage/course/components/tab_bar/tab_bar.vue

@ -0,0 +1,117 @@
<template>
<view class="tab-list">
<block v-for="(e,i) in tabList" :key="i">
<view :class="['tab_no', curTabID == e.id ? 'tab_yes':'']" @click="tabChange(e)">
<view class="tab-txt">{{e.name}}
<!-- <view class="tab-hint" v-if="e.hint"><text>{{hintValue}}</text></view> -->
</view>
</view>
</block>
</view>
</template>
<script>
const tabArr = [{name:'全部订单',id:0},{name:'待上课',id:1},{name:'已上课',id:2},{name:'已取消',id:3}];
export default {
name: 'tabBar',
props: {
tabList:{
type: Array,
default: ()=>(tabArr),
},
curTabID:{
type: Number,
default:0
},
hintValue:{
type: Number,
default:0
},
isBottomBorder: {
type: Boolean,
default: false
}
},
data(){
return {
// curTabID: 0
}
},
methods:{
tabChange(item){
// this.curTabID = ID;
this.$emit('change', item)
},
}
}
</script>
<style lang="scss">
@import '~style/public.scss';
.tab-list{
width: 750rpx;
background-color: #fff;
display: flex;
align-items: center;
justify-content: space-around;
.tab_no{
position: relative;
flex-shrink: 0;
flex-grow: 1;
height: 100rpx;
line-height: 100rpx;
text-align: center;
.tab-txt{
position: relative;
display: inline-block;
font-size: 28rpx;
font-weight: 700;
color: #9A9A9D;
&::after{
content: '';
transition: all .2s;
position: absolute;
left: 50%;
bottom: 2rpx;
transform: translateX(-50%) translateY(50%);
display: block;
// width: 70%;
width: 40rpx;
height: 10rpx;
border-radius: 5rpx;
background-color: #009874;
opacity: 0;
}
// .tab-hint{
// position: absolute;
// top: 20rpx;
// right: -36rpx;
// width: 36rpx;
// height: 36rpx;
// border-radius: 50%;
// background-color: #EA5061;
// display: flex;
// align-items: center;
// justify-content: space-around;
// >text{
// color: #FFFFFF;
// font-size: 24rpx;
// font-weight: 400;
// }
// }
}
&.tab_yes{
.tab-txt{
color: #009874;
&::after{
opacity: 1;
transform: translateX(-50%) translateY(0);
}
}
}
}
}
</style>

192
src/subpackage/course/components/task_section/task_section.vue

@ -0,0 +1,192 @@
<template>
<view class="task-section">
<view class="ts-list" v-for="(e,i) in taskList" :key="i">
<view class="tl-item">
<view class="ti-line">
<view>{{e.created_at!=''?formatDate({date: e.created_at}) : '-'}}</view>
<view v-if="taskType==''" :class="[e.work_status==0?'status-red':'status-gray']">{{e.work_status==0?'未完成':e.work_status==1?'已完成':'-'}}</view>
<view v-if="taskType=='finish'" class="status-gray">完成情况{{e.complete_nums||0}}/{{e.total_nums||0}}</view>
</view>
<view class="ti-desc" :class="e.expande?'desc-omit':''" :id="'noname'+i">
{{e.work_content || ''}}
<image class="td-img" @click="expandeChange(i)" v-if="e.isShowExpande" src="/subpackage/course/static/images/icon/arrow_green.png"></image>
</view>
<view class="ti-end">
<view hover-class="hover-active" @click="toTaskDetail(e)">查看</view>
</view>
</view>
</view>
</view>
</template>
<script>
import util from '@/utils/util';
export default {
props:{
// taskInfo: {
// type: Object,
// default: ()=>({})
// },
taskInfo:{
type: Array,
default() {
return [];
}
},
taskType:{
type: String,
default: '' //finish
},
},
computed: {
},
data() {
return {
taskList: [],
}
},
created() {
let _list = this.taskInfo || []
if(_list.length > 0){
_list.forEach((value,index)=>{
value['expande'] = false
value['isShowExpande'] = false
})
this.$nextTick(_=>{
this.taskList = _list
})
}
},
methods: {
formatDate: util.formatDate,
expandeChange(index){
this.taskList[index].isShowExpande = false
this.taskList[index].expande = false
},
async initDesc(){
let that = this
let { taskList } = this
for(var i in taskList){
let res = await this.getQueryResult(i);
if(res==1){
this.taskList[i].isShowExpande = true
this.taskList[i].expande = true
}
}
},
getQueryResult(i){
let that = this
return new Promise((rs,rj)=>{
/**
* 自定义组件需使用uni.createSelectorQuery().in(this)方法
* 页面上直接使用uni.createSelectorQuery()方法即可
* **/
let query = uni.createSelectorQuery().in(this); //wx.createSelectorQuery();
//id
let _id = "noname"+i
query.select('#noname'+i).boundingClientRect()
query.exec(function (res) {
console.log("获取节点信息:",res)
//res mjltest\
if (res[0].height / 20 > 3) {
rs(1)
} else {
rs(2)
}
rj(false)
})
})
},
toTaskDetail(item){
// let _query = {
// work_number: item.work_number,
// work_coach_name: item.work_coach_name,
// created_at: item.created_at,
// }
if(this.taskType == 'finish')return util.routeTo(`/subpackage/course/pages/task_finish_list/task_finish_list?work_number=${item.work_number}`,'nT');;
util.routeTo(`/subpackage/course/pages/task_detail/task_detail?id=${item.id}`,'nT');
},
// toTaskDetail(item){
// // util.routeTo(`/subpackage/manage/pages/student/task_detail/task_detail?query=${util.jsonStr(item)}`,'nT')
// // util.routeTo(`/subpackage/manage/pages/student/task_detail/task_detail?id=${item.id}`,'nT')
// },
}
}
</script>
<style lang="scss">
@import '~style/public.scss';
.task-section{
.ts-list{
margin-bottom: 24rpx;
.tl-item{
// flex-grow: 1;
padding: 30rpx 42rpx;
background-color: #FFFFFF;
.ti-line{
margin-bottom: 20rpx;
@include centerFlex(space-between);
>view{
&:first-child{
color: #1A1A1A;
font-size: 32rpx;
font-weight: 700;
line-height: 44rpx;
}
&:nth-child(2){
margin: 0 6rpx;
font-size: 28rpx;
line-height: 40rpx;
}
}
.status-gray{
color: #9C9C9F;
}
.status-red{
color: #EA5061;
}
}
.ti-desc{
position: relative;
color: #1A1A1A;
font-size: 28rpx;
line-height: 20px;
.td-img{
position: absolute;
bottom: 0;
right: 0;
width: 24rpx;
height: 24rpx;
}
}
.desc-omit{
@include textHide(3);
}
.ti-end{
margin-top: 30rpx;
@include centerFlex(flex-end);
>view{
margin-left: 20rpx;
padding: 12rpx 0;
width: 156rpx;
border-radius: 6rpx;
font-size: 28rpx;
line-height: 40rpx;
text-align: center;
color: #009874;
border: 2rpx solid #009874;
}
}
}
}
}
</style>

33
src/subpackage/course/js/course_api.js

@ -0,0 +1,33 @@
import { ORIGIN } from '../../../js/api';
export const COURSE_API = {
stadiumList:`${ORIGIN}/admin/stadium/list`, // 店铺列表
courseHome:`${ORIGIN}/admin/assistant/venueCourse/home`, //课程首页
stuCourse:`${ORIGIN}/admin/assistant/venueCourse/student`, //学员课程
stuInfo:`${ORIGIN}/admin/assistant/venueCourse/studentInfo`, //学员课程 - 详情
stuWorkInfo:`${ORIGIN}/admin/assistant/venueCourse/studentWorkInfo`, //学员作业详情
arrangeStuAcCoach:`${ORIGIN}/admin/assistant/venueCourse/arrangeStudentAcCoach`, //学员课程 - 详情 - 安排上课[私教课] - 获取教练
arrangeStuAc:`${ORIGIN}/admin/assistant/venueCourse/arrangeStudentAc`, //学员课程 - 详情 - 安排上课[私教课]
subscribePri:`${ORIGIN}/admin/assistant/venueCourse/subscribePri`, //约课记录 - 私教课
subscribeBclass:`${ORIGIN}/admin/assistant/venueCourse/subscribeBclass`, //约课记录 - 大班课
subscribeInfo:`${ORIGIN}/admin/assistant/venueCourse/subscribeInfo`, //约课记录 - 详情
setBclassAc:`${ORIGIN}/admin/assistant/venueCourse/setBclassAc`, //约课记录 - 大班课提前确认上课
cancelBclassAc:`${ORIGIN}/admin/assistant/venueCourse/cancelBclassAc`, //约课记录 - 大班课取消上课
cancelStuAc:`${ORIGIN}/admin/assistant/venueCourse/cancelStudentAc`, //约课记录 - 详情 - 某个学员取消上课
bclassStus:`${ORIGIN}/admin/assistant/venueCourse/bclassStudents`, //约课记录 - 详情 - 获取大班课可添加学员
bclassStuAdd:`${ORIGIN}/admin/assistant/venueCourse/bclassStudentAdd`, //约课记录 - 详情 - 大班课添加学员
sclassManage:`${ORIGIN}/admin/assistant/venueCourse/sclass`, //班级管理
sclassInfo:`${ORIGIN}/admin/assistant/venueCourse/sclassInfo`, //班级管理 - 详情
sclassConfirm:`${ORIGIN}/admin/assistant/venueCourse/sclassConfirm`, //班级管理 - 成班课确认成班
stuCanChangeSclass:`${ORIGIN}/admin/assistant/venueCourse/studentCanChangeSclass`, //班级管理 - 学员详情 - 可换班级列表
resetStuSclass:`${ORIGIN}/admin/assistant/venueCourse/resetStudentSclass`, //班级管理 - 学员详情 - 换班
sclassStuWork:`${ORIGIN}/admin/assistant/venueCourse/sclassStudentWork`, //班级管理 - 作业完成情况
sclassTimeChange:`${ORIGIN}/admin/assistant/venueCourse/sclassTimeChange`, //班级管理 - 修改上课时间
}
export default COURSE_API;

10
src/subpackage/course/js/course_server.js

@ -0,0 +1,10 @@
import { Server } from '../../../js/server';
class CourseServer extends Server {
constructor(props){
super(props)
}
}
export default new CourseServer();

409
src/subpackage/course/pages/arrange_class/arrange_class.vue

@ -0,0 +1,409 @@
<template>
<view class="arrange-class">
<view class="ac-info">
<view>{{pageInfo.brand_name || ''}}{{pageInfo.stadium_name ||'-'}}</view>
<view>课程名称{{pageInfo.course_name || '-'}}</view>
<view>上课教练{{pageInfo.course_coach || '-'}}</view>
<view>
<text>学员信息{{pageInfo.student_name || ''}}{{pageInfo.student_gender!=''?`${pageInfo.student_gender||''}`:''}} {{' '+(pageInfo.student_phone||'')}}</text>
<image src="/subpackage/course/static/images/icon/phone.png" @click="phoneCall(pageInfo.student_phone)"></image>
</view>
<view>剩余课时{{pageInfo.period_nums_surplus || 0}} {{pageInfo.period_nums || 0}})</view>
</view>
<view class="ac-section">
<view class="as-tit">{{pageInfo.next_class_number || '-'}}</view>
<!-- 上课教练 -->
<view class="as-line">
<view class="al-txt"><text>*</text>上课教练</view>
<picker class="al-picker" :value="coachName" :range="coachs" @change="coachBindChange">
<view class="al-view al-box">
<view>{{coachName || '请选择上课教练'}}</view>
<image src="/subpackage/course/static/images/icon/triangle.png"></image>
</view>
</picker>
</view>
<!-- 上课日期 -->
<view class="as-line">
<view class="al-txt"><text>*</text>上课日期</view>
<picker class="al-picker" mode="date" :value="submitInfo.date" @change="bindDateChange" >
<view class="al-view al-date">
<view class="ad-txt">{{submitInfo.date}}</view>
<view class="ad-img">
<image src="/subpackage/course/static/images/icon/calendar.png"></image>
</view>
</view>
</picker>
</view>
<!-- 上课时间 -->
<view class="as-line">
<view class="al-txt"><text>*</text>上课时间</view>
<picker class="al-picker" :value="submitInfo.start" :range="timeList" @change="startBindChange">
<view class="al-view al-time">
<view>{{submitInfo.start}}</view>
<image src="/subpackage/course/static/images/icon/triangle.png"></image>
</view>
</picker>
<view class="al-to"></view>
<picker class="al-picker" :value="submitInfo.end" :range="timeList" @change="endBindChange">
<view class="al-view al-time">
<view>{{submitInfo.end}}</view>
<image src="/subpackage/course/static/images/icon/triangle.png"></image>
</view>
</picker>
</view>
<!-- 上课场地 -->
<view class="as-line" v-if="pageInfo.is_booking_venue == true">
<view class="al-txt"><text>*</text>上课场地<view class="at-type">({{pageInfo.course_venue_type || '-'}})</view></view>
<picker class="al-picker" :value="venueName" :range="venues" @change="venueBindChange">
<view class="al-view al-box">
<view>{{venueName || '请选择场地'}}</view>
<image src="/subpackage/course/static/images/icon/triangle.png"></image>
</view>
</picker>
</view>
</view>
<view class="ac-fixed">
<view hover-class="hover-active" @click="confirmChange">确定</view>
</view>
</view>
</template>
<script>
import util from '@/utils/util';
import boxServer from '../../js/course_server';
import BOX_API from '../../js/course_api';
import { mapState } from 'vuex';
export default {
computed: {
...mapState([ 'brandInfo',]),
timeList(){
let _list = []
for(let i = 0; i<24; i++){
_list.push(`${i<10?'0'+i:i}:00`)
}
return _list;
},
coachs(){
let { coachList } = this
let _arr = []
if(coachList.length > 0){
_arr = this.coachList.map(e=>e.name)
}
return _arr || [];
},
venues(){
let { venueList } = this
let _arr = []
if(venueList.length > 0){
_arr = this.venueList.map(e=>e.name)
}
return _arr || [];
},
},
data() {
return {
coachList: [], //
coachName: "", //
venueList: [], //
venueName: "", //
pageInfo: {},
submitInfo: {
coach_id: "",
date: "",
start: "",
end: "",
venue_id: "",
},
}
},
async onLoad(options){
// let _query = util.jsonPar(options.query);
// this.pageInfo = _query
this.getStuInfo(options.order_no)
},
methods: {
//
bindDateChange: function(e) {
let _selectDate = e.target.value
this.submitInfo.date = _selectDate
},
startBindChange(e){
console.log(e);
let _list = this.timeList || [];
this.submitInfo.start = _list[e.detail.value] || ''
},
endBindChange(e){
console.log(e);
let _list = this.timeList || [];
this.submitInfo.end = _list[e.detail.value] || ''
},
coachBindChange(e){
console.log(e);
let _list = this.coachs || [];
this.coachName = _list[e.detail.value] || ''
this.submitInfo.coach_id = this.coachList[e.detail.value].id
},
venueBindChange(e){
console.log(e);
let _list = this.venues || [];
this.venueName = _list[e.detail.value] || ''
this.submitInfo.venue_id = this.venueList[e.detail.value].id
},
phoneCall(mobile) {
let _phoneStr = mobile || ''
let _phoneArr = _phoneStr.split(',') || [];
uni.showActionSheet({
itemList: _phoneArr,
success: res =>{
uni.makePhoneCall({
phoneNumber: _phoneArr[res.tapIndex]
})
}
})
},
confirmChange(){
let { pageInfo, submitInfo } = this
let { coach_id, date, start, end, venue_id } = this.submitInfo
if(coach_id==''||date==""||start=="" ||end=="" || (pageInfo.is_booking_venue==true && venue_id==''))return util.showNone("请完善必选项!");
let nowTime = util.formatDate(new Date(),'-') // 2020-07-21
if(new Date(nowTime).getTime() > new Date(date).getTime())return util.showNone("上课日期不能小于当前系统日期!");
// 2021-09-01便
if(Date.parse('2021-09-01 '+ start) >= Date.parse('2021-09-01 '+ end))return util.showNone("上课时间的结束时间不能小于起始时间!");
let _data = {
order_no: pageInfo.order_no,
coach_id, //ID
date, //
start, //
end, //
}
if(pageInfo.is_booking_venue == true)_data["venue_id"] = venue_id; //ID
util.showLoad();
boxServer.get({
url: BOX_API.arrangeStuAc, //[]
data: _data,
failMsg: '加载失败!'
})
.then(res=>{
util.hideLoad();
util.showNone("操作成功!");
setTimeout(_=>{ uni.navigateBack() }, 1200)
})
},
// -
getStuInfo(order_no){
let { brandInfo } = this
util.showLoad();
boxServer.get({
url: BOX_API.stuInfo,
data: {
brand_id: brandInfo.brand.id,
order_no,
},
failMsg: '加载失败!'
})
.then(res=>{
util.hideLoad();
this.pageInfo = res
this.getArrangeAcCoach(res.order_no);
})
},
// [] -
getArrangeAcCoach(order_no){
let { brandInfo } = this
util.showLoad();
boxServer.get({
url: BOX_API.arrangeStuAcCoach,
data: {
brand_id: brandInfo.brand.id,
order_no,
},
failMsg: '加载失败!'
})
.then(res=>{
util.hideLoad();
this.coachList = res.coachs || []
this.venueList = res.venues || []
})
},
}
}
</script>
<style lang="scss">
@import '~style/public.scss';
page{
background: #F2F2F7;
}
.arrange-class{
position: relative;
padding-bottom: 150rpx;
.ac-info{
padding: 28rpx 22rpx 30rpx;
background-color: #FFFFFF;
>view{
color: #1A1A1A;
font-size: 28rpx;
line-height: 52rpx;
&:first-child{
font-weight: 700;
margin-bottom: 4rpx;
}
&+view{
@include centerFlex(flex-start);
>image{
margin-left: 20rpx;
flex-shrink: 0;
width: 32rpx;
height: 32rpx;
}
}
}
}
.ac-section{
margin: 12rpx 0;
padding: 30rpx 28rpx 50rpx;
background-color: #FFFFFF;
.as-tit{
padding-bottom: 4rpx;
color: #333333;
font-size: 36rpx;
font-weight: 700;
line-height: 50rpx;
}
.as-line{
margin: 20rpx 46rpx 0 6rpx;
@include centerFlex(flex-start);
.al-txt{
position: relative;
margin-right: 18rpx;
flex-shrink: 0;
color: #1A1A1A;
font-size: 28rpx;
line-height: 44rpx;
>text{
color: #EA5061;
font-size: 32rpx;
}
.at-type{
position: absolute;
bottom: -36rpx;
left: 0;
min-width: 130rpx;
text-align: center;
color: #9C9C9F;
font-size: 24rpx;
line-height: 34rpx;
}
}
.al-picker{
flex-grow: 1;
}
.al-view{
flex-grow: 1;
padding-left: 20rpx;
height: 76rpx;
border-radius: 10rpx;
background-color: #F2F2F7;
@include centerFlex(flex-start);
}
.al-box{
>view{
flex-grow: 1;
color: #9C9C9F;
font-size: 28rpx;
line-height: 40rpx;
}
>image{
margin: 0 18rpx;
flex-shrink: 0;
width: 22rpx;
height: 22rpx;
}
}
.al-date{
.ad-txt{
flex-grow: 1;
color: #1A1A1A;
font-size: 28rpx;
line-height: 40rpx;
border-right: 2rpx solid #D8D8D8;
}
.ad-img{
flex-shrink: 0;
height: 76rpx;
padding: 0 16rpx 0 18rpx;
@include centerFlex(center);
>image{
flex-shrink: 0;
width: 34rpx;
height: 34rpx;
}
}
}
.al-time{
>view{
flex-grow: 1;
color: #1A1A1A;
font-size: 28rpx;
line-height: 40rpx;
min-width: 80rpx;
}
>image{
margin: 0 18rpx;
flex-shrink: 0;
width: 22rpx;
height: 22rpx;
}
}
.al-to{
margin: 0 28rpx;
flex-shrink: 0;
color: #B2B2B2;
font-size: 32rpx;
line-height: 44rpx;
}
}
}
.ac-fixed{
position: fixed;
bottom: 0;
left: 0;
padding: 20rpx 0;
width: 750rpx;
background-color: #FFFFFF;
>view{
margin: 0 auto;
padding: 24rpx 0;
width: 670rpx;
border-radius: 44rpx;
background-color: #009874;
color: #FFFFFF;
font-size: 28rpx;
line-height: 40rpx;
text-align: center;
font-weight: 700;
}
}
}
</style>

226
src/subpackage/course/pages/class_add_student/class_add_student.vue

@ -0,0 +1,226 @@
<template>
<view class="add-student">
<view class="as-search">
<view class="as-box">
<image src="/static/images/icon/search.png"></image>
<input class="ab-ipt" placeholder="请输入学员姓名/电话查找" confirm-type="search" v-model="searchText" @change="searchChange"/>
</view>
</view>
<view class="as-name">课程名称{{pageInfo.course_name||'-'}}</view>
<view class="as-list" v-for="(e,i) in studentList" :key="i">
<view class="al-item" @click="itemChange(e,i)">
<image :class="[submitInfo.order_no==e.order_no?'ai-img':'ai-icon']" :src="submitInfo.order_no==e.order_no?'/static/images/icon/selected_987.png':''"></image>
<view class="ai-info">
<view>学员信息{{e.student_name||'-'}}{{e.student_gender || '-'}} {{userInfo.type==2?e.student_phone:''}}</view>
<view>剩余课时<text>{{e.course_period_nums_surplus || 0}}课时</text><text>{{e.course_period_nums_use||0}}/{{e.course_period_nums_total||0}})</text></view>
</view>
</view>
</view>
<view class="as-fixed">
<view hover-class="hover-active" @click="btnChange()">确认添加学员</view>
</view>
</view>
</template>
<script>
import util from '@/utils/util';
import boxServer from '../../js/course_server';
import BOX_API from '../../js/course_api';
import { mapState } from 'vuex';
export default {
computed:{
...mapState([ 'brandInfo',]),
},
data() {
return {
pageInfo: {},
studentList: [],
searchText: "",
submitInfo: {
order_no: "",
subscribe_no: "",
},
}
},
onLoad(options) {
this.submitInfo.subscribe_no = options.subscribe_no
this.getSubStudent(options.subscribe_no)
},
methods: {
//
searchChange(e){
let { searchText, pageInfo } = this
if(searchText == '')return this.studentList = pageInfo.students;
this.studentList = pageInfo.students.filter(e=>e.student_name.indexOf(searchText)!=-1||e.student_phone.indexOf(searchText)!=-1 );
},
itemChange(info){
this.submitInfo.order_no = info.order_no
},
btnChange(){
if(this.submitInfo.order_no=='')return util.showNone('请选择需要添加的学员!');
util.showModal({
title: '是否确认添加学员上课?',
content: '',
showCancel: true,
success: modalRes=>{
if(modalRes.confirm){
this.getSubAdd()
}
}
})
},
//
getSubAdd(){
let { brandInfo } = this
let { order_no, subscribe_no} = this.submitInfo
util.showLoad();
boxServer.get({
url: BOX_API.bclassStuAdd,
data: {
brand_id: brandInfo.brand.id,
order_no,
subscribe_no,
},
failMsg: '加载失败!'
})
.then(res=>{
util.hideLoad();
util.showNone('操作成功!');
setTimeout(_=>{
this.getSubStudent(subscribe_no);
util.previousPageFunction({
fnName: 'refreshList',
query: { isLoad: false},
});
},1200);
})
},
//
getSubStudent(subscribe_no){
let { brandInfo } = this
util.showLoad();
boxServer.get({
url: BOX_API.bclassStus,
data: {
brand_id: brandInfo.brand.id,
subscribe_no,
},
failMsg: '加载失败!'
})
.then(res=>{
util.hideLoad();
this.searchText = ""
this.submitInfo.order_no = ""
this.pageInfo = res || {};
this.studentList = this.pageInfo.students || []
})
},
}
}
</script>
<style lang="scss">
@import '~style/public.scss';
page{
background: #F2F2F7;
}
.add-student{
position: relative;
padding-bottom: 170rpx;
.as-search{
padding: 26rpx 24rpx;
background-color: #FFFFFF;
.as-box{
padding: 0rpx 20rpx;
height: 92rpx;
border-radius: 10rpx;
background-color: #F2F2F7;
@include centerFlex(flex-start);
>image{
flex-shrink: 0;
margin-right: 20rpx;
width: 40rpx;
height: 40rpx;
}
.ab-ipt{
flex-grow: 1;
color: #1A1A1A;
font-size: 32rpx;
}
}
}
.as-name{
margin-top: 2rpx;
padding: 26rpx 30rpx;
background-color: #FFFFFF;
color: #1A1A1A;
font-size: 28rpx;
font-weight: 700;
}
.as-list{
margin-top: 2rpx;
.al-item{
padding: 28rpx 40rpx;
display: flex;
justify-content: flex-start;
background-color: #FFFFFF;
>image{
flex-shrink: 0;
margin-right: 28rpx;
}
.ai-icon{
width: 36rpx;
height: 36rpx;
border-radius: 50%;
border: 2rpx solid #9A9A9D;
}
.ai-img{
width: 40rpx;
height: 40rpx;
}
.ai-info{
flex-grow: 1;
margin-top: -10rpx;
>view{
color: #1A1A1A;
font-size: 28rpx;
line-height: 52rpx;
>text{
&:first-child{
color: #009874;
}
&:nth-child(2){
color: #9C9C9F;
}
}
}
}
}
}
.as-fixed{
position: fixed;
bottom: 0;
left: 0;
padding: 22rpx 0;
width: 750rpx;
background-color: #FFFFFF;
border-top: 2rpx solid #F2F2F7;
>view{
margin: 0 auto;
padding: 34rpx 0;
width: 670rpx;
border-radius: 10rpx;
background-color: #009874;
color: #FFFFFF;
font-size: 32rpx;
line-height: 44rpx;
text-align: center;
}
}
}
</style>

242
src/subpackage/course/pages/class_student_detail/class_student_detail.vue

@ -0,0 +1,242 @@
<template>
<view class="class-student-detail">
<view class="csd-section">
<view class="cs-view">学员姓名{{pageInfo.student_name||'-'}}{{pageInfo.student_gender||'-'}} </view>
<!-- 只有教务才有 -->
<view class="cs-view">
<text>学员电话{{pageInfo.student_phone ||'-'}}</text>
<image src="/subpackage/course/static/images/icon/phone.png" @click="phoneCall(pageInfo.student_phone)"></image>
</view>
<view class="cs-view">剩余课时{{pageInfo.course_period_residue ||0}}课时 {{pageInfo.course_period_nums_use||0}}/{{pageInfo.course_period_nums||0}})</view>
<view class="cs-end" v-if="pageInfo.order_status==0||pageInfo.order_status==1">
<!-- 只有教务才有 -->
<view class="ce-btn1" hover-class="hover-active" @click="isShowClass=true" >转班</view>
</view>
</view>
<view class="csd-record">
<view class="cr-tit">上课记录</view>
<sclass-record-section :recordInfo="pageInfo.student_period_time"></sclass-record-section>
</view>
<!-- 转班弹框 -->
<class-reset-modal
:isShowClass="isShowClass"
:info="pageInfo"
:canlist="classList"
@confirmReset="confirmReset"
@closeReset="isShowClass=false"
></class-reset-modal>
</view>
</template>
<script>
import util from '@/utils/util';
import boxServer from '../../js/course_server';
import BOX_API from '../../js/course_api';
import { mapState } from 'vuex';
import class_reset_modal from '../../components/class_reset_modal/class_reset_modal.vue';
import sclass_record_section from '../../components/sclass_record_section/sclass_record_section.vue';
export default {
components: {
'class-reset-modal': class_reset_modal,
'sclass-record-section': sclass_record_section,
},
computed: {
...mapState([ 'brandInfo',]),
},
data() {
return {
pageInfo: {},
isShowClass: false,
classList: [],
resetInfo: {},
}
},
async onLoad(options){
let _query = util.jsonPar(options.query);
this.pageInfo = _query
this.$nextTick(_=>{
this.getCanlist(this.pageInfo.course_id);
})
},
methods: {
phoneCall(mobile) {
let _phoneStr = mobile || ''
let _phoneArr = _phoneStr.split(',') || [];
uni.showActionSheet({
itemList: _phoneArr,
success: res =>{
uni.makePhoneCall({
phoneNumber: _phoneArr[res.tapIndex]
})
}
})
},
//
confirmReset(e){
let { brandInfo, pageInfo } = this
util.showLoad();
boxServer.get({
url: BOX_API.resetStuSclass,
data: {
brand_id: brandInfo.brand.id,
old_id: pageInfo.sclass_id,
new_id: e.new_id,
user_id: pageInfo.user_id,
user_order_no: pageInfo.order_no,
},
failMsg: '加载失败!'
})
.then(res=>{
util.hideLoad();
util.showNone('操作成功!');
setTimeout(_=>{
uni.navigateBack({delta:2})
util.previousPageFunction({
fnName: 'refreshList',
query: { isLoad: false},
});
}, 1200)
})
},
//
getCanlist(course_id){
let { brandInfo, pageInfo } = this
util.showLoad();
boxServer.get({
url: BOX_API.stuCanChangeSclass,
data: {
brand_id: brandInfo.brand.id,
course_id,
},
failMsg: '加载失败!'
})
.then(res=>{
util.hideLoad();
this.classList = res.list || []
})
},
}
}
</script>
<style lang="scss">
@import '~style/public.scss';
page{
background: #FFFFFF;
}
.class-student-detail{
position: relative;
padding-bottom: 160rpx;
.csd-section{
padding: 24rpx 22rpx 0;
.cs-view{
color: #1A1A1A;
font-size: 28rpx;
line-height: 52rpx;
@include centerFlex(flex-start);
>image{
margin-left: 30rpx;
flex-shrink: 0;
width: 32rpx;
height: 32rpx;
}
}
.cs-end{
margin-top: 16rpx;
padding: 30rpx 0;
border-top: 2rpx solid #E5E5E5;
@include centerFlex(flex-end);
>view{
margin-left: 20rpx;
padding: 12rpx 0;
width: 156rpx;
text-align: center;
font-size: 28rpx;
line-height: 40rpx;
border-radius: 6rpx;
border: 2rpx solid #009874;
}
.ce-btn1{
color: #009874;
background-color: #FFFFFF;
}
.ce-btn2{
color: #FFFFFF;
background-color: #009874;
}
}
}
.csd-record{
padding-bottom: 26rpx;
border-top: 24rpx solid #F2F2F7;
.cr-tit{
padding: 26rpx 22rpx;
color: #1A1A1A;
font-size: 28rpx;
line-height: 52rpx;
}
.cds-tab{
margin: 0 24rpx;
border: 2rpx solid #E8E8E8;
background-color: #F6F8F8;
@include centerFlex(flex-start);
>view{
height: 110rpx;
color: #1A1A1A;
font-size: 28rpx;
text-align: center;
@include centerFlex(center);
&:first-child {
width: 166rpx;
}
&:nth-child(2){
width: 338rpx;
border-left: 2rpx solid #E8E8E8;
border-right: 2rpx solid #E8E8E8;
}
&:nth-child(3){
width: 194rpx;
// border-right: 2rpx solid #E8E8E8;
}
}
}
.cds-list{
.cl-item{
margin: 0 24rpx;
border-left: 2rpx solid #E8E8E8;
border-right: 2rpx solid #E8E8E8;
border-bottom: 2rpx solid #E8E8E8;
background-color: #FFFFFF;
@include centerFlex(flex-start);
>view{
height: 110rpx;
color: #1A1A1A;
font-size: 28rpx;
text-align: center;
@include centerFlex(center);
&:first-child {
width: 166rpx;
}
&:nth-child(2){
width: 338rpx;
border-left: 2rpx solid #E8E8E8;
border-right: 2rpx solid #E8E8E8;
}
&:nth-child(3){
width: 194rpx;
}
}
.ci-txt-green{
color: #009874;
}
.ci-txt-red{
color: #EA5061;
}
}
}
}
}
</style>

250
src/subpackage/course/pages/class_time_change/class_time_change.vue

@ -0,0 +1,250 @@
<template>
<view class="class-time-change">
<view class="ctc-info">
<view class="ci-weight">{{pageInfo.brand_name||'-'}}</view>
<view>课程名称{{pageInfo.course_name||'-'}}</view>
<view>所在班级{{pageInfo.sclass_name||'-'}}</view>
</view>
<view class="ctc-section">
<view class="cs-tit">{{pageInfo.lesson_no|| 0}}</view>
<view class="cs-line">
<view class="cl-txt"><text>*</text>上课日期</view>
<picker class="cl-picker" mode="date" :value="pageInfo.period_date" @change="bindDateChange" >
<view class="cl-box">
<view class="cb-txt">{{pageInfo.period_date}}</view>
<view class="cb-img">
<image src="/subpackage/course/static/images/icon/calendar.png"></image>
</view>
</view>
</picker>
</view>
<view class="cs-line">
<view class="cl-txt"><text>*</text>上课时间</view>
<picker class="cl-picker" :value="pageInfo.period_start_time" :range="timeList" @change="startBindChange">
<view class="cl-view">
<view>{{pageInfo.period_start_time}}</view>
<image src="/subpackage/course/static/images/icon/triangle.png"></image>
</view>
</picker>
<view class="cl-to"></view>
<picker class="cl-picker" :value="pageInfo.period_end_time" :range="timeList" @change="endBindChange">
<view class="cl-view">
<view>{{pageInfo.period_end_time}}</view>
<image src="/subpackage/course/static/images/icon/triangle.png"></image>
</view>
</picker>
</view>
</view>
<view class="fixed-btn">
<view hover-class="hover-active" @click="sclassTimeChange">确认更改</view>
</view>
</view>
</template>
<script>
import util from '@/utils/util';
import boxServer from '../../js/course_server';
import BOX_API from '../../js/course_api';
import { mapState } from 'vuex';
export default {
computed: {
...mapState([ 'brandInfo',]),
timeList(){
let _list = []
for(let i = 0; i<24; i++){
_list.push(`${i<10?'0'+i:i}:00`)
}
return _list;
},
},
data() {
return {
pageInfo: {
period_date: "",
period_start_time: "",
period_end_time: "",
},
}
},
onLoad(options){
let _query = util.jsonPar(options.query);
this.pageInfo = _query
},
methods: {
//
bindDateChange: function(e) {
let _selectDate = e.target.value
this.pageInfo.period_date = _selectDate
},
startBindChange(e){
console.log(e);
let _list = this.timeList || [];
this.pageInfo.period_start_time = _list[e.detail.value] || ''
},
endBindChange(e){
console.log(e);
let _list = this.timeList || [];
this.pageInfo.period_end_time = _list[e.detail.value] || ''
},
//
sclassTimeChange(){
let { pageInfo, brandInfo } = this
if(pageInfo.period_date==''|| pageInfo.period_start_time==''|| pageInfo.period_end_time=='')return util.showNone("请完善必选项!");
let nowTime = util.formatDate(new Date(),'-') // 2020-07-21
if(new Date(nowTime).getTime() > new Date(pageInfo.period_date).getTime())return util.showNone("上课日期不能小于当前系统日期!");
// 2021-09-01便
if(Date.parse('2021-09-01 '+ pageInfo.period_start_time) >= Date.parse('2021-09-01 '+ pageInfo.period_end_time))return util.showNone("上课时间的结束时间不能小于起始时间!");
this.$emit('closeChange')
util.showLoad();
boxServer.get({
url: BOX_API.sclassTimeChange,
data: {
brand_id: brandInfo.brand.id,
id: pageInfo.sclass_id,
lesson_no: pageInfo.lesson_no,
period_date: pageInfo.period_date,
period_start_time: pageInfo.period_start_time,
period_end_time: pageInfo.period_end_time,
},
failMsg: '加载失败!'
})
.then(res=>{
util.hideLoad();
util.showNone('操作成功!');
setTimeout(_=>{
uni.navigateBack()
util.previousPageFunction({
fnName: 'refreshList',
query: { isLoad: false},
});
}, 1200)
})
},
}
}
</script>
<style lang="scss">
@import '~style/public.scss';
page{
background: #F2F2F7;
}
.class-time-change{
position: relative;
padding-bottom: 160rpx;
.ctc-info{
padding: 24rpx 22rpx;
background-color: #FFFFFF;
>view{
color: #1A1A1A;
font-size: 28rpx;
line-height: 52rpx;
}
.ci-weight{
font-weight: 700;
}
}
.ctc-section{
margin: 12rpx 0;
padding: 30rpx 56rpx 58rpx 28rpx;
background-color: #FFFFFF;
.cs-tit{
color: #333333;
font-size: 36rpx;
font-weight: 700;
line-height: 50rpx;
margin-bottom: 16rpx;
}
.cs-line{
margin-top: 32rpx;
@include centerFlex(flex-start);
.cl-txt{
margin-right: 20rpx;
flex-shrink: 0;
color: #1A1A1A;
font-size: 32rpx;
line-height: 44rpx;
>text{
color: #EA5061;
}
}
.cl-box{
flex-grow: 1;
padding-left: 20rpx;
height: 88rpx;
border-radius: 10rpx;
background-color: #F2F2F7;
@include centerFlex(flex-start);
.cb-txt{
flex-grow: 1;
border-right: 2rpx solid #D8D8D8;
color: #1A1A1A;
font-size: 28rpx;
}
.cb-img{
height: 88rpx;
padding: 0 22rpx 0 18rpx;
@include centerFlex(center);
>image{
width: 34rpx;
height: 34rpx;
}
}
}
.cl-picker{
flex-grow: 1;
}
.cl-view{
padding-left: 20rpx;
flex-grow: 1;
height: 88rpx;
border-radius: 10rpx;
background-color: #F2F2F7;
@include centerFlex(flex-end);
>view{
flex-grow: 1;
color: #1A1A1A;
font-size: 28rpx;
min-width: 80rpx;
}
>image{
margin: 0 18rpx;
flex-shrink: 0;
width: 22rpx;
height: 22rpx;
}
}
.cl-to{
margin: 0 26rpx;
flex-shrink: 0;
color: #B2B2B2;
font-size: 32rpx;
line-height: 44rpx;
}
}
}
.fixed-btn{
position: fixed;
bottom: 0;
left: 0;
width: 750rpx;
padding: 20rpx 0 24rpx;
background-color: #FFFFFF;
z-index: 2;
>view{
margin: auto;
padding: 24rpx 0;
width: 670rpx;
border-radius: 10rpx;
background-color: #009874;
color: #FFFFFF;
font-size: 28rpx;
text-align: center;
font-weight: 700;
}
}
}
</style>

242
src/subpackage/course/pages/index/index.vue

@ -0,0 +1,242 @@
<template>
<view class="index-content">
<view class="ic-head">
<store-name :theme="'light'"></store-name>
</view>
<view class="ic-section">
<view class="is-box">
<view class="ib-line">
<view class="il-view">
<view>进行中</view>
<view>{{pageInfo.ongoing_nums || 0}}</view>
</view>
<view class="il-cut"></view>
<view class="il-view">
<view>已结束</view>
<view>{{pageInfo.ended_nums || 0}}</view>
</view>
</view>
<view class="ib-line">
<view class="il-view">
<view>今日待上课</view>
<view>{{pageInfo.dsk_nums || 0}}</view>
</view>
<view class="il-cut"></view>
<view class="il-view">
<view>今日已上课</view>
<view>{{pageInfo.ysk_nums || 0}}</view>
</view>
</view>
</view>
</view>
<view class="ic-tablist" v-for="(e,i) in tabList" :key="i">
<view class="it-title">{{e.type}}</view>
<view class="it-tabs">
<view class="itt-item" v-for="(item,index) in e.itemList" :key="index" @click="tabChange(e.id,item.id)">
<view>
<image :src="'/subpackage/course/static/images/tab/tab_'+ e.id +'_'+ item.id + '.png'"></image>
<view>{{item.name}}</view>
</view>
</view>
</view>
</view>
</view>
</template>
<script>
import util from '@/utils/util';
import boxServer from '../../js/course_server';
import BOX_API from '../../js/course_api';
import { mapState } from 'vuex'
import store_name from '../../components/store_name/store_name';
const tabList = [
{
type: "更多操作",
id: 0,
itemList:[
{
id: 0,
name: "学员课程",
},
{
id: 1,
name: "私教课上课记录",
},
{
id: 2,
name: "大班上课记录",
},
{
id: 3,
name: "班级管理",
},
],
},
]
export default {
components: {
'store-name': store_name
},
computed:{
...mapState([ 'brandInfo',]),
...mapState({
curStoreInfo: state => state.device.curStoreInfo,
}),
},
watch: {
curStoreInfo(newVal, oldVal) {
this.pageInfo = {};
this.getCourseHome({
stadium_id: newVal.id,
})
}
},
data() {
return {
tabList,
pageInfo: {},
isShowAgain: false,
}
},
async onLoad(){
// console.log("",this.brandInfo)
try{
util.showLoad();
let _brandInfo = await this.$store.dispatch('getBrandInfo');
await this.$store.dispatch('getStoreList');
this.getCourseHome({
stadium_id: this.curStoreInfo.id,
})
util.hideLoad();
}catch(err){
util.hideLoad();
}
},
onShow() {
if(this.isShowAgain)this.getCourseHome({stadium_id: this.curStoreInfo.id,});
},
methods: {
tabChange(id1,id2){
// if(path=='')return util.showNone('');
let _type_id = `${id1}-${id2}`
util.routeTo(`/subpackage/course/pages/manage_list/manage_list?type_id=${_type_id}`,'nT')
},
getCourseHome({stadium_id}){
let { brandInfo } = this
// util.showLoad();
boxServer.get({
url: BOX_API.courseHome,
data: {
brand_id: brandInfo.brand.id,
stadium_id,
},
failMsg: '加载失败!'
})
.then(res=>{
// util.hideLoad();
this.pageInfo = res
this.isShowAgain = true
})
.catch(util.hideLoad)
},
}
}
</script>
<style lang="scss">
@import '~style/public.scss';
page{
background: #FFFFFF;
}
.index-content{
.ic-head{
width: 750rpx;
height: 218rpx;
background-color: #009874;
}
.ic-section{
position: relative;
width: 750rpx;
height: 320rpx;
background-color: #F2F2F7;
.is-box{
position: absolute;
top: -100rpx;
left: 40rpx;
width: 670rpx;
padding-bottom: 50rpx;
// height: 378rpx;
border-radius: 10rpx;
background-color: #FFFFFF;
.ib-line{
padding: 60rpx 0 10rpx;
@include centerFlex(flex-start);
.il-view{
margin-left: 60rpx;
flex-grow: 1;
>view{
&:first-child{
color: #9C9C9F;
font-size: 28rpx;
line-height: 40rpx;
}
&:nth-child(2){
color: #1A1A1A;
font-size: 40rpx;
line-height: 56rpx;
font-weight: 700;
}
}
}
.il-cut{
flex-shrink: 0;
width: 2rpx;
height: 92rpx;
background-color: #D8D8D8;
}
}
}
}
.ic-tablist{
padding-bottom: 24rpx;
background: #FFFFFF;
.it-title{
padding: 52rpx 40rpx 0rpx;
color: #1A1A1A;
font-size: 28rpx;
line-height: 40rpx;
}
.it-tabs{
display: flex;
flex-wrap: wrap;
.itt-item{
margin: 60rpx 0 20rpx;
flex-wrap: wrap;
flex-shrink: 0;
width: 33.33%;
>view{
display: flex;
flex-direction: column;
flex-wrap: wrap;
justify-content: center;
align-items: center;
>image{
width: 52rpx;
height: 52rpx;
}
>view{
margin-top: 20rpx;
color: #1A1A1A;
font-size: 28rpx;
line-height: 40rpx;
text-align: center;
}
}
}
}
}
}
</style>

396
src/subpackage/course/pages/manage_detail/bclass_reserve_detail/bclass_reserve_detail.vue

@ -0,0 +1,396 @@
<template>
<view class="bclass-reserve-detail">
<view class="brd-line">
<view>{{pageInfo.brand_name||''}}({{pageInfo.stadium_name||'-'}})</view>
<view :class="[pageInfo.status_text=='已上课'?'bl-gray':pageInfo.status_text=='已取消'?'bl-red':'bl-green']">{{pageInfo.status_text||'-'}}</view>
</view>
<view class="brd-section">
<view>预约单号<text>{{pageInfo.subscribe_no||''}}</text></view>
<view>预约时间<text>{{pageInfo.subscribe_at||''}} </text></view>
<!-- 已取消才显示 -->
<block v-if="pageInfo.status_text=='已取消'">
<view>取消时间<text>{{pageInfo.cancel_time||''}}</text></view>
<view>取消原因<text>{{pageInfo.cancel_reason||''}}</text></view>
</block>
</view>
<view class="brd-section">
<view>上课信息</view>
<view>上课时间<text>{{pageInfo.date||''}}{{pageInfo.week||''}} {{pageInfo.start_duration||''}}-{{pageInfo.end_duration||''}}</text></view>
<view>上课地点<text>{{pageInfo.addr||''}}</text></view>
<view>上课教练<text>{{pageInfo.coach_name||''}}</text></view>
<view>课程名称<text>{{pageInfo.course_name||''}}</text></view>
<view>课程类型<text>{{pageInfo.course_kind||''}}</text></view>
</view>
<view class="brd-stu">
<view class="bs-tit">学员信息</view>
<view class="bs-line">
<view>已预约人数{{pageInfo.bclass_nums||0}}<text>上课区间{{pageInfo.bclass_nums_min||0}}-{{pageInfo.bclass_nums_max||0}}</text></view>
<!-- 待确认待上课才显示 -->
<view v-if="pageInfo.status_text=='待确认'||pageInfo.status_text=='待上课'" @click="toAddStu">添加学员</view>
</view>
<view class="bs-list" v-for="(e,i) in pageInfo.students" :key="i">
<view class="bl-item">
<view class="bi-info">
<view>{{e.student_name||'-'}}({{e.student_gender||'-'}})
<block v-if="e.student_phone!=''">
<text>{{e.student_phone||'-'}}</text>
<image src="/subpackage/course/static/images/icon/phone.png" @click="phoneCall(e.student_phone)"></image>
</block>
</view>
<view>预约时间{{e.subscribe_at||''}}</view>
</view>
<!-- 待确认待上课才显示 -->
<view
class="bi-btn"
hover-class="hover-active"
v-if="pageInfo.status_text=='待确认'||pageInfo.status_text=='待上课'"
@click="cancelClassStuChange(1,e)"
>取消上课</view>
</view>
</view>
</view>
<!-- 待确认待上课才显示 -->
<view class="brd-fixed" v-if="pageInfo.status_text=='待确认'||pageInfo.status_text=='待上课'">
<view class="bf-line">
<view class="bl-btn1" hover-class="hover-active" @click="cancelClassChange(0)">取消上课</view>
<view class="bl-btn2" hover-class="hover-active" @click="bclassConfirm" v-if="pageInfo.status_text=='待确认'">确认上课</view>
</view>
</view>
<cancel-class-modal
v-if="isCancelClass"
@reasonConfirm="reasonConfirm"
@reasonClose="isCancelClass=false"
></cancel-class-modal>
</view>
</template>
<script>
import util from '@/utils/util';
import boxServer from '../../../js/course_server';
import BOX_API from '../../../js/course_api';
import { mapState } from 'vuex';
import cancel_class_modal from '../../../components/cancel_class_modal/cancel_class_modal.vue';
export default {
components: {
'cancel-class-modal': cancel_class_modal,
},
computed:{
...mapState([ 'brandInfo',]),
},
data() {
return {
isCancelClass: false,
pageInfo: {},
cancelType: "",
submitInfo: {
type: "", // 0 1
id: -1,
subscribe_no: "",
},
}
},
onLoad(options) {
this.submitInfo.id = options.id
this.getDetail(options.id)
},
methods: {
getDetail(id){
let { brandInfo } = this
util.showLoad();
boxServer.get({
url: BOX_API.subscribeInfo,
data: {
brand_id: brandInfo.brand.id,
id,
},
failMsg: '加载失败!'
})
.then(res=>{
util.hideLoad();
this.pageInfo = res
})
},
refreshList(){
let { submitInfo } = this
this.getDetail(submitInfo.id)
},
toAddStu(){
let { pageInfo } = this
util.routeTo(`/subpackage/course/pages/class_add_student/class_add_student?subscribe_no=${pageInfo.subscribe_no}`,'nT');
},
// -
cancelClassChange(type){
this.submitInfo.type = type
this.isCancelClass = true
},
// -
cancelClassStuChange(type,info){
this.submitInfo.type = type
this.submitInfo.subscribe_no = info.student_no
this.isCancelClass = true
},
reasonConfirm(e){
this.isCancelClass = false
let { submitInfo } = this
if(submitInfo.type == 0){
this.getCancelPabAc({
id: submitInfo.id,
reason: e,
})
return;
}
if(submitInfo.type == 1){
this.getCancelPabAc({
subscribe_no: submitInfo.subscribe_no,
reason: e,
})
return;
}
},
// [/]
getCancelPabAc({subscribe_no, id, reason}){
let { brandInfo, submitInfo } = this
let _data = {
brand_id: brandInfo.brand.id,
reason, //
}
if(submitInfo.type == 0)_data["id"] = id;
if(submitInfo.type == 1)_data["subscribe_no"] = subscribe_no;
util.showLoad();
boxServer.get({
url: submitInfo.type == 0? BOX_API.cancelBclassAc:submitInfo.type == 1? BOX_API.cancelStuAc:'',
data: _data,
failMsg: '加载失败!'
})
.then(res=>{
util.hideLoad();
util.showNone('操作成功!');
setTimeout(_=>{
this.refreshList()
util.previousPageFunction({
fnName: 'refreshList',
query: { isLoad: false},
});
}, 1200)
})
},
//
bclassConfirm(){
let { brandInfo, pageInfo } = this
util.showModal({
title: '提示',
content: '是否确认上课?',
showCancel: true,
success: modalRes=>{
if(modalRes.confirm){
util.showLoad();
boxServer.get({
url: BOX_API.setBclassAc,
data: {
brand_id: brandInfo.brand.id,
subscribe_no: pageInfo.subscribe_no, //
},
failMsg: '加载失败!'
})
.then(res=>{
util.hideLoad();
util.showNone('操作成功!');
setTimeout(_=>{
this.refreshList()
util.previousPageFunction({
fnName: 'refreshList',
query: { isLoad: false},
});
}, 1200)
})
}
}
})
},
phoneCall(mobile) {
let _phoneStr = mobile || ''
let _phoneArr = _phoneStr.split(',') || [];
uni.showActionSheet({
itemList: _phoneArr,
success: res =>{
uni.makePhoneCall({
phoneNumber: _phoneArr[res.tapIndex]
})
}
})
},
}
}
</script>
<style lang="scss">
@import '~style/public.scss';
.bclass-reserve-detail{
position: relative;
padding-bottom: 150rpx;
.brd-line{
padding: 24rpx 44rpx 30rpx 30rpx;
background-color: #FFFFFF;
border-bottom: 2rpx solid #E5E5E5;
@include centerFlex(space-between);
>view{
font-size: 28rpx;
line-height: 40rpx;
&:first-child{
color: #1A1A1A;
font-weight: 700;
}
&:nth-child(2){
flex-shrink: 0;
margin-left: 10rpx;
}
}
.bl-green{
color: #009874;
}
.bl-gray{
color: #9C9C9F;
}
.bl-red{
color: #EA5061;
}
}
.brd-section{
margin-bottom: 2rpx;
padding: 25rpx 30rpx 30rpx;
background-color: #FFFFFF;
>view{
color: #9C9C9F;
font-size: 28rpx;
line-height: 52rpx;
>text{
color: #1A1A1A;
}
}
}
.brd-stu{
margin-top: 24rpx;
// padding: 26rpx 30rpx 38rpx;
background-color: #FFFFFF;
.bs-tit{
padding: 30rpx 30rpx 0;
color: #9A9A9D;
font-size: 28rpx;
line-height: 40rpx;
}
.bs-line{
padding: 12rpx 44rpx 26rpx 26rpx;
border-bottom: 2rpx solid #F2F2F7;
@include centerFlex(space-between);
>view{
font-size: 28rpx;
&:first-child{
color: #1A1A1A;
line-height: 52rpx;
>text{
color: #9C9C9F;
}
}
&:nth-child(2){
margin-left: 10rpx;
flex-shrink: 0;
color: #009874;
line-height: 40rpx;
text-decoration: underline;
}
}
}
.bs-list{
.bl-item{
margin: 0 30rpx;
padding: 30rpx 0rpx;
border-bottom: 2rpx solid #D8D8D8;
@include centerFlex(space-between);
.bi-info{
>view{
&:first-child{
color: #333333;
font-size: 32rpx;
line-height: 44rpx;
>text{
margin: 0 28rpx 0 40rpx;
}
>image{
flex-shrink: 0;
width: 32rpx;
height: 32rpx;
}
}
&:nth-child(2){
margin-top: 6rpx;
color: #B2B2B2;
font-size: 28rpx;
line-height: 40rpx;
}
}
}
.bi-btn{
padding: 12rpx 0;
width: 140rpx;
border: 2rpx solid #EA5061;
border-radius: 6rpx;
color: #EA5061;
font-size: 28rpx;
line-height: 40rpx;
text-align: center;
}
}
}
}
.brd-fixed{
position: fixed;
bottom: 0;
left: 0;
padding: 30rpx 0;
width: 750rpx;
background-color: #FFFFFF;
.bf-line{
margin-right: 32rpx;
@include centerFlex(flex-end);
>view{
margin-left: 20rpx;
padding: 20rpx 0;
width: 192rpx;
font-size: 28rpx;
text-align: center;
font-weight: 700;
border-radius: 6rpx;
}
.bl-btn1{
color: #EA5061;
border: 2rpx solid #EA5061;
background-color: #FFFFFF;
}
.bl-btn2{
color: #FFFFFF;
border: 2rpx solid #009874;
background-color: #009874;
}
.bl-btn3{
color: #009874;
border: 2rpx solid #009874;
background-color: #FFFFFF;
}
}
}
}
</style>

540
src/subpackage/course/pages/manage_detail/class_manage_detail/class_manage_detail.vue

@ -0,0 +1,540 @@
<template>
<view class="class-manage-detail" :class="[curTabID==2?'cmd-content':'']">
<view class="cmd-tab">
<tab-bar :tabList="tabList" :curTabID="curTabID" @change="tabChange"></tab-bar>
</view>
<!-- 班级详情 -->
<block v-if="curTabID==0">
<view class="cmd-status">课程状态<text :class="[pageInfo.sclass_status==2?'cs-gray':pageInfo.sclass_status==3?'cs-red':'cs-green']">{{zh_sclass_status(pageInfo.sclass_status)||'-'}}</text></view>
<view class="cmd-section">
<view>课程信息</view>
<view>{{pageInfo.brand_name||''}}{{pageInfo.stadium_name||'-'}}</view>
<view><text>课程名称</text>{{pageInfo.course_name||''}}</view>
<view><text>课程课时数量</text>{{pageInfo.course_number ||0}}节课</view>
<view><text>课时时长</text>{{pageInfo.course_time_length}}分钟</view>
<view><text>课程有效期</text>{{pageInfo.course_valid_period||''}}</view>
<!-- 成班中失败 -->
<block v-if="pageInfo.sclass_status==0||pageInfo.sclass_status==3">
<view><text>成班区间人数</text>{{pageInfo.sclass_min_nums||''}}-{{pageInfo.sclass_max_nums||''}}</view>
<view><text>报名截止时间</text>{{pageInfo.sclass_join_deadline||''}}</view>
</block>
</view>
<view class="cmd-section">
<view>班级信息</view>
<view><text>班级id</text>{{pageInfo.sclass_number||''}}</view>
<view><text>班级名称</text>{{pageInfo.sclass_name||''}}</view>
<view><text>班级人数</text>{{pageInfo.sclass_nums||''}}</view>
<view><text>上课教练</text>{{pageInfo.sclass_coach||''}}</view>
<view><text>上课地点</text>{{pageInfo.sclass_addr||''}}</view>
<view><text>课程日期</text>{{pageInfo.sclass_date||''}}</view>
</view>
<view class="cmd-fixed" v-if="pageInfo.sclass_status==0">
<view hover-class="hover-active" @click="confirmClass()">确认成班</view>
</view>
</block>
<!-- 班级学员 -->
<view class="cmd-stu" v-for="(e,i) in pageInfo.students" :key="i" v-if="curTabID==1">
<view class="cs-item" @click="toStuDetail(e)">
<view class="ci-line">
<view>{{e.student_name||'-'}}{{e.student_gender||'-'}}
<block v-if="e.student_phone!=''">
<text>{{e.student_phone||'-'}}</text>
<image src="/subpackage/course/static/images/icon/phone.png" @click.stop="phoneCall(e.student_phone)"></image>
</block>
</view>
<image src="/subpackage/course/static/images/icon/arrow_black.png"></image>
</view>
<view class="ci-view">剩余课时{{e.course_period_residue||0}} {{e.course_period_nums||0}})</view>
<view class="ci-view"><text>有效期{{e.end_at || ''}}</text></view>
<view class="ci-btn" v-if="e.order_status==0||e.order_status==1">
<view hover-class="hover-active" @click.stop="resetBtn(e)" >转班</view>
</view>
</view>
</view>
<!-- 上课表 -->
<view class="cmd-schedule" v-if="curTabID==2">
<block v-if="pageInfo.sclass_period_time.length > 0">
<view class="cs-tab">
<view>课时</view>
<view>上课时间</view>
<view>上课状态</view>
<view>操作</view>
</view>
<view class="cs-list" v-for="(e,i) in pageInfo.sclass_period_time" :key="i">
<view class="cl-item">
<view>{{e.lesson_no|| '-'}}</view>
<view>{{e.period_date!=''?formatDate({date: e.period_date, partition: '.'}):'-'}}{{`${' '+e.period_start_time || ''}-${e.period_end_time || ''}`}}</view>
<view
:class="[!e.status?'ci-txt-green':'']"
>{{e.status?'已上课':'待上课'}}</view>
<view>
<view hover-class="hover-active" v-if="!e.status" @click="toChangeTime(e)">更改</view>
</view>
</view>
</view>
</block>
<view class="cmd-no" v-if="pageInfo.sclass_period_time.length == 0">
<image src="/subpackage/course/static/images/no_order.png"></image>
<view>暂未排课</view>
</view>
</view>
<!-- 作业列表 -->
<view class="cmd-task" v-if="curTabID==3">
<task-section ref="refTask" :taskInfo="pageInfo.work_list" taskType="finish" v-if="pageInfo.work_list.length>0"></task-section>
<view class="cmd-no" v-if="pageInfo.work_list.length==0">
<image src="/subpackage/course/static/images/no_order.png"></image>
<view>暂未布置作业</view>
</view>
</view>
<!-- 转班弹框 -->
<class-reset-modal
:isShowClass="isShowClass"
:info="pageInfo"
:canlist="classList"
@confirmReset="confirmReset"
@closeReset="isShowClass=false"
></class-reset-modal>
</view>
</template>
<script>
import util from '@/utils/util';
import boxServer from '../../../js/course_server';
import BOX_API from '../../../js/course_api';
import { mapState } from 'vuex';
import tabBar from '../../../components/tab_bar/tab_bar.vue';
import class_reset_modal from '../../../components/class_reset_modal/class_reset_modal.vue';
import task_section from '../../../components/task_section/task_section.vue';
const tabList=[
{name: '班级详情', id: 0}, {name: '班级学员', id: 1}, {name: '上课表', id: 2}, {name: '作业列表', id: 3},
];
export default {
components: {
'tab-bar': tabBar,
'class-reset-modal': class_reset_modal,
'task-section': task_section,
},
computed:{
...mapState([ 'brandInfo',]),
},
data() {
return {
tabList,
curTabID: 0,
isShowClass: false,
classList: [],
pageInfo: {
students: [], //
work_list: [], //
sclass_period_time: [], //
},
optionsId: -1,
resetInfo: {}, //
}
},
onLoad(options) {
this.optionsId = options.id
this.getDetail(options.id)
},
methods: {
formatDate: util.formatDate,
getDetail(id){
let { brandInfo } = this
util.showLoad();
boxServer.get({
url: BOX_API.sclassInfo,
data: {
brand_id: brandInfo.brand.id,
id,
},
failMsg: '加载失败!'
})
.then(res=>{
util.hideLoad();
let _res = res
_res.students = res.students || []
_res.work_list = res.work_list || []
_res.sclass_period_time = res.sclass_period_time || []
this.pageInfo = _res
this.getCanlist(res.course_id);
})
},
zh_sclass_status(status){
let _arr = ["成班中","进行中","已结束","成班失败"]
return _arr[status] || '-';
},
tabChange: util.debounce(function(e){
this.curTabID = e.id;
this.$nextTick(() => {
if(this.curTabID==3 && this.pageInfo.work_list.length>0)this.$refs.refTask.initDesc();
});
}, 300, true),
refreshList(){
this.curTabID = 0
this.getDetail(this.optionsId)
},
//
confirmClass(){
let { brandInfo, pageInfo } = this
util.showModal({
title: '是否确认成班',
content: '确认后代表用户报名成功,提前成立班级安排上课',
showCancel: true,
success: modalRes=>{
if(modalRes.confirm){
util.showLoad();
boxServer.get({
url: BOX_API.sclassConfirm,
data: {
brand_id: brandInfo.brand.id,
id: pageInfo.sclass_id,
},
failMsg: '加载失败!'
})
.then(res=>{
util.hideLoad();
util.showNone('操作成功!');
setTimeout(_=>{this.refreshList()}, 1200)
})
}
}
})
},
toStuDetail(item){
let { pageInfo } = this
let _query = item
_query["course_id"] = pageInfo.course_id
_query["course_name"] = pageInfo.course_name
// _query["sclass_name"] = pageInfo.sclass_name
// _query["sclass_nums"] = pageInfo.sclass_nums
_query["sclass_id"] = pageInfo.sclass_id
console.log("的点点滴滴:", _query)
util.routeTo(`/subpackage/course/pages/class_student_detail/class_student_detail?query=${util.jsonStr(_query)}`,'nT')
},
//
getCanlist(course_id){
let { brandInfo, pageInfo } = this
util.showLoad();
boxServer.get({
url: BOX_API.stuCanChangeSclass,
data: {
brand_id: brandInfo.brand.id,
course_id,
},
failMsg: '加载失败!'
})
.then(res=>{
util.hideLoad();
this.classList = res.list || []
})
},
//
resetBtn(item){
this.isShowClass = true
this.resetInfo.user_id = item.user_id
this.resetInfo.order_no = item.order_no
},
//
confirmReset(e){
// this.resetInfo["new_id"] = e.new_id
let { brandInfo, pageInfo, resetInfo } = this
util.showLoad();
boxServer.get({
url: BOX_API.resetStuSclass,
data: {
brand_id: brandInfo.brand.id,
old_id: pageInfo.sclass_id,
new_id: e.new_id,
user_id: resetInfo.user_id,
user_order_no: resetInfo.order_no,
},
failMsg: '加载失败!'
})
.then(res=>{
util.hideLoad();
util.showNone('操作成功!');
this.isShowClass = false
setTimeout(_=>{this.refreshList()}, 1200)
})
},
//
toChangeTime(item){
let { pageInfo } = this
let _query = {
brand_name: `${pageInfo.brand_name||''}${pageInfo.stadium_name||''}`,
course_name: pageInfo.course_name,
sclass_name: pageInfo.sclass_name,
sclass_id: pageInfo.sclass_id,
lesson_no: item.lesson_no,
period_date: item.period_date,
period_start_time: item.period_start_time,
period_end_time: item.period_end_time,
}
util.routeTo(`/subpackage/course/pages/class_time_change/class_time_change?query=${util.jsonStr(_query)}`,'nT');
},
phoneCall(mobile) {
let _phoneStr = mobile || ''
let _phoneArr = _phoneStr.split(',') || [];
uni.showActionSheet({
itemList: _phoneArr,
success: res =>{
uni.makePhoneCall({
phoneNumber: _phoneArr[res.tapIndex]
})
}
})
},
}
}
</script>
<style lang="scss">
@import '~style/public.scss';
.class-manage-detail{
position: relative;
padding: 102rpx 0 170rpx;
.cmd-tab{
position: fixed;
top: 0;
left: 0;
width: 750rpx;
border-bottom: 2rpx solid #F2F2F7;
z-index: 10;
}
.cmd-status{
margin-top: 24rpx;
padding: 24rpx 48rpx;
background-color: #FFFFFF;
color: #1A1A1A;
font-size: 28rpx;
line-height: 52rpx;
font-weight: 700;
.cs-green{
color: #009874;
}
.cs-gray{
color: #9C9C9F;
}
.cs-red{
color: #EA5061;
}
}
.cmd-section{
margin-top: 2rpx;
padding: 38rpx 48rpx 30rpx;
background-color: #FFFFFF;
>view{
&:first-child{
margin-bottom: 20rpx;
color: #9C9C9F;
font-size: 32rpx;
line-height: 44rpx;
}
&+view{
color: #1A1A1A;
font-size: 28rpx;
line-height: 52rpx;
>text{
color: #9C9C9F;
}
}
}
}
.cmd-fixed{
position: fixed;
bottom: 0;
left: 0;
padding: 22rpx 0;
width: 750rpx;
background-color: #FFFFFF;
border-top: 2rpx solid #F2F2F7;
>view{
margin: 0 auto;
padding: 34rpx 0;
width: 670rpx;
border-radius: 10rpx;
background-color: #009874;
color: #FFFFFF;
font-size: 32rpx;
line-height: 44rpx;
text-align: center;
}
}
.cmd-stu{
margin-top: 24rpx;
.cs-item{
position: relative;
flex-grow: 1;
margin-top: 2rpx;
padding: 26rpx 22rpx 20rpx;
background-color: #FFFFFF;
.ci-line{
margin: 0 26rpx;
@include centerFlex(space-between);
>view{
color: #1A1A1A;
font-size: 28rpx;
line-height: 52rpx;
>text{
margin: 0 30rpx;
}
>image{
flex-shrink: 0;
width: 32rpx;
height: 32rpx;
}
}
>image{
flex-shrink: 0;
width: 20rpx;
height: 20rpx;
}
}
.ci-view{
margin-left: 26rpx;
color: #1A1A1A;
font-size: 28rpx;
line-height: 52rpx;
>text{
color: #9C9C9F;
}
}
.ci-btn{
margin-top: 18rpx;
padding-top: 28rpx;
border-top: 2rpx solid #E5E5E5;
@include centerFlex(flex-end);
>view{
padding: 12rpx 0;
width: 156rpx;
border-radius: 6rpx;
border: 2rpx solid #009874;
color: #009874;
font-size: 28rpx;
line-height: 40rpx;
text-align: center;
}
}
}
}
.cmd-schedule{
padding-top: 24rpx;
border-top: 24rpx solid #F2F2F7;
.cs-tab{
margin: 0 24rpx;
border: 2rpx solid #E8E8E8;
background-color: #F6F8F8;
@include centerFlex(flex-start);
>view{
height: 110rpx;
color: #1A1A1A;
font-size: 28rpx;
text-align: center;
@include centerFlex(center);
&:first-child {
width: 130rpx;
}
&:nth-child(2){
width: 204rpx;
border-left: 2rpx solid #E8E8E8;
border-right: 2rpx solid #E8E8E8;
}
&:nth-child(3){
width: 204rpx;
border-right: 2rpx solid #E8E8E8;
}
&:nth-child(4){
width: 158rpx;
}
}
}
.cs-list{
.cl-item{
margin: 0 24rpx;
border-left: 2rpx solid #E8E8E8;
border-right: 2rpx solid #E8E8E8;
border-bottom: 2rpx solid #E8E8E8;
background-color: #FFFFFF;
@include centerFlex(flex-start);
>view{
height: 110rpx;
color: #1A1A1A;
font-size: 28rpx;
text-align: center;
@include centerFlex(center);
&:first-child {
width: 130rpx;
}
&:nth-child(2){
width: 204rpx;
border-left: 2rpx solid #E8E8E8;
border-right: 2rpx solid #E8E8E8;
}
&:nth-child(3){
width: 204rpx;
border-right: 2rpx solid #E8E8E8;
}
&:nth-child(4){
width: 158rpx;
>view{
padding: 4rpx 0;
width: 110rpx;
border-radius: 6rpx;
background-color: #009874;
color: #FFFFFF;
font-size: 28rpx;
font-weight: 700;
text-align: center;
line-height: 40rpx;
}
}
}
.ci-txt-green{
color: #009874;
}
}
}
}
.cmd-task{
margin-top: 24rpx;
}
.cmd-no{
display: flex;
flex-direction: row;
flex-direction: column;
flex-wrap: wrap;
justify-content: center;
align-items: center;
margin-top: 150rpx;
>image{
width: 346rpx;
height: 346rpx;
}
>view{
margin-top: 46rpx;
color: #9C9C9F;
font-size: 32rpx;
line-height: 44rpx;
text-align: center;
}
}
}
.cmd-content{
min-height: 100vh;
background-color: #FFFFFF;
}
</style>

236
src/subpackage/course/pages/manage_detail/private_reserve_detail/private_reserve_detail.vue

@ -0,0 +1,236 @@
<template>
<view class="private-reserve-detail">
<view class="prd-line">
<view>{{pageInfo.brand_name||''}}({{pageInfo.stadium_name||'-'}})</view>
<view :class="[pageInfo.status_text=='已上课'?'pl-gray':pageInfo.status_text=='已取消'?'pl-red':'pl-green']">{{pageInfo.status_text||'-'}}</view>
</view>
<view class="prd-section">
<view>预约单号<text>{{pageInfo.subscribe_no||''}}</text></view>
<view>预约时间<text>{{pageInfo.subscribe_at||''}}</text></view>
<!-- 已取消才显示 -->
<block v-if="pageInfo.status_text=='已取消'">
<view>取消时间<text>{{pageInfo.cancel_time||''}}</text></view>
<view>取消原因<text>{{pageInfo.cancel_reason||''}}</text></view>
</block>
</view>
<view class="prd-section">
<view>上课信息</view>
<view>上课时间<text>{{pageInfo.date||''}}{{pageInfo.week||'-'}} {{pageInfo.start_duration||''}}-{{pageInfo.end_duration||''}}</text></view>
<view>上课地点<text>{{pageInfo.addr||''}}</text></view>
<view>上课教练<text>{{pageInfo.coach_name||''}}</text></view>
<view>课程名称<text>{{pageInfo.course_name||''}}</text></view>
<view>课程类型<text>{{pageInfo.course_kind||''}}</text></view>
<view>课程节数<text>{{pageInfo.course_period_number_cur||0}}{{pageInfo.course_period_number||0}}</text></view>
</view>
<view class="prd-stu">
<view class="ps-tit">学员信息</view>
<view class="ps-line">
<view class="pl-info">
<view>{{pageInfo.student_name||'-'}}({{pageInfo.student_gender||'-'}})
<block v-if="pageInfo.student_phone!=''">
<text>{{pageInfo.student_phone||'-'}}</text>
<image src="/subpackage/course/static/images/icon/phone.png" @click="phoneCall(pageInfo.student_phone)"></image>
</block>
</view>
<view>预约时间{{pageInfo.subscribe_at||''}}</view>
</view>
<!-- 待上课才显示 -->
<view class="pl-btn" hover-class="hover-active" v-if="pageInfo.status_text=='待上课'" @click="isCancelClass=true">取消上课</view>
</view>
</view>
<cancel-class-modal
v-if="isCancelClass"
@reasonConfirm="reasonConfirm"
@reasonClose="isCancelClass=false"
></cancel-class-modal>
</view>
</template>
<script>
import util from '@/utils/util';
import boxServer from '../../../js/course_server';
import BOX_API from '../../../js/course_api';
import { mapState } from 'vuex';
import cancel_class_modal from '../../../components/cancel_class_modal/cancel_class_modal.vue';
export default {
components: {
'cancel-class-modal': cancel_class_modal,
},
computed:{
...mapState([ 'brandInfo',]),
},
data() {
return {
isCancelClass: false,
pageInfo: {},
optionsId: -1,
}
},
onLoad(options) {
this.optionsId = options.id
this.getDetail(options.id)
},
methods: {
getDetail(id){
let { brandInfo } = this
util.showLoad();
boxServer.get({
url: BOX_API.subscribeInfo,
data: {
brand_id: brandInfo.brand.id,
id,
},
failMsg: '加载失败!'
})
.then(res=>{
util.hideLoad();
this.pageInfo = res
})
},
// [/]
getCancelPabAc({ subscribe_no, reason}){
let { brandInfo } = this
let _data = {
brand_id: brandInfo.brand.id,
reason, //
subscribe_no,
}
util.showLoad();
boxServer.get({
url: BOX_API.cancelStuAc,
data: _data,
failMsg: '加载失败!'
})
.then(res=>{
util.hideLoad();
util.showNone('操作成功!');
setTimeout(_=>{
this.getDetail(this.optionsId)
util.previousPageFunction({
fnName: 'refreshList',
query: { isLoad: false},
});
}, 1200)
})
},
reasonConfirm(e){
this.isCancelClass = false
let { pageInfo } = this
this.getCancelPabAc({
subscribe_no: pageInfo.subscribe_no,
reason: e,
})
},
phoneCall(mobile) {
let _phoneStr = mobile || ''
let _phoneArr = _phoneStr.split(',') || [];
uni.showActionSheet({
itemList: _phoneArr,
success: res =>{
uni.makePhoneCall({
phoneNumber: _phoneArr[res.tapIndex]
})
}
})
},
}
}
</script>
<style lang="scss">
@import '~style/public.scss';
.private-reserve-detail{
.prd-line{
padding: 24rpx 44rpx 30rpx 30rpx;
background-color: #FFFFFF;
border-bottom: 2rpx solid #E5E5E5;
@include centerFlex(space-between);
>view{
font-size: 28rpx;
line-height: 40rpx;
&:first-child{
color: #1A1A1A;
font-weight: 700;
}
&:nth-child(2){
flex-shrink: 0;
margin-left: 10rpx;
}
}
.pl-green{
color: #009874;
}
.pl-gray{
color: #9C9C9F;
}
.pl-red{
color: #EA5061;
}
}
.prd-section{
margin-bottom: 2rpx;
padding: 25rpx 30rpx 30rpx;
background-color: #FFFFFF;
>view{
color: #9C9C9F;
font-size: 28rpx;
line-height: 52rpx;
>text{
color: #1A1A1A;
}
}
}
.prd-stu{
margin-top: 24rpx;
padding: 26rpx 30rpx 38rpx;
background-color: #FFFFFF;
.ps-tit{
color: #9A9A9D;
font-size: 28rpx;
line-height: 40rpx;
}
.ps-line{
margin-top: 26rpx;
@include centerFlex(space-between);
.pl-info{
>view{
&:first-child{
color: #333333;
font-size: 32rpx;
line-height: 44rpx;
>text{
margin: 0 28rpx 0 40rpx;
}
>image{
flex-shrink: 0;
width: 32rpx;
height: 32rpx;
}
}
&:nth-child(2){
margin-top: 6rpx;
color: #B2B2B2;
font-size: 28rpx;
line-height: 40rpx;
}
}
}
.pl-btn{
padding: 12rpx 0;
width: 140rpx;
border: 2rpx solid #EA5061;
border-radius: 6rpx;
color: #EA5061;
font-size: 28rpx;
line-height: 40rpx;
text-align: center;
}
}
}
}
</style>

323
src/subpackage/course/pages/manage_detail/student_course_detail/student_course_detail.vue

@ -0,0 +1,323 @@
<template>
<view class="student-course-detail" :class="[false?'scd-content':'']">
<view class="scd-section">
<view class="ss-status" :class="[pageInfo.order_status==2?'ss-gary':'']">{{pageInfo.order_status==1?'进行中':pageInfo.order_status==2?'已结束':''}}</view>
<view class="ss-view">学员姓名{{pageInfo.student_name || ''}}{{pageInfo.student_gender ||'-'}}</view>
<view class="ss-view">学员电话{{pageInfo.student_phone||''}}
<image src="/subpackage/course/static/images/icon/phone.png" @click="phoneCall(pageInfo.student_phone)"></image>
</view>
<view class="ss-view">剩余课时{{pageInfo.period_nums_surplus||0}}课时 {{pageInfo.period_nums||0}})</view>
<!-- 私教课大班课 才有安排上课 -->
<view class="ss-line" v-if="pageInfo.order_status==1&&(pageInfo.course_kind=='私教课'||pageInfo.course_kind=='大班课')">
<view hover-class="hover-active" @click="toArrangeClass">安排上课</view>
</view>
</view>
<view class="scd-tab">
<tab-bar :tabList="tabList" :curTabID="curTabID" @change="tabChange"></tab-bar>
</view>
<!-- 课程详情 -->
<view class="scd-info" v-if="curTabID==0">
<view class="si-tit">{{pageInfo.brand_name || ''}}({{pageInfo.stadium_name||'-'}})</view>
<view>{{pageInfo.course_name||''}}</view>
<view><text>课程类型</text>{{pageInfo.course_kind||''}}</view>
<view><text>总课时</text>{{pageInfo.period_nums||0}}</view>
<!-- 私教课大班课 -->
<block v-if="pageInfo.course_kind=='私教课'||pageInfo.course_kind=='大班课'">
<view><text>购买课时</text>{{pageInfo.period_nums_gm||0}}</view>
<view><text>赠送课时</text>{{pageInfo.period_nums_zs||0}}</view>
<view><text>有效期至</text>{{pageInfo.course_end||''}}</view>
<view><text>课时时长</text>{{pageInfo.period_time||'-'}}/</view>
<view><text>上课教练</text>{{pageInfo.course_coach||''}}</view>
<!-- 私教课才有上课内容 -->
<view v-if="pageInfo.course_kind=='私教课'"><text>上课内容</text></view>
<view><text>上课是否需要场地</text>不含场地费用</view>
</block>
<!-- 成班课 -->
<block v-if="pageInfo.course_kind=='成班课'">
<view><text>课时时长</text>{{pageInfo.period_time||'-'}}/</view>
<view><text>有效期至</text>{{pageInfo.course_end||''}}</view>
<view class="si-tit si-mar">班级信息</view>
<view><text>班级id</text>{{pageInfo.sclass_no||''}}</view>
<view><text>班级名称</text>{{pageInfo.sclass_name||''}}</view>
<view><text>班级人数</text>{{pageInfo.sclass_nums||0}}</view>
<view><text>上课教练</text>{{pageInfo.course_coach||''}}</view>
<view><text>上课地点</text>{{pageInfo.sclass_addr||''}}</view>
<view><text>课程日期</text>{{pageInfo.sclass_date||''}}</view>
</block>
</view>
<!-- 上课记录 -->
<view class="scd-record" v-if="curTabID==1">
<!-- 私教课大班课 -->
<view class="sr-list" v-for="(e,i) in pageInfo.subscribe_period_time" :key="i" v-if="pageInfo.course_kind=='私教课'||pageInfo.course_kind=='大班课'">
<view class="sl-item">
<view>
<view class="si-box">
<view>预约单号{{e.subscribe_no}}</view>
<view :class="[e.status_text=='已取消'?'sb-red':e.status_text=='已上课'?'sb-gray':'sb-green']">{{e.status_text||'-'}}</view>
</view>
<view class="si-time">{{e.created_at||'-'}} 预约</view>
</view>
<view class="si-wei">课程节数{{e.lesson_no||0}}{{e.lesson_no_total||0}}</view>
<view><text>上课时间</text>{{e.date||''}}{{e.week||'-'}} {{e.start_duration||''}}-{{e.end_duration||''}}</view>
<view><text>上课地点</text>{{e.addr||''}}</view>
<view><text>上课教练</text>{{e.coach_name||''}}</view>
<!-- 已取消显示 -->
<block v-if="e.status_text=='已取消'">
<view><text>取消时间</text>{{e.cancel_time||''}}</view>
<view><text>取消原因</text>{{e.cancel_reason||''}}</view>
</block>
</view>
</view>
<view class="sr-sclass" v-if="pageInfo.course_kind=='成班课'">
<sclass-record-section :recordInfo="pageInfo.sclass_period_time"></sclass-record-section>
</view>
</view>
<!-- 作业列表 -->
<view class="scd-task" v-if="curTabID==2">
<task-section ref="refTask" :taskInfo="pageInfo.student_work_list"></task-section>
</view>
</view>
</template>
<script>
import util from '@/utils/util';
import boxServer from '../../../js/course_server';
import BOX_API from '../../../js/course_api';
import { mapState } from 'vuex';
import tabBar from '../../../components/tab_bar/tab_bar.vue';
import sclass_record_section from '../../../components/sclass_record_section/sclass_record_section.vue';
import task_section from '../../../components/task_section/task_section.vue';
const tabList=[
{name: '课程详情', id: 0}, {name: '上课记录', id: 1}, {name: '作业列表', id: 2},
];
export default {
components: {
'tab-bar': tabBar,
'sclass-record-section': sclass_record_section,
'task-section': task_section,
},
computed:{
...mapState([ 'brandInfo',]),
},
data() {
return {
tabList,
curTabID: 0,
pageInfo: {
subscribe_period_time: [], //[/]
sclass_period_time: [], //[]
student_work_list: [], //
},
}
},
onLoad(options) {
this.getDetail(options.order_no)
},
methods: {
getDetail(order_no){
let { brandInfo } = this
util.showLoad();
boxServer.get({
url: BOX_API.stuInfo,
data: {
brand_id: brandInfo.brand.id,
order_no,
},
failMsg: '加载失败!'
})
.then(res=>{
util.hideLoad();
this.pageInfo = res
})
},
tabChange: util.debounce(function(e){
this.curTabID = e.id;
this.refreshList();
this.$nextTick(() => {
if(this.curTabID==2)this.$refs.refTask.initDesc();
});
}, 300, true),
refreshList(){
},
toArrangeClass(){
let { pageInfo } = this
util.routeTo(`/subpackage/course/pages/arrange_class/arrange_class?order_no=${pageInfo.order_no}`,'nT');
},
phoneCall(mobile) {
let _phoneStr = mobile || ''
let _phoneArr = _phoneStr.split(',') || [];
uni.showActionSheet({
itemList: _phoneArr,
success: res =>{
uni.makePhoneCall({
phoneNumber: _phoneArr[res.tapIndex]
})
}
})
},
}
}
</script>
<style lang="scss">
@import '~style/public.scss';
page{
background: #F2F2F7;
}
.student-course-detail{
.scd-section{
border-bottom: 26rpx solid #F2F2F7;
position: relative;
padding: 24rpx 24rpx 18rpx;
background-color: #FFFFFF;
.ss-status{
position: absolute;
top: 24rpx;
right: 24rpx;
color: #009874;
font-size: 28rpx;
line-height: 52rpx;
}
.ss-gary{
color: #9A9A9D;
}
.ss-view{
padding-right: 84rpx;
color: #1A1A1A;
font-size: 28rpx;
line-height: 52rpx;
@include centerFlex(flex-start);
>image{
margin-left: 30rpx;
flex-shrink: 0;
width: 32rpx;
height: 32rpx;
}
}
.ss-line{
margin-top: 18rpx;
padding: 28rpx 0 12rpx;
border-top: 2rpx solid #E5E5E5;
@include centerFlex(flex-end);
>view{
padding: 12rpx 0;
width: 156rpx;
border-radius: 6rpx;
background-color: #009874;
color: #FFFFFF;
font-size: 28rpx;
line-height: 40rpx;
text-align: center;
}
}
}
.scd-tab{
border-bottom: 2rpx solid #F2F2F7;
}
.scd-info{
padding: 26rpx 44rpx 30rpx;
background-color: #FFFFFF;
>view{
color: #1A1A1A;
font-size: 28rpx;
line-height: 52rpx;
>text{
color: #9C9C9F;
}
}
.si-tit{
margin: 0 2rpx 14rpx;
color: #1A1A1A;
font-size: 28rpx;
line-height: 40rpx;
font-weight: 700;
}
.si-view{
color: #9C9C9F;
font-size: 28rpx;
line-height: 52rpx;
>text{
color: #1A1A1A;
}
}
.si-mar{
margin-top: 40rpx;
}
}
.scd-record{
.sr-list{
margin-bottom: 24rpx;
.sl-item{
padding: 24rpx 44rpx 30rpx;
background-color: #FFFFFF;
>view{
&:first-child{
margin-bottom: 18rpx;
padding-bottom: 26rpx;
border-bottom: 2rpx solid #E8E8E8;
}
&+view{
color: #1A1A1A;
font-size: 28rpx;
line-height: 52rpx;
>text{
color: #9A9A9D;
}
}
}
.si-box{
@include centerFlex(space-between);
>view{
font-size: 28rpx;
line-height: 40rpx;
&:first-child{
color: #333333;
font-weight: 700;
}
&:nth-child(2){
flex-shrink: 0;
}
}
.sb-green{
color: #009874;
}
.sb-gray{
color: #9C9C9F;
}
.sb-red{
color: #EA5061;
}
}
.si-time{
margin-top: 12rpx;
color: #9A9A9D;
font-size: 24rpx;
line-height: 34rpx;
}
.si-wei{
font-weight: 700;
}
}
}
.sr-sclass{
padding: 20rpx 0 100rpx;
background-color: #FFFFFF;
}
}
.scd-task{
margin-top: 24rpx;
}
}
.scd-content{
min-height: 100vh;
background-color: #FFFFFF;
}
</style>

352
src/subpackage/course/pages/manage_list/manage_list.vue

@ -0,0 +1,352 @@
<template>
<view class="manage-list">
<view class="ml-head">
<store-name></store-name>
<block v-if="isShowOrder">
<view class="mh-view">
<image class="mv-icon" src="/static/images/icon/search.png"></image>
<input class="mv-ipt" :placeholder="plaTxt" confirm-type="search" v-model="searchText" @confirm="onSearch"/>
</view>
<tab-bar :tabList="tabList" :curTabID="curTabID" @change="tabChange"></tab-bar>
</block>
</view>
<block v-if="isShowOrder">
<view class="ml-list" v-for="(e,i) in orderList" :key="i" v-if="orderList.length > 0">
<student-course-item :orderInfo="e" v-if="typeId == '0-0'"></student-course-item>
<private-reserve-item :orderInfo="e" v-if="typeId == '0-1'" @priclassCancel="cancelCalss"></private-reserve-item>
<bclass-reserve-item :orderInfo="e" v-if="typeId == '0-2'" @bclassCancel="cancelCalss" @bclassConfirm="bclassConfirm"></bclass-reserve-item>
<class-manage-item :orderInfo="e" v-if="typeId == '0-3'"></class-manage-item>
</view>
<view class="no-item no-list" v-if="orderList.length == 0">
<image src="/subpackage/course/static/images/no_order.png"></image>
<view>{{ tipsText }}</view>
</view>
</block>
<view class="no-list" v-if="!isShowOrder">
<image src="/subpackage/course/static/images/no_order.png"></image>
<view>{{ tipsText }}</view>
</view>
</view>
</template>
<script>
import util from '@/utils/util';
import boxServer from '../../js/course_server';
import BOX_API from '../../js/course_api';
import { mapState } from 'vuex';
import tabBar from '../../components/tab_bar/tab_bar.vue';
import store_name from '../../components/store_name/store_name';
import student_course_item from '../../components/manage/student_course_item/student_course_item.vue';
import private_reserve_item from '../../components/manage/private_reserve_item/private_reserve_item.vue';
import bclass_reserve_item from '../../components/manage/bclass_reserve_item/bclass_reserve_item.vue';
import class_manage_item from '../../components/manage/class_manage_item/class_manage_item.vue';
export default {
components: {
'tab-bar': tabBar,
'store-name': store_name,
'student-course-item': student_course_item,
'private-reserve-item': private_reserve_item,
'bclass-reserve-item': bclass_reserve_item,
'class-manage-item': class_manage_item,
},
computed:{
...mapState([ 'brandInfo',]),
...mapState({
curStoreInfo: state => state.device.curStoreInfo,
}),
titleName(){
let { typeId } = this;
if(typeId == '0-0')return '学员管理';
if(typeId == '0-1')return '私教约课记录';
if(typeId == '0-2')return '大班约课记录';
if(typeId == '0-3')return '班级管理';
return '订单管理列表';
},
tipsText(){
let { typeId } = this;
if(typeId == '0-0')return '暂无学员';
if(typeId == '0-1')return '暂无约课记录';
if(typeId == '0-2')return '暂无约课记录';
if(typeId == '0-3')return '暂无班级';
return '';
},
plaTxt(){
let { typeId } = this;
if(typeId == '0-0')return '请输入课程名称/学员姓名/电话查找';
if(typeId == '0-1')return '请输入课程名称/学员姓名/电话查找';
if(typeId == '0-2')return '请输入教练姓名查找';
if(typeId == '0-3')return '请输入课程名称/班级名称查找';
return '';
},
tabList(){
let _list0 = [{name: '全部', id: 0, status: ''}, {name: '进行中', id: 1, status: 1}, {name: '已结束', id: 2, status: 2}, {name: '已退款', id: 3, status: 3}];
let _list1 = [{name: '全部', id: 0, status: 'all'}, {name: '待上课', id: 1, status: 'dsk'}, {name: '已上课', id: 2, status: 'ysk'}, {name: '已取消', id: 3, status: 'yqx'}];
let _list2 = [{name: '全部', id: 0, status: 'all'}, {name: '待确认', id: 1, status: 'dqr'}, {name: '待上课', id: 2, status: 'dsk'}, {name: '已上课', id: 3, status: 'ysk'}, {name: '已取消', id: 4, status: 'yqx'}];
let _list3 = [{name: '全部', id: 0, status: ''}, {name: '成班中', id: 1, status: 0}, {name: '进行中', id: 2, status: 1}, {name: '已结束', id: 3, status: 2}, {name: '失败', id: 4, status: 3}];
let { typeId } = this;
if(typeId == '0-0')return _list0;
if(typeId == '0-1')return _list1;
if(typeId == '0-2')return _list2;
if(typeId == '0-3')return _list3;
return [];
},
},
watch: {
curStoreInfo(newVal, oldVal) {
this.orderList = [];
// console.log("", newVal)
this.storeInfo = newVal
// this.$nextTick(_=>{
// })
this.getOrderList({})
}
},
data() {
return {
typeId: "",
curTabID: 0,
curStatus: "",
searchText: "",
storeInfo: {},
isShowOrder: false,
orderList: [],
page: 1,
}
},
async onLoad(options){
// let _query = util.jsonPar(options.query);
// this.optionsQuery = _query
try{
util.showLoad();
let _brandInfo = await this.$store.dispatch('getBrandInfo');
await this.$store.dispatch('getStoreList');
util.hideLoad();
this.typeId = options.type_id || ''
this.storeInfo.id = this.curStoreInfo.id || ''
this.$nextTick(_=>{
uni.setNavigationBarTitle({
title: this.titleName
})
this.getOrderList({})
})
}catch(err){
util.hideLoad();
}
},
onReachBottom(){
let { page } = this;
this.getOrderList({
page: ++page
})
},
methods: {
tabChange: util.debounce(function(e){
this.curTabID = e.id;
this.curStatus = e.status
this.refreshList();
}, 300, true),
refreshList(){
this.page = 1;
this.orderList = [];
this.getOrderList({});
},
//
onSearch(){
this.page = 1
this.orderList = []
this.getOrderList({})
},
getApi(){
let { typeId } = this
if(typeId == '0-0')return BOX_API.stuCourse; //
if(typeId == '0-1')return BOX_API.subscribePri; //
if(typeId == '0-2')return BOX_API.subscribeBclass; //
if(typeId == '0-3')return BOX_API.sclassManage; //
},
getOrderList({page=1, page_size=20}){
let { brandInfo, storeInfo, curTabID, typeId, curStatus, searchText } = this
let _data = {
page,
page_size,
stadium_id: storeInfo.id,
brand_id: brandInfo.brand.id,
}
if(searchText!='')_data["keyword"] = searchText;
if(typeId=='0-0')_data["order_status"] = curStatus;
if(typeId!='0-0')_data["status"] = curStatus;
util.showLoad();
boxServer.get({
url: this.getApi(),
data: _data,
failMsg: '加载失败!'
})
.then(res=>{
util.hideLoad();
let _list = res.list || [];
if(page == 1){
this.orderList = _list;
if(curTabID==0 && this.orderList.length==0)this.isShowOrder = false;
else this.isShowOrder = true;
return;
}
if(_list.length<=0)return util.showNone('没有更多!');
this.page = page;
this.orderList = [...this.orderList, ...res.list];
})
},
//
cancelCalss(e){
if(e.course_kind=='私教课'){
this.getCancelPabAc({
course_kind: e.course_kind,
subscribe_no: e.subscribe_no,
reason: e.reason,
})
return;
}
if(e.course_kind=='大班课'){
this.getCancelPabAc({
course_kind: e.course_kind,
id: e.id,
reason: e.reason,
})
return;
}
},
// [/]
getCancelPabAc({ course_kind, subscribe_no, id, reason}){
let { brandInfo } = this
let _data = {
brand_id: brandInfo.brand.id,
reason, //
}
if(course_kind=='私教课')_data["subscribe_no"] = subscribe_no;
if(course_kind=='大班课')_data["id"] = id;
util.showLoad();
boxServer.get({
url: course_kind=='大班课'? BOX_API.cancelBclassAc:course_kind=='私教课'? BOX_API.cancelStuAc:'',
data: _data,
failMsg: '加载失败!'
})
.then(res=>{
util.hideLoad();
util.showNone('操作成功!');
setTimeout(_=>{ this.refreshList() }, 1200)
})
},
//
bclassConfirm(e){
util.showModal({
title: '提示',
content: '是否确认上课?',
showCancel: true,
success: modalRes=>{
if(modalRes.confirm){
this.getBclassAc({subscribe_no: e})
}
}
})
},
//
getBclassAc({ subscribe_no}){
let { brandInfo } = this
util.showLoad();
boxServer.get({
url: BOX_API.setBclassAc,
data: {
brand_id: brandInfo.brand.id,
subscribe_no, //
},
failMsg: '加载失败!'
})
.then(res=>{
util.hideLoad();
util.showNone('操作成功!');
setTimeout(_=>{ this.refreshList() }, 1200)
})
},
}
}
</script>
<style lang="scss">
@import '~style/public.scss';
page{
background: #F2F2F7;
}
.manage-list{
position: relative;
padding-top: 292rpx;
padding-bottom: 24rpx;
.ml-head{
position: fixed;
top: 0;
left: 0;
width: 750rpx;
background-color: #FFFFFF;
border-bottom: 2rpx solid #F2F2F7;
z-index: 6;
.mh-view{
margin: 0 24rpx;
padding: 0 20rpx;
flex-grow: 1;
height: 92rpx;
border-radius: 10rpx;
background-color: #F2F2F7;
@include centerFlex(flex-start);
.mv-icon{
margin-right: 20rpx;
flex-shrink: 0;
width: 40rpx;
height: 40rpx;
}
.mv-ipt{
flex-grow: 1;
color: #333;
font-size: 32rpx;
line-height: 44rpx;
}
}
}
.ml-list{
margin-top: 24rpx;
}
.no-item{
margin-top: 128rpx;
}
.no-list{
display: flex;
flex-direction: row;
flex-direction: column;
flex-wrap: wrap;
justify-content: center;
align-items: center;
>image{
width: 346rpx;
height: 346rpx;
}
>view{
margin: 46rpx 0;
color: #9C9C9F;
font-size: 32rpx;
line-height: 44rpx;
text-align: center;
}
}
}
</style>

138
src/subpackage/course/pages/task_detail/task_detail.vue

@ -0,0 +1,138 @@
<template>
<view class="task-detail">
<view class="td-info">
<view class="td-txt">布置作业时间{{formatDate({date: pageInfo.created_at, partition: '/'}) || '-'}}</view>
<view class="td-txt">发布人{{pageInfo.work_coach_name || '-'}}</view>
<view class="td-txt td-tit">作业内容</view>
<view class="td-txt">{{pageInfo.work_content || '-'}}</view>
<view class="td-line">
<view>视频链接{{pageInfo.work_video || '无'}}</view>
<view @click="copyOrder(pageInfo.work_video)">复制</view>
</view>
<image class="td-img" mode="aspectFill" v-for="(e,i) in pageInfo.work_imgs" :key="i" :src="e || ''" @tap="previewImageWork(e)"></image>
</view>
<view class="td-info">
<view class="td-txt">作业提交时间{{pageInfo.student_work_at!=''?formatDate({date: pageInfo.student_work_at, partition: '/'}) : ''}}</view>
<view class="td-txt">提交人{{pageInfo.student_name || '-'}}</view>
<view class="td-txt td-tit">完成情况</view>
<view class="td-txt">{{pageInfo.student_work_content ||'无'}}</view>
<view class="td-line">
<view>视频链接{{pageInfo.student_work_video || '无'}}</view>
<view @click="copyOrder(pageInfo.student_work_video)">复制</view>
</view>
<image class="td-img" mode="aspectFill" v-for="(e,i) in pageInfo.student_work_imgs" :key="i" :src="e || ''" @tap="previewImageStu(e)"></image>
</view>
</view>
</template>
<script>
import util from '@/utils/util';
import boxServer from '../../js/course_server';
import BOX_API from '../../js/course_api';
import { mapState } from 'vuex';
export default {
computed:{
...mapState([ 'brandInfo',]),
},
data() {
return {
pageInfo: {},
}
},
async onLoad(options){
// let _query = util.jsonPar(options.query);
// this.pageInfo = _query
this.getWorkInfo(options.id)
},
methods: {
formatDate: util.formatDate,
copyOrder(data){
uni.setClipboardData({ data })
},
previewImageWork(img){
uni.previewImage({
current: img,
urls: this.pageInfo.work_imgs
})
},
//
previewImageStu(img) {
// var current = e.target.dataset.src
uni.previewImage({
current: img,
urls: this.pageInfo.student_work_imgs
})
},
// -
getWorkInfo(id){
let { brandInfo } = this
util.showLoad();
boxServer.get({
url: BOX_API.stuWorkInfo,
data: {
brand_id: brandInfo.brand.id,
id,
},
failMsg: '加载失败!'
})
.then(res=>{
util.hideLoad();
this.pageInfo = res
})
},
}
}
</script>
<style lang="scss">
@import '~style/public.scss';
// page{
// background: #F2F2F7;
// }
.task-detail{
.td-info{
margin-bottom: 12rpx;
padding: 24rpx 0 30rpx;
background-color: #FFFFFF;
.td-txt{
margin: 0 60rpx 0 24rpx;
color: #1A1A1A;
font-size: 28rpx;
line-height: 40rpx;
}
.td-tit{
font-weight: 700;
margin: 44rpx 24rpx 20rpx;
}
.td-line{
margin: 30rpx 60rpx 0 26rpx;
flex-grow: 1;
padding: 30rpx 4rpx 6rpx;
border-top: 2rpx solid #D8D8D8;
@include centerFlex(flex-start);
>view{
font-size: 28rpx;
&:first-child{
color: #9A9A9D;
line-height: 40rpx;
@include textHide(1);
}
&:nth-child(2){
margin-left: 20rpx;
flex-shrink: 0;
color: #009874;
}
}
}
.td-img{
margin: 24rpx 16rpx 0 30rpx;
display: inline-block;
width: 200rpx;
height: 200rpx;
border-radius: 10rpx;
}
}
}
</style>

146
src/subpackage/course/pages/task_finish_list/task_finish_list.vue

@ -0,0 +1,146 @@
<template>
<view class="task-finish-list">
<block v-if="workList.length>0">
<view class="tfl-box">
<view>布置作业时间{{ pageInfo.created_at!=''?formatDate({date: pageInfo.created_at, partition: '/'}) : '-'}}</view>
<view>发布人{{pageInfo.work_coach_name||'-'}}</view>
</view>
<view class="tfl-list" v-for="(e,i) in workList" :key="i">
<view class="tl-item" @click="toDetail(e)">
<view class="ti-info">
<view>{{e.student_name||'-'}}{{e.student_gender||'-'}}</view>
<view>{{e.student_phone ||'-'}}</view>
</view>
<view class="ti-section">
<view v-if="e.work_status==1">{{e.student_work_at!=''?formatDate({date: e.student_work_at,}) :'-'}}</view>
<view class="ts-line">
<view :class="[e.work_status==1?'':'tl-txt']">{{e.work_status==1?'已完成':'未完成'}}</view>
<image src="/subpackage/course/static/images/icon/arrow_black.png"></image>
</view>
</view>
</view>
</view>
<!-- <view class="fixed-btn">
<view hover-class="hover-active" @click="batchRemind">批量提醒完成</view>
</view> -->
</block>
</view>
</template>
<script>
import util from '@/utils/util';
import boxServer from '../../js/course_server';
import BOX_API from '../../js/course_api';
import { mapState } from 'vuex';
export default {
computed:{
...mapState([ 'brandInfo',]),
},
data() {
return {
pageInfo: {},
workList: [],
}
},
onLoad(options) {
let { work_number } = options
this.pageInfo = options
this.$nextTick(_=>{
this.getClassWork()
})
},
methods: {
formatDate: util.formatDate,
// -
getClassWork(){
let { brandInfo } = this
let { work_number } = this.pageInfo
util.showLoad();
boxServer.get({
url: BOX_API.sclassStuWork,
data: {
brand_id: brandInfo.brand.id,
work_number,
},
failMsg: '加载失败!'
})
.then(res=>{
util.hideLoad();
let _list = res || []
this.workList = _list
if(_list.length>0){
this.pageInfo["created_at"] = _list[0].created_at
this.pageInfo["work_coach_name"] = _list[0].work_coach_name
}
})
},
toDetail(item){
util.routeTo(`/subpackage/course/pages/task_detail/task_detail?id=${item.id}`,'nT')
},
//
batchRemind(){
util.showNone('开发中!');
},
}
}
</script>
<style lang="scss">
@import '~style/public.scss';
page{
background: #F2F2F7;
}
.task-finish-list{
position: relative;
padding-bottom: 160rpx;
.tfl-box{
flex-grow: 1;
padding: 24rpx 22rpx;
background-color: #FFFFFF;
border-bottom: 12rpx solid #F2F2F7;
>view{
color: #1A1A1A;
font-size: 28rpx;
line-height: 52rpx;
}
}
.tfl-list{
.tl-item{
padding: 20rpx 36rpx 20rpx 46rpx;
background-color: #FFFFFF;
border-bottom: 2rpx solid #F2F2F7;
@include centerFlex(space-between);
.ti-info{
>view{
color: #1A1A1A;
font-size: 28rpx;
line-height: 52rpx;
}
}
.ti-section{
color: #9C9C9F;
font-size: 28rpx;
line-height: 52rpx;
.ts-time{
}
.ts-line{
@include centerFlex(flex-end);
>image{
margin: 0 2rpx 0 20rpx;
flex-shrink: 0;
width: 20rpx;
height: 20rpx;
}
.tl-txt{
color: #EA5061;
}
}
}
}
}
}
</style>

BIN
src/subpackage/course/static/images/icon/arrow_b2.png

After

Width: 40  |  Height: 40  |  Size: 251 B

BIN
src/subpackage/course/static/images/icon/arrow_black.png

After

Width: 20  |  Height: 20  |  Size: 624 B

BIN
src/subpackage/course/static/images/icon/arrow_green.png

After

Width: 24  |  Height: 24  |  Size: 653 B

BIN
src/subpackage/course/static/images/icon/arrow_white.png

After

Width: 28  |  Height: 28  |  Size: 563 B

BIN
src/subpackage/course/static/images/icon/calendar.png

After

Width: 34  |  Height: 34  |  Size: 786 B

BIN
src/subpackage/course/static/images/icon/close_gray.png

After

Width: 34  |  Height: 34  |  Size: 667 B

BIN
src/subpackage/course/static/images/icon/phone.png

After

Width: 32  |  Height: 32  |  Size: 1.1 KiB

BIN
src/subpackage/course/static/images/icon/triangle.png

After

Width: 22  |  Height: 22  |  Size: 428 B

BIN
src/subpackage/course/static/images/no_order.png

After

Width: 346  |  Height: 346  |  Size: 14 KiB

BIN
src/subpackage/course/static/images/tab/tab_0_0.png

After

Width: 52  |  Height: 52  |  Size: 2.1 KiB

BIN
src/subpackage/course/static/images/tab/tab_0_1.png

After

Width: 52  |  Height: 52  |  Size: 2.5 KiB

BIN
src/subpackage/course/static/images/tab/tab_0_2.png

After

Width: 52  |  Height: 52  |  Size: 2.4 KiB

BIN
src/subpackage/course/static/images/tab/tab_0_3.png

After

Width: 52  |  Height: 52  |  Size: 2.2 KiB

6
src/subpackage/device/components/order/organize_detail/organize_detail.vue

@ -34,7 +34,8 @@
<view class="tb-title">约玩信息</view> <view class="tb-title">约玩信息</view>
<view class="tb-line"> <view class="tb-line">
<view>约玩主题<text>{{ orderInfo.theme || '-' }}</text></view> <view>约玩主题<text>{{ orderInfo.theme || '-' }}</text></view>
<block v-if="orderInfo.type == 'Main'">
<!-- 20211028 测试 参与也要显示订场信息 -->
<block v-if="orderInfo.type == 'Main' || orderInfo.type == 'Sub'">
<view class="yw-place-box" v-if="orderInfo.original_order&&orderInfo.original_order.sessions"> <view class="yw-place-box" v-if="orderInfo.original_order&&orderInfo.original_order.sessions">
<view class="yw-title">预定场地</view> <view class="yw-title">预定场地</view>
<view class="yw-place"> <view class="yw-place">
@ -43,8 +44,8 @@
</view> </view>
</view> </view>
</view> </view>
<view>订场费用<text>{{ orderInfo.original_order.pay_amount || 0 }}</text></view>
</block> </block>
<view v-if="orderInfo.type == 'Main'">订场费用<text>{{ orderInfo.original_order.pay_amount || 0 }}</text></view>
<view v-if="orderInfo.type == 'Sub'">报名费用<text>{{orderInfo.price_per_person || 0}}</text></view> <view v-if="orderInfo.type == 'Sub'">报名费用<text>{{orderInfo.price_per_person || 0}}</text></view>
</view> </view>
@ -267,7 +268,6 @@ export default {
flex-shrink: 0; flex-shrink: 0;
width: 40rpx; width: 40rpx;
height: 40rpx; height: 40rpx;
background-color: skyblue;
} }
>view{ >view{

2
src/subpackage/order/js/api.js

@ -9,7 +9,7 @@ export const ORDER_API = {
userValueCardRecharge:`${ORIGIN}/admin/userValueCard/recharge`, // 用户储值卡-充值_copy userValueCardRecharge:`${ORIGIN}/admin/userValueCard/recharge`, // 用户储值卡-充值_copy
momentOrderInfo:`${ORIGIN}/admin/perfect/moment/order/get`, // 后台-高光时刻订单详情_copy momentOrderInfo:`${ORIGIN}/admin/perfect/moment/order/get`, // 后台-高光时刻订单详情_copy
hardwareOrderInfo:`${ORIGIN}/admin/assistant/hardware/order/get`, // 硬件管理-订单详情_copy hardwareOrderInfo:`${ORIGIN}/admin/assistant/hardware/order/get`, // 硬件管理-订单详情_copy
rentballRefundDeposit:`${ORIGIN}/admin/stadium/rentball/order/refundDeposit`, // 退押金-后台
rentballRefundDeposit:`${ORIGIN}/admin/assistant/rentball/refundDeposit`, // 退押金-后台
hardwareOrderGet:`${ORIGIN}/admin/assistant/hardware/order/get`, // 硬件订单详情 储物柜/售货柜/水阀/咖啡机/租售柜 hardwareOrderGet:`${ORIGIN}/admin/assistant/hardware/order/get`, // 硬件订单详情 储物柜/售货柜/水阀/咖啡机/租售柜
lockEndBill:`${ORIGIN}/admin/stadium/locker/endBill`, // 储物柜-结束计费 lockEndBill:`${ORIGIN}/admin/stadium/locker/endBill`, // 储物柜-结束计费
currentUser:`${ORIGIN}/admin/assistant/currentUser`, // 获取当前用户信息 currentUser:`${ORIGIN}/admin/assistant/currentUser`, // 获取当前用户信息

12
src/subpackage/order/pages/club_rental/detail/detail.vue

@ -196,6 +196,16 @@ export default {
}) })
}, },
depositRefundBtn: util.debounce(function(){ depositRefundBtn: util.debounce(function(){
util.showModal({
title: '提示',
content: '是否确认退回押金',
success: mRes=>{
if(mRes.confirm)this.refundReq();
}
})
}, 300, true),
refundReq(){
util.showLoad(); util.showLoad();
let { orderInfo } = this; let { orderInfo } = this;
server.post({ server.post({
@ -215,7 +225,7 @@ export default {
} }
}) })
.catch(util.hideLoad) .catch(util.hideLoad)
}, 300, true)
}
}, },
} }
</script> </script>

10
src/subpackage/order/pages/devices/detail/detail.vue

@ -4,8 +4,8 @@
<o-header <o-header
:logo='orderInfo.stadium_logo' :logo='orderInfo.stadium_logo'
:source='orderInfo.stadium_name' :source='orderInfo.stadium_name'
:phone='orderInfo.phone'
:name='orderInfo.name'
:phone='orderInfo.mobile'
:name='orderInfo.nickname'
:status='pay_txt(orderInfo.pay_status)' :status='pay_txt(orderInfo.pay_status)'
></o-header> ></o-header>
<view class="rent-info dcd-box"> <view class="rent-info dcd-box">
@ -27,9 +27,9 @@
</a-line> </a-line>
<view class="ri-line"></view> <view class="ri-line"></view>
<view class="ri-price"> <view class="ri-price">
<s-line :keyname="'积分抵扣'" :value="orderInfo.deduction_amount || '0'"></s-line>
<s-line :keyname="'折扣金额'" :value="orderInfo.discount_amount || '0'"></s-line>
<s-line :keyname="'优惠券优惠'" :value="orderInfo.coupons_amount || '0'"></s-line>
<s-line :keyname="'积分抵扣'" :value="'¥' + (orderInfo.deduction_amount || '0')"></s-line>
<s-line :keyname="'折扣金额'" :value="'¥' + (orderInfo.discount_amount || '0')"></s-line>
<s-line :keyname="'优惠券优惠'" :value="'¥' + (orderInfo.coupons_amount || '0')"></s-line>
<view class="rp-total"><text>合计支付</text>{{orderInfo.pay_amount || '0'}}</view> <view class="rp-total"><text>合计支付</text>{{orderInfo.pay_amount || '0'}}</view>
</view> </view>
</view> </view>

8
src/subpackage/order/pages/mall/detail/detail.vue

@ -81,8 +81,8 @@
<view class="ms-fixed-bar"> <view class="ms-fixed-bar">
<view class="mfb-btns"> <view class="mfb-btns">
<!-- <view>查看退款</view> --> <!-- <view>查看退款</view> -->
<view v-if="orderInfo.status == 1" class="red" @click="toRefund">主动退款</view>
<view v-if="orderInfo.status == 1" class="green" @click="toSendOut">发货</view>
<view v-if="isRufundBtn" class="red" @click="toRefund">主动退款</view>
<view v-if="orderInfo.status == 1&&orderInfo.after_sale_status == 0" class="green" @click="toSendOut">发货</view>
</view> </view>
</view> </view>
</view> </view>
@ -98,6 +98,10 @@ import server from '../../../js/server';
import util from '../../../../../utils/util'; import util from '../../../../../utils/util';
export default { export default {
computed: { computed: {
isRufundBtn(){
let { orderInfo } = this;
return (orderInfo.status!=6 || orderInfo.status != 7) && orderInfo.after_sale_status == 0
},
order_custom(){ order_custom(){
let { orderInfo } = this; let { orderInfo } = this;
if(orderInfo&&orderInfo.product_order_custom)return (orderInfo.product_order_custom || {}) if(orderInfo&&orderInfo.product_order_custom)return (orderInfo.product_order_custom || {})

25
src/subpackage/order/pages/mall/refund_operate/refund_operate.vue

@ -7,10 +7,13 @@
<view>{{ refundLs[0].product_name || '-' }}</view> <view>{{ refundLs[0].product_name || '-' }}</view>
</view> </view>
<view class="rgi-list" v-else> <view class="rgi-list" v-else>
<view class="rl-item" v-for="(e, i) in refundLs" :key="i">
<image mode="aspectFill" :src="e.product_imgs"></image>
<view>{{ e.product_name || '-' }}</view>
</view>
<block v-for="(e, i) in refundLs" :key="i">
<view class="rl-item" v-if="i<=2">
<image mode="aspectFill" :src="e.product_imgs"></image>
<view>{{ e.product_name || '-' }}</view>
</view>
</block>
</view> </view>
<view class="rgi-total"> <view class="rgi-total">
@ -19,8 +22,8 @@
</view> </view>
</view> </view>
<view class="ro-box ro-refund-info"> <view class="ro-box ro-refund-info">
<view class="rri-txt">最大可退金额 <text>{{ orderInfo.pay_amount || 0 }}</text>含运费{{ orderInfo.product_logistics_price || 0 }}</view>
<view class="rri-txt">可退积分{{ orderInfo.deduction_integral || 0 }} 积分</view>
<view class="rri-txt">最大可退金额 <text>{{ orderInfo.extension.refundable_amount || 0 }}</text>含运费{{ orderInfo.product_logistics_price || 0 }}</view>
<view class="rri-txt">可退积分{{ orderInfo.extension.refundable_integral || 0 }} 积分</view>
<!-- 不支持部分退款 --> <!-- 不支持部分退款 -->
<!-- <view class="rri-line"> <!-- <view class="rri-line">
<view class="rl-name"><text>*</text>退款金额</view> <view class="rl-name"><text>*</text>退款金额</view>
@ -69,7 +72,9 @@ export default {
}, },
data(){ data(){
return { return {
orderInfo: {},
orderInfo: {
extension: {}
},
selectedLs: '', selectedLs: '',
refundAmount: '', refundAmount: '',
refundIntegral: '', refundIntegral: '',
@ -91,8 +96,8 @@ export default {
brand_id: orderInfo.brand_id, brand_id: orderInfo.brand_id,
order_no: orderInfo.order_no, order_no: orderInfo.order_no,
product_cart_id: orderInfo.product_order_goods.map(ele=>ele.product_cart_id).join(','), product_cart_id: orderInfo.product_order_goods.map(ele=>ele.product_cart_id).join(','),
integral: orderInfo.integral,
amount: orderInfo.amount,
integral: orderInfo.extension.refundable_integral || 0,
amount: orderInfo.extension.refundable_amount || 0,
}) })
} }
}) })
@ -120,7 +125,7 @@ export default {
util.hideLoad(); util.hideLoad();
if(res.data.code == 0){ if(res.data.code == 0){
util.showNone(res.data.message || '操作成功!'); util.showNone(res.data.message || '操作成功!');
setInterval(util.routeTo, 1200);
setTimeout(util.routeTo, 1200);
}else{ }else{
util.showNone(res.data.message || '操作失败!'); util.showNone(res.data.message || '操作失败!');
} }

12
src/subpackage/order/pages/mall/send_out/send_out.vue

@ -42,7 +42,7 @@
<view class="og-list"> <view class="og-list">
<view class="ol-item" v-for="(e, i) in waitdeliverLs" :key="i" @click="goodsItemClick(e)"> <view class="ol-item" v-for="(e, i) in waitdeliverLs" :key="i" @click="goodsItemClick(e)">
<view class="oi-select"> <view class="oi-select">
<image v-if="selectedSendOutIds.includes(e.product_id)" mode="aspectFit" src="/subpackage/order/static/images/selected.png"></image>
<image v-if="selectedSendOutIds.includes(e.product_cart_id)" mode="aspectFit" src="/subpackage/order/static/images/selected.png"></image>
</view> </view>
<image mode="aspecfFill" :src="e.product_imgs"></image> <image mode="aspecfFill" :src="e.product_imgs"></image>
<view class="oi-info"> <view class="oi-info">
@ -177,14 +177,14 @@ export default {
// id // id
selectedSendOutIds(){ selectedSendOutIds(){
let { selectedSendOutLs } = this; let { selectedSendOutLs } = this;
return selectedSendOutLs.map(e=>e.product_id);
return selectedSendOutLs.map(e=>e.product_cart_id);
}, },
// //
isSelectedAllSendOut(){ isSelectedAllSendOut(){
let { selectedSendOutIds, waitdeliverLs } = this; let { selectedSendOutIds, waitdeliverLs } = this;
let _unLs = []; // let _unLs = []; //
if(!waitdeliverLs.length)return false; if(!waitdeliverLs.length)return false;
_unLs = waitdeliverLs.filter(ele => !selectedSendOutIds.includes(ele.product_id));
_unLs = waitdeliverLs.filter(ele => !selectedSendOutIds.includes(ele.product_cart_id));
return _unLs.length == 0; return _unLs.length == 0;
} }
}, },
@ -230,10 +230,10 @@ export default {
this.getInfo(order_no); this.getInfo(order_no);
}, },
confirmSendOutBtn: util.debounce(function(){ confirmSendOutBtn: util.debounce(function(){
let { order_no, selectedSendOutLs, selectedWarehouse, sendOutMethod, curlogisticsName, logisticsOrderNum, sendOutRemark } = this;
let { order_no, selectedSendOutLs, selectedSendOutIds, selectedWarehouse, sendOutMethod, curlogisticsName, logisticsOrderNum, sendOutRemark } = this;
let _query = { let _query = {
order_no, order_no,
ids: selectedSendOutLs.map(ele=>ele.product_cart_id),
ids: selectedSendOutIds,
esh_type: selectedWarehouse.erp_type, esh_type: selectedWarehouse.erp_type,
esh_id: selectedWarehouse.erp_id, esh_id: selectedWarehouse.erp_id,
logistics_type: sendOutMethod, logistics_type: sendOutMethod,
@ -285,7 +285,7 @@ export default {
}, },
goodsItemClick(e){ goodsItemClick(e){
let { selectedSendOutIds, selectedSendOutLs } = this; let { selectedSendOutIds, selectedSendOutLs } = this;
if(selectedSendOutIds.includes(e.product_id))return this.selectedSendOutLs = selectedSendOutLs.filter(ele=>ele.product_id !=e.product_id);
if(selectedSendOutIds.includes(e.product_cart_id))return this.selectedSendOutLs = selectedSendOutLs.filter(ele=>ele.product_cart_id !=e.product_cart_id);
this.selectedSendOutLs = [ ...selectedSendOutLs, e]; this.selectedSendOutLs = [ ...selectedSendOutLs, e];
}, },
tabChange(idx){ tabChange(idx){

6
src/subpackage/order/pages/rent_and_sale/detail/detail.vue

@ -42,9 +42,9 @@
<block slot="name">产生费用</block> <block slot="name">产生费用</block>
</a-line> </a-line>
<block v-if="orderInfo.pay_status == 2"> <block v-if="orderInfo.pay_status == 2">
<s-line :keyname="'积分抵扣'" :value="'¥' + (orderInfo.deduction_amount || '0')"></s-line>
<s-line :keyname="'折扣金额'" :value="'¥' + (orderInfo.discount_amount || '0')"></s-line>
<s-line :keyname="'优惠券优惠'" :value="'¥'+ (orderInfo.coupons_amount || '0')"></s-line>
<s-line :keyname="'积分抵扣'" :value="'-¥' + (orderInfo.deduction_amount || '0')"></s-line>
<s-line :keyname="'折扣金额'" :value="'-¥' + (orderInfo.discount_amount || '0')"></s-line>
<s-line :keyname="'优惠券优惠'" :value="'-¥'+ (orderInfo.coupons_amount || '0')"></s-line>
<view class="rpi-total"><text>合计支付</text>{{ orderInfo.rent_amount || '0' }}</view> <view class="rpi-total"><text>合计支付</text>{{ orderInfo.rent_amount || '0' }}</view>
<view class="ras-border"></view> <view class="ras-border"></view>
<view class="rpi-refund-info"> <view class="rpi-refund-info">

2
src/subpackage/order/pages/spectacular_monent/detail/detail.vue

@ -18,7 +18,7 @@
<a-line :value="orderInfo.price_type_text || '-'"> <a-line :value="orderInfo.price_type_text || '-'">
<block slot="name">产品名称</block> <block slot="name">产品名称</block>
</a-line> </a-line>
<block v-if="orderInfo.order_type == 0">
<block v-if="orderInfo.order_type == 0 || orderInfo.order_type == 2">
<a-line :value="orderInfo.venue_name || '-'"> <a-line :value="orderInfo.venue_name || '-'">
<block slot="name">场地</block> <block slot="name">场地</block>
</a-line> </a-line>

Loading…
Cancel
Save