zhengyiming
2 天以前 80dc90be027ee26869c63860b7d6a0759a03546b
fix: 修改首页ui
19个文件已修改
7个文件已添加
673 ■■■■ 已修改文件
apps/taro/src/styles/mixins.scss 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
apps/taro/src/styles/nut.scss 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
apps/taro/src/subpackages/recharge/phoneBillRecharge/InnerPage.vue 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
apps/taro/src/subpackages/recharge/phoneBillRecharge/phoneBillRecharge.vue 23 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
packages/components/src/assets/icon-alipay.png 补丁 | 查看 | 原始文档 | blame | 历史
packages/components/src/assets/icon-weixin-pay.png 补丁 | 查看 | 原始文档 | blame | 历史
packages/components/src/assets/recharge/icon-add.png 补丁 | 查看 | 原始文档 | blame | 历史
packages/components/src/assets/recharge/icon-edit.png 补丁 | 查看 | 原始文档 | blame | 历史
packages/components/src/assets/recharge/icon-info.png 补丁 | 查看 | 原始文档 | blame | 历史
packages/components/src/assets/recharge/icon-init-add.png 补丁 | 查看 | 原始文档 | blame | 历史
packages/components/src/assets/recharge/icon-select.png 补丁 | 查看 | 原始文档 | blame | 历史
packages/components/src/components/Card/AccountAddCardV2.vue 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
packages/components/src/components/Card/AccountCardV2.vue 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
packages/components/src/components/Dialog/ConfirmDialog.vue 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
packages/components/src/components/SelectPayTypeFormItem/SelectPayTypeFormItem.vue 23 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
packages/components/src/styles/card.scss 110 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
packages/components/src/styles/components.scss 119 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
packages/components/src/styles/layout.scss 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
packages/components/src/styles/mixins.scss 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
packages/components/src/styles/nut.scss 25 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
packages/components/src/styles/rechargeGrid.scss 139 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
packages/components/src/utils/common.ts 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
packages/components/src/views/PhoneBillRecharge/PhoneBillRecharge.vue 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
packages/components/src/views/PhoneBillRecharge/PhoneBillRechargeBaseForm.vue 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
packages/components/src/views/PhoneBillRecharge/PhoneBillRechargeStep1.vue 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
packages/components/src/views/PhoneBillRecharge/PhoneBillRechargeStep2.vue 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
apps/taro/src/styles/mixins.scss
@@ -74,3 +74,9 @@
    color: transparent;
  }
}
@mixin placeholder {
  color: var(--bole-text-color-secondary) !important;
  font-size: 30px;
  line-height: 42px;
}
apps/taro/src/styles/nut.scss
@@ -1,5 +1,6 @@
@use './function.scss' as *;
@use './hairline.scss' as *;
@use './mixins.scss' as *;
:root,
page {
@@ -130,9 +131,7 @@
  }
  .bole-input-text-placeholder {
    color: boleGetCssVar('text-color', 'placeholder') !important;
    font-size: 26rpx;
    line-height: 20rpx;
    @include placeholder;
  }
  .form-item-divider {
apps/taro/src/subpackages/recharge/phoneBillRecharge/InnerPage.vue
@@ -13,6 +13,8 @@
      :showAliPay="!isInWeChat"
      :showWeixinPay="isInWeChat"
      @missName="handleMissName"
      @editUserAccount="handleEditUserAccount"
      @currentChange="emit('currentChange', $event)"
    />
  </ContentScrollView>
</template>
@@ -29,6 +31,10 @@
defineOptions({
  name: 'InnerPage',
});
const emit = defineEmits<{
  (e: 'currentChange', current: 'step1' | 'step2'): void;
}>();
const isDev = process.env.NODE_ENV === 'development';
@@ -56,4 +62,10 @@
    });
  } catch (error) {}
}
function handleEditUserAccount(userAccountId: string) {
  RouteHelper.navigateTo({
    url: `${RouterPath.editPhoneUserAccount}?id=${userAccountId}`,
  });
}
</script>
apps/taro/src/subpackages/recharge/phoneBillRecharge/phoneBillRecharge.vue
@@ -1,20 +1,23 @@
<template>
  <PageLayout
    class="phoneBillRecharge-page-wrapper"
    :style="{
    :style="
      current === 'step2' && {
      backgroundImage: `url(${OssAssets.common.PhoneBillRechargePageBg})`,
    }"
      }
    "
    :title="current != 'step2' && title"
  >
    <template #navigationBar>
    <template #navigationBar v-if="current === 'step2'">
      <TransparentNavigationBar
        :title="'话费充值'"
        :title="title"
        :is-absolute="false"
        mode="dark"
        navigationArrowWhite
      >
      </TransparentNavigationBar>
    </template>
    <InnerPage />
    <InnerPage @currentChange="handleCurrentChange" />
  </PageLayout>
