From fcce15c0b86c0dbcab80b20405c69fe63991ac15 Mon Sep 17 00:00:00 2001 From: xingyu4j Date: Wed, 11 Jun 2025 20:15:27 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20formatNumber=20=E7=A7=BB=E5=8A=A8?= =?UTF-8?q?=E5=88=B0=20@vben/utils?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/web-antd/src/adapter/vxe-table.ts | 31 +++++----------- apps/web-antd/src/utils/index.ts | 1 - .../views/crm/business/modules/detail-data.ts | 4 +-- .../crm/receivable/modules/detail-data.ts | 4 +-- .../receivable/plan/modules/detail-data.ts | 4 +-- .../src/views/mall/product/spu/index.vue | 3 +- .../mall/trade/delivery/pickUpOrder/index.vue | 3 +- .../src/views/mall/trade/order/index.vue | 8 ++--- .../user/components/user-account-info.vue | 3 +- apps/web-antd/src/views/member/user/data.ts | 4 +-- .../member/user/modules/balance-form.vue | 2 +- apps/web-antd/src/views/pay/cashier/index.vue | 3 +- .../wallet/rechargePackage/modules/form.vue | 2 +- .../base/shared}/src/utils/formatNumber.ts | 35 +++++++++++-------- packages/@core/base/shared/src/utils/index.ts | 1 + 15 files changed, 48 insertions(+), 60 deletions(-) rename {apps/web-antd => packages/@core/base/shared}/src/utils/formatNumber.ts (84%) diff --git a/apps/web-antd/src/adapter/vxe-table.ts b/apps/web-antd/src/adapter/vxe-table.ts index 7e71fd5ff..206cf57a1 100644 --- a/apps/web-antd/src/adapter/vxe-table.ts +++ b/apps/web-antd/src/adapter/vxe-table.ts @@ -10,7 +10,12 @@ import { setupVbenVxeTable, useVbenVxeGrid, } from '@vben/plugins/vxe-table'; -import { isFunction, isString } from '@vben/utils'; +import { + floatToFixed2, + formatToFractionDigit, + isFunction, + isString, +} from '@vben/utils'; import { Button, Image, Popconfirm, Switch } from 'ant-design-vue'; @@ -313,33 +318,13 @@ setupVbenVxeTable({ // add by 星语:数量格式化,例如说:金额 vxeUI.formats.add('formatNumber', { tableCellFormatMethod({ cellValue }, digits = 2) { - if (cellValue === null || cellValue === undefined) { - return ''; - } - if (isString(cellValue)) { - cellValue = Number.parseFloat(cellValue); - } - // 如果非 number,则直接返回空串 - if (Number.isNaN(cellValue)) { - return ''; - } - return cellValue.toFixed(digits); + return formatToFractionDigit(cellValue, digits); }, }); vxeUI.formats.add('formatAmount2', { tableCellFormatMethod({ cellValue }) { - if (cellValue === null || cellValue === undefined) { - return '0.00'; - } - if (isString(cellValue)) { - cellValue = Number.parseFloat(cellValue); - } - // 如果非 number,则直接返回空串 - if (Number.isNaN(cellValue)) { - return '0.00'; - } - return `${(cellValue / 100).toFixed(2)}元`; + return `${floatToFixed2(cellValue)}元`; }, }); }, diff --git a/apps/web-antd/src/utils/index.ts b/apps/web-antd/src/utils/index.ts index eb173b636..aaa0682f5 100644 --- a/apps/web-antd/src/utils/index.ts +++ b/apps/web-antd/src/utils/index.ts @@ -1,7 +1,6 @@ export * from './constants'; export * from './dict'; export * from './download'; -export * from './formatNumber'; export * from './formCreate'; export * from './rangePickerProps'; export * from './routerHelper'; diff --git a/apps/web-antd/src/views/crm/business/modules/detail-data.ts b/apps/web-antd/src/views/crm/business/modules/detail-data.ts index 0e16a01fe..5ff123f36 100644 --- a/apps/web-antd/src/views/crm/business/modules/detail-data.ts +++ b/apps/web-antd/src/views/crm/business/modules/detail-data.ts @@ -1,9 +1,7 @@ import type { VxeTableGridOptions } from '#/adapter/vxe-table'; import type { DescriptionItemSchema } from '#/components/description'; -import { formatDateTime } from '@vben/utils'; - -import { erpPriceInputFormatter } from '#/utils'; +import { erpPriceInputFormatter, formatDateTime } from '@vben/utils'; /** 详情页的字段 */ export function useDetailSchema(): DescriptionItemSchema[] { diff --git a/apps/web-antd/src/views/crm/receivable/modules/detail-data.ts b/apps/web-antd/src/views/crm/receivable/modules/detail-data.ts index 7468b6c2d..880f8e192 100644 --- a/apps/web-antd/src/views/crm/receivable/modules/detail-data.ts +++ b/apps/web-antd/src/views/crm/receivable/modules/detail-data.ts @@ -3,10 +3,10 @@ import type { DescriptionItemSchema } from '#/components/description'; import { h } from 'vue'; -import { formatDateTime } from '@vben/utils'; +import { erpPriceInputFormatter, formatDateTime } from '@vben/utils'; import { DictTag } from '#/components/dict-tag'; -import { DICT_TYPE, erpPriceInputFormatter } from '#/utils'; +import { DICT_TYPE } from '#/utils'; /** 详情页的字段 */ export function useDetailSchema(): DescriptionItemSchema[] { diff --git a/apps/web-antd/src/views/crm/receivable/plan/modules/detail-data.ts b/apps/web-antd/src/views/crm/receivable/plan/modules/detail-data.ts index d74100f07..85b5b5efd 100644 --- a/apps/web-antd/src/views/crm/receivable/plan/modules/detail-data.ts +++ b/apps/web-antd/src/views/crm/receivable/plan/modules/detail-data.ts @@ -3,10 +3,10 @@ import type { DescriptionItemSchema } from '#/components/description'; import { h } from 'vue'; -import { formatDateTime } from '@vben/utils'; +import { erpPriceInputFormatter, formatDateTime } from '@vben/utils'; import { DictTag } from '#/components/dict-tag'; -import { DICT_TYPE, erpPriceInputFormatter } from '#/utils'; +import { DICT_TYPE } from '#/utils'; /** 详情页的字段 */ export function useDetailSchema(): DescriptionItemSchema[] { diff --git a/apps/web-antd/src/views/mall/product/spu/index.vue b/apps/web-antd/src/views/mall/product/spu/index.vue index 34f1979c8..0b7802496 100644 --- a/apps/web-antd/src/views/mall/product/spu/index.vue +++ b/apps/web-antd/src/views/mall/product/spu/index.vue @@ -8,6 +8,7 @@ import { useRouter } from 'vue-router'; import { confirm, DocAlert, Page } from '@vben/common-ui'; import { downloadFileFromBlobPart, + fenToYuan, handleTree, treeToString, } from '@vben/utils'; @@ -24,7 +25,7 @@ import { updateStatus, } from '#/api/mall/product/spu'; import { $t } from '#/locales'; -import { fenToYuan, ProductSpuStatusEnum } from '#/utils'; +import { ProductSpuStatusEnum } from '#/utils'; import { useGridColumns, useGridFormSchema } from './data'; diff --git a/apps/web-antd/src/views/mall/trade/delivery/pickUpOrder/index.vue b/apps/web-antd/src/views/mall/trade/delivery/pickUpOrder/index.vue index e5e5fc449..e5bb21c95 100644 --- a/apps/web-antd/src/views/mall/trade/delivery/pickUpOrder/index.vue +++ b/apps/web-antd/src/views/mall/trade/delivery/pickUpOrder/index.vue @@ -5,6 +5,7 @@ import type { MallOrderApi } from '#/api/mall/trade/order'; import { h, onMounted, ref } from 'vue'; import { Page, prompt } from '@vben/common-ui'; +import { fenToYuan } from '@vben/utils'; import { Card, Input, message } from 'ant-design-vue'; @@ -15,7 +16,7 @@ import { getOrderSummary, } from '#/api/mall/trade/order'; import { SummaryCard } from '#/components/summary-card'; -import { DeliveryTypeEnum, fenToYuan, TradeOrderStatusEnum } from '#/utils'; +import { DeliveryTypeEnum, TradeOrderStatusEnum } from '#/utils'; import { useGridColumns, useGridFormSchema } from './data'; diff --git a/apps/web-antd/src/views/mall/trade/order/index.vue b/apps/web-antd/src/views/mall/trade/order/index.vue index c3fc83ea8..983affb8e 100644 --- a/apps/web-antd/src/views/mall/trade/order/index.vue +++ b/apps/web-antd/src/views/mall/trade/order/index.vue @@ -6,6 +6,7 @@ import { h } from 'vue'; import { useRouter } from 'vue-router'; import { DocAlert, Page, prompt, useVbenModal } from '@vben/common-ui'; +import { fenToYuan } from '@vben/utils'; import { Image, List, Tag, Textarea } from 'ant-design-vue'; @@ -13,12 +14,7 @@ import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table'; import { getOrderPage, updateOrderRemark } from '#/api/mall/trade/order'; import { DictTag } from '#/components/dict-tag'; import { $t } from '#/locales'; -import { - DeliveryTypeEnum, - DICT_TYPE, - fenToYuan, - TradeOrderStatusEnum, -} from '#/utils'; +import { DeliveryTypeEnum, DICT_TYPE, TradeOrderStatusEnum } from '#/utils'; import { useGridColumns, useGridFormSchema } from './data'; import DeleveryForm from './modules/delevery-form.vue'; diff --git a/apps/web-antd/src/views/member/user/components/user-account-info.vue b/apps/web-antd/src/views/member/user/components/user-account-info.vue index 097d9beba..846fd584f 100644 --- a/apps/web-antd/src/views/member/user/components/user-account-info.vue +++ b/apps/web-antd/src/views/member/user/components/user-account-info.vue @@ -2,10 +2,11 @@ import type { MemberUserApi } from '#/api/member/user'; import type { PayWalletApi } from '#/api/pay/wallet/balance'; +import { fenToYuan } from '@vben/utils'; + import { Card } from 'ant-design-vue'; import { useDescription } from '#/components/description'; -import { fenToYuan } from '#/utils'; withDefaults( defineProps<{ diff --git a/apps/web-antd/src/views/member/user/data.ts b/apps/web-antd/src/views/member/user/data.ts index 1232cca3a..866160f4d 100644 --- a/apps/web-antd/src/views/member/user/data.ts +++ b/apps/web-antd/src/views/member/user/data.ts @@ -3,6 +3,8 @@ import type { VxeTableGridOptions } from '#/adapter/vxe-table'; import { h } from 'vue'; +import { convertToInteger, formatToFraction } from '@vben/utils'; + import { Tag } from 'ant-design-vue'; import { z } from '#/adapter/form'; @@ -12,9 +14,7 @@ import { getSimpleTagList } from '#/api/member/tag'; import { getAreaTree } from '#/api/system/area'; import { CommonStatusEnum, - convertToInteger, DICT_TYPE, - formatToFraction, getDictOptions, getRangePickerDefaultProps, } from '#/utils'; diff --git a/apps/web-antd/src/views/member/user/modules/balance-form.vue b/apps/web-antd/src/views/member/user/modules/balance-form.vue index 3c0b7377f..c11b1d479 100644 --- a/apps/web-antd/src/views/member/user/modules/balance-form.vue +++ b/apps/web-antd/src/views/member/user/modules/balance-form.vue @@ -4,6 +4,7 @@ import type { MemberUserApi } from '#/api/member/user'; import { ref } from 'vue'; import { useVbenModal } from '@vben/common-ui'; +import { formatToFraction } from '@vben/utils'; import { message } from 'ant-design-vue'; @@ -11,7 +12,6 @@ import { useVbenForm } from '#/adapter/form'; import { getUser, updateUser } from '#/api/member/user'; import { getWallet } from '#/api/pay/wallet/balance'; import { $t } from '#/locales'; -import { formatToFraction } from '#/utils'; import { useBalanceFormSchema } from '../data'; diff --git a/apps/web-antd/src/views/pay/cashier/index.vue b/apps/web-antd/src/views/pay/cashier/index.vue index 3fa92eea9..c4973bf45 100644 --- a/apps/web-antd/src/views/pay/cashier/index.vue +++ b/apps/web-antd/src/views/pay/cashier/index.vue @@ -6,7 +6,7 @@ import { useRoute, useRouter } from 'vue-router'; import { Page, useVbenModal } from '@vben/common-ui'; import { useTabs } from '@vben/hooks'; -import { formatDate } from '@vben/utils'; +import { fenToYuan, formatDate } from '@vben/utils'; import { Button, @@ -19,7 +19,6 @@ import { import { getOrder, submitOrder } from '#/api/pay/order'; import { - fenToYuan, PayChannelEnum, PayDisplayModeEnum, PayOrderStatusEnum, diff --git a/apps/web-antd/src/views/pay/wallet/rechargePackage/modules/form.vue b/apps/web-antd/src/views/pay/wallet/rechargePackage/modules/form.vue index e872a078c..022189120 100644 --- a/apps/web-antd/src/views/pay/wallet/rechargePackage/modules/form.vue +++ b/apps/web-antd/src/views/pay/wallet/rechargePackage/modules/form.vue @@ -4,6 +4,7 @@ import type { WalletRechargePackageApi } from '#/api/pay/wallet/rechargePackage' import { computed, ref } from 'vue'; import { useVbenModal } from '@vben/common-ui'; +import { fenToYuan, yuanToFen } from '@vben/utils'; import { message } from 'ant-design-vue'; @@ -14,7 +15,6 @@ import { updatePackage, } from '#/api/pay/wallet/rechargePackage'; import { $t } from '#/locales'; -import { fenToYuan, yuanToFen } from '#/utils'; import { useFormSchema } from '../data'; diff --git a/apps/web-antd/src/utils/formatNumber.ts b/packages/@core/base/shared/src/utils/formatNumber.ts similarity index 84% rename from apps/web-antd/src/utils/formatNumber.ts rename to packages/@core/base/shared/src/utils/formatNumber.ts index ad3b211c7..4af124e50 100644 --- a/apps/web-antd/src/utils/formatNumber.ts +++ b/packages/@core/base/shared/src/utils/formatNumber.ts @@ -1,12 +1,25 @@ -// TODO @xingyu:感觉 formatToFraction 可以整合起来;【优先级:低】 +import { isEmpty, isString, isUndefined } from './inference'; + +/** + * 将一个整数转换为分数保留传入的小数 + * @param num + * @param digit + */ +export function formatToFractionDigit( + num: number | string | undefined, + digit: number = 2, +): string { + if (isUndefined(num)) return '0.00'; + const parsedNumber = isString(num) ? Number.parseFloat(num) : num; + return (parsedNumber / 100).toFixed(digit); +} + /** * 将一个整数转换为分数保留两位小数 * @param num */ export function formatToFraction(num: number | string | undefined): string { - if (num === undefined) return '0.00'; - const parsedNumber = typeof num === 'string' ? Number.parseFloat(num) : num; - return (parsedNumber / 100).toFixed(2); + return formatToFractionDigit(num, 2); } /** @@ -17,9 +30,7 @@ export function formatToFraction(num: number | string | undefined): string { */ export function floatToFixed2(num: number | string | undefined): string { let str = '0.00'; - if (num === undefined) { - return str; - } + if (isUndefined(num)) return str; const f = formatToFraction(num); const decimalPart = f.toString().split('.')[1]; const len = decimalPart ? decimalPart.length : 0; @@ -45,8 +56,8 @@ export function floatToFixed2(num: number | string | undefined): string { * @param num */ export function convertToInteger(num: number | string | undefined): number { - if (num === undefined) return 0; - const parsedNumber = typeof num === 'string' ? Number.parseFloat(num) : num; + if (isUndefined(num)) return 0; + const parsedNumber = isString(num) ? Number.parseFloat(num) : num; return Math.round(parsedNumber * 100); } @@ -125,7 +136,6 @@ export function erpCountInputFormatter(num: number | string | undefined) { return erpNumberFormatter(num, ERP_COUNT_DIGIT); } -// noinspection JSCommentMatchesSignature /** * 【ERP】格式化数量,保留三位小数 * @@ -148,7 +158,6 @@ export function erpPriceInputFormatter(num: number | string | undefined) { return erpNumberFormatter(num, ERP_PRICE_DIGIT); } -// noinspection JSCommentMatchesSignature /** * 【ERP】格式化金额,保留二位小数 * @@ -167,9 +176,7 @@ export function erpPriceTableColumnFormatter(cellValue: any) { * @return 总价格。如果有任一为空,则返回 undefined */ export function erpPriceMultiply(price: number, count: number) { - if (price === null || count === null) { - return undefined; - } + if (isEmpty(price) || isEmpty(count)) return undefined; return Number.parseFloat((price * count).toFixed(ERP_PRICE_DIGIT)); } diff --git a/packages/@core/base/shared/src/utils/index.ts b/packages/@core/base/shared/src/utils/index.ts index a1d553fad..8e57292f6 100644 --- a/packages/@core/base/shared/src/utils/index.ts +++ b/packages/@core/base/shared/src/utils/index.ts @@ -3,6 +3,7 @@ export * from './date'; export * from './diff'; export * from './dom'; export * from './download'; +export * from './formatNumber'; export * from './inference'; export * from './letter'; export * from './merge';