mirror of
https://github.com/CorentinTh/it-tools.git
synced 2025-05-05 05:47:10 -04:00
feat(new tool): RMB Uppercase Converter
Fix #891. Taken from 6297c10cb0
This commit is contained in:
parent
cb5b462e11
commit
6530d37b1a
5 changed files with 162 additions and 0 deletions
|
@ -6,6 +6,7 @@ import { tool as asciiTextDrawer } from './ascii-text-drawer';
|
||||||
|
|
||||||
import { tool as textToUnicode } from './text-to-unicode';
|
import { tool as textToUnicode } from './text-to-unicode';
|
||||||
import { tool as safelinkDecoder } from './safelink-decoder';
|
import { tool as safelinkDecoder } from './safelink-decoder';
|
||||||
|
import { tool as rmbNumbers } from './rmb-numbers';
|
||||||
import { tool as pdfSignatureChecker } from './pdf-signature-checker';
|
import { tool as pdfSignatureChecker } from './pdf-signature-checker';
|
||||||
import { tool as numeronymGenerator } from './numeronym-generator';
|
import { tool as numeronymGenerator } from './numeronym-generator';
|
||||||
import { tool as macAddressGenerator } from './mac-address-generator';
|
import { tool as macAddressGenerator } from './mac-address-generator';
|
||||||
|
@ -107,6 +108,7 @@ export const toolsByCategory: ToolCategory[] = [
|
||||||
listConverter,
|
listConverter,
|
||||||
tomlToJson,
|
tomlToJson,
|
||||||
tomlToYaml,
|
tomlToYaml,
|
||||||
|
rmbNumbers,
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
12
src/tools/rmb-numbers/index.ts
Normal file
12
src/tools/rmb-numbers/index.ts
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
import { CurrencyYen } from '@vicons/tabler';
|
||||||
|
import { defineTool } from '../tool';
|
||||||
|
|
||||||
|
export const tool = defineTool({
|
||||||
|
name: 'RMB Uppercase Converter',
|
||||||
|
path: '/rmb-numbers',
|
||||||
|
description: 'RMB/Renminbi Capitalization Conversion Tool',
|
||||||
|
keywords: ['rmb', 'renminbi', 'cny', 'number', 'uppercase', '人民币', '大写', '转换'],
|
||||||
|
component: () => import('./rmb-numbers.vue'),
|
||||||
|
icon: CurrencyYen,
|
||||||
|
createdAt: new Date('2024-04-29'),
|
||||||
|
});
|
37
src/tools/rmb-numbers/rmb-numbers.service.test.ts
Normal file
37
src/tools/rmb-numbers/rmb-numbers.service.test.ts
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
import { describe, expect, it } from 'vitest';
|
||||||
|
import { rmb } from './rmb-numbers.service';
|
||||||
|
|
||||||
|
describe('rmb-case-converter', () => {
|
||||||
|
it('rmb to convert rmb numbers to uppercase', async () => {
|
||||||
|
expect(rmb(123)).to.deep.equal([
|
||||||
|
{
|
||||||
|
type: 'number',
|
||||||
|
value: '壹',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'unit',
|
||||||
|
value: '佰',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'number',
|
||||||
|
value: '贰',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'unit',
|
||||||
|
value: '拾',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'number',
|
||||||
|
value: '叁',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'unit',
|
||||||
|
value: '元',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'cut',
|
||||||
|
value: '整',
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
});
|
67
src/tools/rmb-numbers/rmb-numbers.service.ts
Normal file
67
src/tools/rmb-numbers/rmb-numbers.service.ts
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
export { rmb };
|
||||||
|
|
||||||
|
const numbers = ['零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖'];
|
||||||
|
const leftUnits = ['元', '拾', '佰', '仟', '万', '拾', '佰', '仟', '亿', '拾', '佰', '仟', '万', '拾', '佰', '仟', '万'];
|
||||||
|
const rightUnits = ['角', '分'];
|
||||||
|
|
||||||
|
function rmb(value: number) {
|
||||||
|
if (Object.prototype.toString.call(value) === '[object Number]' && value >= 0.01) {
|
||||||
|
const fragment: any = [];
|
||||||
|
const [leftValues, rightValues] = String(value).split('.').map(part => part.split('').map(i => Number(i)));
|
||||||
|
|
||||||
|
const leftValueLength = leftValues.length; // 整数部分位数
|
||||||
|
const unit1 = leftValueLength - 1; // 元位
|
||||||
|
const unit5 = leftValueLength - 5; // 万位
|
||||||
|
const unit9 = leftValueLength - 9; // 亿位
|
||||||
|
const unit13 = leftValueLength - 13; // 万亿位
|
||||||
|
const unit17 = leftValueLength - 17; // 万万亿位
|
||||||
|
const hasLeftValue = leftValueLength > 1 || leftValues[0] > 0; // 整数部分不为0
|
||||||
|
const hasRightValue = rightValues && (rightValues[0] > 0 || rightValues[1] > 0); // 小数部分不为0
|
||||||
|
const has678Value = leftValues[unit5 - 1] > 0 || leftValues[unit5 - 2] > 0 || leftValues[unit5 - 3] > 0; // 拾万、佰万或仟万位不为0
|
||||||
|
const overflowIndex = leftValueLength - leftUnits.length; // 溢出位索引
|
||||||
|
|
||||||
|
let leftUnitIndex = 0;
|
||||||
|
for (let i = leftValueLength - 1; i >= 0; i--) {
|
||||||
|
if (leftValues[i] === 0 && (i === unit5 || i === unit9 || i === unit13 || i === unit17) && leftValues[i + 1] > 0) {
|
||||||
|
// 当前位为0,且当前位为万、亿、万亿、万万亿,且低一位不为0
|
||||||
|
fragment.unshift({ type: 'number', value: numbers[leftValues[i]] });
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((leftValues[i] > 0) || (i === unit1 && hasLeftValue) || (i === unit5 && has678Value) || i === unit9 || i === unit13 || i === unit17) {
|
||||||
|
// 元、万、亿、万亿、万万亿或当前位不为0
|
||||||
|
fragment.unshift({ type: 'unit', value: leftUnits[leftUnitIndex] });
|
||||||
|
}
|
||||||
|
|
||||||
|
if (leftValues[i] > 0 || (leftValues[i + 1] > 0 && i !== unit5 && i !== unit9 && i !== unit13 && i !== unit17) || i <= overflowIndex) {
|
||||||
|
// 当前位不为0,或低一位不为0且当前位非万、亿、万亿、万万亿,或当前为溢出位
|
||||||
|
fragment.unshift({ type: 'number', value: numbers[leftValues[i]] });
|
||||||
|
}
|
||||||
|
|
||||||
|
leftUnitIndex++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasRightValue) {
|
||||||
|
// 角
|
||||||
|
if (rightValues[0] > 0 || hasLeftValue) { // 角位不为0,或整数位不为0
|
||||||
|
fragment.push({ type: 'number', value: numbers[rightValues[0]] });
|
||||||
|
}
|
||||||
|
if (rightValues[0] > 0) { // 角位不为0
|
||||||
|
fragment.push({ type: 'unit', value: rightUnits[0] });
|
||||||
|
}
|
||||||
|
// 分
|
||||||
|
if (rightValues[1] > 0) {
|
||||||
|
fragment.push({ type: 'number', value: numbers[rightValues[1]] });
|
||||||
|
fragment.push({ type: 'unit', value: rightUnits[1] });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else { // 没有小数位
|
||||||
|
fragment.push({ type: 'cut', value: '整' });
|
||||||
|
}
|
||||||
|
return fragment;
|
||||||
|
}
|
||||||
|
return [
|
||||||
|
{ type: 'number', value: '零' },
|
||||||
|
{ type: 'unit', value: '元' },
|
||||||
|
{ type: 'cut', value: '整' },
|
||||||
|
];
|
||||||
|
};
|
44
src/tools/rmb-numbers/rmb-numbers.vue
Normal file
44
src/tools/rmb-numbers/rmb-numbers.vue
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { useThemeVars } from 'naive-ui';
|
||||||
|
import { rmb } from './rmb-numbers.service';
|
||||||
|
|
||||||
|
const themeVars = useThemeVars();
|
||||||
|
const inputRmb = ref(23);
|
||||||
|
const outputRmb = computed(() => rmb(inputRmb.value)); ;
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div flex flex-col gap-2>
|
||||||
|
<c-card title="Lower Case Amount">
|
||||||
|
<n-input-number v-model:value="inputRmb" max="100000000000" min="0" placeholder="Enter the amount in lowercase (example: 1314.52)" :show-button="false" w-full />
|
||||||
|
</c-card>
|
||||||
|
|
||||||
|
<div my-16px divider />
|
||||||
|
|
||||||
|
<c-card title="Amount in Capital Letters" flex flex-col>
|
||||||
|
<div m-0 m-x-auto>
|
||||||
|
<span
|
||||||
|
v-for="(item, index) in outputRmb"
|
||||||
|
:key="index"
|
||||||
|
:class="item.type"
|
||||||
|
>
|
||||||
|
{{ item.value }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</c-card>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="less" scoped>
|
||||||
|
.unit {
|
||||||
|
font-size: 1.4em;
|
||||||
|
color: v-bind('themeVars.successColor');
|
||||||
|
}
|
||||||
|
.number {
|
||||||
|
font-size: 2.4em;
|
||||||
|
}
|
||||||
|
.cut {
|
||||||
|
font-size: 1.4em;
|
||||||
|
color: v-bind('themeVars.errorColor');
|
||||||
|
}
|
||||||
|
</style>
|
Loading…
Add table
Add a link
Reference in a new issue