</template>
@@ -26,6 +29,16 @@
defineOptions({
  name: 'phoneBillRecharge',
});
type Current = 'step1' | 'step2';
const title = '话费充值';
const current = ref<Current>();
function handleCurrentChange(val: Current) {
  current.value = val;
}
</script>
<style lang="scss">
packages/components/src/assets/icon-alipay.png

packages/components/src/assets/icon-weixin-pay.png

packages/components/src/assets/recharge/icon-add.png
packages/components/src/assets/recharge/icon-edit.png
packages/components/src/assets/recharge/icon-info.png
packages/components/src/assets/recharge/icon-init-add.png
packages/components/src/assets/recharge/icon-select.png
packages/components/src/components/Card/AccountAddCardV2.vue
New file
@@ -0,0 +1,37 @@
<template>
  <div class="account-cardV2">
    <div class="account-cardV2-add-tips-wrapper">
      <img :src="IconInfo" class="account-cardV2-add-tips-icon" />
      <div class="account-cardV2-add-tips">{{ tip }}</div>
    </div>
    <div class="account-cardV2-top">
      <div class="account-cardV2-content-wrapper" @click="emit('add')">
        <img :src="IconInitAdd" class="account-cardV2-init-add-icon" />
        <div class="account-cardV2-add-content">{{ content }}</div>
      </div>
    </div>
    <div class="account-cardV2-remark">{{ remark }}</div>
  </div>
</template>
<script setup lang="ts">
import IconInitAdd from '../../assets/recharge/icon-init-add.png';
import IconInfo from '../../assets/recharge/icon-info.png';
defineOptions({
  name: 'AccountAddCardV2',
});
type Props = {
  content?: string;
  remark?: string;
  showEditBtn?: boolean;
  tip?: string;
};
const props = withDefaults(defineProps<Props>(), {});
const emit = defineEmits<{
  (e: 'add'): void;
}>();
</script>
packages/components/src/components/Card/AccountCardV2.vue
New file
@@ -0,0 +1,42 @@
<template>
  <div class="account-cardV2">
    <div class="account-cardV2-top">
      <div class="account-cardV2-content-wrapper">
        <div class="account-cardV2-content">{{ content }}</div>
        <img
          v-if="showEditBtn"
          :src="IconEdit"
          class="account-cardV2-edit-icon"
          @click="emit('edit')"
        />
      </div>
      <div class="account-cardV2-add-wrapper" @click="emit('add')">
        <img :src="IconAdd" class="account-cardV2-add-icon" />
        <div class="account-cardV2-add-text">新增</div>
      </div>
    </div>
    <div class="account-cardV2-remark">{{ remark }}</div>
  </div>
</template>
<script setup lang="ts">
import IconAdd from '../../assets/recharge/icon-add.png';
import IconEdit from '../../assets/recharge/icon-edit.png';
defineOptions({
  name: 'AccountCardV2',
});
type Props = {
  content?: string;
  remark?: string;
  showEditBtn?: boolean;
};
const props = withDefaults(defineProps<Props>(), {});
const emit = defineEmits<{
  (e: 'add'): void;
  (e: 'edit'): void;
}>();
</script>
packages/components/src/components/Dialog/ConfirmDialog.vue
@@ -1,14 +1,22 @@
<template>
  <nut-dialog title="请核对充值信息并支付" v-model:visible="visible" class="confirm-dialog-wrapper">
  <nut-dialog
    title="请核对充值信息并支付"
    v-model:visible="visible"
    custom-class="confirm-dialog-wrapper"
  >
    <div class="confirm-dialog-content">
      <div class="confirm-dialog-content-tips">
        <slot name="tips">
          该产品为慢充模式,0-24小时内到账,介意请勿付款! 充值前请仔细阅读充值须知!
        </slot>
      </div>
      <div class="confirm-dialog-content-info-wrapper">
        <div class="confirm-dialog-content-info-cic"></div>
      <div class="confirm-dialog-content-info">
        <slot name="info"></slot>
      </div>
      </div>
      <div class="confirm-dialog-content-warning">
        <slot name="warning">
          同一号码充值期间,未到账前切勿在其他任何平台再次充值。因此造成的资金损失须用户自行承担!!!
