| <template> | |
|   <view class="page__view"> | |
| 		<navbar title="填写订单" leftClick @leftClick="$utils.navigateBack" /> | |
| 
 | |
|     <view class="main"> | |
| 
 | |
|       <productCard :data="orderInfo"></productCard> | |
| 
 | |
|       <uv-form  | |
|         ref="form" | |
|         :model="form" | |
|         errorType="toast" | |
|       > | |
|         <view class="card"> | |
|           <view class="card-header">联系人信息</view> | |
|           <view class="form-item"> | |
|             <uv-form-item prop="name" :customStyle="formItemStyle"> | |
|               <view class="form-item-label"> | |
|                 <image class="icon" src="@/pages_order/static/icon-require.png" mode="widthFix"></image> | |
|                 真实姓名 | |
|               </view> | |
|               <view class="form-item-content"> | |
|                 <formInput v-model="form.name"></formInput> | |
|               </view> | |
|             </uv-form-item> | |
|           </view> | |
|           <view class="form-item"> | |
|             <uv-form-item prop="phone" :customStyle="formItemStyle"> | |
|               <view class="form-item-label"> | |
|                 <image class="icon" src="@/pages_order/static/icon-require.png" mode="widthFix"></image> | |
|                 手机号码 | |
|               </view> | |
|               <view class="form-item-content"> | |
|                 <formInput v-model="form.phone"></formInput> | |
|               </view> | |
|             </uv-form-item> | |
|           </view> | |
|         </view> | |
|         <view class="card"> | |
|           <view class="card-header">订单详情</view> | |
|           <view style="margin-top: 16rpx;"> | |
|             <uv-form-item prop="members" :customStyle="formItemStyle"> | |
|               <view> | |
|                 <peopleNumberInput style="width: calc(100vw - 40rpx*2);" | |
|                   v-model="form.prices" | |
|                   :options="orderInfo.priceList" | |
|                 ></peopleNumberInput> | |
|  | |
|                 <memberChooseView | |
|                   :members.sync="form.members" | |
|                 ></memberChooseView> | |
|               </view> | |
|             </uv-form-item> | |
|           </view> | |
|         </view> | |
|         <view class="card"> | |
|           <view class="card-header">其他</view> | |
|           <view class="form-item"> | |
|             <uv-form-item prop="couponId" :customStyle="formItemStyle"> | |
|               <view class="form-item-label">选择优惠券</view> | |
|               <view class="form-item-content"> | |
|                 <view class="flex row" @click="jumpToSelectCoupon"> | |
|                   <view v-if="form.couponId" class="text">{{ couponInfo.title }}</view> | |
|                   <view v-else class="text placeholder">请选择</view> | |
|                   <uv-icon name="arrow-right" color="#C6C6C6" size="32rpx"></uv-icon> | |
|                 </view> | |
|               </view> | |
|             </uv-form-item> | |
|           </view> | |
|           <view class="form-item"> | |
|             <uv-form-item prop="receiptId" :customStyle="formItemStyle"> | |
|               <view class="form-item-label">选择发票类型</view> | |
|               <view class="form-item-content"> | |
|                 <view class="flex row" @click="jumpToSelectInvoice"> | |
|                   <view v-if="form.receiptId" class="text">{{ getInvoiceDesc(form.receiptId) }}</view> | |
|                   <view v-else class="text placeholder">请选择</view> | |
|                   <uv-icon name="arrow-right" color="#C6C6C6" size="32rpx"></uv-icon> | |
|                 </view> | |
|               </view> | |
|             </uv-form-item> | |
|           </view> | |
|         </view> | |
|       </uv-form> | |
|        | |
|       <view class="notice"> | |
|         <!-- <view class="notice-header">下单须知</view> --> | |
|         <view class="notice-content"> | |
|           <!-- todo: check key --> | |
| 				  <!-- <uv-parse :content="configList['order_instructions']"></uv-parse> --> | |
|           如有特殊病史或有不宜参加的旅程(项目)、男女报名如无法同住、分开报名需安排同住同车等,请备注 | |
|         </view> | |
|       </view> | |
|  | |
|     </view> | |
|    | |
| 		<view class="bottom"> | |
|       <view class="agreement"> | |
| 				<uv-checkbox-group | |
| 					v-model="checkboxValue" | |
| 					shape="circle" | |
| 				> | |
| 					<uv-checkbox | |
| 						size="40rpx" | |
| 						icon-size="40rpx" | |
| 						activeColor="#00A9FF" | |
| 						:name="1" | |
| 					></uv-checkbox> | |
| 				</uv-checkbox-group> | |
| 				<view class="desc"> | |
|           我已阅读并同意 | |
| 					<text class="highlight" @click="$refs.modal.open('unsubscribe_policy', '退订政策')">《退订政策》</text> | |
| 					<text class="highlight" @click="$refs.modal.open('model_contract', '合同范本')">《合同范本》</text> | |
| 					<text class="highlight" @click="$refs.modal.open('booking_instructions', '预订须知')">《预订须知》</text> | |
| 					<text class="highlight" @click="$refs.modal.open('safety_reminder', '安全提示')">《安全提示》</text> | |
| 				</view> | |
| 			</view> | |
|       <view class="flex bar"> | |
|         <view class="col price"> | |
|           <view class="flex price-label"> | |
|             已选<view class="highlight">{{ `${totolPeople}人` }}</view>总额 | |
|           </view> | |
|           <view class="flex price-value"> | |
|             ¥<view class="highlight">{{ totalPrice }}</view> | |
|           </view> | |
|         </view> | |
|         <button class="col btn btn-primary btn-pay" @click="onPay">立即支付</button> | |
|       </view> | |
|     </view> | |
|  | |
| 		<agreementModal ref="modal" @confirm="onConfirmAgreement"></agreementModal> | |
|  | |
|   </view> | |
| </template> | |
|  | |
| <script> | |
| 	import { mapState } from 'vuex' | |
|  | |
|   import productCard from '@/pages_order/order/components/productCard.vue' | |
|   import peopleNumberInput from './peopleNumberInput.vue' | |
|   import memberChooseView from './memberChooseView.vue' | |
|   import formInput from '@/pages_order/components/formInput.vue' | |
| 	import agreementModal from '@/pages_order/components/agreementModal.vue' | |
|  | |
|   export default { | |
|     components: { | |
|       productCard, | |
|       peopleNumberInput, | |
|       memberChooseView, | |
|       formInput, | |
|       agreementModal, | |
|     }, | |
|     data() { | |
|       return { | |
|         form: { | |
|           name: '', | |
|           phone: '', | |
|           prices: [], | |
|           members: [], | |
|           couponId: '', | |
|           receiptId: '', | |
|         }, | |
|         rules: { | |
|           'name': { | |
|             type: 'string', | |
|             required: true, | |
|             message: '请输入真实姓名', | |
|           }, | |
|           'phone': { | |
|             type: 'string', | |
|             required: true, | |
|             message: '请输入手机号码', | |
|           }, | |
|           'prices': { | |
|             type: 'array', | |
|             message: '请选择人数', | |
|             validator: (rule, value, callback) => { | |
|  | |
|               if (value.some(num => num > 0)) { | |
|                 return true | |
|               } | |
|  | |
|               return false | |
|             }, | |
|           }, | |
|           'members': { | |
|             type: 'array', | |
|             required: true, | |
|             message: '请选择出行人', | |
|           }, | |
|         }, | |
|         checkboxValue: [], | |
|         formItemStyle: { padding: 0 }, | |
|       } | |
|     }, | |
|     computed: { | |
| 			...mapState(['configList', 'userInfo', 'orderInfo', 'couponInfo']), | |
|       productPackage() { | |
|         const { time, product } = this.orderInfo | |
|         const { dateList } = product || {} | |
|  | |
|         return dateList?.find?.(item => item.id === time) || {} | |
|       }, | |
|       totolPeople() { | |
|         const { prices } = this.orderInfo | |
|  | |
|         return prices.reduce((total, num) => { | |
|           return total + num | |
|         }, 0) | |
|       }, | |
|       priceOrigin() { | |
|         const { prices, priceList } = this.orderInfo | |
|  | |
|         return prices.reduce((total, num, index) => { | |
|           return total + priceList[index].price * (num || 0) | |
|         }, 0) | |
|       }, | |
|       discount() { | |
|         return this.couponInfo?.discountAmount || 0 | |
|       }, | |
| 			totalPrice() { | |
|         return this.priceOrigin - this.discount | |
| 			}, | |
|     }, | |
|     onShow() { | |
|       if (this.couponInfo) { | |
|         this.form.couponId = this.couponInfo.id | |
|       } | |
|     }, | |
|     onLoad(arg) { | |
|       console.log('onLoad') | |
|       console.log('orderInfo', this.orderInfo) | |
|       this.initData() | |
|     }, | |
| 		onReady() { | |
| 			this.$refs.form.setRules(this.rules); | |
| 		}, | |
|     onUnload() { | |
|       this.$store.commit('setCouponInfo', null) | |
|     }, | |
|     methods: { | |
|       initData() { | |
|         const { | |
|           time, | |
|           prices, | |
|           priceList, | |
|           members, | |
|         } = this.orderInfo | |
|  | |
|         console.log('priceList', priceList) | |
|         console.log('members', members) | |
|          | |
|         let arr = [] | |
|  | |
|         this.form = { | |
|           name: '', | |
|           phone: '', | |
|           prices, | |
|           members: members.map(item => ({ ...item, isSelected: true })), | |
|           couponId: '', | |
|           receiptId: '', | |
|         } | |
|       }, | |
|       jumpToSelectCoupon() { | |
|         uni.navigateTo({ | |
|           url: `/pages_order/coupon/couponSelect/index` | |
|         }) | |
|       }, | |
|       getCouponDesc() { | |
|         // todo | |
|       }, | |
|       jumpToSelectInvoice() { | |
|         // todo | |
|       }, | |
|       getInvoiceDesc() { | |
|         // todo | |
|       }, | |
|       onConfirmAgreement(confirm) { | |
|         if (confirm) { | |
|           this.checkboxValue = [1] | |
|         } else { | |
|           this.checkboxValue = [] | |
|         } | |
|       }, | |
|       async onPay() { | |
|         if(!this.checkboxValue.length){ | |
|           return uni.showToast({ | |
|             title: '请先同意《用户协议》《隐私协议》《消费者告知》', | |
|             icon:'none' | |
|           }) | |
|         } | |
|          | |
|         try { | |
|           await this.$refs.form.validate() | |
|            | |
|           const { | |
|             product, | |
|             time, | |
|             priceList, | |
|           } = this.orderInfo | |
|  | |
|           console.log('priceList', priceList) | |
|           console.log('members', members) | |
|            | |
|           const { | |
|             name, | |
|             phone, | |
|             prices, | |
|             members, | |
|             couponId, | |
|             receiptId, | |
|           } = this.form | |
|  | |
|           const { startDate, endDate } = this.productPackage | |
|  | |
|           // let json = members.map(member => { | |
|           //   const { periodId } = member | |
|           //   const { period_dictText, price } = priceList.find(item => item.periodId === periodId) || {} | |
|  | |
|           //   return { | |
|           //     ...member, | |
|           //     period_dictText, | |
|           //     price, | |
|           //   } | |
|           // }) | |
|  | |
|           // console.log('json', json) | |
|  | |
|           let params = { | |
|             activityId: product.id, | |
|             startDate,  | |
|             endDate, | |
|             dayNum: this.$dayjs(endDate).diff(this.$dayjs(startDate), 'day'), | |
|             couponId, | |
|             receiptId, | |
|             name, | |
|             phone, | |
|             priceOrigin: this.priceOrigin, | |
|             discount: this.discount, | |
|             priceDiscount: this.totalPrice, | |
|             payAmount: this.totalPrice, | |
|             tourisIds: members.map(touris => touris.id).join(';'), | |
|             // jsonObject: JSON.stringify(json), | |
|           } | |
|  | |
|           const orderId = await this.$fetch('createOrder', params) | |
|  | |
|           uni.navigateTo({ | |
|             url: `/pages_order/order/orderPay/index?id=${orderId}` | |
|           }) | |
|  | |
|         } catch (err) { | |
|           console.log('createOrder', err) | |
|         } | |
|  | |
|       }, | |
|     }, | |
|   } | |
| </script> | |
|  | |
| <style scoped lang="scss"> | |
| 
 | |
|   @import '../styles/style.scss'; | |
| 
 | |
|   .price { | |
|     justify-content: flex-start; | |
| 
 | |
|     &-label { | |
|       justify-content: flex-start; | |
|       column-gap: 12rpx; | |
|       font-family: PingFang SC; | |
|       font-weight: 400; | |
|       font-size: 24rpx; | |
|       line-height: 1.4; | |
|       color: #626262; | |
| 
 | |
|       .highlight { | |
|         font-size: 24rpx; | |
|         font-weight: 500; | |
|         color: $uni-color; | |
|       } | |
|     } | |
| 
 | |
|     &-value { | |
|       justify-content: flex-start; | |
|       column-gap: 8rpx; | |
|       font-family: PingFang SC; | |
|       font-weight: 500; | |
|       font-size: 24rpx; | |
|       line-height: 1.4; | |
|       color: $uni-color; | |
|        | |
|       .highlight { | |
|         font-size: 40rpx; | |
|       } | |
|     } | |
|   } | |
| 
 | |
|   .btn-pay { | |
|     flex: none; | |
|     width: auto; | |
|     padding: 14rpx 74rpx; | |
|   } | |
| 
 | |
| </style> |