diff --git a/.eslintrc.cjs b/.eslintrc.cjs index 7edaef0..dd4162d 100644 --- a/.eslintrc.cjs +++ b/.eslintrc.cjs @@ -24,6 +24,7 @@ module.exports = { 'quote-props': ['error', 'consistent'], 'no-eval': ['error', { allowIndirect: true }], 'jsdoc/require-returns': 0, + 'jsdoc/require-jsdoc': 0, 'jsdoc/require-param-description': 0, 'jsdoc/require-returns-description': 0, 'jsdoc/require-param-type': 0 diff --git a/apps/bika.js b/apps/bika.js index 8e84497..e32fb69 100644 --- a/apps/bika.js +++ b/apps/bika.js @@ -1,6 +1,7 @@ import { Bika, common, Pixiv } from '../model/index.js' import { Config } from '../components/index.js' import { Admin } from './admin.js' +import translateChinaNum from '../tools/translateChinaNum.js' // 汉字数字匹配正则 const numReg = '[零一壹二两三四五六七八九十百千万亿\\d]+' @@ -64,7 +65,7 @@ export class NewBika extends plugin { if (!await this._Authentication(e)) return e.reply(Pixiv.startMsg) let regRet = e.msg.match(searchReg) - let page = common.translateChinaNum(regRet[5]) + let page = translateChinaNum(regRet[5]) await Bika.search(regRet[3], page, regRet[2]) .then(res => common.recallSendForwardMsg(e, res)) .catch(err => common.handleException(e, err)) @@ -78,8 +79,8 @@ export class NewBika extends plugin { if (!await this._Authentication(e)) return e.reply(Pixiv.startMsg) let regRet = e.msg.match(comicPageReg) - let page = common.translateChinaNum(regRet[4]) - let order = common.translateChinaNum(regRet[6]) + let page = translateChinaNum(regRet[4]) + let order = translateChinaNum(regRet[6]) await Bika.comicPage(regRet[2], page, order) .then(res => common.recallSendForwardMsg(e, res)) .catch(err => common.handleException(e, err)) diff --git a/apps/events/notice_group.js b/apps/events/notice_group.js index 88d4a0f..fff1711 100644 --- a/apps/events/notice_group.js +++ b/apps/events/notice_group.js @@ -1,6 +1,7 @@ import { common } from '../../model/index.js' import { Config } from '../../components/index.js' import moment from 'moment' +import formatDuration from '../../tools/formatDuration.js' Bot.on?.('notice.group', async (e) => { let msg @@ -142,7 +143,7 @@ Bot.on?.('notice.group', async (e) => { } // 禁言 (这里仅处理机器人被禁言) case 'ban': { - const forbiddenTime = common.formatTime(e.duration, 'default') + const forbiddenTime = formatDuration(e.duration, 'default') if (!Config.getGroup(e.group_id).botBeenBanned) return false diff --git a/apps/groupAdmin/groupAdmin.js b/apps/groupAdmin/groupAdmin.js index 0362c00..93a984a 100644 --- a/apps/groupAdmin/groupAdmin.js +++ b/apps/groupAdmin/groupAdmin.js @@ -1,9 +1,11 @@ import _ from 'lodash' import moment from 'moment' import { Config } from '../../components/index.js' -import { common, GroupAdmin as Ga, puppeteer, QQApi, GroupBannedWords } from '../../model/index.js' -import cronValidate from '../../tools/cronValidate.js' import { Time_unit } from '../../constants/other.js' +import { GroupAdmin as Ga, GroupBannedWords, QQApi, common, puppeteer } from '../../model/index.js' +import cronValidate from '../../tools/cronValidate.js' +import translateChinaNum from '../../tools/translateChinaNum.js' + // API请求错误文案 const API_ERROR = '❎ 出错辣,请稍后重试' // 正则 @@ -169,7 +171,7 @@ export class GroupAdmin extends plugin { let qq = e.message.find(item => item.type == 'at')?.qq let reg = `#禁言\\s?((\\d+)\\s)?(${Numreg})?(${TimeUnitReg})?` let regRet = e.msg.match(new RegExp(reg)) - const time = common.translateChinaNum(regRet[3]) + const time = translateChinaNum(regRet[3]) new Ga(e).muteMember( e.group_id, qq ?? regRet[2], e.user_id, time, regRet[4] ).then(res => e.reply(res)) @@ -221,7 +223,7 @@ export class GroupAdmin extends plugin { // 解析正则 let regRet = Autisticreg.exec(e.msg) // 获取数字 - let TabooTime = common.translateChinaNum(regRet[2] || 5) + let TabooTime = translateChinaNum(regRet[2] || 5) let Company = Time_unit[_.toUpper(regRet[3]) || '分'] @@ -407,7 +409,7 @@ export class GroupAdmin extends plugin { if (!common.checkPermission(e, 'admin', 'admin')) { return true } let regRet = noactivereg.exec(e.msg) - regRet[2] = common.translateChinaNum(regRet[2] || 1) + regRet[2] = translateChinaNum(regRet[2] || 1) // 确认清理直接执行 if (regRet[1] == '确认清理') { try { @@ -423,7 +425,7 @@ export class GroupAdmin extends plugin { } } // 查看和清理都会发送列表 - let page = common.translateChinaNum(regRet[5] || 1) + let page = translateChinaNum(regRet[5] || 1) let msg = null try { msg = await new Ga(e).getNoactiveInfo( @@ -472,7 +474,7 @@ export class GroupAdmin extends plugin { } // 发送列表 let page = e.msg.match(new RegExp(Numreg)) - page = page ? common.translateChinaNum(page[0]) : 1 + page = page ? translateChinaNum(page[0]) : 1 new Ga(e).getNeverSpeakInfo(e.group_id, page) .then(res => common.getforwardMsg(e, res, { isxml: true, @@ -484,7 +486,7 @@ export class GroupAdmin extends plugin { // 查看不活跃排行榜和入群记录 async RankingList (e) { let num = e.msg.match(new RegExp(Numreg)) - num = num ? common.translateChinaNum(num[0]) : 10 + num = num ? translateChinaNum(num[0]) : 10 let msg = '' if (/(不活跃|潜水)/.test(e.msg)) { msg = await new Ga(e).InactiveRanking(e.group_id, num) diff --git a/apps/groupAdmin/privateGroupAdmin.js b/apps/groupAdmin/privateGroupAdmin.js index 1cdffa7..eacfdf2 100644 --- a/apps/groupAdmin/privateGroupAdmin.js +++ b/apps/groupAdmin/privateGroupAdmin.js @@ -1,5 +1,6 @@ import { GroupAdmin as Ga, common } from '../../model/index.js' import { Time_unit } from '../../constants/other.js' +import translateChinaNum from '../../tools/translateChinaNum.js' // 正则 const Numreg = '[一壹二两三四五六七八九十百千万亿\\d]+' const TimeUnitReg = Object.keys(Time_unit).join('|') @@ -34,7 +35,7 @@ export class PrivateGroupAdmin extends plugin { async muteMember (e) { if (!common.checkPermission(e, 'master')) return let regRet = e.msg.match(muteMemberReg) - const time = common.translateChinaNum(regRet[3]) + const time = translateChinaNum(regRet[3]) let res = await new Ga(e).muteMember(regRet[1], regRet[2], e.user_id, time, regRet[4]) e.reply(res) } diff --git a/apps/pixiv.js b/apps/pixiv.js index 934920d..7ea4cca 100644 --- a/apps/pixiv.js +++ b/apps/pixiv.js @@ -3,6 +3,7 @@ import { Config } from '../components/index.js' import { Pixiv, common, setu } from '../model/index.js' import { Admin } from './admin.js' import { ImageRPSS } from '../constants/pixiv.js' +import translateChinaNum from '../tools/translateChinaNum.js' // 文案 const SWITCH_ERROR = '主人没有开放这个功能哦(*/ω\*)' // 汉字数字匹配正则 @@ -106,7 +107,7 @@ export class NewPixiv extends plugin { e.reply(Pixiv.startMsg) - let page = common.translateChinaNum(regRet[6]) + let page = translateChinaNum(regRet[6]) await Pixiv.Rank(page, regRet[2], regRet[3], regRet[4]) .then(res => common.recallSendForwardMsg(e, res)) .catch(err => common.handleException(e, err)) @@ -123,7 +124,7 @@ export class NewPixiv extends plugin { e.reply(Pixiv.startMsg) - let page = common.translateChinaNum(regRet[4]) + let page = translateChinaNum(regRet[4]) await Pixiv[`${regRet[1] ? 's' : 'vilipixS'}earchTags`](regRet[2], page, !setu.getR18(e.group_id)) .then(res => common.recallSendForwardMsg(e, res)) .catch(err => common.handleException(e, err)) @@ -151,7 +152,7 @@ export class NewPixiv extends plugin { e.reply(Pixiv.startMsg) let regRet = uidReg.exec(e.msg) - let page = common.translateChinaNum(regRet[3]) + let page = translateChinaNum(regRet[3]) await Pixiv.userIllust(regRet[1], page, !setu.getR18(e.group_id)) .then(res => common.recallSendForwardMsg(e, res)) @@ -169,7 +170,7 @@ export class NewPixiv extends plugin { e.reply('你要的太多辣,奴家只给你一张辣(•́へ•́ ╬)') num = 1 } - num = common.translateChinaNum(num) + num = translateChinaNum(num) await Pixiv.vilipixRandomImg(num) .then(res => common.recallSendForwardMsg(e, res)) .catch(err => common.handleException(e, err)) @@ -207,7 +208,7 @@ export class NewPixiv extends plugin { e.reply(Pixiv.startMsg) let regRet = e.msg.match(searchUser) - let page = common.translateChinaNum(regRet[3]) + let page = translateChinaNum(regRet[3]) await Pixiv.searchUser(regRet[1], page, !setu.getR18(e.group_id)) .then(res => common.recallSendForwardMsg(e, res)) .catch(err => common.handleException(e, err)) diff --git a/apps/setu.js b/apps/setu.js index d2f8a37..8aa655b 100644 --- a/apps/setu.js +++ b/apps/setu.js @@ -2,6 +2,7 @@ import plugin from '../../../lib/plugins/plugin.js' import { Config } from '../components/index.js' import { setu, common } from '../model/index.js' import { Admin } from './admin.js' +import translateChinaNum from '../tools/translateChinaNum.js' const NumReg = '[零一壹二两三四五六七八九十百千万亿\\d]+' @@ -48,7 +49,7 @@ export class SeSe extends plugin { if (cdTime) return e.reply(` ${setu.CDMsg}你的CD还有${cdTime}`, false, { at: true }) let num = e.msg.match(new RegExp(NumReg)) - num = num ? common.translateChinaNum(num[0]) : 1 + num = num ? translateChinaNum(num[0]) : 1 if (num > 20) { return e.reply('❎ 最大张数不能大于20张') } else if (num > 6) { @@ -76,7 +77,7 @@ export class SeSe extends plugin { num = 1 } else { tag = tag.replace(num[0], '').trim() - num = common.translateChinaNum(num[1]) + num = translateChinaNum(num[1]) } if (num > 20) { @@ -114,7 +115,7 @@ export class SeSe extends plugin { // 设置群撤回间隔和cd async setGroupRecallAndCD (e) { let num = e.msg.match(new RegExp(NumReg)) - num = common.translateChinaNum(num[0]) + num = translateChinaNum(num[0]) let type = /撤回间隔/.test(e.msg) setu.setGroupRecallTimeAndCd(e.group_id, num, type) new Admin().SeSe_Settings(e) @@ -132,7 +133,7 @@ export class SeSe extends plugin { let reg = `^#?设置cd\\s?((\\d+)\\s)?(${NumReg})(s|秒)?$` let regRet = e.msg.match(new RegExp(reg)) let qq = e.message.find(item => item.type == 'at')?.qq ?? regRet[2] - let cd = common.translateChinaNum(regRet[3]) + let cd = translateChinaNum(regRet[3]) if (!qq) return e.reply('❎ 请输入要设置QQ', true) if (!cd) return e.reply('❎ CD为空,请检查', true) setu.setUserCd(e, qq ?? regRet[2], cd) diff --git a/apps/state.js b/apps/state.js index bc6c024..aa15a1e 100644 --- a/apps/state.js +++ b/apps/state.js @@ -6,6 +6,7 @@ import plugin from '../../../lib/plugins/plugin.js' import { Config, Version, Plugin_Name } from '../components/index.js' import { status } from '../constants/other.js' import { State, common, puppeteer } from '../model/index.js' +import formatDuration from '../tools/formatDuration.js' const require = createRequire(import.meta.url) let interval = false @@ -122,7 +123,7 @@ export class NewState extends plugin { const getBotState = async (botList) => { const defaultAvatar = `../../../../../plugins/${Plugin_Name}/resources/state/img/default_avatar.jpg` const BotName = Version.name - const systime = common.formatTime(os.uptime(), 'dd天hh小时mm分', false) + const systime = formatDuration(os.uptime(), 'dd天hh小时mm分', false) const calendar = moment().format('YYYY-MM-DD HH:mm:ss') const dataPromises = botList.map(async (i) => { @@ -141,7 +142,7 @@ const getBotState = async (botList) => { const friendQuantity = bot.fl?.size || 0 const groupQuantity = bot.gl?.size || 0 const groupMemberQuantity = Array.from(bot.gml?.values() || []).reduce((acc, curr) => acc + curr.size, 0) - const runTime = common.formatTime(Date.now() / 1000 - bot.stat?.start_time, 'dd天hh小时mm分', false) + const runTime = formatDuration(Date.now() / 1000 - bot.stat?.start_time, 'dd天hh小时mm分', false) const botVersion = bot.version ? `${bot.version.name}(${bot.version.id})${bot.apk ? ` ${bot.version.version}` : ''}` : `ICQQ(QQ) v${require('icqq/package.json').version}` return `
diff --git a/lib/common/sendMsgModule.js b/lib/common/sendMsgModule.js new file mode 100644 index 0000000..2c39395 --- /dev/null +++ b/lib/common/sendMsgModule.js @@ -0,0 +1,183 @@ +import common from '../../../../lib/common/common.js' +import Config from '../../components/Config.js' +import _ from 'lodash' +import setu from '../../model/setu.js' + +export default class { + /** + * 给主人发消息 + * @param msg + */ + async sendMasterMsg (msg) { + if (Config.whole.notificationsAll) { + // 发送全部管理 + for (let index of Config.masterQQ) { + await common.relpyPrivate(index, msg) + await this.sleep(5000) + } + } else { + // 发给第一个管理 + await common.relpyPrivate(Config.masterQQ[0], msg) + } + } + + /** + * 发送转发消息 + * @async + * @param {object} e - 发送消息的目标对象 + * @param {Array} message - 发送的消息数组,数组每一项为转发消息的一条消息 + * @param {object} [options] - 发送消息的配置项 + * @param {number} [options.recallMsg] - 撤回时间,单位秒,默认为0表示不撤回 + * @param {{nickname: string, user_id: number}} [options.info] - 转发发送人信息 nickname-转发人昵称 user_id-转发人QQ + * @param {string | Array} [options.fkmsg] - 风控消息,不传则默认消息 + * @param {boolean} [options.isxml] - 处理卡片 + * @param {boolean} [options.xmlTitle] - XML 标题 + * @param {boolean} [options.oneMsg] - 用于只有一条消息,不用再转成二维数组 + * @param {boolean | import("icqq").Anonymous} [options.anony] - 匿名消息,若为true则发送匿名消息 + * @param {boolean} [options.shouldSendMsg] - 是否直接发送消息,true为直接发送,否则返回需要发送的消息 + * @returns {Promise} 消息发送结果的Promise对象 + */ + async getforwardMsg (e, message, { + recallMsg = 0, + info, + fkmsg, + isxml, + xmlTitle, + oneMsg, + anony, + shouldSendMsg = true + } = {}) { + let forwardMsg = [] + if (_.isEmpty(message)) throw Error('[Yenai-Plugin][sendforwardMsg][Error]发送的转发消息不能为空') + let add = (msg) => forwardMsg.push( + { + message: msg, + nickname: info?.nickname ?? (e.bot ?? Bot).nickname, + user_id: info?.user_id ?? (e.bot ?? Bot).uin + } + ) + oneMsg ? add(message) : message.forEach(item => add(item)) + // 发送 + if (e.isGroup) { + forwardMsg = await e.group.makeForwardMsg(forwardMsg) + } else { + forwardMsg = await e.friend.makeForwardMsg(forwardMsg) + } + + if (isxml && typeof (forwardMsg.data) !== 'object') { + // 处理转发卡片 + forwardMsg.data = forwardMsg.data.replace('", "') + } + + if (xmlTitle) { + if (typeof (forwardMsg.data) === 'object') { + let detail = forwardMsg.data?.meta?.detail + if (detail) { + detail.news = [{ text: xmlTitle }] + } + } else { + forwardMsg.data = forwardMsg.data + .replace(/\n/g, '') + .replace(/(.+?)<\/title>/g, '___') + .replace(/___+/, `<title color="#777777" size="26">${xmlTitle}`) + } + } + if (shouldSendMsg) { + let msgRes = await this.reply(e, forwardMsg, false, { + anony, + fkmsg, + recallMsg + }) + return msgRes + } else { + return forwardMsg + } + } + + /** + * 发送消息 + * @async + * @param {*} e oicq 事件对象 + * @param {Array | string} msg 消息内容 + * @param {boolean} quote 是否引用回复 + * @param {object} data 其他参数 + * @param {number} data.recallMsg 撤回时间 + * @param {boolean} data.fkmsg 风控消息 + * @param {boolean | import("icqq").Anonymous} data.anony 匿名消息 + * @param {boolean | number} data.at 是否艾特该成员 + * @returns {Promise} 返回发送消息后的结果对象 + */ + async reply (e, msg, quote, { + recallMsg = 0, + fkmsg = '', + at = false, + anony + } = {}) { + if (at && e.isGroup) { + let text = '' + if (e?.sender?.card) { + text = _.truncate(e.sender.card, { length: 10 }) + } + if (at === true) { + at = Number(e.user_id) + } else if (!isNaN(at)) { + let info = e.group.pickMember(at).info + text = info?.card ?? info?.nickname + text = _.truncate(text, { length: 10 }) + } + + if (Array.isArray(msg)) { + msg = [segment.at(at, text), ...msg] + } else { + msg = [segment.at(at, text), msg] + } + } + + let msgRes = null + // 发送消息 + if (e.isGroup) { + // 判断是否开启匿名 + if (anony) { + let getAnonyInfo = await e.group.getAnonyInfo() + if (!getAnonyInfo.enable) { + e.reply('[警告]该群未开启匿名,请启用匿名再使用匿名功能') + anony = false + } + } + msgRes = await e.group.sendMsg(msg, quote ? e : undefined, anony) + } else { + msgRes = await e.reply(msg, quote) + if (!msgRes) await e.reply(fkmsg || '消息发送失败,可能被风控') + } + if (recallMsg > 0 && msgRes?.message_id) { + if (e.isGroup) { + setTimeout(() => e.group.recallMsg(msgRes.message_id), recallMsg * 1000) + } else if (e.friend) { + setTimeout(() => e.friend.recallMsg(msgRes.message_id), recallMsg * 1000) + } + } + return msgRes + } + + /** + * 获取配置的撤回事件和匿名发送普通消息 + * @param {*} e oicq + * @param {Array | string} msg 消息 + * @param {boolean} quote 是否引用回复 + * @param {object} data 其他参数 + * @param {number} data.recallMsg 撤回时间 + * @param {boolean} data.fkmsg 风控消息 + * @param {boolean | import("icqq").Anonymous} data.anony 匿名消息 + * @returns {Promise} + */ + async recallsendMsg (e, msg, quote, data = {}) { + let recallMsg = setu.getRecallTime(e.group_id) + let anony = Config.getGroup(e.group_id).anonymous + let msgRes = this.reply(e, msg, quote, { + recallMsg, + anony, + ...data + }) + return msgRes + } +} diff --git a/lib/request/request.js b/lib/request/request.js index 34a8eb5..1dcb116 100644 --- a/lib/request/request.js +++ b/lib/request/request.js @@ -33,7 +33,7 @@ export default new class { /** * 发送HTTP GET请求并返回响应 * @async - * @function + * @name get * @param {string} url - 请求的URL * @param {object} [options] - 请求的配置项 * @param {object} [options.params] - 请求的参数 diff --git a/model/setu.js b/model/setu.js index cc1d110..b41220d 100644 --- a/model/setu.js +++ b/model/setu.js @@ -3,6 +3,7 @@ import { Data, Plugin_Path, Config } from '../components/index.js' import _ from 'lodash' import { setuMsg } from '../constants/msg.js' import request from '../lib/request/request.js' +import formatDuration from '../tools/formatDuration.js' export default new class setu { constructor () { this.root = `${Plugin_Path}/config/setu` @@ -130,7 +131,7 @@ export default new class setu { over = (this.temp[userId] - present) } if (over <= 0) return false - return common.formatTime(over, 'default', false) + return formatDuration(over, 'default', false) } /** diff --git a/tools/formatDuration.js b/tools/formatDuration.js new file mode 100644 index 0000000..50c4738 --- /dev/null +++ b/tools/formatDuration.js @@ -0,0 +1,71 @@ +/** + * 格式化持续时间。 + * @param {number} time - 要格式化的时间(以秒为单位)。 + * @param {'default' | string | Function} format - 指定的格式,可以是字符串或函数。 + * - 如果为字符串,可以包含占位符(例如"dd"表示天数,"hh"表示小时,"mm"表示分钟,"ss"表示秒),这些占位符将被实际的时间值替换。 + * - 如果为函数,可以自定义处理时间对象并返回格式化结果。 + * @param {boolean} [repair] - 修复小时、分钟和秒的显示格式的可选参数。如果设置为true,并且小时、分钟或秒小于10,则在值前面添加零。 + * @returns {string | object} - 格式化后的持续时间。 + * - 如果format为"default",返回一个字符串,表示格式化后的持续时间。字符串包含天数、小时、分钟和秒的信息,根据时间值的大小,只包含大于零的部分。 + * - 如果format为字符串,根据指定的格式进行替换后返回格式化后的字符串。 + * - 如果format为函数,将时间对象作为参数传递给该函数,并返回函数处理后的结果。 + * - 如果format既不是"default"、字符串,也不是函数,则返回包含天、小时、分钟和秒的时间对象。 + * @example + * // 使用默认格式 + * const result = formatDuration(3665, 'default'); + * // 输出: "1小时1分5秒" + * @example + * // 使用自定义格式 + * const result = formatDuration(3665, 'hh:mm:ss'); + * // 输出: "01:01:05" + * @example + * // 使用自定义处理函数 + * const customFormat = (time) => `${time.hour}h ${time.minute}m ${time.second}s`; + * const result = formatDuration(3665, customFormat); + * // 输出: "1h 1m 5s" + */ +export default function formatDuration (time, format, repair = true) { + const second = parseInt(time % 60) + const minute = parseInt((time / 60) % 60) + const hour = parseInt((time / (60 * 60)) % 24) + const day = parseInt(time / (24 * 60 * 60)) + const timeObj = { + day, + hour: repair && hour < 10 ? `0${hour}` : hour, + minute: repair && minute < 10 ? `0${minute}` : minute, + second: repair && second < 10 ? `0${second}` : second + } + if (typeof format === 'function') { + return format(timeObj) + } + + if (typeof format === 'string') { + format = format + .replace(/dd/g, day) + .replace(/hh/g, timeObj.hour) + .replace(/mm/g, timeObj.minute) + .replace(/ss/g, timeObj.second) + + return format + } + + if (format == 'default') { + let result = '' + + if (day > 0) { + result += `${day}天` + } + if (hour > 0) { + result += `${timeObj.hour}小时` + } + if (minute > 0) { + result += `${timeObj.minute}分` + } + if (second > 0) { + result += `${timeObj.second}秒` + } + return result + } + + return timeObj +} diff --git a/tools/translateChinaNum.js b/tools/translateChinaNum.js new file mode 100644 index 0000000..14b64e5 --- /dev/null +++ b/tools/translateChinaNum.js @@ -0,0 +1,65 @@ +/** + * 使用JS将数字从汉字形式转化为阿拉伯形式 + * @param {string} s_123 + * @returns {number} + */ +export default function translateChinaNum (s_123) { + if (!s_123 && s_123 != 0) return s_123 + // 如果是纯数字直接返回 + if (/^\d+$/.test(s_123)) return Number(s_123) + // 字典 + let map = new Map() + map.set('一', 1) + map.set('壹', 1) // 特殊 + map.set('二', 2) + map.set('两', 2) // 特殊 + map.set('三', 3) + map.set('四', 4) + map.set('五', 5) + map.set('六', 6) + map.set('七', 7) + map.set('八', 8) + map.set('九', 9) + // 按照亿、万为分割将字符串划分为三部分 + let split = '' + split = s_123.split('亿') + let s_1_23 = split.length > 1 ? split : ['', s_123] + let s_23 = s_1_23[1] + let s_1 = s_1_23[0] + split = s_23.split('万') + let s_2_3 = split.length > 1 ? split : ['', s_23] + let s_2 = s_2_3[0] + let s_3 = s_2_3[1] + let arr = [s_1, s_2, s_3] + + // ------------- 对各个部分处理 ------------- + arr = arr.map(item => { + let result = '' + result = item.replace('零', '') + // [ "一百三十二", "四千五百", "三千二百一十三" ] ==> + let reg = new RegExp(`[${Array.from(map.keys()).join('')}]`, 'g') + result = result.replace(reg, substring => { + return map.get(substring) + }) + // [ "1百3十2", "4千5百", "3千2百1十3" ] ==> ["0132", "4500", "3213"] + let temp + temp = /\d(?=千)/.exec(result) + let num1 = temp ? temp[0] : '0' + temp = /\d(?=百)/.exec(result) + let num2 = temp ? temp[0] : '0' + temp = /\d?(?=十)/.exec(result) + let num3 + if (temp === null) { // 说明没十:一百零二 + num3 = '0' + } else if (temp[0] === '') { // 说明十被简写了:十一 + num3 = '1' + } else { // 正常情况:一百一十一 + num3 = temp[0] + } + temp = /\d$/.exec(result) + let num4 = temp ? temp[0] : '0' + return num1 + num2 + num3 + num4 + }) + // 借助parseInt自动去零 + return parseInt(arr.join('')) +}