packages/components/src/components/SelectPayTypeFormItem/SelectPayTypeFormItem.vue
@@ -1,22 +1,33 @@
<template>
  <NutFormItem label="选择支付方式" class="bole-form-item" prop="lifePayType" required>
    <NutRadioGroup v-model="lifePayType" direction="horizontal">
  <Chunk
    borderRadiusSmall
    :hasPaddingBottom="false"
    style="padding: 0"
    class="select-pay-type-view"
  >
    <div class="select-pay-type-form-item-title">选择支付方式</div>
    <NutFormItem class="bole-form-item" prop="lifePayType" required style="padding-bottom: 0">
      <NutRadioGroup
        v-model="lifePayType"
        text-position="left"
        class="select-pay-type-view-form-item-radio-group"
      >
      <BlRadio
        :label="LifeRechargeConstants.LifePayTypeEnum.AliPay"
        shape="button"
        class="select-pay-type-view-form-item-radio"
        v-if="showAliPay"
      >
        <div class="select-pay-type-view-form-item">
          <img class="select-pay-type-view-form-item-icon" :src="IconAliPay" />
          {{
            LifeRechargeConstants.LifePayTypeEnumText[LifeRechargeConstants.LifePayTypeEnum.AliPay]
              LifeRechargeConstants.LifePayTypeEnumText[
                LifeRechargeConstants.LifePayTypeEnum.AliPay
              ]
          }}
        </div>
      </BlRadio>
      <BlRadio
        :label="LifeRechargeConstants.LifePayTypeEnum.WxPay"
        shape="button"
        class="select-pay-type-view-form-item-radio"
        v-if="showWeixinPay"
      >
@@ -29,6 +40,7 @@
      </BlRadio>
    </NutRadioGroup>
  </NutFormItem>
  </Chunk>
