123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261 |
- import { Inject, Provide } from '@midwayjs/decorator';
- import { Context } from '@midwayjs/koa';
- import * as ipdb from 'ipip-ipdb';
- import * as _ from 'lodash';
- import * as moment from 'moment';
- import * as NodeRSA from 'node-rsa';
- import * as crypto from 'crypto'
- import * as speakeasy from 'speakeasy';
- import { BinaryToTextEncoding } from 'crypto';
- /**
- * 帮助类
- */
- @Provide()
- export class Utils {
- @Inject()
- baseDir;
- /**
- * 获得请求IP
- */
- async getReqIP(ctx: Context) {
- const req = ctx.req;
- return (
- req.headers['x-forwarded-for'] ||
- req.socket.remoteAddress.replace('::ffff:', '')
- );
- }
- /**
- * 根据IP获得请求地址
- * @param ip 为空时则为当前请求的IP地址
- */
- async getIpAddr(ctx: Context, ip?: string | string[]) {
- try {
- if (!ip) {
- ip = await this.getReqIP(ctx);
- }
- const bst = new ipdb.BaseStation(`${this.baseDir}/comm/ipipfree.ipdb`);
- const result = bst.findInfo(ip, 'CN');
- const addArr: any = [];
- if (result) {
- addArr.push(result.countryName);
- addArr.push(result.regionName);
- addArr.push(result.cityName);
- return _.uniq(addArr).join('');
- }
- } catch (err) {
- return '无法获取地址信息';
- }
- }
- /**
- * 去除对象的空值属性
- * @param obj
- */
- async removeEmptyP(obj) {
- Object.keys(obj).forEach(key => {
- if (obj[key] === null || obj[key] === '' || obj[key] === 'undefined') {
- delete obj[key];
- }
- });
- }
- /**
- * 线程阻塞毫秒数
- * @param ms
- */
- sleep(ms) {
- return new Promise(resolve => setTimeout(resolve, ms));
- }
- /**
- * 获得最近几天的日期集合
- * @param recently
- */
- getRecentlyDates(recently, format = 'YYYY-MM-DD') {
- moment.locale('zh-cn');
- const dates = [];
- for (let i = 0; i < recently; i++) {
- dates.push(moment().subtract(i, 'days').format(format));
- }
- return dates.reverse();
- }
- /**
- * 获得最近几个月的月数
- * @param recently
- */
- getRecentlyMonths(recently, format = 'YYYY-MM') {
- moment.locale('zh-cn');
- const dates = [];
- const date = moment(Date.now()).format('YYYY-MM');
- for (let i = 0; i < recently; i++) {
- dates.push(moment(date).subtract(i, 'months').format(format));
- }
- return dates.reverse();
- }
- /**
- * 根据开始和结束时间,获得时间段内的日期集合
- * @param start
- * @param end
- */
- getBetweenDays(start, end, format = 'YYYY-MM-DD') {
- moment.locale('zh-cn');
- const dates = [];
- const startTime = moment(start).format(format);
- const endTime = moment(end).format(format);
- const days = moment(endTime).diff(moment(startTime), 'days');
- for (let i = 0; i <= days; i++) {
- dates.push(moment(startTime).add(i, 'days').format(format));
- }
- return dates;
- }
- /**
- * 根据开始和结束时间,获得时间段内的月份集合
- * @param start
- * @param end
- */
- getBetweenMonths(start, end, format = 'YYYY-MM') {
- moment.locale('zh-cn');
- const dates = [];
- const startTime = moment(start).format(format);
- const endTime = moment(end).format(format);
- const months = moment(endTime).diff(moment(startTime), 'months');
- for (let i = 0; i <= months; i++) {
- dates.push(moment(startTime).add(i, 'months').format(format));
- }
- return dates;
- }
- /**
- * 根据开始和结束时间,获得时间段内的小时集合
- * @param start
- * @param end
- */
- getBetweenHours(start, end, format = 'YYYY-MM-DD HH') {
- moment.locale('zh-cn');
- const dates = [];
- const startTime = moment(start).format(format);
- const endTime = moment(end).format(format);
- const hours = moment(endTime).diff(moment(startTime), 'hours');
- for (let i = 0; i <= hours; i++) {
- dates.push(moment(startTime).add(i, 'hours').format(format));
- }
- return dates;
- }
- /**
- * 字段转驼峰法
- * @param obj
- * @returns
- */
- toCamelCase(obj) {
- let camelCaseObject = {};
- for (let i in obj) {
- let camelCase = i.replace(/([-_][a-z])/gi, $1 => {
- return $1.toUpperCase().replace('-', '').replace('_', '');
- });
- camelCaseObject[camelCase] = obj[i];
- }
- return camelCaseObject;
- }
- createOrderNo(prefix) {
- return (
- prefix +
- moment().format('YYYYMMDDHHmmss') +
- _.sampleSize([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], 4).join('')
- );
- }
- signSort(args) {
- let keys = Object.keys(args);
- keys = keys.sort();
- let newArgs = {};
- keys.forEach(key => {
- newArgs[key] = args[key];
- });
- let string = '';
- for (let k in newArgs) {
- string += '&' + k + '=' + newArgs[k];
- }
- string = string.substr(1);
- return string;
- }
- isMerchant(roleIds) {
- return roleIds.findIndex(item => +item === 2) > -1;
- }
- isAgent(roleIds) {
- return roleIds.findIndex(item => +item === 4) > -1;
- }
- stringToHex(str) {
- let hex = '';
- for (let i = 0; i < str.length; i++) {
- hex += str.charCodeAt(i).toString(16);
- }
- return hex;
- }
- hexToString(hexString) {
- // 移除前缀0x,如果有的话
- if (hexString.startsWith('0x')) {
- hexString = hexString.slice(2);
- }
- // 将16进制字符串转换为Buffer
- const buffer = Buffer.from(hexString, 'hex');
- // 将Buffer转换为字符串
- return buffer.toString('utf8');
- }
- signByMD5WithRSA(data, privateKey) {
- const hmac = crypto.createSign('md5WithRSAEncryption');
- // 更新hash对象与传入的数据
- hmac.update(data);
- // 生成哈希值
- return hmac.sign(privateKey, 'base64');
- }
- verifyByMD5WithRSA(data, sign, publicKey) {
- const key = new NodeRSA(publicKey);
- key.setOptions({ signingScheme: 'pkcs1-sha256' });
- return key.verify(data, sign);
- }
- signBySha256(data, secretKey, format: BinaryToTextEncoding = 'hex') {
- const hmac = crypto.createHmac('sha256', secretKey);
- // 更新hash对象与传入的数据
- hmac.update(data);
- // 生成哈希值
- return hmac.digest(format);
- }
- signByHmacSha1(data, secretKey) {
- const hmac = crypto.createHmac('sha1', secretKey);
- // 更新hash对象与传入的数据
- hmac.update(data);
- // 生成哈希值
- return hmac.digest('base64');
- }
- getGoogleSecret() {
- return speakeasy.generateSecret({ length: 20 })
- }
- validGoogleSecret(secret, code) {
- return speakeasy.totp.verify({
- secret: secret,
- encoding: 'base32',
- token: code,
- algorithm: 'sha1'
- })
- }
- }
|