|
|
- <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">
- <!-- style="width: calc(100vw - 40rpx*2);" -->
- <view>
- <peopleNumberInput
- :adults.sync="form.adults"
- :teenager.sync="form.teenager"
- :child.sync="form.child"
- :adultsPrice="productPackage.adultsPrice"
- :teenagerPrice="productPackage.teenagerPrice"
- :childPrice="productPackage.childPrice"
- ></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.label }}</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">
- 我已阅读并同意
- <!-- todo: 替换配置项key -->
- <text class="highlight" @click="$refs.modal.open('config_agreement', '退订政策')">《退订政策》</text>
- <!-- todo: 替换配置项key -->
- <text class="highlight" @click="$refs.modal.open('config_privacy', '合同范本')">《合同范本》</text>
- <!-- todo: 替换配置项key -->
- <text class="highlight" @click="$refs.modal.open('config_privacy', '预订须知')">《预订须知》</text>
- <!-- todo: 替换配置项key -->
- <text class="highlight" @click="$refs.modal.open('config_privacy', '安全提示')">《安全提示》</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: null,
- phone: null,
- adults: 0,
- teenager: 0,
- child: 0,
- members: [],
- couponId: null,
- receiptId: null,
- },
- checkboxValue: [],
- formItemStyle: { padding: 0 },
- }
- },
- computed: {
- ...mapState(['configList', 'userInfo', 'orderInfo', 'couponInfo']),
- productPackage() {
- const { time, product } = this.orderInfo
- const { timeOptions } = product || {}
-
- return timeOptions?.find?.(item => item.id === time) || {}
- },
- totolPeople() {
- const { adults, teenager, child } = this.form
-
- return (adults || 0) + (teenager || 0) + (child || 0)
- },
- totalPrice() {
- const { adults, teenager, child, couponId } = this.form
-
- const { adultsPrice, teenagerPrice, childPrice } = this.productPackage
-
- let total = 0
-
- adults && (total += adults * (adultsPrice || 0))
- teenager && (total += teenager * (teenagerPrice || 0))
- child && (total += child * (childPrice || 0))
-
- couponId && (total -= (this.couponInfo?.price || 0))
-
- return total
- },
- },
- watch: {
- form: {
- handler(val) {
- this.$refs.form.setRules(this.getRules())
- },
- deep: true
- }
- },
- 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.getRules())
- },
- onUnload() {
- this.$store.commit('setCouponInfo', null)
- },
- methods: {
- getRules() {
- const { adults, teenager, child } = this.form
-
- return {
- 'name': {
- type: 'string',
- required: true,
- message: '请输入真实姓名',
- },
- 'phone': {
- type: 'string',
- required: true,
- message: '请输入手机号码',
- },
- 'adults': {
- type: 'number',
- required: true,
- message: '请选择人数',
- validator: (rule, value, callback) => {
-
- if (adults || teenager || child) {
- return true
- }
-
- return false
- },
- },
- 'members': {
- type: 'array',
- required: true,
- message: '请选择出行人',
- },
- }
- },
- initData() {
- const {
- time,
- adults,
- teenager,
- child,
- members,
- } = this.orderInfo
-
- this.form = {
- name: null,
- phone: null,
- adults,
- teenager,
- child,
- members: members.map(item => ({ ...item, isSelected: true })),
- couponId: null,
- receiptId: null,
- }
- },
- 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()
-
- // todo: fetch create order and save wx pay data
- const {
- product,
- time,
- } = this.orderInfo
-
- const {
- name,
- phone,
- adults,
- teenager,
- child,
- members,
- couponId,
- receiptId,
- } = this.form
-
- const { startDate, endDate } = time
- let params = {
- activityId: product.id,
- startDate,
- endDate,
- couponId,
- receiptId,
- name,
- phone,
- }
-
- const result = await this.$fetch('createOrder', params)
-
- // todo: check result includes order id?
-
- const orderInfo = {
- product,
- couponInfo: this.couponInfo,
- time,
- adults,
- teenager,
- child,
- members,
- couponId,
- receiptId,
- name,
- phone,
- }
-
- this.$store.commit('setOrderInfo', orderInfo)
-
- // todo: get id?
- uni.navigateTo({
- url: `/pages_order/order/orderPay/index?id=${result.id}`
- })
-
- } catch (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>
|