</template>
<script setup lang="ts">
@@ -37,6 +49,7 @@
import BlRadio from '../Radio/Radio.vue';
import IconWeixin from '../../assets/icon-weixin-pay.png';
import IconAliPay from '../../assets/icon-alipay.png';
import Chunk from '../Layout/Chunk.vue';
defineOptions({
  name: 'SelectPayTypeFormItem',
packages/components/src/styles/card.scss
@@ -63,12 +63,116 @@
}
.par-account-list {
  padding-top: 32px;
  .nut-radio--button {
    margin-bottom: 20px !important;
    margin-bottom: 26px !important;
    &:last-child {
      margin-right: 20px !important;
      margin-bottom: 20px !important;
      margin-right: 22px !important;
      margin-bottom: 26px !important;
    }
    .nut-radio__button {
      padding: 8px 20px;
      font-size: 22px;
      background-color: transparent;
      border: 1px solid #d9d9d9;
      &.nut-radio__button--active {
        border-color: boleGetCssVar('color', 'primary');
      }
      &::after {
        display: none;
      }
    }
  }
}
.account-cardV2 {
  .account-cardV2-top {
    padding-bottom: 12px;
    border-bottom: 4px solid #f1f1f1;
    display: flex;
    margin-bottom: 20px;
    height: 80px;
    align-items: center;
    .account-cardV2-content-wrapper {
      flex: 1;
      min-width: 0;
      display: flex;
      align-items: center;
      .account-cardV2-content {
        flex-shrink: 1;
        @include ellipsis;
        font-weight: 500;
        font-size: 44px;
        color: boleGetCssVar('text-color', 'primary');
        margin-right: 24px;
        line-height: 1.2;
      }
      .account-cardV2-edit-icon {
        width: 40px;
        height: 40px;
      }
      .account-cardV2-init-add-icon {
        width: 60px;
        height: 60px;
        margin-right: 12px;
      }
      .account-cardV2-add-content {
        flex-shrink: 1;
        @include ellipsis;
        font-weight: 500;
        font-size: 40px;
        color: boleGetCssVar('text-color', 'regular');
        line-height: 1.2;
      }
    }
    .account-cardV2-add-wrapper {
      margin-left: 12px;
      .account-cardV2-add-icon {
        width: 48px;
        height: 48px;
        margin-bottom: 4px;
      }
      .account-cardV2-add-text {
        font-size: 20px;
        color: boleGetCssVar('text-color', 'regular');
        text-align: center;
        line-height: 1.2;
      }
    }
  }
  .account-cardV2-add-tips-wrapper {
    padding-top: 32px;
    display: flex;
    align-items: center;
    margin-bottom: 16px;
    .account-cardV2-add-tips-icon {
      width: 32px;
      height: 32px;
      margin-right: 8px;
    }
    .account-cardV2-add-tips {
      font-size: 22px;
      color: boleGetCssVar('text-color', 'secondary');
    }
  }
  .account-cardV2-remark {
    font-size: 24px;
    line-height: 32px;
    color: boleGetCssVar('text-color', 'regular');
    @include ellipsis;
  }
}
packages/components/src/styles/components.scss
@@ -1,9 +1,9 @@
@use './common.scss' as *;
.recharge-tips-view {
  padding: 32px;
  border-radius: 24px;
  background: linear-gradient(0deg, rgba(10, 90, 255, 0.04), rgba(10, 90, 255, 0.04)), #fff;
  // padding: 32px;
  // border-radius: 24px;
  // background: linear-gradient(0deg, rgba(10, 90, 255, 0.04), rgba(10, 90, 255, 0.04)), #fff;
  .recharge-tips-title {
    color: #1f2229;
@@ -28,27 +28,77 @@
  }
}
.confirm-dialog-wrapper {
  padding: 40px 72px !important;
  width: 686px !important;
  .nut-dialog__header {
    font-weight: bold;
    font-size: 32rpx;
    color: #222222;
    height: 44rpx;
    line-height: 44rpx;
  }
  .nut-dialog__content {
    margin-top: 12px;
    margin-bottom: 32px;
    max-height: auto;
    overflow: visible;
  }
.confirm-dialog-content {
  .confirm-dialog-content-tips {
    margin-bottom: 32px;
      font-size: 22px;
      color: boleGetCssVar('text-color', 'secondary');
      line-height: 30px;
    }
    .confirm-dialog-content-info-wrapper {
      padding: 0 20px;
      position: relative;
      margin-bottom: 32px;
      .confirm-dialog-content-info-cic {
        position: absolute;
        left: 0;
        top: -8px;
        width: 100%;
        height: 27px;
        box-shadow: 0px 3px 8px 0px rgba(2, 140, 255, 0.27);
        border-radius: 28px 28px 28px 28px;
        border: 6px solid #45aaff;
        z-index: -1;
        box-sizing: border-box;
      }
  }
  .confirm-dialog-content-info {
    padding: 24px;
      padding: 36px 24px 40px;
    border-radius: 16px;
    background: #f0f3fa;
    margin-bottom: 16px;
      box-shadow: 0px 3px 6px 0px rgba(2, 140, 255, 0.1),
        inset 0px 6px 5px 0px rgba(126, 196, 255, 0.1);
      background-color: #fff;
    .confirm-dialog-content-info-item {
      display: flex;
      margin-bottom: 20px;
        padding: 22px 0;
        font-size: 28px;
        border-bottom: 1px dashed #cccccc;
        &:first-child {
          padding-top: 0;
        }
      &:last-child {
        margin-bottom: 0;
          padding-bottom: 0;
          border-bottom: none;
      }
      .confirm-dialog-content-info-item-label {
        color: boleGetCssVar('text-color', 'regular');
          color: boleGetCssVar('text-color', 'primary');
        margin-right: 12px;
        text-align: left;
      }
@@ -58,7 +108,7 @@
        min-width: 0;
        @include ellipsis;
        color: boleGetCssVar('text-color', 'primary');
        text-align: left;
          text-align: right;
      }
      &.danger {
@@ -72,8 +122,21 @@
  .confirm-dialog-content-warning {
    color: boleGetCssVar('color', 'danger');
    text-align: left;
    font-size: 32px;
    line-height: 40px;
      font-size: 22px;
      line-height: 30px;
      position: relative;
      &::before {
        content: '*';
        position: absolute;
        left: -20px;
        top: 10px;
        background-color: boleGetCssVar('color', 'danger');
        width: 10px;
        height: 10px;
        border-radius: 50%;
      }
    }
  }
}
@@ -227,7 +290,29 @@
  color: boleGetCssVar('text-color', 'primary');
}
.select-pay-type-view {
  .select-pay-type-form-item-title {
    padding: 32px 0;
    font-size: 28px;
    color: #777777;
    text-align: center;
    border-bottom: 1px solid #f1f1f1;
  }
  .select-pay-type-view-form-item-radio-group {
    width: 100%;
    padding: 0 26px;
    box-sizing: border-box;
  }
.select-pay-type-view-form-item-radio {
    border-bottom: 1px solid #dcdcdc;
    margin-bottom: 0;
    padding: 48px 0;
    &:last-child {
      border-bottom: none;
    }
  .nut-radio__button--active {
    // &::after {
    //   background-color: transparent;
@@ -237,11 +322,13 @@
  .select-pay-type-view-form-item {
    display: flex;
    align-items: center;
    color: #1d1e1e !important;
      color: boleGetCssVar('text-color', 'primary') !important;
      font-size: 28px;
    .select-pay-type-view-form-item-icon {
      width: 32px;
      height: 32px;
      margin-right: 8px;
        width: 48px;
        height: 48px;
        margin-right: 28px;
      }
    }
  }
}
packages/components/src/styles/layout.scss
@@ -66,6 +66,7 @@
  .lp-chunk-content {
    .nut-cell.bole-form-item {
      padding: 0;
      padding-bottom: 48px;
    }
  }
}
packages/components/src/styles/mixins.scss
@@ -74,3 +74,9 @@
    color: transparent;
  }
}
@mixin placeholder {
  color: var(--bole-text-color-secondary) !important;
  font-size: 30px;
  line-height: 42px;
}
packages/components/src/styles/nut.scss
@@ -1,5 +1,6 @@
@use './function.scss' as *;
@use './hairline.scss' as *;
@use './mixins.scss' as *;
:root,
page {
@@ -113,27 +114,37 @@
  }
  .bole-input-text:not(.nut-input--disabled) {
    .h5-input {
    .h5-input,
    .input-text {
      color: boleGetCssVar('text-color', 'primary') !important;
      display: block;
      font-size: 26rpx;
      font-size: 30rpx;
      line-height: 42px;
    }
    .input-placeholder {
      color: boleGetCssVar('text-color', 'placeholder') !important;
      font-size: 26rpx;
      font-size: 30rpx;
      line-height: 42px;
    }
  }
  .bole-input-textarea:not(.nut-input--disabled) {
    color: boleGetCssVar('text-color', 'primary') !important;
    height: 200px;
    height: 300px;
    display: block;
    font-size: 30rpx;
    line-height: 42px;
  }
  [placeholderclass='bole-input-text-placeholder'] {
    &::placeholder {
      @include placeholder;
    }
  }
  .bole-input-text-placeholder {
    color: boleGetCssVar('text-color', 'placeholder') !important;
    font-size: 26rpx;
    line-height: 20rpx;
    @include placeholder;
  }
  .form-item-divider {
packages/components/src/styles/rechargeGrid.scss
@@ -53,41 +53,44 @@
}
.common-content {
  padding: 0 boleGetCssVar('size', 'body-padding-h');
  // padding: 0 boleGetCssVar('size', 'body-padding-h');
}
.parValue-radio-group {
  width: 100%;
  display: grid !important;
  grid-template-columns: repeat(3, 1fr);
  grid-gap: 20px;
  // grid-gap: 20px;
  grid-column-gap: 20px;
  grid-row-gap: 48px;
  padding-top: 18px;
  .parValue-item {
    margin-right: 0;
    .nut-radio__button {
      width: 100%;
      padding: 16rpx 0;
      padding: 30rpx 0 28px;
      background-color: transparent;
      border: 1rpx solid #e2e5eb;
      text-align: center;
      border-radius: 4px;
      border-radius: 10px;
      position: relative;
    }
    .nut-radio__button--active {
      color: #fb5100;
      border-color: #fb5100;
      overflow: hidden;
      color: boleGetCssVar('color', 'primary');
      border-color: boleGetCssVar('color', 'primary');
      &::after {
        border-radius: 8rpx;
        background-color: rgba(251, 81, 0, 0.08);
        opacity: 1;
        background-color: boleGetCssVar('color', 'primary');
        opacity: 0.05;
      }
      .parValue-item-inner {
        .discountTag {
        .discountTag,
        .discount-icon {
          display: block;
        }
      }
@@ -102,51 +105,54 @@
      .amount-wrapper {
        display: flex;
        align-items: flex-end;
        margin-bottom: 4px;
        margin-bottom: 8px;
        .amount {
          font-size: 40px;
          font-weight: 400;
          line-height: 44px;
          line-height: 56px;
        }
        .unit {
          font-size: 24px;
          font-size: 40px;
          font-weight: 400;
          line-height: 32px;
          line-height: 56px;
        }
      }
      .price-wrapper {
        display: flex;
        color: #858d98;
        font-size: 24px;
        color: boleGetCssVar('color', 'primary');
        font-size: 22px;
        font-weight: 400;
        line-height: 32px;
        line-height: 30px;
        .price {
          color: #fb5100;
          margin-left: 6px;
        }
        // .price {
        //   color: #fb5100;
        //   margin-left: 6px;
        // }
      }
      .discountTag {
        display: none;
        position: absolute;
        padding: 2px 8px;
        border-radius: 0px 0 20px 0;
        border: 1px solid #fb5100;
        background: linear-gradient(
          186deg,
          rgba(255, 129, 45, 0.08) 14.82%,
          rgba(238, 67, 67, 0.08) 91.5%
        );
        color: #fb5100;
        padding: 4px 16px;
        border-radius: 20px 0 20px 0;
        background: linear-gradient(90deg, #1aaafe 0%, #0481ff 100%);
        color: #fff;
        font-size: 22px;
        font-weight: 700;
        line-height: 28px;
        line-height: 30px;
        position: absolute;
        top: -2px;
        top: -18px;
        left: -2px;
      }
      .discount-icon {
        display: none;
        position: absolute;
        width: 48px;
        height: 48px;
        bottom: -1px;
        right: -1px;
      }
    }
  }
@@ -162,10 +168,17 @@
  }
  .recharge-button {
    width: 100%;
    margin: 40px 0;
    margin: 40px 0 64px;
    height: 88px;
    &.recharge-button-linear {
      background: linear-gradient(90deg, #40a3ff 0%, #198bfe 100%);
      box-shadow: 0px 8px 20px 0px rgba(11, 169, 255, 0.34);
    }
    .recharge-button-inner {
      display: flex;
      font-size: 32px;
      .recharge-button-text {
        margin-left: 20px;
      }
@@ -183,4 +196,62 @@
      }
    }
  }
  .lp-chunk-wrapper .lp-chunk-content {
    .bole-form-item.user-account-form-item {
      padding-bottom: 32px;
    }
  }
}
:root {
  .nut-form {
    &.chunk-form {
      background-color: #fff;
      border-radius: 16px;
      // .nut-cell-group__wrap {
      //   padding: 0 32px;
      // }
      .nut-cell {
        &.bole-form-item {
          padding: 26px 32px 0;
          &:last-child {
            border-bottom: none;
            .nut-form-item__body__slots {
              border-bottom: none;
            }
          }
          .nut-form-item__body__slots {
            padding-bottom: 26px;
            border-bottom: 2px solid #edebe4;
          }
          .nut-form-item__label {
            font-size: 28px;
            color: boleGetCssVar('text-color', 'regular');
          }
          --nut-radio-label-font-size: 30px;
          .nut-textarea {
            border-radius: 6px;
            border: 2px solid #dcdcdc;
            padding: 10px 16px !important;
          }
        }
      }
    }
  }
}
.chunk-form-actions {
  .recharge-button {
    width: 100%;
    margin: 20px 0;
    height: 88px;
  }
}
packages/components/src/utils/common.ts
@@ -54,6 +54,10 @@
  return addStarForString(str, 2, end);
}
export function addStarForPhone(str: string) {
  return `*${str.substring(str.length - 4)}`;
}
export function formatTimeAgo(date: string, format = 'YYYY-MM-DD HH:mm') {
  const diff = dayjs().diff(date, 'seconds'); // 计算时间差,单位为秒
@@ -185,3 +189,33 @@
  }
  return LifeRechargeConstants.LifePayOrderFrontStatusEnum.支付成功;
}
export class StringUtils {
  static insertSpaces(str: string, space = 4) {
    if (!str) return '';
    const regex = new RegExp(`(.{${space}})`, 'g');
    return str.replace(regex, '$1 ');
  }
  static societyCreditCodeInsertSpaces(str: string) {
    if (!str) return '';
    return str.replace(/(.{4})(.{4})(.{4})(.{6})/g, '$1 $2 $3 $4');
  }
  static idNumberInsertSpaces(str: string) {
    if (!str) return '';
    return str.replace(/(.{3})(.{3})(.{4})(.{4})(.{4})/g, '$1 $2 $3 $4 $5');
  }
  static phoneNumberAddSpace(realPhoneNumber: string) {
    if (!realPhoneNumber) return '';
    return realPhoneNumber.replace(/^(\d{3})(\d*)(\d{4})$/, '$1 $2 $3');
  }
  static formatterNumber(str: string) {
    const cleanedValue = str.replace(/[^\d.]/g, '');
    const singleDotValue = cleanedValue.replace(/(\..*)\./g, '$1');
    const numberValue = parseFloat(singleDotValue);
    return isNaN(numberValue) ? '' : singleDotValue;
  }
}
packages/components/src/views/PhoneBillRecharge/PhoneBillRecharge.vue
@@ -6,11 +6,12 @@
    @go-pay="emit('goPay', $event)"
    @paySuccess="emit('paySuccess', $event)"
    @missName="emit('missName', $event)"
    @editUserAccount="emit('editUserAccount', $event)"
  />
