zhengyiming
2025-02-20 988837b3fbffb8abea06dcb875f5746b9fce3c57
fix: 页面
10个文件已修改
15个文件已添加
748 ■■■■■ 已修改文件
apps/taro/config/index.js 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
apps/taro/src/app.config.ts 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
apps/taro/src/app.ts 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
apps/taro/src/constants/router.ts 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
apps/taro/src/index.html 30 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
apps/taro/src/pages/home/index.vue 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
apps/taro/src/subpackages/recharge/phoneBillRecharge/InnerPage.vue 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
apps/taro/src/subpackages/recharge/phoneBillRecharge/phoneBillRecharge.config.ts 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
apps/taro/src/subpackages/recharge/phoneBillRecharge/phoneBillRecharge.vue 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
packages/components/src/components/Dialog/ConfirmDialog.vue 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
packages/components/src/components/Dialog/ConfirmDialogInfoItem.vue 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
packages/components/src/components/Radio/Radio.vue 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
packages/components/src/components/RechargeTipsView/RechargeTipsView.vue 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
packages/components/src/constants/index.ts 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
packages/components/src/index.ts 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
packages/components/src/styles/components.scss 70 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
packages/components/src/styles/index.scss 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
packages/components/src/styles/nut.scss 173 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
packages/components/src/styles/rechargeGrid.scss 128 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
packages/components/src/styles/var.scss 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
packages/components/src/utils/index.ts 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
packages/components/src/utils/lifeRecharge.ts 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
packages/components/src/utils/plugin.ts 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
packages/components/src/views/PhoneBillRecharge/PhoneBillRecharge.vue 121 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
packages/components/src/views/RechargeGrid/RechargeGrid.vue 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
apps/taro/config/index.js
@@ -193,6 +193,9 @@
  h5: {
    publicPath: '/',
    staticDirectory: 'static',
    router: {
      mode: 'browser',
    },
    postcss: {
      autoprefixer: {
        enable: true,
apps/taro/src/app.config.ts
@@ -51,6 +51,10 @@
        'registerForm/registerForm',
      ],
    },
    {
      root: 'subpackages/recharge',
      pages: ['phoneBillRecharge/phoneBillRecharge'],
    },
  ],
  // preloadRule: {
  //   'pages/mine/index': {
apps/taro/src/app.ts
@@ -10,6 +10,7 @@
import Taro from '@tarojs/taro';
import { VueQueryPlugin, VueQueryPluginOptions } from '@tanstack/vue-query';
import { myClient } from '@/constants/query';
import { VueLifeRechargePlugin, BlLifeRecharge } from '@life-payment/components';
window.uni = Taro;
@@ -82,4 +83,10 @@
App.use(VueQueryPlugin, vueQueryPluginOptions);
const blLifeRecharge = new BlLifeRecharge();
App.use(VueLifeRechargePlugin, {
  blLifeRecharge,
});
export default App;
apps/taro/src/constants/router.ts
@@ -7,4 +7,6 @@
  registerForm = '/subpackages/login/registerForm/registerForm',
  home = '/pages/home/index',
  mine = '/pages/mine/index',
  phoneBillRecharge = '/subpackages/recharge/phoneBillRecharge/phoneBillRecharge',
}
apps/taro/src/index.html
@@ -1,17 +1,19 @@
<!DOCTYPE html>
<html>
<head>
  <meta content="text/html; charset=utf-8" http-equiv="Content-Type">
  <meta content="width=device-width,initial-scale=1,user-scalable=no" name="viewport">
  <meta name="apple-mobile-web-app-capable" content="yes">
  <meta name="apple-touch-fullscreen" content="yes">
  <meta name="format-detection" content="telephone=no,address=no">
  <meta name="apple-mobile-web-app-status-bar-style" content="white">
  <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" >
  <title>vue-mini</title>
  <script><%= htmlWebpackPlugin.options.script %></script>
</head>
<body>
  <div id="app"></div>
</body>
  <head>
    <meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
    <meta content="width=device-width,initial-scale=1,user-scalable=no" name="viewport" />
    <meta name="apple-mobile-web-app-capable" content="yes" />
    <meta name="apple-touch-fullscreen" content="yes" />
    <meta name="format-detection" content="telephone=no,address=no" />
    <meta name="apple-mobile-web-app-status-bar-style" content="white" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
    <title>生活缴费</title>
    <script>
      <%= htmlWebpackPlugin.options.script %>
    </script>
  </head>
  <body>
    <div id="app"></div>
  </body>
