| | |
| | | pages: [ |
| | | 'phoneBillRecharge/phoneBillRecharge', |
| | | 'electricBillRecharge/electricBillRecharge', |
| | | 'gasBillRecharge/gasBillRecharge', |
| | | 'selectPayType/selectPayType', |
| | | 'rechargeResult/rechargeResult', |
| | | 'rechargeElectricResult/rechargeElectricResult', |
| | |
| | | |
| | | phoneBillRecharge = '/subpackages/recharge/phoneBillRecharge/phoneBillRecharge', |
| | | electricBillRecharge = '/subpackages/recharge/electricBillRecharge/electricBillRecharge', |
| | | gasBillRecharge = '/subpackages/recharge/gasBillRecharge/gasBillRecharge', |
| | | order = '/subpackages/order/order/order', |
| | | selectPayType = '/subpackages/recharge/selectPayType/selectPayType', |
| | | rechargeResult = '/subpackages/recharge/rechargeResult/rechargeResult', |
| | |
| | | }); |
| | | const goGasBillRecharge = useAccessLogin(() => { |
| | | Taro.navigateTo({ |
| | | url: `${RouterPath.electricBillRecharge}`, |
| | | url: `${RouterPath.gasBillRecharge}`, |
| | | }); |
| | | }); |
| | | </script> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div>çæ°å
å¼</div> |
| | | </template> |
| | | |
| | | <script setup lang="ts"> |
| | | defineOptions({ |
| | | name: 'InnerPage', |
| | | }); |
| | | </script> |
| | | |
| | | <style lang="scss"> |
| | | @import '@/styles/common.scss'; |
| | | </style> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | export default definePageConfig({ |
| | | disableScroll: true, |
| | | }); |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <PageLayout title="çæ°å
å¼" class="gasBillRecharge-page-wrapper" hasBorder> |
| | | <InnerPage /> |
| | | </PageLayout> |
| | | </template> |
| | | |
| | | <script setup lang="ts"> |
| | | import { PageLayout } from '@/components'; |
| | | import InnerPage from './InnerPage.vue'; |
| | | |
| | | defineOptions({ |
| | | name: 'gasBillRecharge', |
| | | }); |
| | | </script> |
| | |
| | | <template> |
| | | <PageLayout title="å
弿å" class="rechargeResult-page-wrapper" hasBorder> |
| | | <ContentScrollView> |
| | | <RechargeResultView style="margin-top: 40px" @go-back-home="goHome()" /> |
| | | <RechargeResultView style="margin-top: 40px" @go-back-home="goHome()" :orderNo="orderNo" /> |
| | | </ContentScrollView> |
| | | </PageLayout> |
| | | </template> |
| | |
| | | import { PageLayout } from '@/components'; |
| | | import { goHome } from '@/utils'; |
| | | import { RechargeResultView } from '@life-payment/components'; |
| | | import Taro from '@tarojs/taro'; |
| | | |
| | | defineOptions({ |
| | | name: 'rechargeResult', |
| | | }); |
| | | |
| | | const router = Taro.useRouter(); |
| | | const orderNo = router.params?.orderNo ?? ''; |
| | | </script> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div class="account-add-card"><Uploader /> æ°å¢ææºå·</div> |
| | | </template> |
| | | |
| | | <script setup lang="ts"> |
| | | import { Uploader } from '@nutui/icons-vue-taro'; |
| | | |
| | | defineOptions({ |
| | | name: 'AccountAddCard', |
| | | }); |
| | | </script> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div class="account-card"> |
| | | <div class="account-card-top"> |
| | | <div class="account-card-title">{{ title }}</div> |
| | | <div class="account-card-actions"> |
| | | <slot name="action" /> |
| | | </div> |
| | | </div> |
| | | <div class="account-card-content">{{ content }}</div> |
| | | <div class="account-card-remark">{{ remark }}</div> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup lang="ts"> |
| | | defineOptions({ |
| | | name: 'AccountCard', |
| | | }); |
| | | |
| | | type Props = { |
| | | title?: string; |
| | | content?: string; |
| | | remark?: string; |
| | | }; |
| | | |
| | | const props = withDefaults(defineProps<Props>(), {}); |
| | | </script> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div class="par-account-list"></div> |
| | | </template> |
| | | |
| | | <script setup lang="ts"> |
| | | defineOptions({ |
| | | name: 'AccountList', |
| | | }); |
| | | </script> |
| | |
| | | <template> |
| | | <div class="confirm-dialog-content-info-item" :class="{ danger }"> |
| | | <div class="confirm-dialog-content-info-item-label">{{ label }}</div> |
| | | <div class="confirm-dialog-content-info-item-label" :style="{ width: _labelWidth }"> |
| | | {{ label }} |
| | | </div> |
| | | <div class="confirm-dialog-content-info-item-content">{{ content }}</div> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup lang="ts"> |
| | | import Taro from '@tarojs/taro'; |
| | | import { computed } from 'vue'; |
| | | |
| | | defineOptions({ |
| | | name: 'ConfirmDialogInfoItem', |
| | | }); |
| | |
| | | label?: string; |
| | | content?: string | number; |
| | | danger?: boolean; |
| | | labelWidth?: string | number; |
| | | }; |
| | | |
| | | const props = withDefaults(defineProps<Props>(), {}); |
| | | const props = withDefaults(defineProps<Props>(), { |
| | | labelWidth: 'auto', |
| | | }); |
| | | |
| | | const _labelWidth = computed(() => { |
| | | if (typeof props.labelWidth === 'string') { |
| | | return props.labelWidth; |
| | | } |
| | | |
| | | return Taro.pxTransform(props.labelWidth); |
| | | }); |
| | | </script> |
| | |
| | | */ |
| | | Desc, |
| | | } |
| | | |
| | | export const CustomerServicePhone = '16505012333'; |
| | | export const CustomerServiceTips = `å¦å
å¼è¿ç¨ä¸éå°é®é¢ï¼è¯·è系客æ ${CustomerServicePhone}ï¼å¨ä¸å°å¨äº 9:00-17:30ï¼`; |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | @use './common.scss' as *; |
| | | |
| | | .account-add-card { |
| | | border-radius: 16px; |
| | | min-height: 120px; |
| | | border: 1px solid #e8e8e8; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | font-size: 32px; |
| | | color: boleGetCssVar('color', 'primary'); |
| | | } |
| | | |
| | | .account-card { |
| | | border-radius: 16px; |
| | | border: 1px solid #e8e8e8; |
| | | padding: 28px; |
| | | |
| | | .account-card-top { |
| | | display: flex; |
| | | font-size: 28px; |
| | | line-height: 32px; |
| | | align-items: center; |
| | | margin-bottom: 32px; |
| | | |
| | | .account-card-title { |
| | | flex: 1; |
| | | min-width: 0; |
| | | @include ellipsis; |
| | | color: boleGetCssVar('text-color', 'primary'); |
| | | } |
| | | |
| | | .account-card-actions { |
| | | display: flex; |
| | | align-items: center; |
| | | |
| | | .account-card-action { |
| | | color: boleGetCssVar('color', 'primary'); |
| | | } |
| | | |
| | | .account-card-action + .account-card-action { |
| | | margin-left: 10px; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .account-card-content { |
| | | font-size: 36px; |
| | | font-weight: bold; |
| | | line-height: 48px; |
| | | align-items: center; |
| | | margin-bottom: 32px; |
| | | color: boleGetCssVar('text-color', 'primary'); |
| | | @include ellipsis; |
| | | } |
| | | |
| | | .account-card-remark { |
| | | font-size: 28px; |
| | | line-height: 32px; |
| | | color: boleGetCssVar('text-color', 'secondary'); |
| | | @include ellipsis; |
| | | } |
| | | } |
| | | |
| | | .par-account-list { |
| | | .nut-radio--button { |
| | | margin-bottom: 20px !important; |
| | | } |
| | | } |
| | |
| | | .confirm-dialog-content-info-item-label { |
| | | color: boleGetCssVar('text-color', 'regular'); |
| | | margin-right: 12px; |
| | | text-align: left; |
| | | } |
| | | |
| | | .confirm-dialog-content-info-item-content { |
| | |
| | | line-height: 48px; |
| | | } |
| | | |
| | | .recharge-result-view-subtitle { |
| | | font-size: 28px; |
| | | color: boleGetCssVar('text-color', 'primary'); |
| | | margin-bottom: 24px; |
| | | text-align: center; |
| | | line-height: 32px; |
| | | } |
| | | |
| | | .recharge-result-view-tips { |
| | | margin-bottom: 24px; |
| | | font-size: 32px; |
| | |
| | | } |
| | | |
| | | .recharge-result-view-warning { |
| | | margin-bottom: 40px; |
| | | margin-bottom: 24px; |
| | | font-size: 24px; |
| | | color: boleGetCssVar('color', 'warning'); |
| | | line-height: 32px; |
| | | } |
| | | |
| | | .recharge-result-view-customerService { |
| | | margin-bottom: 40px; |
| | | font-size: 24px; |
| | | color: boleGetCssVar('text-color', 'primary'); |
| | | line-height: 32px; |
| | | } |
| | | |
| | | .recharge-result-view-btn-wrapper { |
| | | display: flex; |
| | | justify-content: center; |
| | |
| | | @use './var.scss' as *; |
| | | @use './function.scss' as *; |
| | | @use './orderCard.scss' as *; |
| | | @use './card.scss' as *; |
| | | @use './nut.scss' as *; |
| | | @use './layout.scss' as *; |
| | | @use './rechargeGrid.scss' as *; |
| | |
| | | <template> |
| | | <NutForm |
| | | :model-value="form" |
| | | ref="formRef" |
| | | :rules="rules" |
| | | label-position="top" |
| | | class="order-bill-recharge phone" |
| | | > |
| | | <NutFormItem label="éæ©è¿è¥å:" class="bole-form-item" prop="ispCode" required> |
| | | <NutRadioGroup v-model="form.ispCode" direction="horizontal" @change="changeIspCode"> |
| | | <BlRadio |
| | | :label="key" |
| | | v-for="(val, key) in BlLifeRecharge.constants.IspCodeText" |
| | | :key="key" |
| | | >{{ val }}</BlRadio |
| | | > |
| | | </NutRadioGroup> |
| | | </NutFormItem> |
| | | <NutFormItem label="å
弿æºå·" class="bole-form-item" prop="phone" required> |
| | | <NutInput |
| | | v-model.trim="form.phone" |
| | | class="bole-input-text" |
| | | placeholder="è¯·å¡«åæ¨éè¦å
å¼çææºå·ç " |
| | | type="text" |
| | | /> |
| | | </NutFormItem> |
| | | <NutFormItem |
| | | label="å§å" |
| | | class="bole-form-item" |
| | | prop="name" |
| | | required |
| | | v-if="form.ispCode === BlLifeRecharge.constants.IspCode.dianxin" |
| | | > |
| | | <NutInput |
| | | v-model.trim="form.name" |
| | | class="bole-input-text" |
| | | placeholder="è¯·å¡«åæ¨çå§å" |
| | | type="text" |
| | | /> |
| | | </NutFormItem> |
| | | <NutFormItem label="éæ©å
å¼éé¢" class="bole-form-item" prop="parValue" required> |
| | | <NutRadioGroup v-model="form.parValue" direction="horizontal" class="parValue-radio-group"> |
| | | <NutRadio |
| | | :label="Number(item)" |
| | | :key="item" |
| | | shape="button" |
| | | v-for="item in parValueList" |
| | | class="parValue-item" |
| | | > |
| | | <div class="parValue-item-inner"> |
| | | <div class="amount-wrapper"> |
| | | <div class="amount">{{ item }}</div> |
| | | <div class="unit">å
</div> |
| | | </div> |
| | | <div class="price-wrapper"> |
| | | <div class="price-text">æå</div> |
| | | <div class="price"> |
| | | {{ blLifeRecharge.getRechargeParValue(item, lifePayPhoneRate) }}å
|
| | | </div> |
| | | </div> |
| | | <div class="discountTag">{{ lifePayPhoneRate * 100 }}æ</div> |
| | | </div> |
| | | </NutRadio> |
| | | </NutRadioGroup> |
| | | </NutFormItem> |
| | | <div class="common-content"> |
| | | <nut-button class="recharge-button" type="primary" @click="handleSubmit"> |
| | | <div class="recharge-button-inner"> |
| | | <div>ï¿¥{{ realParValue }}</div> |
| | | <div class="recharge-button-text">ç«å³å
å¼</div> |
| | | </div> |
| | | </nut-button> |
| | | <RechargeTipsView :tips="tips" /> |
| | | </div> |
| | | <ConfirmDialog v-model:visible="confirmDialogVisible" @ok="goPay"> |
| | | <template #info> |
| | | <ConfirmDialogInfoItem label="å
å¼è´¦å·" :content="form.phone" /> |
| | | <ConfirmDialogInfoItem label="å
å¼éé¢" :content="`ï¿¥${form.parValue.toFixed(2)}`" danger /> |
| | | <ConfirmDialogInfoItem label="伿 éé¢" :content="`ï¿¥${discountParValue.toFixed(2)}`" /> |
| | | <ConfirmDialogInfoItem label="å®ä»éé¢" :content="`ï¿¥${realParValue}`" danger /> |
| | | </template> |
| | | </ConfirmDialog> |
| | | </NutForm> |
| | | <PhoneBillRechargeStep1 v-if="current === 'step1'" /> |
| | | <PhoneBillRechargeStep2 |
| | | v-else-if="current === 'step2'" |
| | | v-bind="props" |
| | | @go-pay="emit('goPay', $event)" |
| | | /> |
| | | </template> |
| | | |
| | | <script setup lang="ts"> |
| | | import { |
| | | Form as NutForm, |
| | | FormItem as NutFormItem, |
| | | RadioGroup as NutRadioGroup, |
| | | Radio as NutRadio, |
| | | Input as NutInput, |
| | | Button as NutButton, |
| | | } from '@nutui/nutui-taro'; |
| | | import { FormRules } from '@nutui/nutui-taro/dist/types/__VUE/form/types'; |
| | | import { reactive, ref, computed } from 'vue'; |
| | | import BlRadio from '../../components/Radio/Radio.vue'; |
| | | import { FormValidator } from '../../utils'; |
| | | import { |
| | | useLifeRechargeContext, |
| | | BlLifeRecharge, |
| | | LifePhoneDataCreateLifePayOrderInput, |
| | | LifeRechargeConstants, |
| | | } from '@life-payment/core-vue'; |
| | | import RechargeTipsView from '../../components/RechargeTipsView/RechargeTipsView.vue'; |
| | | import ConfirmDialog from '../../components/Dialog/ConfirmDialog.vue'; |
| | | import ConfirmDialogInfoItem from '../../components/Dialog/ConfirmDialogInfoItem.vue'; |
| | | import { useGetRate, useGetPhoneParValue } from '../../hooks'; |
| | | import { computed, provide } from 'vue'; |
| | | import { useStepper } from 'senin-mini/hooks'; |
| | | import { PhoneBillRechargeContextKey } from './context'; |
| | | import PhoneBillRechargeStep1 from './PhoneBillRechargeStep1.vue'; |
| | | import PhoneBillRechargeStep2 from './PhoneBillRechargeStep2.vue'; |
| | | |
| | | defineOptions({ |
| | | name: 'PhoneBillRecharge', |
| | |
| | | isDev: false, |
| | | }); |
| | | |
| | | const form = reactive({ |
| | | ispCode: '', |
| | | phone: '', |
| | | parValue: 0, |
| | | name: '', |
| | | }); |
| | | const stepperInfo = useStepper(['step1', 'step2'], 'step2'); |
| | | const current = computed(() => stepperInfo.current.value); |
| | | |
| | | const emit = defineEmits<{ |
| | | (e: 'goPay', orderNo: string): void; |
| | | }>(); |
| | | |
| | | const { lifePayPhoneRate } = useGetRate(); |
| | | const { phoneParValueList } = useGetPhoneParValue(); |
| | | |
| | | const parValueList = computed( |
| | | () => phoneParValueList.value.find((x) => x.ispCode === form.ispCode)?.parValue ?? [] |
| | | ); |
| | | |
| | | function changeIspCode(val: LifeRechargeConstants.IspCode) { |
| | | const phoneParValueItem = phoneParValueList.value.find((x) => x.ispCode === val); |
| | | if (phoneParValueItem.parValue.every((x) => Number(x) !== form.parValue)) { |
| | | form.parValue = 0; |
| | | } |
| | | } |
| | | |
| | | const realParValue = computed(() => |
| | | blLifeRecharge.getRechargeParValue(form.parValue, lifePayPhoneRate.value) |
| | | ); |
| | | const discountParValue = computed(() => form.parValue - Number(realParValue.value)); |
| | | |
| | | const { blLifeRecharge } = useLifeRechargeContext(); |
| | | |
| | | const rules = reactive<FormRules>({ |
| | | ispCode: [{ required: true, message: 'è¯·éæ©è¿è¥å' }], |
| | | phone: [ |
| | | { required: true, message: '请è¾å
¥å
弿æºå·' }, |
| | | { validator: FormValidator.validatorPhoneNumber, message: '请è¾å
¥æ£ç¡®çææºå·' }, |
| | | ], |
| | | name: [{ required: true, message: '请è¾å
¥å§å' }], |
| | | parValue: [ |
| | | { required: true, message: 'è¯·éæ©å
å¼éé¢', validator: FormValidator.validatorNumberNotNull }, |
| | | ], |
| | | provide(PhoneBillRechargeContextKey, { |
| | | ...stepperInfo, |
| | | }); |
| | | |
| | | const formRef = ref<any>(null); |
| | | |
| | | function handleSubmit() { |
| | | if (!formRef.value) return; |
| | | formRef.value.validate().then(({ valid, errors }: any) => { |
| | | if (valid) { |
| | | recharge(); |
| | | } |
| | | }); |
| | | } |
| | | |
| | | const tips = [ |
| | | '平尿便
¢å
æå¡ï¼è®¢åæäº¤åï¼è¯è´¹å°äº0 - 24å°æ¶å
å°è´¦ãè¥æªè½ææ¶å°è´¦ï¼ç³»ç»å°èªå¨åèµ·éæ¬¾ã', |
| | | 'å
弿é´ï¼è¥åä¸å·ç 款项æªå°è´¦ï¼è¯·å¿å¨å
¶ä»å¹³å°éå¤å
å¼ï¼ä¸»å¯å¡ä¸å¯åæ¶å
å¼ãå ä¸è¿°æä½å¯¼è´çèµéæå¤±ï¼ç±ç¨æ·èªè¡æ¿æ
ã', |
| | | 'æ¬å¹³å°è¯è´¹å
弿å¡ä¸éç¨äºå·²åæºå·ç ãçµä¿¡å·ç è¥ææ¬ è´¹ï¼ä¹æ æ³å®æå
å¼ãçµä¿¡å·²å®æç»´æ¤çåºåå
æ¬ï¼å¹¿ä¸ãæ±èãæ¹åãåå·ãæ±è¥¿ãæ²³åãæ²³åãç¦å»ºãè¾½å®ãå
¶å®åºåæ£å¨åæ¹æ¬¡è¿è¡ç»´æ¤ä¸ï¼å¨æ¤æé´å¯è½ä¼åºç°å
å¼ä¸æåå¹¶èªå¨é款çæ
åµï¼è¯·æ¨è°
è§£ã', |
| | | '妿¥å°éçæ¥çµï¼å¯¹æ¹ä»¥ç¼´è´¹æè¯¯æä½ççç±è¦æ±å¤ç款项ï¼å¡å¿
ç«å³æé»ï¼è°¨é²è¯éªã', |
| | | 'å
å¼å票ç±è¿è¥åæä¾ï¼æ¨å¯ç»å½ç½ä¸è¥ä¸å
ä¸è½½çµåå票ã', |
| | | ]; |
| | | |
| | | const confirmDialogVisible = ref(false); |
| | | |
| | | function recharge() { |
| | | confirmDialogVisible.value = true; |
| | | } |
| | | |
| | | async function goPay() { |
| | | try { |
| | | let params: LifePhoneDataCreateLifePayOrderInput = { |
| | | userId: blLifeRecharge.accountModel.userId, |
| | | productData: { |
| | | ispCode: form.ispCode, |
| | | parValue: props.isDev ? 0.1 : form.parValue, |
| | | phone: form.phone, |
| | | name: form.ispCode === BlLifeRecharge.constants.IspCode.dianxin ? form.name : '', |
| | | }, |
| | | }; |
| | | let res = await blLifeRecharge.services.createLifePayPhoneOrder(params); |
| | | emit('goPay', res.orderNo); |
| | | } catch (error) {} |
| | | } |
| | | </script> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <NutForm |
| | | :model-value="form" |
| | | ref="formRef" |
| | | :rules="rules" |
| | | label-position="top" |
| | | class="order-bill-recharge phone" |
| | | > |
| | | <NutFormItem label="éæ©è¿è¥å:" class="bole-form-item" prop="ispCode" required> |
| | | <NutRadioGroup v-model="form.ispCode" direction="horizontal"> |
| | | <BlRadio |
| | | :label="key" |
| | | v-for="(val, key) in BlLifeRecharge.constants.IspCodeText" |
| | | :key="key" |
| | | >{{ val }}</BlRadio |
| | | > |
| | | </NutRadioGroup> |
| | | </NutFormItem> |
| | | <NutFormItem label="å
弿æºå·" class="bole-form-item" prop="phone" required> |
| | | <NutInput |
| | | v-model.trim="form.phone" |
| | | class="bole-input-text" |
| | | placeholder="è¯·å¡«åæ¨éè¦å
å¼çææºå·ç " |
| | | type="text" |
| | | /> |
| | | </NutFormItem> |
| | | <NutFormItem |
| | | label="å§å" |
| | | class="bole-form-item" |
| | | prop="name" |
| | | required |
| | | v-if="form.ispCode === BlLifeRecharge.constants.IspCode.dianxin" |
| | | > |
| | | <NutInput |
| | | v-model.trim="form.name" |
| | | class="bole-input-text" |
| | | placeholder="è¯·å¡«åæ¨çå§å" |
| | | type="text" |
| | | /> |
| | | </NutFormItem> |
| | | <slot></slot> |
| | | </NutForm> |
| | | </template> |
| | | |
| | | <script setup lang="ts"> |
| | | import { |
| | | Form as NutForm, |
| | | FormItem as NutFormItem, |
| | | RadioGroup as NutRadioGroup, |
| | | Input as NutInput, |
| | | } from '@nutui/nutui-taro'; |
| | | import { FormRules } from '@nutui/nutui-taro/dist/types/__VUE/form/types'; |
| | | import { reactive, ref, computed } from 'vue'; |
| | | import BlRadio from '../../components/Radio/Radio.vue'; |
| | | import { FormValidator } from '../../utils'; |
| | | import { BlLifeRecharge } from '@life-payment/core-vue'; |
| | | |
| | | defineOptions({ |
| | | name: 'PhoneBillRechargeBaseForm', |
| | | }); |
| | | |
| | | const form = defineModel<{ |
| | | ispCode: string; |
| | | phone: string; |
| | | name: string; |
| | | }>('form'); |
| | | |
| | | const rules = reactive<FormRules>({ |
| | | ispCode: [{ required: true, message: 'è¯·éæ©è¿è¥å' }], |
| | | phone: [ |
| | | { required: true, message: '请è¾å
¥å
弿æºå·' }, |
| | | { validator: FormValidator.validatorPhoneNumber, message: '请è¾å
¥æ£ç¡®çææºå·' }, |
| | | ], |
| | | name: [{ required: true, message: '请è¾å
¥å§å' }], |
| | | }); |
| | | |
| | | const formRef = ref<any>(null); |
| | | |
| | | defineExpose({ |
| | | validate: computed(() => formRef.value.validate), |
| | | }); |
| | | </script> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <PhoneBillRechargeBaseForm ref="formRef" v-model:form="form"> |
| | | <div class="common-content"> |
| | | <nut-button class="recharge-button" type="primary" @click="handleNext"> |
| | | <div class="recharge-button-inner"> |
| | | <div class="recharge-button-text">ç«å³å
å¼</div> |
| | | </div> |
| | | </nut-button> |
| | | </div> |
| | | </PhoneBillRechargeBaseForm> |
| | | </template> |
| | | |
| | | <script setup lang="ts"> |
| | | import { |
| | | Form as NutForm, |
| | | FormItem as NutFormItem, |
| | | RadioGroup as NutRadioGroup, |
| | | Radio as NutRadio, |
| | | Input as NutInput, |
| | | Button as NutButton, |
| | | } from '@nutui/nutui-taro'; |
| | | import { FormRules } from '@nutui/nutui-taro/dist/types/__VUE/form/types'; |
| | | import { reactive, ref, computed, provide } from 'vue'; |
| | | import BlRadio from '../../components/Radio/Radio.vue'; |
| | | import { FormValidator } from '../../utils'; |
| | | import { |
| | | useLifeRechargeContext, |
| | | BlLifeRecharge, |
| | | LifePhoneDataCreateLifePayOrderInput, |
| | | LifeRechargeConstants, |
| | | } from '@life-payment/core-vue'; |
| | | import RechargeTipsView from '../../components/RechargeTipsView/RechargeTipsView.vue'; |
| | | import ConfirmDialog from '../../components/Dialog/ConfirmDialog.vue'; |
| | | import ConfirmDialogInfoItem from '../../components/Dialog/ConfirmDialogInfoItem.vue'; |
| | | import { useGetRate, useGetPhoneParValue } from '../../hooks'; |
| | | import PhoneBillRechargeBaseForm from './PhoneBillRechargeBaseForm.vue'; |
| | | import { usePhoneBillRechargeContext } from './context'; |
| | | |
| | | defineOptions({ |
| | | name: 'PhoneBillRechargeStep1', |
| | | }); |
| | | |
| | | const form = reactive({ |
| | | ispCode: '', |
| | | phone: '', |
| | | name: '', |
| | | }); |
| | | |
| | | const { goToNext } = usePhoneBillRechargeContext(); |
| | | |
| | | const formRef = ref<any>(null); |
| | | |
| | | function handleNext() { |
| | | if (!formRef.value) return; |
| | | formRef.value.validate().then(({ valid, errors }: any) => { |
| | | if (valid) { |
| | | goToNext(); |
| | | } |
| | | }); |
| | | } |
| | | </script> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <NutForm |
| | | :model-value="form" |
| | | ref="formRef" |
| | | :rules="rules" |
| | | label-position="top" |
| | | class="order-bill-recharge phone" |
| | | > |
| | | <NutFormItem class="bole-form-item"> |
| | | <!-- <AccountAddCard /> --> |
| | | <NutRadioGroup v-model="val1" direction="horizontal" class="par-account-list"> |
| | | <NutRadio label="1" shape="button">Option 1</NutRadio> |
| | | <NutRadio label="2" shape="button">Option 2</NutRadio> |
| | | <NutRadio label="3" shape="button">Option 3</NutRadio> |
| | | <NutRadio label="4" shape="button">Option 4</NutRadio> |
| | | <NutRadio label="5" shape="button">Option 5</NutRadio> |
| | | <NutRadio label="6" shape="button">Option 6</NutRadio> |
| | | </NutRadioGroup> |
| | | <AccountCard title="å
弿æºå·" content="18858418480" remark="çå°æ¹éªå²çå¼å§å"> |
| | | <template #action> |
| | | <div class="account-card-action">æ°å¢</div> |
| | | </template> |
| | | </AccountCard> |
| | | </NutFormItem> |
| | | |
| | | <NutFormItem label="éæ©å
å¼éé¢" class="bole-form-item" prop="parValue" required> |
| | | <NutRadioGroup v-model="form.parValue" direction="horizontal" class="parValue-radio-group"> |
| | | <NutRadio |
| | | :label="Number(item)" |
| | | :key="item" |
| | | shape="button" |
| | | v-for="item in parValueList" |
| | | class="parValue-item" |
| | | > |
| | | <div class="parValue-item-inner"> |
| | | <div class="amount-wrapper"> |
| | | <div class="amount">{{ item }}</div> |
| | | <div class="unit">å
</div> |
| | | </div> |
| | | <div class="price-wrapper"> |
| | | <div class="price-text">æå</div> |
| | | <div class="price"> |
| | | {{ blLifeRecharge.getRechargeParValue(item, lifePayPhoneRate) }}å
|
| | | </div> |
| | | </div> |
| | | <div class="discountTag">{{ lifePayPhoneRate * 100 }}æ</div> |
| | | </div> |
| | | </NutRadio> |
| | | </NutRadioGroup> |
| | | </NutFormItem> |
| | | <div class="common-content"> |
| | | <nut-button class="recharge-button" type="primary" @click="handleSubmit"> |
| | | <div class="recharge-button-inner"> |
| | | <div>ï¿¥{{ realParValue }}</div> |
| | | <div class="recharge-button-text">ç«å³å
å¼</div> |
| | | </div> |
| | | </nut-button> |
| | | <RechargeTipsView :tips="tips" /> |
| | | </div> |
| | | <ConfirmDialog v-model:visible="confirmDialogVisible" @ok="goPay"> |
| | | <template #info> |
| | | <ConfirmDialogInfoItem label="å
å¼è´¦å·" :content="form.phone" /> |
| | | <ConfirmDialogInfoItem label="å
å¼éé¢" :content="`ï¿¥${form.parValue.toFixed(2)}`" danger /> |
| | | <ConfirmDialogInfoItem label="伿 éé¢" :content="`ï¿¥${discountParValue.toFixed(2)}`" /> |
| | | <ConfirmDialogInfoItem label="å®ä»éé¢" :content="`ï¿¥${realParValue}`" danger /> |
| | | </template> |
| | | </ConfirmDialog> |
| | | </NutForm> |
| | | </template> |
| | | |
| | | <script setup lang="ts"> |
| | | import { |
| | | Form as NutForm, |
| | | FormItem as NutFormItem, |
| | | RadioGroup as NutRadioGroup, |
| | | Radio as NutRadio, |
| | | Input as NutInput, |
| | | Button as NutButton, |
| | | } from '@nutui/nutui-taro'; |
| | | import { FormRules } from '@nutui/nutui-taro/dist/types/__VUE/form/types'; |
| | | import { reactive, ref, computed, provide } from 'vue'; |
| | | import { FormValidator } from '../../utils'; |
| | | import { |
| | | useLifeRechargeContext, |
| | | BlLifeRecharge, |
| | | LifePhoneDataCreateLifePayOrderInput, |
| | | LifeRechargeConstants, |
| | | } from '@life-payment/core-vue'; |
| | | import RechargeTipsView from '../../components/RechargeTipsView/RechargeTipsView.vue'; |
| | | import ConfirmDialog from '../../components/Dialog/ConfirmDialog.vue'; |
| | | import ConfirmDialogInfoItem from '../../components/Dialog/ConfirmDialogInfoItem.vue'; |
| | | import { useGetRate, useGetPhoneParValue } from '../../hooks'; |
| | | import { CustomerServiceTips } from '../../constants'; |
| | | import AccountAddCard from '../../components/Card/AccountAddCard.vue'; |
| | | import AccountCard from '../../components/Card/AccountCard.vue'; |
| | | |
| | | defineOptions({ |
| | | name: 'PhoneBillRechargeStep2', |
| | | }); |
| | | |
| | | type Props = { |
| | | isDev?: boolean; |
| | | }; |
| | | |
| | | const props = withDefaults(defineProps<Props>(), { |
| | | isDev: false, |
| | | }); |
| | | |
| | | const form = reactive({ |
| | | ispCode: '', |
| | | phone: '', |
| | | parValue: 0, |
| | | name: '', |
| | | }); |
| | | |
| | | const val1 = ref(''); |
| | | |
| | | const emit = defineEmits<{ |
| | | (e: 'goPay', orderNo: string): void; |
| | | }>(); |
| | | |
| | | const { lifePayPhoneRate } = useGetRate(); |
| | | const { phoneParValueList } = useGetPhoneParValue(); |
| | | |
| | | const parValueList = computed(() => { |
| | | const _parValueList = |
| | | phoneParValueList.value.find((x) => x.ispCode === form.ispCode)?.parValue ?? []; |
| | | return blLifeRecharge.filterParValueList(_parValueList); |
| | | }); |
| | | |
| | | function changeIspCode(val: LifeRechargeConstants.IspCode) { |
| | | const phoneParValueItem = phoneParValueList.value.find((x) => x.ispCode === val); |
| | | if (phoneParValueItem.parValue.every((x) => Number(x) !== form.parValue)) { |
| | | form.parValue = 0; |
| | | } |
| | | } |
| | | |
| | | const realParValue = computed(() => |
| | | blLifeRecharge.getRechargeParValue(form.parValue, lifePayPhoneRate.value) |
| | | ); |
| | | const discountParValue = computed(() => form.parValue - Number(realParValue.value)); |
| | | |
| | | const { blLifeRecharge } = useLifeRechargeContext(); |
| | | |
| | | const rules = reactive<FormRules>({ |
| | | parValue: [ |
| | | { required: true, message: 'è¯·éæ©å
å¼éé¢', validator: FormValidator.validatorNumberNotNull }, |
| | | ], |
| | | }); |
| | | |
| | | const formRef = ref<any>(null); |
| | | |
| | | function handleSubmit() { |
| | | if (!formRef.value) return; |
| | | formRef.value.validate().then(({ valid, errors }: any) => { |
| | | if (valid) { |
| | | recharge(); |
| | | } |
| | | }); |
| | | } |
| | | |
| | | const tips = [ |
| | | '平尿便
¢å
æå¡ï¼è®¢åæäº¤åï¼è¯è´¹å°äº0 - 24å°æ¶å
å°è´¦ãè¥æªè½ææ¶å°è´¦ï¼ç³»ç»å°èªå¨åèµ·éæ¬¾ã', |
| | | 'å
弿é´ï¼è¥åä¸å·ç 款项æªå°è´¦ï¼è¯·å¿å¨å
¶ä»å¹³å°éå¤å
å¼ï¼ä¸»å¯å¡ä¸å¯åæ¶å
å¼ãå ä¸è¿°æä½å¯¼è´çèµéæå¤±ï¼ç±ç¨æ·èªè¡æ¿æ
ã', |
| | | 'æ¬å¹³å°è¯è´¹å
弿å¡ä¸éç¨äºå·²åæºå·ç ãçµä¿¡å·ç è¥ææ¬ è´¹ï¼ä¹æ æ³å®æå
å¼ãçµä¿¡å·²å®æç»´æ¤çåºåå
æ¬ï¼å¹¿ä¸ãæ±èãæ¹åãåå·ãæ±è¥¿ãæ²³åãæ²³åãç¦å»ºãè¾½å®ãå
¶å®åºåæ£å¨åæ¹æ¬¡è¿è¡ç»´æ¤ä¸ï¼å¨æ¤æé´å¯è½ä¼åºç°å
å¼ä¸æåå¹¶èªå¨é款çæ
åµï¼è¯·æ¨è°
è§£ã', |
| | | '妿¥å°éçæ¥çµï¼å¯¹æ¹ä»¥ç¼´è´¹æè¯¯æä½ççç±è¦æ±å¤ç款项ï¼å¡å¿
ç«å³æé»ï¼è°¨é²è¯éªã', |
| | | 'å
å¼å票ç±è¿è¥åæä¾ï¼æ¨å¯ç»å½ç½ä¸è¥ä¸å
ä¸è½½çµåå票ã', |
| | | CustomerServiceTips, |
| | | ]; |
| | | |
| | | const confirmDialogVisible = ref(false); |
| | | |
| | | function recharge() { |
| | | confirmDialogVisible.value = true; |
| | | } |
| | | |
| | | async function goPay() { |
| | | try { |
| | | let params: LifePhoneDataCreateLifePayOrderInput = { |
| | | userId: blLifeRecharge.accountModel.userId, |
| | | productData: { |
| | | ispCode: form.ispCode, |
| | | parValue: props.isDev ? 0.1 : form.parValue, |
| | | phone: form.phone, |
| | | name: form.ispCode === BlLifeRecharge.constants.IspCode.dianxin ? form.name : '', |
| | | }, |
| | | }; |
| | | let res = await blLifeRecharge.services.createLifePayPhoneOrder(params); |
| | | emit('goPay', res.orderNo); |
| | | } catch (error) {} |
| | | } |
| | | </script> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | import type { InjectionKey, UnwrapNestedRefs, Ref } from 'vue'; |
| | | import { inject } from 'vue'; |
| | | import { UseStepperReturn } from 'senin-mini/hooks'; |
| | | |
| | | type PhoneBillRechargeSteps = 'step1' | 'step2'; |
| | | |
| | | export interface PhoneBillRechargeContext |
| | | extends UseStepperReturn< |
| | | PhoneBillRechargeSteps, |
| | | PhoneBillRechargeSteps[], |
| | | PhoneBillRechargeSteps |
| | | > { |
| | | // form: UnwrapNestedRefs<{ |
| | | // ispCode: string; |
| | | // phone: string; |
| | | // parValue: number; |
| | | // name: string; |
| | | // }>; |
| | | } |
| | | |
| | | export const PhoneBillRechargeContextKey: InjectionKey<PhoneBillRechargeContext> = Symbol( |
| | | 'PhoneBillRechargeContextKey' |
| | | ); |
| | | |
| | | export function usePhoneBillRechargeContext() { |
| | | return inject(PhoneBillRechargeContextKey); |
| | | } |
| | |
| | | <template> |
| | | <div class="recharge-result-view"> |
| | | <div class="recharge-result-view-title">{{ title }}</div> |
| | | <div class="recharge-result-view-subtitle">订åå·ï¼{{ orderNo }}</div> |
| | | <div class="recharge-result-view-tips"> |
| | | åä¸å·ç å
弿é´ï¼æªå°è´¦ååå¿å¨å
¶ä»ä»»ä½å¹³å°å次å
å¼ãå æ¤é æçèµéæå¤±é¡»ç¨æ·èªè¡æ¿æ
ï¼ï¼ï¼ |
| | | </div> |
| | | <div class="recharge-result-view-warning"> |
| | | 妿¥å°éçæ¥çµï¼å¯¹æ¹ä»¥ç¼´è´¹æè¯¯æä½ççç±è¦æ±å¤ç款项ï¼å¡å¿
ç«å³æé»ï¼è°¨é²è¯éª!!! |
| | | </div> |
| | | <div class="recharge-result-view-customerService">{{ CustomerServiceTips }}</div> |
| | | <div class="recharge-result-view-btn-wrapper"> |
| | | <div class="recharge-result-view-btn" @click="emit('goBackHome')">åé¦é¡µ</div> |
| | | </div> |
| | |
| | | |
| | | <script setup lang="ts"> |
| | | import { LifeRechargeConstants } from '@life-payment/core-vue'; |
| | | import { CustomerServiceTips } from '../../constants'; |
| | | |
| | | defineOptions({ |
| | | name: 'RechargeResultView', |
| | |
| | | label="çµç½ç±»å" |
| | | :content="blLifeRecharge.constants.ElectricTypeText[form.electricType]" |
| | | /> |
| | | <ConfirmDialogInfoItem label="çµè´¹ç±»å" content="ä½å®
" /> |
| | | <ConfirmDialogInfoItem :label-width="96" label="æ·å·" :content="form.electricAccount" /> |
| | | <ConfirmDialogInfoItem label="å
å¼éé¢" :content="`ï¿¥${form.parValue.toFixed(2)}`" danger /> |
| | | <ConfirmDialogInfoItem label="伿 éé¢" :content="`ï¿¥${discountParValue.toFixed(2)}`" /> |
| | | <ConfirmDialogInfoItem label="å®ä»éé¢" :content="`ï¿¥${realParValue}`" danger /> |
| | |
| | | import NumberInput from '../../components/Input/NumberInput.vue'; |
| | | import { useGetRate, useGetElectricParValue } from '../../hooks'; |
| | | import { FormValidator } from '../../utils'; |
| | | import { CustomerServiceTips } from '../../constants'; |
| | | |
| | | defineOptions({ |
| | | name: 'electricBillRecharge', |
| | |
| | | const { lifePayElectricRate } = useGetRate(); |
| | | const { electricParValueList } = useGetElectricParValue(); |
| | | |
| | | const parValueList = computed( |
| | | () => electricParValueList.value.find((x) => x.cityName === form.province)?.parValue ?? [] |
| | | ); |
| | | const parValueList = computed(() => { |
| | | const parValueList = |
| | | electricParValueList.value.find((x) => x.cityName === form.province)?.parValue ?? []; |
| | | return blLifeRecharge.filterParValueList(parValueList); |
| | | }); |
| | | |
| | | const electricCityList = computed( |
| | | () => electricParValueList.value.find((x) => x.cityName === form.province)?.childCityList ?? [] |
| | |
| | | '为确ä¿å
å¼é¡ºå©è¿è¡ï¼ç®åå¹³å°ä¸æ¯æå¯¹æ¬ 款éé¢è¶
è¿1000å
çè´¦æ·è¿è¡å
å¼ï¼ä¸æ¯æ¬¡å
å¼éé¢å¿
é¡»é«äºæ¬ è´¹æ»é¢ã', |
| | | '妿¥å°éçæ¥çµï¼å¯¹æ¹ä»¥ç¼´è´¹æè¯¯æä½ççç±è¦æ±å¤ç款项ï¼å¡å¿
ç«å³æé»ï¼è°¨é²è¯éªã', |
| | | 'ä¸åæ¶ï¼è¯·æ¨å¡å¿
å确填å宿´ççå¸åæ·å·ä¿¡æ¯ãå
å¼å®æåï¼å票ç±è¿è¥åæä¾ï¼æ¨å¯ç»å½ç½ä¸è¥ä¸å
ä¸è½½å¯¹åºççµåå票ã', |
| | | CustomerServiceTips, |
| | | ]; |
| | | |
| | | const confirmDialogVisible = ref(false); |
| | |
| | | "name": "@life-payment/core-vue", |
| | | "main": "src/index.ts", |
| | | "module": "./src/index.ts", |
| | | "types": "./dist/types/index.d.ts", |
| | | "source": "./src/index.ts", |
| | | "version": "0.0.3", |
| | | "scripts": { |
| | |
| | | "name": "@life-payment/core", |
| | | "main": "src/index.ts", |
| | | "module": "./src/index.ts", |
| | | "types": "./dist/types/index.d.ts", |
| | | "source": "./src/index.ts", |
| | | "version": "0.0.2", |
| | | "scripts": { |
| | |
| | | getRechargeParValue(amount: number | string, rate: number) { |
| | | return (Number(amount) * rate).toFixed(2); |
| | | } |
| | | |
| | | MaxParValue = 300; |
| | | |
| | | filterParValueList(parValueList: string[]) { |
| | | return parValueList.filter((x) => Number(x) <= this.MaxParValue); |
| | | } |
| | | } |