|  |  |  | 
|---|
|  |  |  | 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> | 
|---|
| New file | 
|  |  |  | 
|---|
|  |  |  | <template> | 
|---|
|  |  |  | <div>燃气充值</div> | 
|---|
|  |  |  | </template> | 
|---|
|  |  |  |  | 
|---|
|  |  |  | <script setup lang="ts"> | 
|---|
|  |  |  | defineOptions({ | 
|---|
|  |  |  | name: 'InnerPage', | 
|---|
|  |  |  | }); | 
|---|
|  |  |  | </script> | 
|---|
|  |  |  |  | 
|---|
|  |  |  | <style lang="scss"> | 
|---|
|  |  |  | @import '@/styles/common.scss'; | 
|---|
|  |  |  | </style> | 
|---|
| New file | 
|  |  |  | 
|---|
|  |  |  | export default definePageConfig({ | 
|---|
|  |  |  | disableScroll: true, | 
|---|
|  |  |  | }); | 
|---|
| New file | 
|  |  |  | 
|---|
|  |  |  | <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> | 
|---|
| New file | 
|  |  |  | 
|---|
|  |  |  | <template> | 
|---|
|  |  |  | <div class="account-add-card"><Uploader /> 新增手机号</div> | 
|---|
|  |  |  | </template> | 
|---|
|  |  |  |  | 
|---|
|  |  |  | <script setup lang="ts"> | 
|---|
|  |  |  | import { Uploader } from '@nutui/icons-vue-taro'; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | defineOptions({ | 
|---|
|  |  |  | name: 'AccountAddCard', | 
|---|
|  |  |  | }); | 
|---|
|  |  |  | </script> | 
|---|
| New file | 
|  |  |  | 
|---|
|  |  |  | <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> | 
|---|
| New file | 
|  |  |  | 
|---|
|  |  |  | <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)`; | 
|---|
| New file | 
|  |  |  | 
|---|
|  |  |  | @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> | 
|---|
| New file | 
|  |  |  | 
|---|
|  |  |  | <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> | 
|---|
| New file | 
|  |  |  | 
|---|
|  |  |  | <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> | 
|---|
| New file | 
|  |  |  | 
|---|
|  |  |  | <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> | 
|---|
| New file | 
|  |  |  | 
|---|
|  |  |  | 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); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|