| | |
| | | <LoadingLayout :loading="isLoading" :error="isError" :loadError="refetch"> |
| | | <ContentScrollView hasPaddingTop> |
| | | <ServiceDetailAddressCard |
| | | :name="defaultAddress?.name ?? ''" |
| | | :contactPhoneNumber="defaultAddress?.contactPhoneNumber ?? ''" |
| | | :addressDetail="defaultAddress?.addressDetail ?? ''" |
| | | :name="selectedAddress?.name ?? ''" |
| | | :contactPhoneNumber="selectedAddress?.contactPhoneNumber ?? ''" |
| | | :addressDetail="selectedAddress?.addressDetail ?? ''" |
| | | showArrow |
| | | @click="goSelectAddress" |
| | | /> |
| | | <div class="addStandardOrder-detail-card"> |
| | | <nut-card |
| | | :img-url="'//img10.360buyimg.com/n2/s240x240_jfs/t1/210890/22/4728/163829/6163a590Eb7c6f4b5/6390526d49791cb9.jpg!q70.jpg'" |
| | | :title="detail?.name ?? ''" |
| | | :price="toThousand(spec?.price ?? 0)" |
| | | class="service-good-card" |
| | | <ServiceDetailGoodCard |
| | | :name="detail?.name" |
| | | :price="spec?.price" |
| | | :specName="spec?.name" |
| | | :specNumber="specNumber" |
| | | :imgUrl="detail?.files?.[0]" |
| | | /> |
| | | <!-- <List> |
| | | <ListItem title="服务时间"> |
| | | <template #extra> |
| | | <div class="mine-service-detail-view-list-item">{{ '请选择' }}</div> |
| | | </template> |
| | | </ListItem> |
| | | <ListItem title="服务机构"> |
| | | <template #extra> |
| | | <div class="mine-service-detail-view-list-item">{{ '请选择' }}</div> |
| | | </template> |
| | | </ListItem> |
| | | </List> --> |
| | | <nut-form :model-value="form" ref="formRef" :rules="rules" class="addStandardOrder-form"> |
| | | <nut-form-item |
| | | label="服务开始时间:" |
| | | class="bole-form-item" |
| | | prop="beginTime" |
| | | label-width="90px" |
| | | > |
| | | <template #prolist> |
| | | <div class="card-tag-list"> |
| | | <span class="tag">{{ spec?.name }}</span> |
| | | </div> |
| | | </template> |
| | | <template #origin> |
| | | <div></div> |
| | | </template> |
| | | <template #footer> |
| | | <div class="card-footer">x{{ specNumber }}</div> |
| | | </template> |
| | | </nut-card> |
| | | </div> |
| | | <ChooseInputWithDatePicker |
| | | v-model="form.beginTime" |
| | | :minDate="nowDate" |
| | | placeholder="请选择" |
| | | type="datetime" |
| | | format="YYYY-MM-DD HH:mm:ss" |
| | | ></ChooseInputWithDatePicker> |
| | | </nut-form-item> |
| | | <nut-form-item |
| | | label="服务结束时间:" |
| | | class="bole-form-item" |
| | | prop="endTime" |
| | | label-width="90px" |
| | | > |
| | | <ChooseInputWithDatePicker |
| | | v-model="form.endTime" |
| | | :minDate="endMinTime" |
| | | :maxDate="endMaxTime" |
| | | placeholder="请选择" |
| | | type="datetime" |
| | | format="YYYY-MM-DD HH:mm:ss" |
| | | ></ChooseInputWithDatePicker> |
| | | </nut-form-item> |
| | | <nut-form-item |
| | | label="服务机构:" |
| | | class="bole-form-item" |
| | | prop="enterpriseEmployeeId" |
| | | label-width="90px" |
| | | > |
| | | <ChooseInputWithSuppliers |
| | | v-model:supplierEnterpriseId="form.supplierEnterpriseId" |
| | | placeholder="请选择" |
| | | :serviceId="id" |
| | | :beginTime="form.beginTime" |
| | | :endTime="form.endTime" |
| | | v-model:enterpriseEmployeeId="form.enterpriseEmployeeId" |
| | | v-model:enterpriseEmployeeName="form.enterpriseEmployeeName" |
| | | v-model:supplierEnterpriseName="form.supplierEnterpriseName" |
| | | ></ChooseInputWithSuppliers> |
| | | </nut-form-item> |
| | | <nut-form-item |
| | | label="备注:" |
| | | class="bole-form-item alignTop" |
| | | prop="remark" |
| | | label-width="90px" |
| | | > |
| | | <nut-textarea |
| | | v-model="form.remark" |
| | | class="bole-input-textarea" |
| | | rows="4" |
| | | placeholder="请填写备注信息" |
| | | > |
| | | </nut-textarea> |
| | | </nut-form-item> |
| | | </nut-form> |
| | | </ContentScrollView> |
| | | <PageFooter> |
| | | <PageFooter class="order-settle-bar"> |
| | | <div class="order-settle-price-wrapper"> |
| | | <div class="order-settle-price-label">支付:</div> |
| | | <nut-price :price="totlePrice" size="large" /> |
| | | </div> |
| | | <PageFooterBtn type="primary" class="business-card-btn" @click="goConfirm" |
| | | >立即下单</PageFooterBtn |
| | | > |
| | | </PageFooter> |
| | | <nut-address |
| | | v-model:visible="form.selectAddressVisible" |
| | | v-model:value="form.addressId" |
| | | type="exist" |
| | | :exist-address="existAddress" |
| | | :is-show-custom-address="false" |
| | | @selected="selected" |
| | | exist-address-title="选择地址" |
| | | ></nut-address> |
| | | </LoadingLayout> |
| | | </template> |
| | | |
| | | <script setup lang="ts"> |
| | | import { ServiceDetailAddressCard } from '@12333/components'; |
| | | import { |
| | | ServiceDetailAddressCard, |
| | | ServiceDetailGoodCard, |
| | | List, |
| | | ListItem, |
| | | ChooseInputWithDatePicker, |
| | | } from '@12333/components'; |
| | | import Taro from '@tarojs/taro'; |
| | | import * as standardServiceServices from '@12333/services/apiV2/standardService'; |
| | | import { RouterPath } from '@/constants'; |
| | | import { useStandardServiceDetail } from '@12333/hooks'; |
| | | import { toThousand } from '@12333/utils'; |
| | | import * as standardOrderServices from '@12333/services/apiV2/standardOrder'; |
| | | import { FormRules } from '@nutui/nutui-taro/dist/types/__VUE/form/types'; |
| | | import dayjs from 'dayjs'; |
| | | import { EnumUserBankCardAccess } from '@12333/constants'; |
| | | import { Message } from '@12333/utils'; |
| | | |
| | | defineOptions({ |
| | | name: 'InnerPage', |
| | |
| | | const specId = route.params?.specId ?? ''; |
| | | const specNumber = Number(route.params?.specNumber); |
| | | |
| | | const form = reactive({ |
| | | addressId: '', |
| | | selectAddressVisible: false, |
| | | beginTime: '', |
| | | endTime: '', |
| | | supplierEnterpriseId: '', |
| | | supplierEnterpriseName: '', |
| | | enterpriseEmployeeId: '', |
| | | enterpriseEmployeeName: '', |
| | | remark: '', |
| | | }); |
| | | |
| | | const nowDate = dayjs().toDate(); |
| | | const endMinTime = computed(() => { |
| | | if (form.beginTime) { |
| | | return dayjs(form.beginTime).add(1, 'minute').toDate(); |
| | | } else { |
| | | return dayjs().toDate(); |
| | | } |
| | | }); |
| | | const endMaxTime = computed(() => { |
| | | if (form.beginTime) { |
| | | return dayjs(dayjs(form.beginTime).format('YYYY-MM-DD 23:59:59')).toDate(); |
| | | } else { |
| | | return undefined; |
| | | } |
| | | }); |
| | | |
| | | const rules = reactive<FormRules>({ |
| | | beginTime: [{ required: true, message: '请选择服务开始时间' }], |
| | | endTime: [{ required: true, message: '请选择服务结束时间' }], |
| | | enterpriseEmployeeId: [{ required: true, message: '请选择服务机构' }], |
| | | }); |
| | | |
| | | const { isLoading, isError, detail, refetch } = useStandardServiceDetail({ |
| | | id, |
| | | }); |
| | |
| | | |
| | | const { infiniteLoadingProps } = useEnterpriseAddresses({ |
| | | rows: 100, |
| | | onSuccess(res) { |
| | | const data = res.pages[0].data; |
| | | const address = data.find((item) => item.isDefault); |
| | | if (address) { |
| | | form.addressId = address.id; |
| | | } else { |
| | | form.addressId = data[0].id; |
| | | } |
| | | }, |
| | | }); |
| | | |
| | | const defaultAddress = computed(() => { |
| | | const address = infiniteLoadingProps.value.flattenListData.find((item) => item.isDefault); |
| | | const existAddress = computed(() => { |
| | | return infiniteLoadingProps.value.flattenListData.map((x) => ({ |
| | | id: x.id, |
| | | addressDetail: x.addressDetail, |
| | | cityName: '', |
| | | countyName: '', |
| | | provinceName: '', |
| | | selectedAddress: x.id === form.addressId, |
| | | townName: '', |
| | | name: x.name, |
| | | phone: x.contactPhoneNumber, |
| | | })); |
| | | }); |
| | | |
| | | const selectedAddress = computed(() => { |
| | | const address = infiniteLoadingProps.value.flattenListData.find( |
| | | (item) => item.id === form.addressId |
| | | ); |
| | | return address || infiniteLoadingProps.value.flattenListData[0]; |
| | | }); |
| | | |
| | | function goCancel() { |
| | | Taro.navigateTo({ |
| | | url: `${RouterPath.mineReserveServiceCancel}?id=${id}`, |
| | | function goSelectAddress() { |
| | | // Taro.navigateTo({ |
| | | // url: `${RouterPath.addressManange}?mode=select`, |
| | | // }); |
| | | form.selectAddressVisible = true; |
| | | } |
| | | |
| | | const selected = (prevExistAdd, nowExistAdd, arr) => { |
| | | form.addressId = nowExistAdd.id; |
| | | }; |
| | | |
| | | const totlePrice = computed(() => { |
| | | return (spec.value?.price ?? 0) * specNumber; |
| | | }); |
| | | |
| | | const formRef = ref<any>(null); |
| | | function goConfirm() { |
| | | if (!formRef.value) return; |
| | | formRef.value.validate().then(({ valid, errors }: any) => { |
| | | if (valid) { |
| | | addStandardOrder(); |
| | | } |
| | | }); |
| | | } |
| | | |
| | | function goConfirm() { |
| | | Taro.navigateTo({ |
| | | url: `${RouterPath.mineReserveServiceConfirm}?id=${id}`, |
| | | }); |
| | | async function addStandardOrder() { |
| | | try { |
| | | let params: API.AddStandardOrderCommand = { |
| | | serviceId: detail.value.id, |
| | | serviceName: detail.value.name, |
| | | serviceCode: detail.value.code, |
| | | specId: spec.value.id, |
| | | specName: spec.value.name, |
| | | specPrice: spec.value.price ?? 0, |
| | | specNumber: specNumber, |
| | | addressId: form.addressId, |
| | | name: detail.value.name, |
| | | contactPhoneNumber: selectedAddress.value.contactPhoneNumber, |
| | | provinceCode: selectedAddress.value.provinceCode, |
| | | provinceContent: selectedAddress.value.provinceContent, |
| | | cityCode: selectedAddress.value.cityCode, |
| | | cityContent: selectedAddress.value.cityContent, |
| | | areaCode: selectedAddress.value.areaCode, |
| | | areaContent: selectedAddress.value.areaContent, |
| | | addressName: selectedAddress.value.addressName, |
| | | addressDetail: selectedAddress.value.addressDetail, |
| | | longitude: selectedAddress.value.longitude, |
| | | latitude: selectedAddress.value.latitude, |
| | | beginTime: dayjs(form.beginTime).format('YYYY-MM-DD HH:mm'), |
| | | endTime: dayjs(form.endTime).format('YYYY-MM-DD HH:mm'), |
| | | supplierEnterpriseId: form.supplierEnterpriseId, |
| | | enterpriseEmployeeIds: [form.enterpriseEmployeeId], |
| | | remark: form.remark, |
| | | payAccess: EnumUserBankCardAccess.WeChatPay, |
| | | }; |
| | | let res = await standardOrderServices.addStandardOrder(params); |
| | | if (res) { |
| | | payStandardOrder(res); |
| | | } |
| | | } catch (error) {} |
| | | } |
| | | |
| | | async function payStandardOrder(orderId: string) { |
| | | try { |
| | | let params: API.PayStandardOrderCommand = { |
| | | id: orderId, |
| | | }; |
| | | let res = await standardOrderServices.payStandardOrder(params); |
| | | if (res) { |
| | | await Taro.requestPayment({ |
| | | timeStamp: res.timestamp, |
| | | nonceStr: res.nonceStr, |
| | | package: res.package, |
| | | signType: res.signType as any, |
| | | paySign: res.paySign, |
| | | }); |
| | | Message.success('支付成功'); |
| | | Taro.redirectTo({ |
| | | url: `${RouterPath.mineOrderDetail}?id=${orderId}`, |
| | | }); |
| | | } |
| | | } catch (error) {} |
| | | } |
| | | </script> |
| | | |
| | | <style lang="scss"> |
| | | @import '@/styles/common.scss'; |
| | | |
| | | .addStandardOrder-page-wrapper { |
| | | .addStandardOrder-form { |
| | | .nut-cell-group__wrap { |
| | | box-shadow: none; |
| | | |
| | | .input-text, |
| | | .h5-textarea { |
| | | text-align: right !important; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .order-settle-bar { |
| | | .order-settle-price-wrapper { |
| | | height: 100%; |
| | | flex: 1; |
| | | min-width: 0; |
| | | display: flex; |
| | | align-items: center; |
| | | margin-left: 28px; |
| | | |
| | | .order-settle-price-label { |
| | | color: boleGetCssVar('text-color', 'primary'); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | </style> |