</template>
<script setup lang="ts">
import { computed, provide, useAttrs } from 'vue';
import { computed, provide, useAttrs, watch } from 'vue';
import { useStepper } from 'senin-mini/hooks';
import { PhoneBillRechargeContextKey } from './context';
import PhoneBillRechargeStep1 from './PhoneBillRechargeStep1.vue';
@@ -28,21 +29,24 @@
const stepperInfo = useStepper(['step1', 'step2'], 'step2');
const current = computed(() => stepperInfo.current.value);
const outCurrent = defineModel<'step1' | 'step2'>({
  set(value) {
    stepperInfo.goTo(value);
  },
  get() {
    return stepperInfo.current.value;
  },
});
const emit = defineEmits<{
  (e: 'goPay', orderNo: string): void;
  (e: 'paySuccess', orderNo: string): void;
  (e: 'missName', userAccountId: string): void;
  (e: 'editUserAccount', userAccountId: string): void;
  (e: 'currentChange', current: 'step1' | 'step2'): void;
}>();
watch(
  current,
  (newVal) => {
    emit('currentChange', newVal);
  },
  {
    immediate: true,
  }
);
provide(PhoneBillRechargeContextKey, {
  ...stepperInfo,
});
packages/components/src/views/PhoneBillRecharge/PhoneBillRechargeBaseForm.vue
@@ -4,7 +4,7 @@
    ref="formRef"
    :rules="rules"
    label-position="top"
    class="order-bill-recharge phone"
    class="order-bill-recharge phone chunk-form"
  >
    <NutFormItem label="选择运营商:" class="bole-form-item" prop="ispCode" required>
      <NutRadioGroup v-model="form.ispCode" direction="horizontal" @change="handleIspCodeChange">
