|
@@ -0,0 +1,254 @@
|
|
|
+<template>
|
|
|
+ <div>
|
|
|
+ <BaseModal
|
|
|
+ v-model:show="show"
|
|
|
+ position="bottom"
|
|
|
+ round
|
|
|
+ closeable
|
|
|
+ safe-area-inset-bottom
|
|
|
+ @closed="cleanBookInfo"
|
|
|
+ teleport="body"
|
|
|
+ >
|
|
|
+ <div class="flex flex-col h-[550px]">
|
|
|
+ <div
|
|
|
+ class="flex items-center justify-center text-xl text-black-3 font-semibold py-15"
|
|
|
+ >
|
|
|
+ 立即拼团
|
|
|
+ </div>
|
|
|
+ <van-form class="flex-1">
|
|
|
+ <van-cell-group>
|
|
|
+ <van-field name="目的地" label="目的地">
|
|
|
+ <template #input>{{ projectData.endPlace }}</template>
|
|
|
+ </van-field>
|
|
|
+ <van-field name="成团人数" label="成团人数">
|
|
|
+ <template #input>{{ pinTuanData.maxCount }}人成团</template>
|
|
|
+ </van-field>
|
|
|
+ <van-field name="出发日期" label="出发日期">
|
|
|
+ <template #input>{{ pinTuanData.travelStartTime }}</template>
|
|
|
+ </van-field>
|
|
|
+ <van-field name="成人数量" label="成人数量">
|
|
|
+ <template #input>
|
|
|
+ <van-stepper
|
|
|
+ v-model="bookInfo.adultNumber"
|
|
|
+ theme="round"
|
|
|
+ button-size="20"
|
|
|
+ min="1"
|
|
|
+ :max="pinTuanData.maxCount - pinTuanData.nowCount"
|
|
|
+ disable-input
|
|
|
+ style="--van-stepper-button-round-theme-color: #fd9a00"
|
|
|
+ />
|
|
|
+ </template>
|
|
|
+ </van-field>
|
|
|
+ <van-field name="儿童数量" label="儿童数量">
|
|
|
+ <template #input>
|
|
|
+ <van-stepper
|
|
|
+ v-model="bookInfo.childrenNumber"
|
|
|
+ theme="round"
|
|
|
+ min="0"
|
|
|
+ :max="pinTuanData.maxCount - pinTuanData.nowCount"
|
|
|
+ button-size="20"
|
|
|
+ disable-input
|
|
|
+ style="--van-stepper-button-round-theme-color: #fd9a00"
|
|
|
+ />
|
|
|
+ </template>
|
|
|
+ </van-field>
|
|
|
+ <van-field
|
|
|
+ v-model="bookInfo.customerName"
|
|
|
+ required
|
|
|
+ name="联系人"
|
|
|
+ label="联系人"
|
|
|
+ placeholder="请输入联系人"
|
|
|
+ :rules="[{ required: true, message: '请输入联系人' }]"
|
|
|
+ />
|
|
|
+ <van-field
|
|
|
+ v-model="bookInfo.customerMobile"
|
|
|
+ required
|
|
|
+ type="tel"
|
|
|
+ name="联系电话"
|
|
|
+ label="联系电话"
|
|
|
+ placeholder="请输入联系电话"
|
|
|
+ :rules="[{ required: true, message: '请输入联系电话' }]"
|
|
|
+ />
|
|
|
+ <van-field
|
|
|
+ v-model="bookInfo.customerWechat"
|
|
|
+ required
|
|
|
+ name="微信号"
|
|
|
+ label="微信号"
|
|
|
+ placeholder="请输入微信号"
|
|
|
+ :rules="[{ required: true, message: '请输入微信号' }]"
|
|
|
+ />
|
|
|
+ <van-field
|
|
|
+ v-model="bookInfo.customerMobileStandby"
|
|
|
+ name="备用电话"
|
|
|
+ label="备用电话"
|
|
|
+ placeholder="请输入备用联系电话"
|
|
|
+ />
|
|
|
+ </van-cell-group>
|
|
|
+ </van-form>
|
|
|
+
|
|
|
+ <div class="h-70 flex items-center justify-between space-x-40 px-15">
|
|
|
+ <div class="text-[#FF0000] w-1/3 text-sm">
|
|
|
+ <span>¥</span>
|
|
|
+ <span class="text-4xl">{{ priceToArray(totalPrice ?? 0)[0] }}</span>
|
|
|
+ <span>.{{ priceToArray(totalPrice ?? 0)[1] }}</span>
|
|
|
+ </div>
|
|
|
+ <van-button
|
|
|
+ @click="handleSubmit"
|
|
|
+ class="flex-1"
|
|
|
+ style="height: 40px"
|
|
|
+ type="primary"
|
|
|
+ :loading="submitLoading"
|
|
|
+ >提交</van-button
|
|
|
+ >
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </BaseModal>
|
|
|
+ <TravelProjectDetailPinTuanKaiTuanApplyModal
|
|
|
+ v-model:show="applyKaiTuanModalOptions.show"
|
|
|
+ :title="applyKaiTuanModalOptions.title"
|
|
|
+ />
|
|
|
+ <TravelProjectDetailPinTuanResultModal
|
|
|
+ v-model:show="resultModalOptions.show"
|
|
|
+ :pin-tuan-info="resultModalOptions.data"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script setup>
|
|
|
+const props = defineProps({
|
|
|
+ pinTuanData: {
|
|
|
+ type: Object,
|
|
|
+ default: () => {},
|
|
|
+ },
|
|
|
+ projectData: {
|
|
|
+ type: Object,
|
|
|
+ default: () => {},
|
|
|
+ },
|
|
|
+});
|
|
|
+
|
|
|
+const fromUserId = useRouteQuery("fromUserId");
|
|
|
+
|
|
|
+const show = defineModel("show", false);
|
|
|
+
|
|
|
+const id = useRouteParam("id");
|
|
|
+
|
|
|
+const dayjs = useDayjs();
|
|
|
+
|
|
|
+const bookInfo = reactive({
|
|
|
+ startDate: null,
|
|
|
+ adultNumber: 1,
|
|
|
+ childrenNumber: 0,
|
|
|
+ customerName: "",
|
|
|
+ customerMobile: "",
|
|
|
+ customerMobileStandby: "",
|
|
|
+ customerWechat: "",
|
|
|
+});
|
|
|
+
|
|
|
+function cleanBookInfo() {
|
|
|
+ bookInfo.startDate = null;
|
|
|
+ bookInfo.adultNumber = 1;
|
|
|
+ bookInfo.childrenNumber = 0;
|
|
|
+ bookInfo.customerName = "";
|
|
|
+ bookInfo.customerMobile = "";
|
|
|
+ bookInfo.customerMobileStandby = "";
|
|
|
+ bookInfo.customerWechat = "";
|
|
|
+}
|
|
|
+
|
|
|
+const totalPrice = ref(0);
|
|
|
+const loading = ref(false);
|
|
|
+async function calcTotalPrice() {
|
|
|
+ try {
|
|
|
+ loading.value = true;
|
|
|
+ const { data } = await request(
|
|
|
+ "/website/app/tourProjectGroupPurchase/calcTotalAmount",
|
|
|
+ {
|
|
|
+ query: {
|
|
|
+ id: props.pinTuanData.id,
|
|
|
+ adultCount: bookInfo.adultNumber ?? 0,
|
|
|
+ childrenCount: bookInfo.childrenNumber ?? 0,
|
|
|
+ },
|
|
|
+ }
|
|
|
+ );
|
|
|
+ totalPrice.value = data.totalPrice ?? 0;
|
|
|
+ loading.value = false;
|
|
|
+ } catch (error) {
|
|
|
+ loading.value = false;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+watch(
|
|
|
+ [() => bookInfo.adultNumber, () => bookInfo.childrenNumber, show],
|
|
|
+ () => {
|
|
|
+ if (!show.value) return;
|
|
|
+ calcTotalPrice();
|
|
|
+ },
|
|
|
+ {
|
|
|
+ deep: true,
|
|
|
+ }
|
|
|
+);
|
|
|
+
|
|
|
+const applyKaiTuanModalOptions = reactive({
|
|
|
+ show: false,
|
|
|
+ title: "",
|
|
|
+});
|
|
|
+
|
|
|
+const resultModalOptions = reactive({
|
|
|
+ show: false,
|
|
|
+ data: {},
|
|
|
+});
|
|
|
+
|
|
|
+const submitLoading = ref(false);
|
|
|
+async function handleSubmit() {
|
|
|
+ if (!bookInfo.customerName) {
|
|
|
+ showToast("请填写联系人");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (!bookInfo.customerMobile) {
|
|
|
+ showToast("请填写联系电话");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (!bookInfo.customerWechat) {
|
|
|
+ showToast("请填写微信号");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ try {
|
|
|
+ submitLoading.value = true;
|
|
|
+ // 验证是否超过最大人数
|
|
|
+ const { data } = await request(
|
|
|
+ `/website/app/tourProjectGroupPurchase/view?id=${props.pinTuanData.id}`
|
|
|
+ );
|
|
|
+ if (
|
|
|
+ // 超出团购数量
|
|
|
+ data.nowCount +
|
|
|
+ (bookInfo.adultNumber ?? 0) +
|
|
|
+ (bookInfo.childrenNumber ?? 0) >
|
|
|
+ data.maxCount
|
|
|
+ ) {
|
|
|
+ applyKaiTuanModalOptions.show = true;
|
|
|
+ applyKaiTuanModalOptions.title = `此团库存仅剩余${data.maxCount - data.nowCount}位,若需要开团请直接联系客服为你新开拼团`;
|
|
|
+ submitLoading.value = false;
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ const { data: resData } = await request("/website/tourism/myOrder/add", {
|
|
|
+ method: "post",
|
|
|
+ body: {
|
|
|
+ projectId: id.value,
|
|
|
+ type: "1",
|
|
|
+ ...bookInfo,
|
|
|
+ startDate: props.pinTuanData.travelStartTime,
|
|
|
+ groupId: props.pinTuanData.id,
|
|
|
+ childrenNumber: bookInfo.childrenNumber ?? 0,
|
|
|
+ shareId: fromUserId.value,
|
|
|
+ },
|
|
|
+ });
|
|
|
+ submitLoading.value = false;
|
|
|
+ show.value = false;
|
|
|
+ resultModalOptions.data = resData;
|
|
|
+ resultModalOptions.show = true;
|
|
|
+ } catch (error) {
|
|
|
+ submitLoading.value = false;
|
|
|
+ }
|
|
|
+}
|
|
|
+</script>
|
|
|
+
|
|
|
+<style lang="scss" scoped></style>
|