</html>
apps/taro/src/pages/home/index.vue
@@ -1,7 +1,7 @@
<template>
  <PageLayoutWithBg class="index-page-wrapper" :title="'生活缴费'" :need-auth="false">
    <ContentView>
      <RechargeGrid />
      <RechargeGrid @phoneBillRecharge="goPhoneBillRecharge" />
    </ContentView>
  </PageLayoutWithBg>
</template>
@@ -10,25 +10,21 @@
import { useUser, useInfiniteLoading } from '@/hooks';
import { useUserStore } from '@/stores/modules/user';
import Taro from '@tarojs/taro';
import _ from 'lodash';
import IconLogo from '@/assets/home/icon-logo.png';
import { OrderInputType } from '@life-payment/constants';
import { RechargeGrid } from '@life-payment/components';
const { locationCity } = useUser();
const userStore = useUserStore();
const queryState = reactive({});
const list = ref([
  'https://storage.360buyimg.com/jdc-article/NutUItaro34.jpg',
  'https://storage.360buyimg.com/jdc-article/NutUItaro2.jpg',
  'https://storage.360buyimg.com/jdc-article/welcomenutui.jpg',
  'https://storage.360buyimg.com/jdc-article/fristfabu.jpg',
]);
const selectItem = ref();
function goPhoneBillRecharge() {
  Taro.navigateTo({
    url: RouterPath.phoneBillRecharge,
  })
    .then(() => {
      console.log('Navigate successfully');
    })
    .catch((err) => {
      console.error('Navigation failed:', err);
    });
}
</script>
<style lang="scss">
apps/taro/src/subpackages/recharge/phoneBillRecharge/InnerPage.vue
New file
@@ -0,0 +1,13 @@
<template>
  <ContentScrollView :paddingH="false">
    <PhoneBillRecharge />
  </ContentScrollView>
</template>
<script setup lang="ts">
import { PhoneBillRecharge } from '@life-payment/components';
defineOptions({
  name: 'InnerPage',
});
</script>
apps/taro/src/subpackages/recharge/phoneBillRecharge/phoneBillRecharge.config.ts
New file
@@ -0,0 +1,3 @@
export default definePageConfig({
  disableScroll: true,
});
apps/taro/src/subpackages/recharge/phoneBillRecharge/phoneBillRecharge.vue
New file
@@ -0,0 +1,14 @@
<template>
  <PageLayout title="话费充值" class="phoneBillRecharge-page-wrapper" hasBorder :need-auth="false">
    <InnerPage />
  </PageLayout>
</template>
<script setup lang="ts">
import { PageLayout } from '@/components';
import InnerPage from './InnerPage.vue';
defineOptions({
  name: 'phoneBillRecharge',
});
</script>
packages/components/src/components/Dialog/ConfirmDialog.vue
New file
@@ -0,0 +1,24 @@
<template>
  <nut-dialog title="请核对充值信息并支付" v-model:visible="visible">
    <div class="confirm-dialog-content">
      <div class="confirm-dialog-content-tips">
        该产品为慢充模式,0-24小时内到账,介意请勿付款! 充值前请仔细阅读充值须知!
      </div>
      <div class="confirm-dialog-content-info">
        <slot name="info"></slot>
      </div>
    </div>
  </nut-dialog>
</template>
<script setup lang="ts">
defineOptions({
  name: 'ConfirmDialog',
});
// type Props = {};
// const props = withDefaults(defineProps<Props>(), {});
const visible = defineModel<boolean>('visible');
</script>
packages/components/src/components/Dialog/ConfirmDialogInfoItem.vue
New file
@@ -0,0 +1,20 @@
<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-content">{{ content }}</div>
  </div>
</template>
<script setup lang="ts">
defineOptions({
  name: 'ConfirmDialogInfoItem',
});
type Props = {
  label?: string;
  content?: string;
  danger?: boolean;
};
const props = withDefaults(defineProps<Props>(), {});
</script>
packages/components/src/components/Radio/Radio.vue
New file
@@ -0,0 +1,17 @@
<template>
  <Radio class="bl-radio">
    <template #default><slot /> </template>
    <template #checkedIcon>
      <IconFont name="checked" color="var(--bole-color-primary)" />
    </template>
  </Radio>