@@ -22,6 +22,7 @@
        class="bole-input-text"
        placeholder="请填写您需要充值的手机号码"
        type="text"
        placeholderClass="bole-input-text-placeholder"
      />
    </NutFormItem>
    <NutFormItem label="机主姓名" class="bole-form-item" prop="name" required>
@@ -30,6 +31,7 @@
        class="bole-input-text"
        placeholder="请填写充值手机号对应的户主姓名"
        type="text"
        placeholderClass="bole-input-text-placeholder"
      />
    </NutFormItem>
    <slot></slot>
packages/components/src/views/PhoneBillRecharge/PhoneBillRechargeStep1.vue
@@ -12,7 +12,8 @@
      >
      </NutTextarea>
    </NutFormItem>
    <div class="common-content">
  </PhoneBillRechargeBaseForm>
  <div class="chunk-form-actions">
      <nut-button class="recharge-button" type="primary" @click="handleNext">
        <div class="recharge-button-inner">
          <div class="recharge-button-text">保存</div>
@@ -24,7 +25,6 @@
        </div>
      </nut-button>
    </div>
  </PhoneBillRechargeBaseForm>
</template>
<script setup lang="ts">
packages/components/src/views/PhoneBillRecharge/PhoneBillRechargeStep2.vue
@@ -6,8 +6,8 @@
    label-position="top"
    class="order-bill-recharge phone"
  >
    <Chunk borderRadiusSmall>
      <NutFormItem class="bole-form-item" prop="currentUserAccountId">
    <Chunk borderRadiusSmall :hasPaddingBottom="false">
      <NutFormItem class="bole-form-item user-account-form-item" prop="currentUserAccountId">
        <NutRadioGroup
          v-model="form.currentUserAccountId"
          direction="horizontal"
