Commit a6c77b1602389c981e91e7da4d4a6de356222762

Authored by 曾国涛
1 parent 04358c9a

feat(invoice): optimize invoice components and add Chinese currency conversion utility

- Add dynamic invoice type display in Invoice.tsx.
- Refactor InvoiceDetailTable.tsx to simplify code and remove unnecessary comments.
- Optimize data processing and UI display in InvoiceModal.tsx.
- Improve component structure and add orderId mapping in InvoiceRecordDetailModal.tsx.
- Enhance InvoicingDrawerForm.tsx with total price calculation and validation.- Implement Chinese currency conversion function in numberUtil.ts.
- Various code cleanups and documentation improvements.
src/pages/Invoice/components/Invoice.tsx
@@ -154,7 +154,11 @@ export default ({ data }) => { @@ -154,7 +154,11 @@ export default ({ data }) => {
154 发票号码:<InvoiceInfo>{data.invoiceNumber}</InvoiceInfo> 154 发票号码:<InvoiceInfo>{data.invoiceNumber}</InvoiceInfo>
155 </Col> 155 </Col>
156 <Col className="title col_18 no-border"> 156 <Col className="title col_18 no-border">
157 - 电子发票(增值税专用发票) 157 + 电子发票(
  158 + {data.type === 'SPECIAL_TICKET'
  159 + ? '增值税专用发票'
  160 + : '增值税普通发票'}
  161 + )
158 </Col> 162 </Col>
159 <UnderLine className="UnderLine"> 163 <UnderLine className="UnderLine">
160 <div></div> 164 <div></div>
src/pages/Invoice/components/InvoiceDetailTable.tsx
@@ -3,13 +3,14 @@ import { InvoiceProjectSelect } from &#39;@/pages/Invoice/components/InvoiceProjectS @@ -3,13 +3,14 @@ import { InvoiceProjectSelect } from &#39;@/pages/Invoice/components/InvoiceProjectS
3 import { 3 import {
4 ActionType, 4 ActionType,
5 EditableProTable, 5 EditableProTable,
  6 + ProCard,
6 ProColumns, 7 ProColumns,
  8 + ProFormField,
7 } from '@ant-design/pro-components'; 9 } from '@ant-design/pro-components';
8 import { useEffect, useRef, useState } from 'react'; 10 import { useEffect, useRef, useState } from 'react';
9 11
10 export default ({ recordId, details, updateDetails, readOnly }) => { 12 export default ({ recordId, details, updateDetails, readOnly }) => {
11 const [editableKeys, setEditableRowKeys] = useState([]); 13 const [editableKeys, setEditableRowKeys] = useState([]);
12 - const [invoiceProject, setInvoiceProject] = useState({});  
13 const ref = useRef<ActionType>(); 14 const ref = useRef<ActionType>();
14 useEffect(() => { 15 useEffect(() => {
15 updateDetails(details); 16 updateDetails(details);
@@ -26,12 +27,7 @@ export default ({ recordId, details, updateDetails, readOnly }) =&gt; { @@ -26,12 +27,7 @@ export default ({ recordId, details, updateDetails, readOnly }) =&gt; {
26 ellipsis: true, 27 ellipsis: true,
27 readonly: readOnly, 28 readonly: readOnly,
28 renderFormItem: () => { 29 renderFormItem: () => {
29 - return (  
30 - <InvoiceProjectSelect  
31 - setInvoiceProject={setInvoiceProject}  
32 - readOnly={readOnly}  
33 - />  
34 - ); 30 + return <InvoiceProjectSelect readOnly={readOnly} />;
35 }, 31 },
36 }, 32 },
37 { 33 {
@@ -131,46 +127,27 @@ export default ({ recordId, details, updateDetails, readOnly }) =&gt; { @@ -131,46 +127,27 @@ export default ({ recordId, details, updateDetails, readOnly }) =&gt; {
131 onValuesChange: (record, recordList) => { 127 onValuesChange: (record, recordList) => {
132 //修改recordList中tid为record.tid的元素,将它的specification属性设置为invoiceProject的specification属性 128 //修改recordList中tid为record.tid的元素,将它的specification属性设置为invoiceProject的specification属性
133 const records = recordList.map((item) => { 129 const records = recordList.map((item) => {
134 - if (  
135 - record &&  
136 - item.tid === record.tid &&  
137 - item.projectName !==  
138 - '*' +  
139 - invoiceProject.productAndServiceCatagoryAbbreviation +  
140 - '*' +  
141 - invoiceProject?.name &&  
142 - item.specification !== invoiceProject?.specification  
143 - ) {  
144 - console.log(item.projectName);  
145 - console.log(invoiceProject?.name);  
146 - item.projectName =  
147 - '*' +  
148 - invoiceProject.productAndServiceCatagoryAbbreviation +  
149 - '*' +  
150 - invoiceProject?.name;  
151 - item.specification = invoiceProject?.specification;  
152 - item.unit = invoiceProject?.unit;  
153 - item.taxRate = invoiceProject?.taxRate * 100;  
154 - }  
155 return item; 130 return item;
156 }); 131 });
157 updateDetails(records); 132 updateDetails(records);
158 }, 133 },
159 }} 134 }}
160 /> 135 />
161 - {/*{<ProCard title="表格数据" headerBordered collapsible defaultCollapsed>  
162 - <ProFormField  
163 - ignoreFormItem  
164 - fieldProps={{  
165 - style: {  
166 - width: '100%',  
167 - },  
168 - }}  
169 - mode="read"  
170 - valueType="jsonCode"  
171 - text={JSON.stringify(details)}  
172 - />  
173 - </ProCard>}*/} 136 + {
  137 + <ProCard title="表格数据" headerBordered collapsible defaultCollapsed>
  138 + <ProFormField
  139 + ignoreFormItem
  140 + fieldProps={{
  141 + style: {
  142 + width: '100%',
  143 + },
  144 + }}
  145 + mode="read"
  146 + valueType="jsonCode"
  147 + text={JSON.stringify(details)}
  148 + />
  149 + </ProCard>
  150 + }
174 </> 151 </>
175 ); 152 );
176 }; 153 };
src/pages/Invoice/components/InvoiceModal.tsx
@@ -6,15 +6,15 @@ import { useEffect, useState } from &#39;react&#39;; @@ -6,15 +6,15 @@ import { useEffect, useState } from &#39;react&#39;;
6 6
7 export default ({ recordId, getRecord, button }) => { 7 export default ({ recordId, getRecord, button }) => {
8 const [data, setData] = useState<any>({}); 8 const [data, setData] = useState<any>({});
  9 + const getData = async () => {
  10 + let ret = await postServiceInvoiceGetInvoiceRecord({
  11 + query: {
  12 + id: recordId,
  13 + },
  14 + });
  15 + setData(ret.data);
  16 + };
9 useEffect(() => { 17 useEffect(() => {
10 - const getData = async () => {  
11 - let ret = await postServiceInvoiceGetInvoiceRecord({  
12 - query: {  
13 - id: recordId,  
14 - },  
15 - });  
16 - setData(ret.data);  
17 - };  
18 if (recordId) { 18 if (recordId) {
19 getData(); 19 getData();
20 } 20 }
@@ -25,8 +25,12 @@ export default ({ recordId, getRecord, button }) =&gt; { @@ -25,8 +25,12 @@ export default ({ recordId, getRecord, button }) =&gt; {
25 title="预览发票" 25 title="预览发票"
26 trigger={button ? button : <a type="primary">预览</a>} 26 trigger={button ? button : <a type="primary">预览</a>}
27 onOpenChange={(open) => { 27 onOpenChange={(open) => {
28 - if (open && getRecord) {  
29 - setData(getRecord()); 28 + if (open) {
  29 + if (getRecord) {
  30 + setData(getRecord());
  31 + } else {
  32 + getData();
  33 + }
30 } 34 }
31 }} 35 }}
32 width={1200} 36 width={1200}
src/pages/Invoice/components/InvoiceProjectSelect.tsx
@@ -2,12 +2,7 @@ import { postServiceConstListInvoiceDetailNames } from &#39;@/services&#39;; @@ -2,12 +2,7 @@ import { postServiceConstListInvoiceDetailNames } from &#39;@/services&#39;;
2 import { Select, Tooltip } from 'antd'; 2 import { Select, Tooltip } from 'antd';
3 import { useState } from 'react'; 3 import { useState } from 'react';
4 4
5 -export const InvoiceProjectSelect = ({  
6 - readOnly,  
7 - value,  
8 - onChange,  
9 - setInvoiceProject,  
10 -}) => { 5 +export const InvoiceProjectSelect = ({ readOnly, value, onChange }) => {
11 const [options, setOptions] = useState<any[]>([]); 6 const [options, setOptions] = useState<any[]>([]);
12 // 定义防抖函数 7 // 定义防抖函数
13 let timeoutId = null; 8 let timeoutId = null;
@@ -20,16 +15,22 @@ export const InvoiceProjectSelect = ({ @@ -20,16 +15,22 @@ export const InvoiceProjectSelect = ({
20 }, 15 },
21 }); 16 });
22 const data = res.data; 17 const data = res.data;
23 - console.log('invoiceProject' + JSON.stringify(data)); 18 +
24 setOptions( 19 setOptions(
25 data.map((item) => { 20 data.map((item) => {
  21 + console.log(item);
26 return { 22 return {
  23 + key: item.id,
27 label: 24 label:
28 '*' + 25 '*' +
29 item.productAndServiceCatagoryAbbreviation + 26 item.productAndServiceCatagoryAbbreviation +
30 '*' + 27 '*' +
31 item?.name, 28 item?.name,
32 - value: item.id, 29 + value:
  30 + '*' +
  31 + item.productAndServiceCatagoryAbbreviation +
  32 + '*' +
  33 + item?.name,
33 ...item, 34 ...item,
34 }; 35 };
35 }), 36 }),
@@ -48,7 +49,6 @@ export const InvoiceProjectSelect = ({ @@ -48,7 +49,6 @@ export const InvoiceProjectSelect = ({
48 placeholder="请选择开票项目" 49 placeholder="请选择开票项目"
49 filterOption={(input, option) => (option?.label ?? '').includes(input)} 50 filterOption={(input, option) => (option?.label ?? '').includes(input)}
50 onChange={(e) => { 51 onChange={(e) => {
51 - setInvoiceProject(options.find((item) => item.value === e));  
52 onChange(e); 52 onChange(e);
53 }} 53 }}
54 defaultValue={value} 54 defaultValue={value}
src/pages/Invoice/components/InvoiceRecordDetailModal.tsx
@@ -51,6 +51,7 @@ export default ({ id, setVisible }) =&gt; { @@ -51,6 +51,7 @@ export default ({ id, setVisible }) =&gt; {
51 id: id, 51 id: id,
52 }, 52 },
53 }); 53 });
  54 + console.log(ret.data);
54 const updatedInvoiceDetails = ret.data.invoiceDetails?.map( 55 const updatedInvoiceDetails = ret.data.invoiceDetails?.map(
55 (item, index) => ({ 56 (item, index) => ({
56 ...item, // 保留原有属性 57 ...item, // 保留原有属性
@@ -79,7 +80,23 @@ export default ({ id, setVisible }) =&gt; { @@ -79,7 +80,23 @@ export default ({ id, setVisible }) =&gt; {
79 id: id, 80 id: id,
80 }, 81 },
81 }); 82 });
82 - return ret.data; 83 + const data = ret.data;
  84 + const orderIdMap = data.orderIdMap;
  85 + const orderIdList = [];
  86 + //遍历orderIdMap属性。
  87 + for (const key in orderIdMap) {
  88 + if (key in Object.getOwnPropertyNames(orderIdMap)) {
  89 + const orderId = {
  90 + mainId: key,
  91 + subIds: orderIdMap[key],
  92 + };
  93 + orderIdList.push(orderId);
  94 + }
  95 + }
  96 + return {
  97 + ...data,
  98 + orderIdList: orderIdList,
  99 + };
83 }} 100 }}
84 submitter={{ 101 submitter={{
85 render: () => { 102 render: () => {
@@ -233,7 +250,7 @@ export default ({ id, setVisible }) =&gt; { @@ -233,7 +250,7 @@ export default ({ id, setVisible }) =&gt; {
233 /> 250 />
234 <ProFormFieldSet 251 <ProFormFieldSet
235 name="list" 252 name="list"
236 - label="订单号" 253 + label="订单号"
237 transform={(value: any) => ({ 254 transform={(value: any) => ({
238 list: value, 255 list: value,
239 startTime: value[0], 256 startTime: value[0],
@@ -241,21 +258,37 @@ export default ({ id, setVisible }) =&gt; { @@ -241,21 +258,37 @@ export default ({ id, setVisible }) =&gt; {
241 })} 258 })}
242 > 259 >
243 <ProFormList 260 <ProFormList
244 - name="subOrderIds" 261 + name="orderIdList"
245 creatorButtonProps={false} 262 creatorButtonProps={false}
246 itemRender={({}, { record }) => { 263 itemRender={({}, { record }) => {
247 return ( 264 return (
248 - <> 265 + <Space>
249 <Button 266 <Button
  267 + key={record.mainId}
250 className="pl-1 pr-0" 268 className="pl-1 pr-0"
251 type="link" 269 type="link"
252 target="_blank" 270 target="_blank"
253 - href={'/order?subOrderId=' + record} 271 + href={'/order?id=' + record.mainId}
254 > 272 >
255 - {record} 273 + {record.mainId}
256 </Button> 274 </Button>
  275 + (
  276 + {record.subIds.map((item) => {
  277 + return (
  278 + <Button
  279 + key={item}
  280 + className="pl-1 pr-0"
  281 + type="link"
  282 + target="_blank"
  283 + href={'/order?subOrderId=' + item}
  284 + >
  285 + {item}
  286 + </Button>
  287 + );
  288 + })}
  289 + )
257 <Divider type="vertical" /> 290 <Divider type="vertical" />
258 - </> 291 + </Space>
259 ); 292 );
260 }} 293 }}
261 > 294 >
src/pages/Invoice/index.tsx
@@ -319,14 +319,14 @@ const InvoicePage = () =&gt; { @@ -319,14 +319,14 @@ const InvoicePage = () =&gt; {
319 render: (text, record) => { 319 render: (text, record) => {
320 return [ 320 return [
321 /*<InvoiceRecordDetailModal 321 /*<InvoiceRecordDetailModal
322 - key="detail"  
323 - id={record.id}  
324 - subOrderIds={record.subOrderIds}  
325 - onClose={()=>{  
326 - waitDealrecordActionRef.current?.reload();  
327 - }  
328 - }  
329 - />*/ 322 + key="detail"
  323 + id={record.id}
  324 + subOrderIds={record.subOrderIds}
  325 + onClose={()=>{
  326 + waitDealrecordActionRef.current?.reload();
  327 + }
  328 + }
  329 + />*/
330 <a 330 <a
331 key="detail" 331 key="detail"
332 onClick={() => { 332 onClick={() => {
src/pages/Order/components/InvoicingDrawerForm.tsx
@@ -9,6 +9,7 @@ import { @@ -9,6 +9,7 @@ import {
9 postServiceInvoiceQueryCompanyInfo, 9 postServiceInvoiceQueryCompanyInfo,
10 } from '@/services'; 10 } from '@/services';
11 import { enumToSelect } from '@/utils'; 11 import { enumToSelect } from '@/utils';
  12 +import { convertCurrency } from '@/utils/numberUtil';
12 import { 13 import {
13 DrawerForm, 14 DrawerForm,
14 ProCard, 15 ProCard,
@@ -51,7 +52,19 @@ export default ({ dataList, setVisible, onClose }) =&gt; { @@ -51,7 +52,19 @@ export default ({ dataList, setVisible, onClose }) =&gt; {
51 <InvoiceModal 52 <InvoiceModal
52 key={'invoicePreview'} 53 key={'invoicePreview'}
53 button={<Button type="primary"> 发票预览 </Button>} 54 button={<Button type="primary"> 发票预览 </Button>}
54 - getRecord={form.getFieldsValue} 55 + getRecord={() => {
  56 + const totalPrice = dataList.reduce(
  57 + (accumulator, currentValue) => {
  58 + return accumulator + currentValue.subOrderPayment;
  59 + },
  60 + 0,
  61 + );
  62 + return {
  63 + ...form.getFieldsValue(),
  64 + totalPrice: totalPrice,
  65 + totalPriceText: convertCurrency(totalPrice),
  66 + };
  67 + }}
55 />, 68 />,
56 ...defaultDoms, 69 ...defaultDoms,
57 ]; 70 ];
@@ -148,6 +161,7 @@ export default ({ dataList, setVisible, onClose }) =&gt; { @@ -148,6 +161,7 @@ export default ({ dataList, setVisible, onClose }) =&gt; {
148 width="md" 161 width="md"
149 name="partyATaxid" 162 name="partyATaxid"
150 label="购方税号" 163 label="购方税号"
  164 + rules={[{ required: true, message: '购方税号必填' }]}
151 placeholder="请输入名称" 165 placeholder="请输入名称"
152 /> 166 />
153 <ProFormText 167 <ProFormText
@@ -244,6 +258,7 @@ export default ({ dataList, setVisible, onClose }) =&gt; { @@ -244,6 +258,7 @@ export default ({ dataList, setVisible, onClose }) =&gt; {
244 name="invoiceDetails" 258 name="invoiceDetails"
245 label="开票明细" 259 label="开票明细"
246 initialValue={dataList.map((item) => { 260 initialValue={dataList.map((item) => {
  261 + console.log('item:' + JSON.stringify(item));
247 return { 262 return {
248 subOrderId: item.id, 263 subOrderId: item.id,
249 /*projectName: item.productName,*/ 264 /*projectName: item.productName,*/
@@ -251,7 +266,7 @@ export default ({ dataList, setVisible, onClose }) =&gt; { @@ -251,7 +266,7 @@ export default ({ dataList, setVisible, onClose }) =&gt; {
251 unit: item.unit, 266 unit: item.unit,
252 quantity: item.quantity, 267 quantity: item.quantity,
253 price: item.productPrice, 268 price: item.productPrice,
254 - totalPrice: item.totalPayment, 269 + totalPrice: item.subOrderPayment,
255 }; 270 };
256 })} 271 })}
257 rules={[ 272 rules={[
@@ -342,13 +357,36 @@ export default ({ dataList, setVisible, onClose }) =&gt; { @@ -342,13 +357,36 @@ export default ({ dataList, setVisible, onClose }) =&gt; {
342 label="规格型号" 357 label="规格型号"
343 rules={[ 358 rules={[
344 { 359 {
345 - message: '规格型号不能超过20个字符!',  
346 - max: 20,  
347 - },  
348 - {  
349 message: '规格型号不能为空!', 360 message: '规格型号不能为空!',
350 required: true, 361 required: true,
351 }, 362 },
  363 + {
  364 + validator: (_, value) => {
  365 + let len = 0;
  366 + // 判断是否为全角字符
  367 + for (let i = 0; i < value.length; i++) {
  368 + // 获取字符的Unicode值
  369 + const code = value.charCodeAt(i);
  370 + // 判断是否为全角字符
  371 + if (
  372 + (code >= 0xff01 && code <= 0xff5e) ||
  373 + (code >= 0x4e00 && code <= 0x9fff)
  374 + ) {
  375 + len += 2; // 全角字符
  376 + } else {
  377 + len += 1; // 半角字符
  378 + }
  379 + }
  380 + console.log(value);
  381 + console.log(len);
  382 + if (len <= 40) {
  383 + return Promise.resolve();
  384 + }
  385 + return Promise.reject(
  386 + new Error('规格型号不能超过40个字符!'),
  387 + );
  388 + },
  389 + },
352 ]} 390 ]}
353 placeholder="请输入名称" 391 placeholder="请输入名称"
354 /> 392 />
src/pages/Order/components/OrderDrawer.tsx
@@ -1721,10 +1721,7 @@ export default ({ onClose, data, subOrders, orderOptType }) =&gt; { @@ -1721,10 +1721,7 @@ export default ({ onClose, data, subOrders, orderOptType }) =&gt; {
1721 optionItemRender(item) { 1721 optionItemRender(item) {
1722 if (item.type === 'add') { 1722 if (item.type === 'add') {
1723 return ( 1723 return (
1724 - <div  
1725 - style={{ fontSize: '11px' }}  
1726 - title={item.name + '(新增商品信息)'}  
1727 - > 1724 + <div title={item.name + '(新增商品信息)'}>
1728 <span style={{ color: '#333333' }}> 1725 <span style={{ color: '#333333' }}>
1729 {item.label} 1726 {item.label}
1730 </span> 1727 </span>
@@ -1735,7 +1732,6 @@ export default ({ onClose, data, subOrders, orderOptType }) =&gt; { @@ -1735,7 +1732,6 @@ export default ({ onClose, data, subOrders, orderOptType }) =&gt; {
1735 } 1732 }
1736 return ( 1733 return (
1737 <div 1734 <div
1738 - style={{ fontSize: '11px' }}  
1739 title={ 1735 title={
1740 item.label + 1736 item.label +
1741 ' | ' + 1737 ' | ' +
src/services/definition.ts
@@ -768,6 +768,9 @@ export interface ApplyInvoiceDto { @@ -768,6 +768,9 @@ export interface ApplyInvoiceDto {
768 */ 768 */
769 isUrgentText?: string; 769 isUrgentText?: string;
770 logicDelete?: boolean; 770 logicDelete?: boolean;
  771 + orderIdMap?: {
  772 + [propertyName: string]: Array<number>;
  773 + };
771 /** 774 /**
772 * @description 775 * @description
773 * 买方注册地址 776 * 买方注册地址
@@ -1500,6 +1503,9 @@ export interface InvoiceRecordDto { @@ -1500,6 +1503,9 @@ export interface InvoiceRecordDto {
1500 */ 1503 */
1501 isUrgentText?: string; 1504 isUrgentText?: string;
1502 logicDelete?: boolean; 1505 logicDelete?: boolean;
  1506 + orderIdMap?: {
  1507 + [propertyName: string]: Array<number>;
  1508 + };
1503 /** 1509 /**
1504 * @description 1510 * @description
1505 * 买方注册地址 1511 * 买方注册地址
src/utils/numberUtil.ts
@@ -7,3 +7,104 @@ export function getRandomNumber(numDigits: number) { @@ -7,3 +7,104 @@ export function getRandomNumber(numDigits: number) {
7 const max = Math.pow(10, numDigits) - 1; 7 const max = Math.pow(10, numDigits) - 1;
8 return Math.floor(Math.random() * (max - min + 1)) + min; 8 return Math.floor(Math.random() * (max - min + 1)) + min;
9 } 9 }
  10 +
  11 +//代码如下所示:
  12 +export function convertCurrency(moneyParm) {
  13 + let money = moneyParm;
  14 + //汉字的数字
  15 + let cnNums = new Array(
  16 + '零',
  17 + '壹',
  18 + '贰',
  19 + '叁',
  20 + '肆',
  21 + '伍',
  22 + '陆',
  23 + '柒',
  24 + '捌',
  25 + '玖',
  26 + );
  27 + //基本单位
  28 + let cnIntRadice = new Array('', '拾', '佰', '仟');
  29 + //对应整数部分扩展单位
  30 + let cnIntUnits = new Array('', '万', '亿', '兆');
  31 + //对应小数部分单位
  32 + let cnDecUnits = new Array('角', '分', '毫', '厘');
  33 + //整数金额时后面跟的字符
  34 + let cnInteger = '整';
  35 + //整型完以后的单位
  36 + let cnIntLast = '圆';
  37 + //最大处理的数字
  38 + let maxNum = 999999999999999.9999;
  39 + //金额整数部分
  40 + let integerNum;
  41 + //金额小数部分
  42 + let decimalNum;
  43 + //输出的中文金额字符串
  44 + let chineseStr = '';
  45 + //分离金额后用的数组,预定义
  46 + let parts;
  47 + if (money === '') {
  48 + return '';
  49 + }
  50 + money = parseFloat(money);
  51 + if (money >= maxNum) {
  52 + //超出最大处理数字
  53 + return '';
  54 + }
  55 + if (money === 0) {
  56 + chineseStr = cnNums[0] + cnIntLast + cnInteger;
  57 + return chineseStr;
  58 + }
  59 + //转换为字符串
  60 + let moneyText = money.toString();
  61 + if (moneyText.indexOf('.') === -1) {
  62 + integerNum = moneyText;
  63 + decimalNum = '';
  64 + } else {
  65 + parts = moneyText.split('.');
  66 + integerNum = parts[0];
  67 + decimalNum = parts[1].substr(0, 4);
  68 + }
  69 + //获取整型部分转换
  70 + if (parseInt(integerNum, 10) > 0) {
  71 + let zeroCount = 0;
  72 + let IntLen = integerNum.length;
  73 + for (let i = 0; i < IntLen; i++) {
  74 + const n = integerNum.substr(i, 1);
  75 + const p = IntLen - i - 1;
  76 + const q = p / 4;
  77 + const m = p % 4;
  78 + if (n === '0') {
  79 + zeroCount++;
  80 + } else {
  81 + if (zeroCount > 0) {
  82 + chineseStr += cnNums[0];
  83 + }
  84 + //归零
  85 + zeroCount = 0;
  86 + chineseStr += cnNums[parseInt(n)] + cnIntRadice[m];
  87 + }
  88 + if (m === 0 && zeroCount < 4) {
  89 + chineseStr += cnIntUnits[q];
  90 + }
  91 + }
  92 + chineseStr += cnIntLast;
  93 + }
  94 + //小数部分
  95 + if (decimalNum !== '') {
  96 + let decLen = decimalNum.length;
  97 + for (let k = 0; k < decLen; k++) {
  98 + let n = decimalNum.substr(k, 1);
  99 + if (n !== '0') {
  100 + chineseStr += cnNums[Number(n)] + cnDecUnits[k];
  101 + }
  102 + }
  103 + }
  104 + if (chineseStr === '') {
  105 + chineseStr += cnNums[0] + cnIntLast + cnInteger;
  106 + } else if (decimalNum === '') {
  107 + chineseStr += cnInteger;
  108 + }
  109 + return chineseStr;
  110 +}