uniappx 插件 nutpi-idcard 开发与使用指南(适配鸿蒙)
HBuilderX 4.62 开始,uni-app 支持嵌入鸿蒙原生组件
nutpi
坚果派拥有若干华为HDE,以及若干其他领域的三十余位万粉博主运营。专注于研究的技术包括鸿蒙、仓颉、AI、BlueOS,小米操作系统等。团队聚焦“鸿蒙原生应用”、“智能物联”和“AI赋能”、“人工智能”四大领域的技术分享,希望推动国产新技术!
535篇原创内容
公众号
在移动应用开发中,数字的本地化显示是一个常见需求。特别是在中文环境下,我们经常需要将阿拉伯数字转换为中文数字,或者进行相反的转换。今天为大家介绍一个功能强大的 UTS 插件 —— nutpi-chinese-number-format
,它专门解决中文数字格式化的各种需求。
nutpi-chinese-number-format
是一个专为 uni-app 和 uni-app x 项目设计的中文数字格式化插件。它基于 UTS(UniApp TypeScript)技术开发,提供了完整的 TypeScript 类型定义,确保开发过程中的类型安全。
我们需要如图方式,先创建项目,选择 uniappx,vue3
image-20250605231523307
接下来我们就可以新建 uni_modules 插件,这里面我们选择 uts 插件-API 插件。
image-20250605231648288
后面就是大家编写代码的过程了,这里面需要注意的是,因为这个插件和平台的关联性不是很大,所以我们在插件的根目录下创建 index.uts 里面实现我的逻辑就好。
该插件采用 UTS(UniApp TypeScript)技术开发,相比传统的 JavaScript 插件具有以下优势:
插件内部采用了高效的映射表设计:
// 基本数字映射
const NUMBER_MAPS = {
base: {
"0": ["0", "0", "零", "〇"],
"1": ["1", "1", "一", "壹"],
"2": ["2", "2", "二", "貳", "贰"],
// ...
},
"zh-TW": {
units: ["", "十", "百", "千"],
bigUnits: [
"",
"萬",
"億",
"兆",
"京",
"垓",
"秭",
"穰",
"溝",
"澗",
"正",
"載",
],
point: "點",
uppercase: {
/* 繁体大写映射 */
},
},
"zh-CN": {
units: ["", "十", "百", "千"],
bigUnits: [
"",
"万",
"亿",
"兆",
"京",
"垓",
"秭",
"穰",
"沟",
"涧",
"正",
"载",
],
point: "点",
uppercase: {
/* 简体大写映射 */
},
},
};
为了优化性能,插件还预计算了反向映射表:
// 预计算反向映射表以优化 toNumber 函数性能
const REVERSE_BASE_MAP: Record<string, string> = {};
for (const numKey in NUMBER_MAPS.base) {
NUMBER_MAPS.base[numKey].forEach((charVariant) => {
REVERSE_BASE_MAP[charVariant] = numKey;
});
}
import { toChinese } from "@/uni_modules/nutpi-chinese-number-format";
// 基础转换
const result1 = toChinese(); // "一二三"
const result2 = toChinese(123.45); // "一二三點四五"
// 指定地区
const result3 = toChinese(, "zh-CN"); // "一二三"
const result4 = toChinese(123.45, "zh-CN"); // "一二三点四五"
import { toNumber } from "@/uni_modules/nutpi-chinese-number-format";
const num1 = toNumber("一二三"); // 123
const num2 = toNumber("一二三點四五"); // 123.45
const num3 = toNumber("一萬二千三百四十五"); // 12345
import { toChineseWithUnits } from "@/uni_modules/nutpi-chinese-number-format";
// 自动添加合适的单位
const result1 = toChineseWithUnits(); // "一萬二千三百四十五"
const result2 = toChineseWithUnits(, "zh-CN"); // "一万二千三百四十五"
const result3 = toChineseWithUnits(); // "一億二千三百四十五萬六千七百八十九"
import { toUpperCase } from "@/uni_modules/nutpi-chinese-number-format";
// 转换为大写中文数字
const result1 = toUpperCase("一二三"); // "壹貳參"
const result2 = toUpperCase("一二三", "zh-CN"); // "壹贰叁"
import { toChineseApproximate } from "@/uni_modules/nutpi-chinese-number-format";
// 大数字的近似表示
const result1 = toChineseApproximate(); // "一點二億"
const result2 = toChineseApproximate(, {
locale: "zh-CN",
precision: ,
}); // "一点二三亿"
import { toChineseMonth } from "@/uni_modules/nutpi-chinese-number-format";
// 简单格式
const month1 = toChineseMonth(); // "十月"
const month2 = toChineseMonth(); // "十一月"
// 传统格式
const month3 = toChineseMonth(, { format: "traditional" }); // "正月"
const month4 = toChineseMonth(, {
format: "traditional",
locale: "zh-CN",
}); // "腊月"
// 在商品详情页显示中文价格
const price = ;
const chinesePrice = toChineseWithUnits(price, "zh-CN"); // "一万二千八百八十八"
// 发票或收据中的金额大写
const amount = "一万二千三百四十五";
const uppercaseAmount = toUpperCase(amount, "zh-CN"); // "壹万贰仟叁佰肆拾伍"
// 传统日历中的月份显示
const months = [];
for (let i = ; i <= ; i++) {
months.push(toChineseMonth(i, { format: "traditional", locale: "zh-CN" }));
}
// ["正月", "二月", "三月", ..., "腊月"]
// 用户量统计的友好显示
const userCount = ;
const friendlyCount = toChineseApproximate(userCount, {
locale: "zh-CN",
precision: ,
}); // "一点二万"
<template>
<view class="number-demo">
<view class="section">
<text class="title">基础转换</text>
<text>数字 {{ originalNumber }} 转中文:{{ chineseNumber }}</text>
<text>中文转数字:{{ convertedNumber }}</text>
</view>
<view class="section">
<text class="title">带单位转换</text>
<text>{{ largeNumber }} → {{ chineseWithUnits }}</text>
</view>
<view class="section">
<text class="title">大写转换</text>
<text>{{ chineseText }} → {{ uppercaseText }}</text>
</view>
<view class="section">
<text class="title">月份转换</text>
<text>{{ currentMonth }}月 → {{ chineseMonth }}</text>
<text>传统格式:{{ traditionalMonth }}</text>
</view>
</view>
</template>
<script setup lang="ts">
import {
toChinese,
toChineseWithUnits,
toNumber,
toUpperCase,
toChineseApproximate,
toChineseMonth,
type Locales,
} from "@/uni_modules/nutpi-chinese-number-format";
// 响应式数据
const originalNumber = ref(12345);
const largeNumber = ref(123456789);
const chineseText = ref("一二三四五");
const currentMonth = ref(10);
// 计算属性
const chineseNumber = computed(() => toChinese(originalNumber.value, "zh-CN"));
const convertedNumber = computed(() => toNumber("一二三四五"));
const chineseWithUnits = computed(() =>
toChineseWithUnits(largeNumber.value, "zh-CN")
);
const uppercaseText = computed(() => toUpperCase(chineseText.value, "zh-CN"));
const chineseMonth = computed(() => toChineseMonth(currentMonth.value));
const traditionalMonth = computed(() =>
toChineseMonth(currentMonth.value, {
format: "traditional",
locale: "zh-CN",
})
);
</script>
插件在初始化时预计算了反向映射表,避免了运行时的重复计算:
// 预计算反向映射表,提升 toNumber 函数性能
const REVERSE_BASE_MAP: Record<string, string> = {};
for (const numKey in NUMBER_MAPS.base) {
NUMBER_MAPS.base[numKey].forEach((charVariant) => {
REVERSE_BASE_MAP[charVariant] = numKey;
});
}
在处理大数字时,插件采用了分组处理的方式,提高了转换效率:
// 按4位进行分组处理,提高大数字处理效率
const groups = numStr
.split("")
.reverse()
.reduce((acc: string[][], digit: string, i: number) => {
const groupIndex = Math.floor(i / );
if (!acc[groupIndex]) acc[groupIndex] = [];
acc[groupIndex].unshift(digit);
return acc;
}, []);
// toNumber 函数的错误处理
exportfunction toNumber(str: string): number {
let numberStr = "";
let hasInvalidChar = false;
for (const char of str) {
const digit = REVERSE_BASE_MAP[char];
if (digit !== undefined) {
numberStr += digit;
} else {
hasInvalidChar = true;
break;
}
}
if (hasInvalidChar || numberStr.length === ) {
returnNaN; // 转换失败时返回 NaN
}
// 处理多个小数点的情况
const parts = numberStr.split(".");
if (parts.length > ) {
numberStr = parts[] + "." + parts.slice().join("");
}
returnNumber(numberStr);
}
// toChineseMonth 函数的边界检查
export function toChineseMonth(
month: number,
options: MonthOptions = {}
): string {
// 检查月份是否在1到12之间且为整数
if (month < || month > || !Number.isInteger(month)) {
return ""; // 无效月份返回空字符串
}
// ... 其他处理逻辑
}
nutpi-chinese-number-format
文件夹复制到项目的 uni_modules
目录下如果你的项目使用 TypeScript,插件提供了完整的类型定义:
// 类型导入
import type {
Locales,
Options,
MonthOptions,
} from "@/uni_modules/nutpi-chinese-number-format";
// 使用类型
const locale: Locales = "zh-CN";
const options: Options = {
locale: "zh-CN",
precision: ,
};
// 根据用户设备语言自动选择地区
const getLocale = (): Locales => {
const systemLocale = uni.getSystemInfoSync().language;
return systemLocale.includes("TW") || systemLocale.includes("HK")
? "zh-TW"
: "zh-CN";
};
const userLocale = getLocale();
const result = toChinese(, userLocale);
// 安全的数字转换
const safeToNumber = (str: string): number | null => {
const result = toNumber(str);
returnisNaN(result) ? null : result;
};
// 使用示例
const userInput = "一二三";
constnumber = safeToNumber(userInput);
if (number !== null) {
console.log(`转换成功: ${number}`);
} else {
console.log("转换失败,请检查输入格式");
}
// 对于频繁调用的场景,可以缓存结果
const numberCache = new Map<string, string>();
const cachedToChinese = (num: number, locale: Locales = "zh-CN"): string => {
const key = `${num}_${locale}`;
if (numberCache.has(key)) {
return numberCache.get(key)!;
}
const result = toChinese(num, locale);
numberCache.set(key, result);
return result;
};
nutpi-chinese-number-format
是一个功能全面、性能优秀的中文数字格式化插件。它不仅提供了丰富的转换功能,还具备以下优势:
无论是开发电商应用、财务系统,还是需要中文本地化的其他应用,这个插件都能为你提供可靠的中文数字格式化解决方案。
如有问题或建议,请通过以下方式联系:
坚果派社区由小波、狼哥等人创建,团队拥有数位华为 HDE 及 1000+HarmonyOS 开发者,以及若干其他领域的三十余位万粉博主/UP 主运营。
专注于分享的技术包括 HarmonyOS/OpenHarmony、仓颉、ArkUI-X、元服务、AI、BlueOS 操作系统等。团队成员主要聚集在北京,上海,南京,深圳,广州,苏州、长沙、宁夏等地,目前已为华为、vivo、腾讯、亚马逊以及三方技术社区提供各类开发咨询服务 100+。累计粉丝 100+w,孵化开发者 10w+,高校 20+、企业 10+。自研应用 40 款,三方库 80 个,鸿蒙原生应用课程 500+。持续助力鸿蒙仓颉等生态繁荣发展。
参考资料
[1]
UTS 语法: https://uniapp.dcloud.net.cn/tutorial/syntax-uts.html
[2]
UTS API 插件: https://uniapp.dcloud.net.cn/plugin/uts-plugin.html
[3]
Hello UTS: https://gitcode.net/dcloud/hello-uts