@@ -20,24 +20,30 @@
            shape="button"
            v-for="item in userAccountAllList"
            :key="item.id"
            >{{ item.content }}</NutRadio
            >{{ addStarForPhone(item.content) }}</NutRadio
          >
        </NutRadioGroup>
        <AccountCard
        <AccountCardV2
          v-if="userAccountAllList.length > 0"
          title="充值手机号"
          :content="form.phone"
          :content="StringUtils.phoneNumberAddSpace(form.phone)"
          :remark="form.remark"
          :showEditBtn="!!form.currentUserAccountId"
          @add="handleAddUserAccount"
          @edit="emit('editUserAccount', form.currentUserAccountId)"
        >
          <template #action>
            <div class="account-card-action" @click="handleAddUserAccount">新增</div>
          </template>
        </AccountCard>
        <AccountAddCard v-else @click="handleAddUserAccount" />
        </AccountCardV2>
        <AccountAddCardV2
          content="去添加充值号码"
          remark="添加号码将保存在生活缴费进行管理"
          tip="添加正确号码"
          v-else
          @add="handleAddUserAccount"
        />
      </NutFormItem>
    </Chunk>
    <NutFormItem label="选择充值金额" class="bole-form-item" prop="parValue" required>
    <Chunk borderRadiusSmall :hasPaddingBottom="false" title="选择充值金额">
      <NutFormItem class="bole-form-item" prop="parValue" required>
      <NutRadioGroup v-model="form.parValue" direction="horizontal" class="parValue-radio-group">
        <NutRadio
          :label="Number(item)"