</template>
<script setup lang="ts">
import { IconFont } from '@nutui/icons-vue-taro';
import { Radio } from '@nutui/nutui-taro';
defineOptions({
  name: 'bl-radio',
});
</script>
packages/components/src/components/RechargeTipsView/RechargeTipsView.vue
New file
@@ -0,0 +1,27 @@
<template>
  <div class="recharge-tips-view">
    <div class="recharge-tips-title">充值须知</div>
    <div class="recharge-tips-content">
      <div class="recharge-tips-top">
        *同一号码充值期间【切勿多平台重复充值】!!!在下单前,请务必仔细阅读公告内容!!!若接到陌生来电,请勿轻信!!!
      </div>
      <div class="recharge-tips-list">
        <div class="recharge-tips-item" v-for="(item, index) in props.tips" :key="index">
          {{ index + 1 }}.{{ item }}
        </div>
      </div>
    </div>
  </div>
</template>
<script setup lang="ts">
defineOptions({
  name: 'RechargeTipsView',
});
type Props = {
  tips: string[];
};
const props = withDefaults(defineProps<Props>(), {});
</script>
packages/components/src/constants/index.ts
New file
@@ -0,0 +1,14 @@
export enum IspCode {
  /**中国移动 */
  yidong = 'yidong',
  /**中国电信 */
  dianxin = 'dianxin',
  /**中国联通 */
  liantong = 'liantong',
}
export const IspCodeText = {
  [IspCode.yidong]: '中国移动',
  [IspCode.dianxin]: '中国电信',
  [IspCode.liantong]: '中国联通',
};
packages/components/src/index.ts
@@ -1 +1,3 @@
export { default as RechargeGrid } from './views/RechargeGrid/RechargeGrid.vue';
export { default as PhoneBillRecharge } from './views/PhoneBillRecharge/PhoneBillRecharge.vue';
export * from './utils';
packages/components/src/styles/components.scss
New file
@@ -0,0 +1,70 @@
/*postcss-pxtransform disable*/
@use './common.scss' as *;
.recharge-tips-view {
  padding: 16px;
  border-radius: 12px;
  background: linear-gradient(0deg, rgba(10, 90, 255, 0.04), rgba(10, 90, 255, 0.04)), #fff;
  .recharge-tips-title {
    color: #1f2229;
    font-size: 14px;
    font-weight: 700;
    line-height: 18px;
    padding: 4px 0 12px 0;
    border-bottom: 1px solid boleGetCssVar('color', 'primary');
  }
  .recharge-tips-content {
    color: boleGetCssVar('text-color', 'regular');
    font-size: 13px;
    font-weight: 400;
    line-height: 21px;
    padding-top: 16px;
    .recharge-tips-top {
      color: #e03e2d;
      font-size: 18px;
    }
  }
}
.confirm-dialog-content {
  .confirm-dialog-content-tips {
    margin-bottom: 16px;
  }
  .confirm-dialog-content-info {
    padding: 12px;
    border-radius: 8px;
    background: #f0f3fa;
    .confirm-dialog-content-info-item {
      display: flex;
      margin-bottom: 10px;
      &:last-child {
        margin-bottom: 0;
      }
      .confirm-dialog-content-info-item-label {
        color: boleGetCssVar('text-color', 'regular');
        margin-right: 6px;
      }
      .confirm-dialog-content-info-item-content {
        flex: 1;
        min-width: 0;
        @include ellipsis;
        color: boleGetCssVar('text-color', 'primary');
        text-align: left;
      }
      &.danger {
        .confirm-dialog-content-info-item-content {
          color: boleGetCssVar('color', 'danger');
        }
      }
    }
  }
}
packages/components/src/styles/index.scss
@@ -1,7 +1,10 @@
@use 'sass:map';
@use './var.scss' as *;
@use './function.scss' as *;
@use './nut.scss' as *;
@use './layout.scss' as *;
@use './rechargeGrid.scss' as *;
@use './components.scss' as *;
:root,
page {
packages/components/src/styles/nut.scss
New file
@@ -0,0 +1,173 @@
/*postcss-pxtransform disable*/
@use './function.scss' as *;
@use './hairline.scss' as *;
:root,
page {
  .category-searchbar-container {
    padding: 30px;
  }
  .h5-view.nut-popup.nut-popup--bottom {
    padding-bottom: constant(safe-area-inset-bottom);
    padding-bottom: env(safe-area-inset-bottom);
  }
  .nut-button.dark-btn {
    color: boleGetCssVar('text-color', 'primary') !important;
  }
  .nut-form {
    .nut-cell-group__wrap {
      margin-top: 0;
      border-radius: 0;
      box-shadow: none;
    }
    .nut-cell.bole-form-item {
      --nut-form-item-label-width: 120px;
      &:not(.alignTop) {
        align-items: center !important;
      }
      &.labelTop {
        display: block;
      }
      padding: 30rpx;
      &::after {
        border-bottom: 1px solid #f0f0f0;
        left: 30rpx;
        right: 30rpx;
        display: none;
      }
      .nut-form-item__body__tips {
        position: absolute;
        bottom: 0;
      }
      &:not(.bole-form-item-phone) {
        .nut-form-item__body__tips {
          right: 30rpx;
        }
      }
      .nut-form-item__label {
        font-size: 28rpx;
        color: boleGetCssVar('text-color', 'primary');
      }
      &.vertical {
        flex-direction: column;
        align-items: flex-start !important;
      }
      .nut-form-item__label.required::before {
        position: absolute;
        left: 12rpx;
      }
      .nut-radio-group--horizontal {
        .nut-radio {
          margin-bottom: 0;
          vertical-align: middle;
        }
      }
      .nut-rate {
        vertical-align: middle;
      }
      &.hidden-label {
        .nut-form-item__label {
          opacity: 0;
        }
      }
      .bole-uploader {
        padding-top: 16rpx;
        &.nopaddingtop {
          padding-top: 0;
        }
      }
    }
    .bole-form-item-phone {
      padding: 24rpx 30rpx;
    }
    .nut-uploader {
      // justify-content: flex-end;
    }
    .nut-form-item__top {
      .nut-form-item__label {
        margin-right: 0;
      }
      .nut-form-item__body {
        width: 100%;
      }
    }
  }
  .bole-input-text:not(.nut-input--disabled) {
    .h5-input {
      color: boleGetCssVar('text-color', 'primary') !important;
      display: block;
      font-size: 26rpx;
    }
    .input-placeholder {
      color: boleGetCssVar('text-color', 'placeholder') !important;
      font-size: 26rpx;
    }
  }
  .bole-input-textarea:not(.nut-input--disabled) {
    color: boleGetCssVar('text-color', 'primary') !important;
    height: 100rpx;
  }
  .bole-input-text-placeholder {
    color: boleGetCssVar('text-color', 'placeholder') !important;
    font-size: 26rpx;
    line-height: 20rpx;
  }
  .form-item-divider {
    margin: 0 28px;
    width: calc(100% - 56px);
    color: #f0f0f0;
  }
  // .nut-overlay {
  //   z-index: 20022221 !important;
  // }
  // .nut-popup {
  //   z-index: 2222222222 !important;
  // }
  .nut-tabs__titles-item__smile {
    // display: none;
    opacity: 0;
    transition: width 0.3s ease;
  }
  .nut-tabs__titles.smile .nut-tabs__titles-item.active .nut-tabs__titles-item__smile {
    // display: block;
    opacity: 1;
  }
  .nut-toast {
    z-index: 99999999999;
  }
  .pro-form-item-tips {
    word-break: break-all;
  }
}
packages/components/src/styles/rechargeGrid.scss
New file
@@ -0,0 +1,128 @@
/*postcss-pxtransform disable*/
@use './common.scss' as *;
.recharge-grid-wrapper {
  padding-left: 0 !important;
  margin-top: 20px;
  .recharge-grid-item {
    .nut-grid-item__text {
      font-size: 18px;
      color: boleGetCssVar('text-color', 'primary');
    }
  }
}
.common-content {
  padding: 0 boleGetCssVar('size', 'body-padding-h2');
}
.parValue-radio-group {
  width: 100%;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-gap: 10px;
  .parValue-item {
    margin-right: 0;
    .nut-radio__button {
      width: 100%;
      padding: 8px 0;
      background-color: transparent;
      border: 0.5px solid #e2e5eb;
      text-align: center;
      border-radius: 4px;
      position: relative;
    }
    .nut-radio__button--active {
      color: #fb5100;
      border-color: #fb5100;
      overflow: hidden;
      &::after {
        border-radius: 4px;
        background-color: rgba(251, 81, 0, 0.08);
        opacity: 1;
      }
      .parValue-item-inner {
        .discountTag {
          display: block;
        }
      }
    }
    .parValue-item-inner {
      width: 100%;
      display: flex;
      flex-direction: column;
      align-items: center;
      .amount-wrapper {
        display: flex;
        align-items: flex-end;
        margin-bottom: 2px;
        .amount {
          font-size: 20px;
          font-weight: 400;
          line-height: 22px;
        }
        .unit {
          font-size: 12px;
          font-weight: 400;
          line-height: 16px;
        }
      }
      .price-wrapper {
        display: flex;
        color: #858d98;
        font-size: 12px;
        font-weight: 400;
        line-height: 16px;
        .price {
          color: #fb5100;
          margin-left: 3px;
        }
      }
      .discountTag {
        display: none;
        position: absolute;
        padding: 1px 4px;
        border-radius: 0px 0 10px 0;
        border: 0.5px solid #fb5100;
        background: linear-gradient(
          186deg,
          rgba(255, 129, 45, 0.08) 14.82%,
          rgba(238, 67, 67, 0.08) 91.5%
        );
        color: #fb5100;
        font-size: 11px;
        font-weight: 700;
        line-height: 14px;
        position: absolute;
        top: -1px;
        left: -1px;
      }
    }
  }
}
.phone-bill-recharge {
  .recharge-button {
    width: 100%;
    margin: 20px 0;
    .recharge-button-inner {
      display: flex;
      .recharge-button-text {
        margin-left: 10px;
      }
    }
  }
}
packages/components/src/styles/var.scss
@@ -27,6 +27,7 @@
$bole-size: map.deep-merge(
  (
    'body-padding-h': 28px,
    'body-padding-h2': 14px,
  ),
  $bole-size
);
packages/components/src/utils/index.ts
New file
@@ -0,0 +1,2 @@
export * from './lifeRecharge';
export * from './plugin';
packages/components/src/utils/lifeRecharge.ts
New file
@@ -0,0 +1,5 @@
export class BlLifeRecharge {
  getRechargeParValue(amount: number, rate: number) {
    return (amount * rate).toFixed(2);
  }
}
packages/components/src/utils/plugin.ts
New file
@@ -0,0 +1,25 @@
import { BlLifeRecharge } from './lifeRecharge';
import { inject, shallowReactive } from 'vue';
import type { InjectionKey, UnwrapNestedRefs, Ref } from 'vue';
export type LifeRechargeContext = {
  blLifeRecharge: UnwrapNestedRefs<BlLifeRecharge>;
};
const clientKey: InjectionKey<LifeRechargeContext> = Symbol('blLifeRecharge');
export type VueLifeRechargePluginOptions = {
  blLifeRecharge: BlLifeRecharge;
};
export const VueLifeRechargePlugin = {
  install: (app: any, { blLifeRecharge }: VueLifeRechargePluginOptions) => {
    app.provide(clientKey, {
      blLifeRecharge: shallowReactive(blLifeRecharge),
    });
  },
};
export function useLifeRechargeContext() {
  return inject(clientKey);
}
packages/components/src/views/PhoneBillRecharge/PhoneBillRecharge.vue
New file
@@ -0,0 +1,121 @@
<template>
  <Form
    :model-value="form"
    ref="formRef"
    :rules="rules"
    label-position="top"
    class="phone-bill-recharge"
  >
    <FormItem label="选择运营商:" class="bole-form-item" prop="ispCode" required>
      <RadioGroup v-model="form.ispCode" direction="horizontal">
        <BlRadio :label="key" v-for="(val, key) in IspCodeText" :key="key">{{ val }}</BlRadio>
      </RadioGroup>
    </FormItem>
    <FormItem label="充值手机号" class="bole-form-item" prop="phone" required>
      <Input
        v-model.trim="form.phone"
        class="bole-input-text"
        placeholder="请填写您需要充值的手机号码"
        type="text"
      />
    </FormItem>
    <FormItem label="选择充值金额" class="bole-form-item" prop="parValue" required>
      <RadioGroup v-model="form.parValue" direction="horizontal" class="parValue-radio-group">
        <Radio
          :label="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, rate) }}元</div>
            </div>
            <div class="discountTag">{{ rate * 100 }}折</div>
          </div>
        </Radio>
      </RadioGroup>
    </FormItem>
    <div class="common-content">
      <nut-button class="recharge-button" type="primary" @click="recharge">
        <div class="recharge-button-inner">
          <div>¥{{ form.parValue }}</div>
          <div class="recharge-button-text">立即充值</div>
        </div>
      </nut-button>
      <RechargeTipsView :tips="tips" />
    </div>
    <ConfirmDialog v-model:visible="confirmDialogVisible">
      <template #info>
        <ConfirmDialogInfoItem label="充值账号" content="18858418480" />
        <ConfirmDialogInfoItem label="充值金额" :content="`¥${form.parValue}`" danger />
        <ConfirmDialogInfoItem label="优惠金额" :content="`¥${discountParValue}`" />
        <ConfirmDialogInfoItem label="实付金额" :content="`¥${realParValue}`" danger />
      </template>
    </ConfirmDialog>
  </Form>
</template>
<script setup lang="ts">
import { Form, FormItem, RadioGroup, Radio, Input, 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 { IspCodeText, IspCode } from '../../constants';
import { useLifeRechargeContext } from '../../utils';
import RechargeTipsView from '../../components/RechargeTipsView/RechargeTipsView.vue';
import ConfirmDialog from '../../components/Dialog/ConfirmDialog.vue';
import ConfirmDialogInfoItem from '../../components/Dialog/ConfirmDialogInfoItem.vue';
defineOptions({
  name: 'PhoneBillRecharge',
});
const form = reactive({
  ispCode: IspCode.yidong,
  phone: '',
  parValue: 100,
});
const rate = 0.96;
const parValueList = [50, 100, 200];
const realParValue = computed(() => blLifeRecharge.getRechargeParValue(form.parValue, rate));
const discountParValue = computed(() => form.parValue - Number(realParValue.value));
const { blLifeRecharge } = useLifeRechargeContext();
const rules = reactive<FormRules>({});
const formRef = ref<any>(null);
function handleSubmit() {
  if (!formRef.value) return;
  formRef.value.validate().then(({ valid, errors }: any) => {
    if (valid) {
    }
  });
}
const tips = [
  '平台提供慢充服务,订单提交后,话费将于0 - 24小时内到账。若未能按时到账,系统将自动发起退款。',
  '充值期间,若同一号码款项未到账,请勿在其他平台重复充值;主副卡不可同时充值。因上述操作导致的资金损失,由用户自行承担。',
  '本平台话费充值服务不适用于已停机号码。电信号码若有欠费,也无法完成充值。电信已完成维护的区域包括:广东、江苏、湖北、四川、江西、河北、河南、福建、辽宁。其它区域正在分批次进行维护中,在此期间可能会出现充值不成功并自动退款的情况,请您谅解。',
  '如接到陌生来电,对方以缴费或误操作等理由要求处理款项,务必立即拉黑,谨防诈骗。',
  '售后服务期为充值完成之日起3天。申请售后服务时,需提供录屏证据,请确认接受此要求后再下单,逾期平台不再受理售后申请。',
  '充值发票由运营商提供,您可登录网上营业厅下载电子发票。',
];
const confirmDialogVisible = ref(false);
function recharge() {
  confirmDialogVisible.value = true;
}
</script>
packages/components/src/views/RechargeGrid/RechargeGrid.vue
@@ -1,10 +1,10 @@
<template>
  <MainCell title="生活缴费">
    <Grid square :gutter="20" :column-num="2">
      <GridItem class="publish-circle-friend-file-grid-item" text="话费">
    <Grid square :gutter="20" :column-num="2" class="recharge-grid-wrapper">
      <GridItem class="recharge-grid-item" text="话费" @click="emit('phoneBillRecharge')">
        <Dongdong />
      </GridItem>
      <GridItem class="publish-circle-friend-file-grid-item" text="电费">
      <GridItem class="recharge-grid-item" text="电费" @click="emit('electricityBillRecharge')">
        <Dongdong />
      </GridItem>
    </Grid>
@@ -13,7 +13,6 @@
<script setup lang="ts">
import MainCell from '../../components/Layout/MainCell.vue';
// import Grid from '../../components/Grid/Grid.vue';
import { Grid, GridItem } from '@nutui/nutui-taro';
import { Dongdong } from '@nutui/icons-vue-taro';
@@ -24,4 +23,9 @@
// type Props = {};
// const props = withDefaults(defineProps<Props>(), {});
const emit = defineEmits<{
  (e: 'phoneBillRecharge'): void;
  (e: 'electricityBillRecharge'): void;
}>();
</script>