You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
588 lines
16 KiB
588 lines
16 KiB
<!--新增订单表单弹窗-->
|
|
<template>
|
|
<view class="order-form-popup">
|
|
<view class="popup-header">
|
|
<text class="popup-title">新增订单</text>
|
|
<view class="close-btn" @click="handleCancel">×</view>
|
|
</view>
|
|
|
|
<view class="popup-content">
|
|
<scroll-view class="form-section" scroll-y="true" enable-passive="true" show-scrollbar="false">
|
|
<view class="form-item">
|
|
<text class="label">学生信息</text>
|
|
<view class="student-info">
|
|
<text class="student-name">{{ studentInfo.name || '未选择学生' }}</text>
|
|
</view>
|
|
</view>
|
|
|
|
<view class="form-item">
|
|
<text class="label">课程选择 <text class="required">*</text></text>
|
|
<view class="picker-wrapper" @click="showCoursePicker">
|
|
<text class="picker-text" :class="{ 'placeholder': !formData.course_id }">
|
|
{{ selectedCourse && selectedCourse.name || '请选择课程' }}
|
|
</text>
|
|
<text class="picker-arrow">▼</text>
|
|
</view>
|
|
</view>
|
|
|
|
<view class="form-item">
|
|
<text class="label">支付方式 <text class="required">*</text></text>
|
|
<view class="picker-wrapper" @click="showPaymentPicker">
|
|
<text class="picker-text" :class="{ 'placeholder': !formData.payment_type }">
|
|
{{ selectedPaymentType && selectedPaymentType.label || '请选择支付方式' }}
|
|
</text>
|
|
<text class="picker-arrow">▼</text>
|
|
</view>
|
|
</view>
|
|
|
|
<view class="form-item">
|
|
<text class="label">订单类型 <text class="required">*</text></text>
|
|
<view class="picker-wrapper" @click="showOrderTypePicker">
|
|
<text class="picker-text" :class="{ 'placeholder': !formData.order_type }">
|
|
{{ selectedOrderType && selectedOrderType.label || '请选择订单类型' }}
|
|
</text>
|
|
<text class="picker-arrow">▼</text>
|
|
</view>
|
|
</view>
|
|
|
|
<view class="form-item">
|
|
<text class="label">订单金额 <text class="required">*</text></text>
|
|
<input
|
|
class="form-input readonly"
|
|
type="digit"
|
|
v-model="formData.order_amount"
|
|
placeholder="请先选择课程"
|
|
readonly
|
|
disabled
|
|
/>
|
|
</view>
|
|
|
|
<!-- <view class="form-item">-->
|
|
<!-- <text class="label">课时数</text>-->
|
|
<!-- <input -->
|
|
<!-- class="form-input readonly"-->
|
|
<!-- type="number"-->
|
|
<!-- v-model="formData.total_hours"-->
|
|
<!-- placeholder="请先选择课程"-->
|
|
<!-- readonly-->
|
|
<!-- disabled-->
|
|
<!-- />-->
|
|
<!-- </view>-->
|
|
|
|
<!-- <view class="form-item">-->
|
|
<!-- <text class="label">赠送课时</text>-->
|
|
<!-- <input -->
|
|
<!-- class="form-input readonly"-->
|
|
<!-- type="number"-->
|
|
<!-- v-model="formData.gift_hours"-->
|
|
<!-- placeholder="请先选择课程"-->
|
|
<!-- readonly-->
|
|
<!-- disabled-->
|
|
<!-- />-->
|
|
<!-- </view>-->
|
|
|
|
<view class="form-item">
|
|
<text class="label">备注</text>
|
|
<textarea
|
|
class="form-textarea"
|
|
v-model="formData.remark"
|
|
placeholder="请输入备注信息"
|
|
maxlength="200"
|
|
></textarea>
|
|
</view>
|
|
</scroll-view>
|
|
</view>
|
|
|
|
<view class="popup-footer">
|
|
<view class="footer-btn cancel-btn" @click="handleCancel">取消</view>
|
|
<view class="footer-btn confirm-btn" @click="handleConfirm">确认创建</view>
|
|
</view>
|
|
|
|
<!-- 选择器弹窗 -->
|
|
<uni-popup ref="pickerPopup" type="bottom">
|
|
<view class="picker-content">
|
|
<view class="picker-header">
|
|
<view class="picker-btn" @click="closePicker">取消</view>
|
|
<text class="picker-title">{{ pickerTitle }}</text>
|
|
<view class="picker-btn confirm" @click="confirmPicker">确定</view>
|
|
</view>
|
|
<picker-view class="picker-view" :value="pickerValue" @change="onPickerChange">
|
|
<picker-view-column>
|
|
<view class="picker-item" v-for="(item, index) in pickerOptions" :key="index">
|
|
{{ item.label || item.name }}
|
|
</view>
|
|
</picker-view-column>
|
|
</picker-view>
|
|
</view>
|
|
</uni-popup>
|
|
</view>
|
|
</template>
|
|
|
|
<script>
|
|
import apiRoute from '@/api/apiRoute.js'
|
|
|
|
export default {
|
|
name: 'OrderFormPopup',
|
|
props: {
|
|
visible: {
|
|
type: Boolean,
|
|
default: false
|
|
},
|
|
studentInfo: {
|
|
type: Object,
|
|
default: () => ({})
|
|
},
|
|
resourceId: {
|
|
type: [String, Number],
|
|
default: ''
|
|
}
|
|
},
|
|
data() {
|
|
return {
|
|
formData: {
|
|
student_id: '',
|
|
course_id: '',
|
|
payment_type: '',
|
|
order_type: '',
|
|
order_amount: '',
|
|
total_hours: '',
|
|
gift_hours: '',
|
|
remark: '',
|
|
class_id: '1' // 临时设置默认班级ID,后续需要添加班级选择功能
|
|
},
|
|
|
|
// 选择器相关
|
|
currentPicker: '',
|
|
pickerTitle: '',
|
|
pickerValue: [0],
|
|
pickerOptions: [],
|
|
selectedIndex: 0,
|
|
|
|
// 数据选项
|
|
courseList: [],
|
|
paymentTypes: [
|
|
{ value: 'cash', label: '现金支付' },
|
|
{ value: 'scan_code', label: '扫码支付' },
|
|
{ value: 'subscription', label: '订阅支付' },
|
|
{ value: 'wxpay_online', label: '微信在线代付' }
|
|
],
|
|
orderTypes: [
|
|
{ value: '1', label: '新订单' },
|
|
{ value: '2', label: '续费订单' },
|
|
{ value: '3', label: '内部员工订单' }
|
|
]
|
|
}
|
|
},
|
|
computed: {
|
|
selectedCourse() {
|
|
return this.courseList.find(item => item.id == this.formData.course_id)
|
|
},
|
|
selectedPaymentType() {
|
|
return this.paymentTypes.find(item => item.value === this.formData.payment_type)
|
|
},
|
|
selectedOrderType() {
|
|
return this.orderTypes.find(item => item.value === this.formData.order_type)
|
|
}
|
|
},
|
|
watch: {
|
|
visible(newVal) {
|
|
console.log('visible changed:', newVal)
|
|
if (newVal) {
|
|
console.log('开始初始化表单和加载课程列表')
|
|
this.initForm()
|
|
this.loadCourseList()
|
|
}
|
|
},
|
|
studentInfo: {
|
|
handler(newVal) {
|
|
if (newVal && newVal.id) {
|
|
this.formData.student_id = newVal.id
|
|
}
|
|
},
|
|
immediate: true,
|
|
deep: true
|
|
}
|
|
},
|
|
mounted() {
|
|
console.log('OrderFormPopup mounted, visible:', this.visible)
|
|
// 如果组件挂载时 visible 为 true,主动加载课程列表
|
|
if (this.visible) {
|
|
console.log('组件挂载时 visible 为 true,开始加载课程列表')
|
|
this.loadCourseList()
|
|
}
|
|
},
|
|
methods: {
|
|
initForm() {
|
|
this.formData = {
|
|
student_id: this.studentInfo && this.studentInfo.id || '',
|
|
course_id: '',
|
|
payment_type: '',
|
|
order_type: '',
|
|
order_amount: '',
|
|
total_hours: '',
|
|
gift_hours: '',
|
|
remark: '',
|
|
class_id: '1' // 临时设置默认班级ID
|
|
}
|
|
},
|
|
|
|
async loadCourseList() {
|
|
console.log('loadCourseList 方法被调用')
|
|
try {
|
|
console.log('正在调用课程API: common_getCourseAll')
|
|
const res = await apiRoute.common_getCourseAll({})
|
|
console.log('课程API响应:', res)
|
|
if (res.code === 1) {
|
|
// 过滤状态为1的课程,并格式化数据结构
|
|
this.courseList = (res.data || [])
|
|
.filter(course => course.status === 1)
|
|
.map(course => ({
|
|
id: course.id,
|
|
name: course.course_name,
|
|
price: parseFloat(course.price || 0),
|
|
hours: course.session_count || 0,
|
|
gift_hours: course.gift_session_count || 0,
|
|
duration: course.duration || 0,
|
|
course_type: course.course_type,
|
|
remarks: course.remarks
|
|
}))
|
|
} else {
|
|
console.error('获取课程列表失败:', res.msg)
|
|
this.courseList = []
|
|
}
|
|
} catch (error) {
|
|
console.error('获取课程列表异常:', error)
|
|
this.courseList = []
|
|
}
|
|
},
|
|
|
|
showCoursePicker() {
|
|
this.currentPicker = 'course'
|
|
this.pickerTitle = '选择课程'
|
|
this.pickerOptions = this.courseList
|
|
this.pickerValue = [0]
|
|
this.selectedIndex = 0 // 重置选择索引
|
|
this.$refs.pickerPopup.open()
|
|
},
|
|
|
|
showPaymentPicker() {
|
|
this.currentPicker = 'payment'
|
|
this.pickerTitle = '选择支付方式'
|
|
this.pickerOptions = this.paymentTypes
|
|
this.pickerValue = [0]
|
|
this.selectedIndex = 0 // 重置选择索引
|
|
this.$refs.pickerPopup.open()
|
|
},
|
|
|
|
showOrderTypePicker() {
|
|
this.currentPicker = 'orderType'
|
|
this.pickerTitle = '选择订单类型'
|
|
this.pickerOptions = this.orderTypes
|
|
this.pickerValue = [0]
|
|
this.selectedIndex = 0 // 重置选择索引
|
|
this.$refs.pickerPopup.open()
|
|
},
|
|
|
|
onPickerChange(e) {
|
|
this.selectedIndex = e.detail.value[0]
|
|
},
|
|
|
|
confirmPicker() {
|
|
const selectedOption = this.pickerOptions[this.selectedIndex]
|
|
if (!selectedOption) return
|
|
|
|
switch (this.currentPicker) {
|
|
case 'course':
|
|
this.formData.course_id = selectedOption.id
|
|
// 自动填充课程相关信息
|
|
if (selectedOption.price !== undefined) {
|
|
this.formData.order_amount = selectedOption.price.toString()
|
|
}
|
|
if (selectedOption.hours !== undefined) {
|
|
this.formData.total_hours = selectedOption.hours.toString()
|
|
}
|
|
if (selectedOption.gift_hours !== undefined) {
|
|
this.formData.gift_hours = selectedOption.gift_hours.toString()
|
|
}
|
|
console.log('课程选择后更新表单数据:', this.formData)
|
|
break
|
|
case 'payment':
|
|
this.formData.payment_type = selectedOption.value
|
|
break
|
|
case 'orderType':
|
|
this.formData.order_type = selectedOption.value
|
|
break
|
|
}
|
|
|
|
this.closePicker()
|
|
},
|
|
|
|
closePicker() {
|
|
this.$refs.pickerPopup.close()
|
|
this.currentPicker = ''
|
|
},
|
|
|
|
validateForm() {
|
|
if (!this.formData.student_id) {
|
|
uni.showToast({ title: '请选择学生', icon: 'none' })
|
|
return false
|
|
}
|
|
if (!this.formData.course_id) {
|
|
uni.showToast({ title: '请选择课程', icon: 'none' })
|
|
return false
|
|
}
|
|
if (!this.formData.payment_type) {
|
|
uni.showToast({ title: '请选择支付方式', icon: 'none' })
|
|
return false
|
|
}
|
|
if (!this.formData.order_type) {
|
|
uni.showToast({ title: '请选择订单类型', icon: 'none' })
|
|
return false
|
|
}
|
|
if (!this.formData.order_amount || this.formData.order_amount <= 0) {
|
|
uni.showToast({ title: '请输入有效的订单金额', icon: 'none' })
|
|
return false
|
|
}
|
|
return true
|
|
},
|
|
|
|
async handleConfirm() {
|
|
if (!this.validateForm()) return
|
|
|
|
try {
|
|
uni.showLoading({ title: '创建中...' })
|
|
|
|
const orderData = {
|
|
...this.formData,
|
|
resource_id: this.resourceId,
|
|
staff_id: '', // 将从用户信息中获取
|
|
order_status: 'pending'
|
|
}
|
|
|
|
const res = await apiRoute.xs_orderTableAdd(orderData)
|
|
|
|
if (res.code === 1) {
|
|
uni.showToast({ title: '订单创建成功', icon: 'success' })
|
|
this.$emit('confirm', { orderData, result: res.data })
|
|
} else {
|
|
uni.showToast({ title: res.msg || '创建失败', icon: 'none' })
|
|
}
|
|
} catch (error) {
|
|
console.error('创建订单失败:', error)
|
|
uni.showToast({ title: '创建失败', icon: 'none' })
|
|
} finally {
|
|
uni.hideLoading()
|
|
}
|
|
},
|
|
|
|
handleCancel() {
|
|
this.$emit('cancel')
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
.order-form-popup {
|
|
background: #1a1a1a;
|
|
border-radius: 20rpx 20rpx 0 0;
|
|
color: #ffffff;
|
|
height: 80vh;
|
|
display: flex;
|
|
flex-direction: column;
|
|
}
|
|
|
|
.popup-header {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
padding: 30rpx 40rpx;
|
|
border-bottom: 1px solid #333;
|
|
|
|
.popup-title {
|
|
font-size: 36rpx;
|
|
font-weight: 600;
|
|
color: #ffffff;
|
|
}
|
|
|
|
.close-btn {
|
|
width: 60rpx;
|
|
height: 60rpx;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
font-size: 40rpx;
|
|
color: #888;
|
|
border-radius: 50%;
|
|
background: #333;
|
|
}
|
|
}
|
|
|
|
.popup-content {
|
|
flex: 1;
|
|
overflow: hidden;
|
|
padding: 0;
|
|
min-height: 0; /* 确保flex子项可以收缩 */
|
|
height: 0; /* 在微信小程序中确保flex子项正确计算高度 */
|
|
}
|
|
|
|
.form-section {
|
|
height: 100%;
|
|
width: 100%;
|
|
padding: 40rpx 40rpx 60rpx 40rpx; // 增加底部间距,防止最后一项被遮挡
|
|
/* 确保滚动区域正确计算 */
|
|
box-sizing: border-box;
|
|
|
|
.form-item {
|
|
margin-bottom: 40rpx;
|
|
|
|
.label {
|
|
display: block;
|
|
font-size: 28rpx;
|
|
color: #cccccc;
|
|
margin-bottom: 20rpx;
|
|
|
|
.required {
|
|
color: #ff4757;
|
|
}
|
|
}
|
|
|
|
.student-info {
|
|
padding: 20rpx;
|
|
background: #2a2a2a;
|
|
border-radius: 12rpx;
|
|
|
|
.student-name {
|
|
font-size: 30rpx;
|
|
color: #29D3B4;
|
|
}
|
|
}
|
|
|
|
.picker-wrapper {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
padding: 24rpx 30rpx;
|
|
background: #2a2a2a;
|
|
border-radius: 12rpx;
|
|
border: 1px solid #444;
|
|
|
|
.picker-text {
|
|
flex: 1;
|
|
font-size: 30rpx;
|
|
color: #ffffff;
|
|
|
|
&.placeholder {
|
|
color: #888;
|
|
}
|
|
}
|
|
|
|
.picker-arrow {
|
|
font-size: 24rpx;
|
|
color: #888;
|
|
}
|
|
}
|
|
|
|
.form-input, .form-textarea {
|
|
width: 100%;
|
|
padding: 24rpx 30rpx;
|
|
background: #2a2a2a;
|
|
border: 1px solid #444;
|
|
border-radius: 12rpx;
|
|
color: #ffffff;
|
|
font-size: 30rpx;
|
|
|
|
&::placeholder {
|
|
color: #888;
|
|
}
|
|
|
|
&.readonly {
|
|
background: #1a1a1a;
|
|
border-color: #333;
|
|
color: #888;
|
|
height: 100rpx;
|
|
&::placeholder {
|
|
color: #666;
|
|
}
|
|
}
|
|
}
|
|
|
|
.form-textarea {
|
|
height: 120rpx;
|
|
resize: none;
|
|
}
|
|
}
|
|
}
|
|
|
|
.popup-footer {
|
|
display: flex;
|
|
padding: 30rpx 40rpx;
|
|
padding-bottom: calc(30rpx + env(safe-area-inset-bottom));
|
|
border-top: 1px solid #333;
|
|
gap: 30rpx;
|
|
flex-shrink: 0; /* 确保底部按钮区域不被压缩 */
|
|
background: #1a1a1a; /* 确保背景色一致 */
|
|
|
|
.footer-btn {
|
|
flex: 1;
|
|
height: 88rpx;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
border-radius: 12rpx;
|
|
font-size: 32rpx;
|
|
font-weight: 500;
|
|
|
|
&.cancel-btn {
|
|
background: #cccccc;
|
|
}
|
|
|
|
&.confirm-btn {
|
|
background: linear-gradient(45deg, #29D3B4, #1DB584);
|
|
color: #ffffff;
|
|
}
|
|
}
|
|
}
|
|
|
|
// 选择器样式
|
|
.picker-content {
|
|
background: #1a1a1a;
|
|
border-radius: 20rpx 20rpx 0 0;
|
|
|
|
.picker-header {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
padding: 30rpx 40rpx;
|
|
border-bottom: 1px solid #333;
|
|
|
|
.picker-btn {
|
|
font-size: 30rpx;
|
|
color: #888;
|
|
|
|
&.confirm {
|
|
color: #29D3B4;
|
|
}
|
|
}
|
|
|
|
.picker-title {
|
|
font-size: 32rpx;
|
|
color: #ffffff;
|
|
font-weight: 500;
|
|
}
|
|
}
|
|
|
|
.picker-view {
|
|
height: 400rpx;
|
|
color: #ffffff;
|
|
|
|
.picker-item {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
font-size: 30rpx;
|
|
color: #ffffff;
|
|
}
|
|
}
|
|
}
|
|
</style>
|