@@ -58,17 +64,24 @@
              </div>
            </div>
            <div class="discountTag" v-if="lifePayPhoneRate > 0">{{ lifePayPhoneRate }}折</div>
              <img :src="IconSelect" class="discount-icon" />
          </div>
        </NutRadio>
      </NutRadioGroup>
    </NutFormItem>
    </Chunk>
    <SelectPayTypeFormItem
      v-model="form.lifePayType"
      :showWeixinPay="showWeixinPay"
      :showAliPay="showAliPay"
    ></SelectPayTypeFormItem>
    <div class="common-content">
      <nut-button class="recharge-button" type="primary" @click="handleSubmit">
      <nut-button
        class="recharge-button recharge-button-linear"
        type="primary"
        @click="handleSubmit"
      >
        <div class="recharge-button-inner">
          <div>¥{{ realParValue }}</div>
          <div class="recharge-button-text">立即充值</div>
@@ -100,7 +113,7 @@
} from '@nutui/nutui-taro';
import { FormRules } from '@nutui/nutui-taro/dist/types/__VUE/form/types';
import { reactive, ref, computed, toRef } from 'vue';
import { FormValidator, initLifePayType } from '../../utils';
import { FormValidator, initLifePayType, addStarForPhone, StringUtils } from '../../utils';
import {
  useLifeRechargeContext,
  BlLifeRecharge,
@@ -111,13 +124,14 @@
import ConfirmDialog from '../../components/Dialog/ConfirmDialog.vue';
import ConfirmDialogInfoItem from '../../components/Dialog/ConfirmDialogInfoItem.vue';
import { useGetRate, useGetPhoneParValue, useSetUserAccountBySelect } from '../../hooks';
import AccountAddCard from '../../components/Card/AccountAddCard.vue';
import AccountCard from '../../components/Card/AccountCard.vue';
import AccountAddCardV2 from '../../components/Card/AccountAddCardV2.vue';
import AccountCardV2 from '../../components/Card/AccountCardV2.vue';
import { usePhoneBillRechargeContext, PhoneUserAccountExtraProperties } from './context';
import SelectPayTypeFormItem from '../../components/SelectPayTypeFormItem/SelectPayTypeFormItem.vue';
import { useSelectPayType, useGetPayStatusByOrderNo } from '../../hooks/selectPayType';
import { RechargeProps } from './types';
import Chunk from '../../components/Layout/Chunk.vue';
import IconSelect from '../../assets/recharge/icon-select.png';
defineOptions({
  name: 'PhoneBillRechargeStep2',
@@ -164,6 +178,7 @@
  (e: 'goPay', orderNo: string): void;
  (e: 'paySuccess', orderNo: string): void;
  (e: 'missName', userAccountId: string): void;
  (e: 'editUserAccount', userAccountId: string): void;
}>();
const { lifePayPhoneRate } = useGetRate();
@@ -201,7 +216,9 @@
function handleSubmit() {
  if (!formRef.value) return;
  console.log('form: ', form, formRef.value);
  formRef.value.validate().then(({ valid, errors }: any) => {
    console.log('errors: ', errors);
    if (valid) {
      if (!form.name) {
        emit('missName', form.currentUserAccountId);