function.js 56 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005
  1. 'use strict';
  2. // 通用 function
  3. var fs = require('fs');
  4. var path = require('path');
  5. var md5 = require('md5');
  6. var request = require('koa-request');
  7. var async_request = require('request');
  8. //var iconv = require('iconv-lite');
  9. var C = require('../config');
  10. var redis = require('../libs/redis.js');
  11. var thunkify = require('thunkify');
  12. var exec = require('child_process').exec;
  13. //var sleep = require('es6-sleep');
  14. var logs_obj = require('../libs/logs.js');
  15. var os = require('os');
  16. var logs = new logs_obj();
  17. var _ = require('underscore');
  18. //exports.sleep=sleep;
  19. _.str = require('underscore.string');
  20. _.v = require('validator');
  21. var crypto = require('crypto');
  22. String.prototype.endsWith = function (suffix) {
  23. return this.indexOf(suffix, this.length - suffix.length) !== -1;
  24. };
  25. exports.values = function (obj) {
  26. return Object.keys(obj).map((k) => obj[k]);
  27. };
  28. Date.prototype.format = function (fmt) {
  29. var o = {
  30. "M+": this.getMonth() + 1, //月份
  31. "d+": this.getDate(), //日
  32. "h+": this.getHours() % 12 == 0 ? 12 : this.getHours() % 12, //小时
  33. "H+": this.getHours(), //小时
  34. "m+": this.getMinutes(), //分
  35. "s+": this.getSeconds(), //秒
  36. "q+": Math.floor((this.getMonth() + 3) / 3), //季度
  37. "S": this.getMilliseconds() //毫秒
  38. };
  39. var week = {
  40. "0": "/u65e5",
  41. "1": "/u4e00",
  42. "2": "/u4e8c",
  43. "3": "/u4e09",
  44. "4": "/u56db",
  45. "5": "/u4e94",
  46. "6": "/u516d"
  47. };
  48. if (/(y+)/.test(fmt)) {
  49. fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
  50. }
  51. if (/(E+)/.test(fmt)) {
  52. fmt = fmt.replace(RegExp.$1, ((RegExp.$1.length > 1) ? (RegExp.$1.length > 2 ? "/u661f/u671f" : "/u5468") : "") + week[this.getDay() + ""]);
  53. }
  54. for (var k in o) {
  55. if (new RegExp("(" + k + ")").test(fmt)) {
  56. fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
  57. }
  58. }
  59. return fmt;
  60. }
  61. Date.getDayOfMonth = function (y, Mm) {
  62. if (typeof y == 'undefined') {
  63. y = (new Date()).getFullYear();
  64. }
  65. if (typeof Mm == 'undefined') {
  66. Mm = (new Date()).getMonth();
  67. }
  68. var Feb = (y % 4 == 0) ? 29 : 28;
  69. var aM = new Array(31, Feb, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
  70. return aM[Mm];
  71. };
  72. Date.getLastMonth = function () {
  73. var dt = new Date();
  74. var y = (dt.getMonth() == 0) ? (dt.getFullYear() - 1) : dt.getFullYear();
  75. var m = (dt.getMonth() == 0) ? 11 : dt.getMonth() - 1;
  76. var preM = Date.getDayOfMonth(y, m);
  77. var d = (preM < dt.getDate()) ? preM : dt.getDate();
  78. var new_time = new Date(y, m, d).format("yyyy-MM-dd HH:mm:ss");
  79. return new_time;
  80. };
  81. exports.getLocalIP = function () {
  82. var ifaces = os.networkInterfaces();
  83. console.log(ifaces);
  84. for (var dev in ifaces) {
  85. if (dev.indexOf('eth') == -1) continue;
  86. return ifaces[dev][0]['address']
  87. }
  88. return '127.0.0.1';
  89. };
  90. /**
  91. * @desc 返回当前的格式化时间
  92. * @param format
  93. */
  94. exports.fDatetime = function (format = 'yyyy-MM-dd HH:mm:ss', dateTime) {
  95. if (dateTime) {
  96. return new Date(dateTime).format(format);
  97. }
  98. return new Date().format(format);
  99. };
  100. // 获取某天的起始时间戳 默认为当天 单位秒
  101. exports.beginTimestamp = function (time1) {
  102. time1 = time1 == undefined ? this.timestamp() : parseInt(time1);
  103. var newDate = new Date(time1 * 1000);
  104. return parseInt(new Date(newDate.format('yyyy-MM-dd') + ' 00:00:00').getTime() / 1000);
  105. };
  106. // 计算日期间隔 单位秒,time1 比 time2 晚时为负数
  107. exports.dateDiff = function (time1, time2) {
  108. time1 = this.beginTimestamp(time1); // 计算某天的起始时间戳
  109. time2 = this.beginTimestamp(time2); // 计算某天的起始时间戳
  110. return parseInt((time2 - time1) / (60 * 60 * 24));
  111. };
  112. /*
  113. @todo 取得时间戳,默认取到秒 传零取毫秒
  114. 函数名:timestamp
  115. * 参数:无
  116. * 返回:当前时间的10位UNIX时间戳
  117. */
  118. exports.timestamp = function (flag) {
  119. if (flag == 0) {
  120. return parseInt(new Date().getTime());
  121. }
  122. return parseInt(new Date().getTime() / 1000);
  123. };
  124. // 获取前xx或后xx时间,delta单位为秒
  125. exports.getTimeByDelta = function (delta = 0, from_date_time = null) {
  126. var today = new Date();
  127. if (!this.isNull(from_date_time)) today = new Date(from_date_time);
  128. var yesterday_milliseconds = today.getTime() + 1000 * delta;
  129. var yesterday = new Date();
  130. yesterday.setTime(yesterday_milliseconds);
  131. return yesterday.format("yyyy-MM-dd HH:mm:ss");
  132. };
  133. exports.getTimeStampByDelta = function (delta = 0, from_date_time = null) {
  134. var today = new Date();
  135. if (!this.isNull(from_date_time)) today = new Date(from_date_time);
  136. var yesterday_milliseconds = today.getTime() + 1000 * delta;
  137. return yesterday_milliseconds;
  138. };
  139. /**
  140. * 获取主播当地时区的可预约时间在服务器上的时间
  141. * @param TimezoneOffset 时区(主播的时区。单位分钟)
  142. * (时区的计算是如果比0时区快那么就是-的,如果比0时区慢那么就是正的。如东八区比0时区快8个小时,那么就是-480分钟)
  143. */
  144. exports.getTimeByZone = function (TimezoneOffset) {
  145. var newday = new Date();
  146. let timestamp = parseInt(new Date().getTime() / 60000) * 60000;//服务器上的时间戳(精确到分钟)
  147. var serverTimezoneOffset = new Date().getTimezoneOffset();
  148. TimezoneOffset = TimezoneOffset - serverTimezoneOffset;//主播的时区-服务器的时区。获取时区差
  149. newday.setTime(timestamp - TimezoneOffset * 60 * 1000);
  150. // newday:显示用 timestamp:真正当前时间戳
  151. return {'newday': newday, 'timestamp': timestamp};
  152. }
  153. //AD页面用节目开始日期
  154. exports.anchorReservationTimeDay = function (time) {
  155. var month = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
  156. var tmpM = this.fDatetime("M", time);
  157. var tmpData = month[parseInt(tmpM) - 1] + ' ' + this.fDatetime("dd", time);
  158. return tmpData;
  159. }
  160. //AD节目开始时间
  161. exports.anchorReservationTimeHour = function (time) {
  162. var hour = this.fDatetime("HH", time);
  163. var minute = this.fDatetime("mm", time);
  164. var timeVar = 'am';
  165. if (hour > 12) {
  166. hour = hour - 12;
  167. timeVar = 'pm';
  168. }
  169. var tmpData = hour + ':' + minute + ' ' + timeVar;
  170. return tmpData;
  171. }
  172. /**
  173. * 根据时间戳和主播时区,获取主播的日期格式
  174. * @param time
  175. * @param Timezone
  176. * @returns {{anchorWeek: number, anchorHours: number, anchorMinutes: number}}
  177. */
  178. exports.getAnchorTimeByTimestamp = function (time, Timezone) {
  179. //计算主播的时区
  180. let anchorTimezone = (Timezone / 60) * -1;//根据时区的分钟取反获取到时区
  181. let TimezoneInteger = parseInt(anchorTimezone);
  182. let TimezoneDecimal = (anchorTimezone - TimezoneInteger) * 60;
  183. if (TimezoneInteger > 0) {
  184. TimezoneInteger = '+' + TimezoneInteger;
  185. }
  186. if (TimezoneDecimal) {
  187. Timezone = TimezoneInteger + ':' + TimezoneDecimal;
  188. } else {
  189. Timezone = TimezoneInteger;
  190. }
  191. let Timestamp = new Date().setTime(time * 1000);
  192. let serverTime = new Date(Timestamp).format("yyyy-MM-dd HH:mm:ss");
  193. serverTime = serverTime + Timezone;
  194. let anchorDay = new Date(serverTime).getDay();
  195. let anchorHours = new Date(serverTime).getHours();
  196. let anchorMinutes = new Date(serverTime).getMinutes();
  197. return {anchorWeek: anchorDay, anchorHours: anchorHours, anchorMinutes: anchorMinutes};
  198. }
  199. //var initEnv={};
  200. //exports.luashas=lua.__shas;
  201. exports.Init = function* (Env, actArray) {
  202. var I = {};
  203. var fields = Env.request.body.fields;
  204. if (fields) {
  205. fields = this.rmHtmlAndJsByJson(fields)
  206. for (var field in fields) {
  207. I[field] = fields[field];
  208. }
  209. }
  210. var params = Env.params;
  211. Env.pattern_url = Env.request.url.split("?")[0];
  212. if (params) {
  213. for (var parm in params) {
  214. I[parm] = params[parm];
  215. Env.pattern_url = Env.pattern_url.replace(new RegExp("/" + I[parm] + "/", 'g'), "/*/"); //每次只匹配一个
  216. Env.pattern_url = Env.pattern_url.replace(new RegExp("/" + I[parm] + "$", 'g'), "/*");
  217. }
  218. if (I['apiVer']) {
  219. var pattern = /^v([\.|\d+]+)$/gi;
  220. var tmpVer = pattern.exec(I['apiVer']);
  221. if (tmpVer[1] == undefined) {
  222. I['apiVerNum'] = 1;
  223. } else {
  224. I['apiVerNum'] = tmpVer[1];
  225. }
  226. } else {
  227. I['apiVerNum'] = 1;
  228. }
  229. }
  230. //get参数
  231. var querys = Env.query;
  232. if (querys) {
  233. querys = this.rmHtmlAndJsByJson(querys)
  234. for (var query in querys) {
  235. I[query] = querys[query];
  236. }
  237. }
  238. var errors = {};
  239. if (I) {
  240. // var app_ver = Env.request.accept.headers['app-ver'];
  241. // if (app_ver == undefined){
  242. // app_ver = '';
  243. // }
  244. if (!_.isEmpty(errors)) {
  245. I.errors = errors;
  246. console.log('[ERR] [%s] [%s] [%s] [%s] [%s] [%s] <%s>', new Date().format('yyyy-MM-dd hh:mm:ss'), Env.ip, app_ver,
  247. Env.request.method, Env.req.url, errors, Env.request.accept.headers['user-agent']);
  248. }
  249. //console.log('[INFO] [%s] [%s] [%s] [%s] [%s] <%s>',new Date().format('yyyy-MM-dd hh:mm:ss'),Env.ip,app_ver,
  250. //Env.request.method,Env.req.url,Env.request.accept.headers['user-agent']);
  251. //console.log('[Input] [%O]',I);
  252. }
  253. I.real_ip = Env.request.accept.headers['x-real-ip'];
  254. I.is_https = Env.request.accept.headers['is_https'];
  255. if (!this.isNull(I.is_https)) {
  256. I.protocol = "https";
  257. } else {
  258. I.protocol = "http";
  259. }
  260. if (this.isNull(I.real_ip)) {
  261. I.real_ip = Env.request.accept.headers.host;
  262. }
  263. this.addDebugLogs("I.real_ip:" + I.real_ip);
  264. Env.clientip = Env.request.accept.headers['x-forwarded-for'];
  265. if (this.isNull(I.clientip)) {
  266. Env.clientip = Env.request.accept.headers['x-client-ip'];
  267. if (this.isNull(Env.clientip)) {
  268. Env.clientip = Env.request.req.headers['x-forwarded-for'] || Env.request.req.connection.remoteAddress ||
  269. Env.request.req.socket.remoteAddress || Env.request.req.connection.socket.remoteAddress;
  270. if (!this.isNull(Env.clientip)) {
  271. Env.clientip = Env.clientip.match(/\d+.\d+.\d+.\d+/);
  272. Env.clientip = !this.isNull(Env.clientip) ? Env.clientip[0] : '';
  273. }
  274. }
  275. }
  276. if (!this.isNull(I.is_ajax) && I.is_ajax == 1) Env.request.accept.headers['x-requested-with'] = 'xmlhttprequest';
  277. //this.addOtherLogs("imrw/imrw",[JSON.stringify(["##http receive:",Env.req.url,"clientip",Env.clientip,I,Env.session.userid,Env.request.req.headers['cookie']])]);
  278. return I;
  279. };
  280. /*
  281. @todo获取页面返回信息(返回对象)
  282. @status 状态码
  283. @msg 返回信息
  284. @level 返回信息等级
  285. @data 数据项(对象)
  286. */
  287. exports.returnMsg = function (status, msg, level, data) {
  288. var returnData = {};
  289. var code = status || 10200;
  290. returnData.state = {
  291. msg: msg || "",
  292. code: code
  293. };
  294. returnData.data = {};
  295. if (typeof data === "object" && data !== null) {
  296. returnData.data = data;
  297. }
  298. if (C.env != 'production') {
  299. this.addLogs(['[RETURN] [%s] [%s]', status, msg]);
  300. }
  301. return returnData;
  302. };
  303. exports.pcCheckParams = function* (ctx) {
  304. ctx.I = yield this.Init(ctx, [1, 11]);
  305. if (ctx.I.errors) {
  306. ctx.jsonp = this.returnMsg(10400, ctx.I.errors.msg, ctx.I.errors.level);
  307. return false;
  308. } else {
  309. return true;
  310. }
  311. };
  312. /*
  313. @todo 获取随机数
  314. @len 随机数位数
  315. */
  316. exports.getRandom = function (len) {
  317. return Math.floor(Math.random() * (Math.pow(10, len) - Math.pow(10, len - 1)) + Math.pow(10, len - 1));
  318. };
  319. /**
  320. * 获取指定范围的随机数
  321. * @param Min
  322. * @param Max
  323. * @returns {*}
  324. * @constructor
  325. */
  326. exports.RandomNumBoth = function (Min, Max) {
  327. return Math.floor(Math.random() * (Max - Min + 1) + Min);
  328. }
  329. var all_chat = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'];
  330. exports.getRandomNumAndChat = function (len) {
  331. var random_str = '';
  332. for (var i = 0; i < len; i++) {
  333. var c = all_chat[Math.floor(Math.random() * (all_chat.length))];
  334. random_str += c;
  335. }
  336. return random_str;
  337. };
  338. /**
  339. * 随机生成字母
  340. * @type {string[]}
  341. */
  342. var randomChat = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'];
  343. exports.getRandomChat = function (len) {
  344. var random_str = '';
  345. for (var i = 0; i < len; i++) {
  346. var c = randomChat[Math.floor(Math.random() * (randomChat.length))];
  347. random_str += c;
  348. }
  349. return random_str;
  350. };
  351. exports.intArray = function (arr) {
  352. if (_.isObject(arr)) {
  353. for (var i in arr) {
  354. if (_.v.isIn(i, ['uid'])) {
  355. arr[i] = parseInt(arr[i]);
  356. }
  357. }
  358. }
  359. };
  360. /*
  361. isJson 尝试判断字符串是否为json类型。返回json对象或false
  362. */
  363. exports.isJson = function (str) {
  364. try {
  365. return JSON.parse(str);
  366. } catch (e) {
  367. return false;
  368. }
  369. };
  370. /**
  371. * @desc 取得范围内的随机数
  372. * @param min
  373. * @param max
  374. * @returns {*}
  375. */
  376. exports.getRandomNum = function (min, max) {
  377. var range = max - min;
  378. var rand = Math.random();
  379. return (min + Math.round(rand * range));
  380. };
  381. exports.pad = function (number, length, pos) {
  382. var str = '' + number;
  383. while (str.length < length) {
  384. if ('r' == pos) {
  385. str = str + '0';
  386. } else {
  387. str = '0' + str;
  388. }
  389. }
  390. return str;
  391. };
  392. /**
  393. * @desc 转成16进制
  394. * @param chr
  395. * @param padLen
  396. */
  397. exports.toHex = function (chr, padLen) {
  398. if (null == padLen) {
  399. padLen = 2;
  400. }
  401. return this.pad(chr.toString(16), padLen);
  402. };
  403. /**
  404. * @desc 获取登陆的设备
  405. * @param ua
  406. * @returns {*}
  407. */
  408. exports.getDevice = function (ua) {
  409. if (ua && ua.length > 0) {
  410. ua = ua.toLowerCase();
  411. if (ua.match(/iPhone/i) == "iphone") {
  412. return 'iphone';
  413. } else if (ua.match(/Android/i) == "android") {
  414. return 'android';
  415. }
  416. }
  417. return '';
  418. };
  419. /**
  420. * @desc 取得推流的一些参数
  421. * @param device
  422. * @returns {*}
  423. */
  424. exports.getPushParms = function (device) {
  425. return device == 'android' ? C.android_push_parms : (device == 'iphone' ? C.ios_push_parms : {});
  426. };
  427. /**
  428. * @desc socket通知
  429. * @param url
  430. */
  431. exports.socketNotify = function (url) {
  432. var options = {
  433. url: url
  434. };
  435. async_request.get(options, function (error, response, body) {
  436. if (error) {
  437. console.log(error);
  438. }
  439. console.log(body);
  440. });
  441. };
  442. /**
  443. * @desc 生成直播url
  444. * @param uid 主播id
  445. * @param lhid live_history自增id
  446. * @returns {string}
  447. */
  448. exports.genLiveUrl = function (uid, lhid) {
  449. var url = C.live.live_url;
  450. url = _.str.sprintf(url, uid, lhid);
  451. return url;
  452. };
  453. /**
  454. * @desc 生成IM地址
  455. * @param uid
  456. * @returns {string}
  457. */
  458. exports.genImUrl = function (tokenKey, uid) {
  459. var url = C.im_url;
  460. url = _.str.sprintf(url, uid, tokenKey);
  461. return url;
  462. };
  463. /**
  464. * @desc 生成flv播放地址
  465. * @param path
  466. * @returns {string}
  467. */
  468. exports.genFlvPlayBackUrl = function (path) {
  469. return C.live.flv_playback_url + path;
  470. };
  471. exports.isNull = function (obj) {
  472. if (obj == null || typeof(obj) == "undefined" || obj.length == 0) {
  473. return true;
  474. }
  475. if (typeof(obj) == 'object' && !(obj instanceof Date) && Object.keys(obj).length == 0) {
  476. return true;
  477. }
  478. return false;
  479. };
  480. // private method for UTF-8 encoding
  481. exports._utf8_encode = function (string) {
  482. string = string.replace(/\r\n/g, "\n");
  483. let utftext = "";
  484. for (let n = 0; n < string.length; n++) {
  485. let c = string.charCodeAt(n);
  486. if (c < 128) {
  487. utftext += String.fromCharCode(c);
  488. } else if ((c > 127) && (c < 2048)) {
  489. utftext += String.fromCharCode((c >> 6) | 192);
  490. utftext += String.fromCharCode((c & 63) | 128);
  491. } else {
  492. utftext += String.fromCharCode((c >> 12) | 224);
  493. utftext += String.fromCharCode(((c >> 6) & 63) | 128);
  494. utftext += String.fromCharCode((c & 63) | 128);
  495. }
  496. }
  497. return utftext;
  498. };
  499. // private method for UTF-8 decoding
  500. exports._utf8_decode = function (utftext) {
  501. let string = "";
  502. let i = 0;
  503. let c = 0, c1 = 0, c2 = 0, c3 = 0;
  504. while (i < utftext.length) {
  505. c = utftext.charCodeAt(i);
  506. if (c < 128) {
  507. string += String.fromCharCode(c);
  508. i++;
  509. } else if ((c > 191) && (c < 224)) {
  510. c2 = utftext.charCodeAt(i + 1);
  511. string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
  512. i += 2;
  513. } else {
  514. c2 = utftext.charCodeAt(i + 1);
  515. c3 = utftext.charCodeAt(i + 2);
  516. string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
  517. i += 3;
  518. }
  519. }
  520. return string;
  521. };
  522. // public method for encoding
  523. exports.base64_encode = function (input) {
  524. let _keyStr = C._keyStr;
  525. let output = "";
  526. let chr1, chr2, chr3, enc1, enc2, enc3, enc4;
  527. let i = 0;
  528. input = this._utf8_encode(input);
  529. while (i < input.length) {
  530. chr1 = input.charCodeAt(i++);
  531. chr2 = input.charCodeAt(i++);
  532. chr3 = input.charCodeAt(i++);
  533. enc1 = chr1 >> 2;
  534. enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
  535. enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
  536. enc4 = chr3 & 63;
  537. if (isNaN(chr2)) {
  538. enc3 = enc4 = 64;
  539. } else if (isNaN(chr3)) {
  540. enc4 = 64;
  541. }
  542. output = output +
  543. _keyStr.charAt(enc1) + _keyStr.charAt(enc2) +
  544. _keyStr.charAt(enc3) + _keyStr.charAt(enc4);
  545. }
  546. return output;
  547. };
  548. // public method for decoding
  549. exports.base64_decode = function (input) {
  550. let _keyStr = C._keyStr;
  551. let output = "";
  552. let chr1, chr2, chr3;
  553. let enc1, enc2, enc3, enc4;
  554. let i = 0;
  555. input = input.replace(/[^A-Za-z0-9\(\)\-]/g, "");
  556. while (i < input.length) {
  557. enc1 = _keyStr.indexOf(input.charAt(i++));
  558. enc2 = _keyStr.indexOf(input.charAt(i++));
  559. enc3 = _keyStr.indexOf(input.charAt(i++));
  560. enc4 = _keyStr.indexOf(input.charAt(i++));
  561. chr1 = (enc1 << 2) | (enc2 >> 4);
  562. chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
  563. chr3 = ((enc3 & 3) << 6) | enc4;
  564. output = output + String.fromCharCode(chr1);
  565. if (enc3 != 64) {
  566. output = output + String.fromCharCode(chr2);
  567. }
  568. if (enc4 != 64) {
  569. output = output + String.fromCharCode(chr3);
  570. }
  571. }
  572. output = this._utf8_decode(output);
  573. return output;
  574. };
  575. exports.myEncode = function (str) {
  576. str = str.toString();
  577. let private_key = C.private_key;
  578. let str2 = "";
  579. for (let i = 0, j = 0; i < str.length; i++, j++) {
  580. if (j > private_key.length - 1) j = 0;
  581. str2 += String.fromCharCode(str.charCodeAt(i) ^ private_key.charCodeAt(j));
  582. }
  583. return this.base64_encode(str2);
  584. };
  585. exports.myDecode = function (str) {
  586. str = str.toString();
  587. let private_key = C.private_key;
  588. str = this.base64_decode(str);
  589. let str2 = "";
  590. for (let i = 0, j = 0; i < str.length; i++, j++) {
  591. if (j > private_key.length - 1) j = 0;
  592. str2 += String.fromCharCode(str.charCodeAt(i) ^ private_key.charCodeAt(j));
  593. }
  594. return str2;
  595. };
  596. /**
  597. * @desc 取得sdk sign
  598. * @param token
  599. * @param ts
  600. */
  601. exports.genSdkSign = function (token, ts) {
  602. var md5Str = 'token' + token + 'ts' + ts;
  603. var md5Str = md5.digest_s(md5.digest_s(md5Str) + '.' + C.sdk_sign_key);
  604. return md5Str;
  605. };
  606. /**
  607. * @desc 取得m3u8的长度
  608. * @param hlsUrl
  609. * @returns {*|number}
  610. */
  611. exports.getM3u8Len = function* (hlsUrl) {
  612. var content = yield this.urlGetContent(hlsUrl);
  613. var pattern = /#EXTINF:([\d|.+]+),/g;
  614. var arr = '';
  615. var len = 0;
  616. while ((arr = pattern.exec(content)) != null) {
  617. len += parseFloat(arr[1]);
  618. }
  619. return Math.floor(len);
  620. };
  621. exports.assertParamNull = function* (parent_obj, key_str) {
  622. var key_arr = key_str.split(",");
  623. for (let i = 0; i < key_arr.length; i++) {
  624. var field = _.str.trim(key_arr[i]);
  625. var exe_str = _.str.vsprintf("this.isNull(parent_obj.%s)", [field]);
  626. if (eval(exe_str)) {
  627. this.throwErr(this.log("err:", "params %s is null!", [key_arr[i]]));
  628. return false;
  629. }
  630. }
  631. return true;
  632. }
  633. /**
  634. * @desc 取得sdk sign
  635. * @param token
  636. * @param ts
  637. */
  638. exports.checkParamsNull = function* (Env, key_str) {
  639. if (this.isNull(Env.I)) Env.I = yield this.Init(Env);
  640. return yield this.assertParamNull(Env.I, key_str);
  641. };
  642. exports.log = function (level, tpl, arr) {
  643. arr = arr || [];
  644. var line = _.str.vsprintf(tpl, arr);
  645. console.log(line);
  646. logs.addLogs("debug/debug", [line]);
  647. return line;
  648. };
  649. exports.addOtherLogs = function (name, data) {
  650. logs.addLogs(name, data);
  651. }
  652. exports.addDebugLogs = function (data) {
  653. if (!this.isNull(C.NO_LOG_DEBUG)) return;
  654. logs.addLogs("debug/debug", data);
  655. }
  656. exports.addLogs = function (data) {
  657. logs.addLogs("debug/debug", data);
  658. //logs.addLogs("sys/sys",data);
  659. }
  660. exports.addErrLogs = function (data) {
  661. logs.addLogs("debug/debug", data);
  662. //logs.addLogs("sys/sys",data);
  663. logs.addLogs("err/err", data);
  664. console.log([data]);
  665. }
  666. exports.addSlowLogs = function (data) {
  667. logs.addLogs("slow/slow", data);
  668. }
  669. exports.addWebErrLogs = function (data) {
  670. logs.addLogs("web_err/web_err", data);
  671. }
  672. exports.vsprintf = function (tpl, arr = []) {
  673. return _.str.vsprintf(tpl, arr);
  674. };
  675. exports.sqlprintf = function (tpl, arr = []) {
  676. for (var i = 0; i < arr.length; i++) {
  677. var item = arr[i];
  678. if (typeof(item) == 'string') item = "'" + item + "'";
  679. arr[i] = item;
  680. }
  681. return _.str.vsprintf(tpl, arr);
  682. };
  683. exports.logFile = function (level, tpl, arr) {
  684. arr = arr || [];
  685. var line = _.str.vsprintf(tpl, arr);
  686. console.log(level + ":" + line);
  687. return line;
  688. };
  689. exports.assert = function (ctx, str) {
  690. if (false == eval(str)) {
  691. this.throwErr(str + " not match!");
  692. }
  693. return true;
  694. };
  695. exports.imCheckParamsNull = function* (req_data, key_str) {
  696. if (this.isNull(req_data)) this.throwErr("req data is null");
  697. var key_arr = key_str.split(",");
  698. for (let i = 0; i < key_arr.length; i++) {
  699. var field = _.str.trim(key_arr[i]);
  700. var exe_str = _.str.vsprintf("this.isNull(req_data.%s)", [field]);
  701. if (eval(exe_str)) {
  702. this.throwErr(this.log("err:", "params %s is null!", [key_arr[i]]));
  703. return false;
  704. }
  705. }
  706. return true;
  707. };
  708. exports.isValidNumber = function* (int_value) {
  709. if (int_value < Number.MAX_SAFE_INTEGER / 1000 && int_value > Number.MIN_SAFE_INTEGER / 1000) return true;
  710. return false;
  711. }
  712. exports.imAssert = function (req_data, str) {
  713. if (false == eval(str)) {
  714. this.throwErr(str + " not match!");
  715. }
  716. return true;
  717. };
  718. exports.throwErr = function (msg, code = null, data = null, use_msg = false) {
  719. code = code || 10003;
  720. var err = new Error(msg);
  721. this.log("err:", " msg: %s, code:%s", [msg, code]);
  722. err.code = code;
  723. err.data = data;
  724. err.use_msg = use_msg;
  725. throw err;
  726. }
  727. /**
  728. *
  729. * @param code
  730. * @param data
  731. * @param show_code 0:表示男士 1:表示女士
  732. * @param role_type
  733. */
  734. exports.throwErrCode = function (code, data = null, show_code = null, role_type = null) {
  735. var msg = this.makeErrMsg(code, role_type);
  736. if (this.isNull(show_code)) this.throwErr(msg, code, data, true);
  737. else this.throwErr(msg, show_code, data, true);
  738. }
  739. /**
  740. *
  741. * @param code
  742. * @param params
  743. * @param data
  744. * @param show_code 0:表示男士 1:表示女士
  745. * @param role_type
  746. */
  747. exports.throwErrCodeWithParam = function (code, params = [], data = null, show_code = null, role_type = null) {
  748. var msg = this.makeErrMsgWithParam(code, params, role_type);
  749. if (this.isNull(show_code)) this.throwErr(msg, code, data, true);
  750. else this.throwErr(msg, show_code, data, true);
  751. }
  752. /**
  753. *
  754. * @param code
  755. * @param role_type 0:表示男士 1:表示女士
  756. * @returns {*}
  757. */
  758. exports.makeErrMsg = function (code, role_type = null) {
  759. let real_code = code;
  760. if (!this.isNull(role_type)) {
  761. if (1 == role_type) real_code += "anchor";
  762. else real_code += "man";
  763. if (real_code in C.err_msg) {
  764. } else {
  765. real_code = code
  766. }
  767. ;
  768. }
  769. var msg = C.err_msg[real_code];
  770. if (this.isNull(msg)) {
  771. msg = C.err_msg["10003"];
  772. }
  773. return msg;
  774. }
  775. /**
  776. *
  777. * @param code
  778. * @param params
  779. * @param role_type 0:表示男士 1:表示女士
  780. * @returns {*}
  781. */
  782. exports.makeErrMsgWithParam = function (code, params = [], role_type = null) {
  783. let real_code = code;
  784. if (!this.isNull(role_type)) {
  785. if (1 == role_type) real_code += "anchor";
  786. else real_code += "man";
  787. if (real_code in C.err_msg) {
  788. } else {
  789. real_code = code
  790. }
  791. ;
  792. }
  793. var msg = C.err_msg[real_code];
  794. if (this.isNull(msg)) {
  795. msg = C.err_msg["10003"];
  796. }
  797. else msg = _.str.vsprintf(msg, params);
  798. return msg;
  799. }
  800. exports.tipsWithParam = function (code, params = []) {
  801. var msg = C.tips[code];
  802. if (this.isNull(msg)) {
  803. msg = '';
  804. }
  805. else msg = _.str.vsprintf(msg, params);
  806. return msg;
  807. }
  808. // 组装缩略图名字
  809. exports.makeThumb = function (img, type) {
  810. if (this.isNull(img)) return '';
  811. if (this.isNull(C.thumb_suffix[type])) return img;
  812. var suffix = C.thumb_suffix[type];
  813. var img_name_list = img.split('.');
  814. if (img_name_list.length <= 1) return img + suffix;
  815. img_name_list[img_name_list.length - 2] += suffix;
  816. return img_name_list.join(".");
  817. }
  818. //单位毫秒
  819. exports.sleep = function* (time) {
  820. return new Promise(function (resolve, reject) {
  821. setTimeout(function () {
  822. resolve();
  823. }, time);
  824. });
  825. }
  826. exports.exists = function* (path) {
  827. return new Promise(function (resolve, reject) {
  828. fs.exists(path, function (exists) {
  829. resolve(exists);
  830. });
  831. });
  832. }
  833. exports.readFile = function* (path) {
  834. return new Promise(function (resolve, reject) {
  835. fs.readFile(path, function (err, data) {
  836. if (err) {
  837. var err = new Error(`Can not read file:${path}`);
  838. err.code = 10003;
  839. reject(err);
  840. } else {
  841. resolve(data);
  842. }
  843. });
  844. });
  845. }
  846. exports.readFileByChunk = function* (path) {
  847. let content = '';
  848. return new Promise(function (resolve, reject) {
  849. let fReadStream = fs.createReadStream(path, {
  850. encoding: 'utf8',
  851. start: 0,
  852. bufferSize: 10240
  853. });
  854. fReadStream.on('data', function (chunk) {
  855. content += chunk;
  856. });
  857. fReadStream.on('end', function () {
  858. resolve(content);
  859. });
  860. });
  861. }
  862. /**
  863. * 获取静态文件的路径
  864. * @param path
  865. * @returns {*}
  866. */
  867. exports.getPublicPath = function (real_ip, is_https) {
  868. var path = this.getImagePrefixByReqHost(real_ip, is_https);
  869. var static_path = path.replace(C.image_upload_path, C.image_static);
  870. return static_path;
  871. }
  872. /**
  873. * 获取文件上传服务器
  874. * @param path
  875. * @returns {*}
  876. */
  877. exports.getServerHost = function (real_ip, is_https) {
  878. var path = this.getImagePrefixByReqHost(real_ip, is_https);
  879. var static_path = path.replace(C.image_upload_path, "");
  880. return static_path;
  881. }
  882. exports.getServerIP = function (real_ip) {
  883. if (!this.isNull(C.image_ip)) return C.image_ip;
  884. if (!this.isNull(real_ip)) return real_ip.split(":")[0];
  885. return C.svr_ip;
  886. }
  887. exports.getCurHost = function (ctx) {
  888. let host = ctx.I.real_ip.split(":");
  889. let ip = host[0];
  890. let port = parseInt(host[1]);
  891. if (host.length == 1) port = 80;
  892. let http = 'http';
  893. let websocket = 'ws';
  894. if (!this.isNull(ctx.I.is_https)) {
  895. if (host.length == 1) port = 443;
  896. http = "https";
  897. websocket = "wss";
  898. }
  899. return {http: http, websocket: websocket, ip: ip, port: port};
  900. }
  901. /**
  902. * 返回请求地址信息
  903. * @param req_host
  904. * @param is_https
  905. * @returns {*}
  906. */
  907. exports.getHostInfo = function (req_host, is_https) {
  908. var proto = !this.isNull(is_https) ? "https" : "http";
  909. if (!this.isNull(C.image_proto)) {
  910. proto = C.image_proto;
  911. }
  912. var port = (C.image_port == 80) ? 80 : C.image_port;
  913. if (!this.isNull(C.image_ip)) {
  914. return {'proto': proto, 'ip': C.image_ip, 'port': port, 'image_upload_path': C.image_upload_path};
  915. } else {
  916. var ip = this.isNull(req_host) ? C.svr_ip : req_host.split(":")[0];
  917. return {'proto': proto, 'ip': ip, 'port': port, 'image_upload_path': C.image_upload_path};
  918. }
  919. }
  920. exports.getImagePrefixByReqHost = function (req_host, is_https) {
  921. var proto = !this.isNull(is_https) ? "https" : "http";
  922. if (!this.isNull(C.image_proto)) {
  923. proto = C.image_proto;
  924. }
  925. var port = (C.image_port == 80 || C.image_port == 443) ? "" : ":" + C.image_port;
  926. var image_prefix = "";
  927. if (!this.isNull(C.image_ip)) {
  928. image_prefix = _.str.vsprintf("%s://%s%s%s", [proto, C.image_ip, port, C.image_upload_path]);
  929. } else {
  930. var ip = this.isNull(req_host) ? C.svr_ip : req_host.split(":")[0];
  931. image_prefix = _.str.vsprintf("%s://%s%s%s", [proto, ip, port, C.image_upload_path]);
  932. }
  933. return image_prefix;
  934. };
  935. exports.replaceRtmpHost = function (req_host, res, is_mobile, is_msite) {
  936. try {
  937. var find = C.RTMP_FLAG;
  938. var msg_str = JSON.stringify(res);
  939. if (req_host.indexOf("192") == 0) {
  940. msg_str = msg_str.replace(new RegExp(C.RTMP_FLAG, 'g'), "192.168.88.133");
  941. } else {
  942. msg_str = msg_str.replace(new RegExp(C.RTMP_FLAG, 'g'), "172.25.32.133");
  943. }
  944. // if (!this.isNull(C.RTMP_HOST)) {
  945. // msg_str = msg_str.replace(new RegExp(C.RTMP_FLAG,'g'), C.RTMP_HOST);
  946. // } else {
  947. // var ip = this.isNull(req_host)?C.svr_ip:req_host.split(":")[0];
  948. // msg_str = msg_str.replace(new RegExp(C.RTMP_FLAG,'g'), ip);
  949. // }
  950. //if (msg_str.indexOf("controlManPushNotice") >= 0) this.addDebugLogs(["qiguaide is mobile:", is_mobile]);
  951. if (this.isNull(is_mobile) && this.isNull(is_msite)) { //pc
  952. msg_str = msg_str.replace(new RegExp("tobefitpublish", 'g'), "publish_flash");
  953. msg_str = msg_str.replace(new RegExp("tobefitplay", 'g'), "play_flash");
  954. } else { // mobile
  955. msg_str = msg_str.replace(new RegExp("tobefitpublish", 'g'), "publish_standard");
  956. msg_str = msg_str.replace(new RegExp("tobefitplay", 'g'), "play_standard");
  957. }
  958. return JSON.parse(msg_str);
  959. } catch (e) {
  960. console.log(e);
  961. return res;
  962. }
  963. };
  964. /* 返回json字符替换
  965. * res 返回json对象
  966. * find 替换的字符串数组
  967. * replace 替换的内容数组
  968. */
  969. exports.replaceResJson = function (res, find, replace) {
  970. try {
  971. var msg_str = JSON.stringify(res);
  972. for (var i = 0; i < find.length; i++) {
  973. msg_str = msg_str.replace(new RegExp(find[i], 'g'), replace[i]);
  974. }
  975. return JSON.parse(msg_str);
  976. } catch (e) {
  977. this.addErrLogs(['replaceResJson 报错', res]);
  978. return res;
  979. }
  980. }
  981. exports.deepCopy = function (obj) {
  982. return JSON.parse(JSON.stringify(obj));
  983. }
  984. exports.setResJson = function (ctx, errno = 0, res_data = null) {
  985. if (!this.isNull(res_data) && !this.isNull(ctx.I.real_ip)) {
  986. var image_prefix = this.getImagePrefixByReqHost(ctx.I.real_ip, ctx.I.is_https);
  987. var request_prefix = this.getShareHost(ctx);
  988. res_data = this.replaceRtmpHost(ctx.I.real_ip, res_data, ctx.is_mobile, ctx.is_msite);
  989. res_data = this.replaceResJson(res_data, [C.pic_prefix, C.request_prefix], [image_prefix, request_prefix]);
  990. //res_data = this.replaceCreditStr(res_data, ctx.credit_type);
  991. }
  992. if (this.isNull(ctx.res_list)) ctx.res_list = [];
  993. ctx.res_list.push(this.packResJson(errno, res_data));
  994. //ctx.jsonp = this.packResJson(errno, res_data);
  995. }
  996. exports.packResJson = function (errno = 0, res_data = null) {
  997. var data;
  998. if (errno == 0) {
  999. data = {"errno": 0, "data": res_data};
  1000. } else {
  1001. data = {"errno": errno, "errmsg": C.err_msg[errno], "data": res_data};
  1002. }
  1003. return data;
  1004. };
  1005. exports.packResErrMsg = function (errno = 0, err_msg = null, res_data = null) {
  1006. let data;
  1007. if (errno == 0) {
  1008. data = {"errno": 0, "data": res_data};
  1009. return data;
  1010. }
  1011. if (this.isNull(err_msg)) {
  1012. data = {"errno": errno, "errmsg": C.err_msg[errno], "data": res_data};
  1013. return data;
  1014. }
  1015. data = {"errno": errno, "errmsg": err_msg, "data": res_data};
  1016. return data;
  1017. }
  1018. exports.setQueryJson = function (fields, where, values, limit = '', order = '', use_redis = false, group = '', having = '') {
  1019. return {
  1020. 'fields': fields,
  1021. 'where': where,
  1022. 'values': values,
  1023. 'limit': limit,
  1024. 'order': order,
  1025. 'use_redis': use_redis,
  1026. 'group': group,
  1027. 'having': having
  1028. };
  1029. }
  1030. //判断是否为接口请求
  1031. exports.isAjax = function (ctx) {
  1032. if ((ctx.request.accept.headers['x-requested-with'] && ctx.request.accept.headers['x-requested-with'].toLowerCase() == 'xmlhttprequest') || !this.isNull(ctx.request.header['dev-type']) || !this.isNull(ctx.I["dev-type"]) || !this.isNull(ctx.request.headers['device']) || !this.isNull(ctx.I["device"])) {
  1033. return true;
  1034. } else {
  1035. return false;
  1036. }
  1037. }
  1038. /**
  1039. * 获取接口请求的客服端类型
  1040. * @param ctx
  1041. * @returns {*}
  1042. */
  1043. exports.getDevType = function (ctx) {
  1044. if (this.isNull(ctx)) return '';
  1045. let devType = ctx.request.header['dev-type'];
  1046. devType = this.isNull(devType) ? ctx.I["dev-type"] : devType;
  1047. return this.isNull(devType) ? 10 : devType;
  1048. }
  1049. /**
  1050. * 获取原图
  1051. * @param fileName
  1052. * @param isBlurry 如果为true则返回模糊图
  1053. * @returns {*}
  1054. */
  1055. exports.getOriginImgUrl = function (fileName, isBlurry = false, replace = '') {
  1056. if (this.isNull(fileName)) return '';
  1057. let cutLetter = fileName.substring(0, 6);
  1058. if (cutLetter == 'http:/' || cutLetter == 'https:') {
  1059. } else if (fileName.indexOf(C.pic_prefix) == 0) {
  1060. } else {
  1061. fileName = _.str.trim(fileName, '/');
  1062. fileName = `${C.pic_prefix}${fileName}`;
  1063. }
  1064. let url = fileName;
  1065. if (replace) {
  1066. url = url.replace("/origin/", "/" + replace + "/");
  1067. }
  1068. if (isBlurry) {
  1069. url = url.replace("/origin/", "/origin_blurry/");
  1070. url = url.replace("/big/", "/big_blurry/");
  1071. url = url.replace("/small/", "/small_blurry/");
  1072. url = url.replace("/micro/", "/micro_blurry/");
  1073. url = url.replace("/tiny/", "/tiny_blurry/");
  1074. var path_list = url.split("/");
  1075. var pic_name = path_list.pop();
  1076. var name_list = pic_name.split(".");
  1077. var ext = name_list.pop();
  1078. var just_name = name_list.join(".");
  1079. let suffix = md5.digest_s(just_name + C.blurry_key);
  1080. path_list.push(suffix + "." + ext);
  1081. url = path_list.join("/");
  1082. }
  1083. return url;
  1084. }
  1085. /**
  1086. * 通过文件名获取文件url地址
  1087. * @param fileName 文件名
  1088. * @returns {*} url地址
  1089. */
  1090. exports.getFileUrl = function (fileName) {
  1091. if (this.isNull(fileName)) return '';
  1092. let cutLetter = fileName.substring(0, 6);
  1093. if (cutLetter == 'http:/' || cutLetter == 'https:') {
  1094. } else if (fileName.indexOf(C.pic_prefix) == 0) {
  1095. } else {
  1096. fileName = _.str.trim(fileName, '/');
  1097. fileName = `${C.pic_prefix}${fileName}`;
  1098. }
  1099. fileName = fileName.replace("/origin/", "/big/");
  1100. fileName = fileName.replace("/origin_blurry", "/big_blurry");
  1101. return fileName;
  1102. };
  1103. // 获取图片对应高分辨压缩图
  1104. exports.getHighThumb = function (fileName) {
  1105. if (this.isNull(fileName)) return "";
  1106. var url = this.getFileUrl(fileName);
  1107. return url;
  1108. url = url.replace("/origin/", "/big/");
  1109. url = url.replace("/origin_blurry", "/big_blurry");
  1110. return url;
  1111. };
  1112. // 获取图片对应较高分辨压缩图
  1113. exports.getBiggerMidThumb = function (fileName) {
  1114. if (this.isNull(fileName)) return "";
  1115. var url = this.getFileUrl(fileName);
  1116. url = url.replace("/big/", "/middle/");
  1117. url = url.replace("/big_blurry", "/middle_blurry");
  1118. url = url.replace("/origin/", "/middle/");
  1119. url = url.replace("/origin_blurry", "/middle_blurry");
  1120. return url;
  1121. };
  1122. // 获取图片对应中分辨压缩图
  1123. exports.getMidThumb = function (fileName) {
  1124. if (this.isNull(fileName)) return "";
  1125. var url = this.getFileUrl(fileName);
  1126. url = url.replace("/big/", "/small/");
  1127. url = url.replace("/big_blurry", "/small_blurry");
  1128. url = url.replace("/origin/", "/small/");
  1129. url = url.replace("/origin_blurry", "/small_blurry");
  1130. return url;
  1131. };
  1132. // 获取图片对应低分辨压缩图
  1133. exports.getLowThumb = function (fileName) {
  1134. if (this.isNull(fileName)) return "";
  1135. var url = this.getFileUrl(fileName);
  1136. url = url.replace("/big/", "/micro/");
  1137. url = url.replace("/big_blurry", "/micro_blurry");
  1138. url = url.replace("/origin/", "/micro/");
  1139. url = url.replace("/origin_blurry", "/micro_blurry");
  1140. return url;
  1141. };
  1142. // 获取图片对应超低分辨压缩图
  1143. exports.getTinyThumb = function (fileName) {
  1144. if (this.isNull(fileName)) return "";
  1145. var url = this.getFileUrl(fileName);
  1146. url = url.replace("/big/", "/tiny/");
  1147. url = url.replace("/big_blurry", "/tiny_blurry");
  1148. url = url.replace("/origin/", "/tiny/");
  1149. url = url.replace("/origin_blurry", "/tiny_blurry");
  1150. return url;
  1151. };
  1152. /**
  1153. * 通过文件名获取图片模糊图url地址
  1154. * @param fileName 文件名
  1155. * @returns {*} url地址
  1156. */
  1157. exports.getBlurryImg = function (fileName) {
  1158. if (this.isNull(fileName)) {
  1159. return '';
  1160. }
  1161. var url = this.getFileUrl(fileName);
  1162. url = url.replace("/origin/", "/origin_blurry/");
  1163. url = url.replace("/big/", "/big_blurry/");
  1164. url = url.replace("/small/", "/small_blurry/");
  1165. url = url.replace("/micro/", "/micro_blurry/");
  1166. url = url.replace("/tiny/", "/tiny_blurry/");
  1167. var path_list = url.split("/");
  1168. var pic_name = path_list.pop();
  1169. var name_list = pic_name.split(".");
  1170. var ext = name_list.pop();
  1171. var just_name = name_list.join(".");
  1172. let suffix = md5.digest_s(just_name + C.blurry_key);
  1173. path_list.push(suffix + "." + ext);
  1174. url = path_list.join("/");
  1175. return url;
  1176. };
  1177. /**
  1178. * 通过文件名获取图片缩略图url地址
  1179. * @param fileName 文件名
  1180. * @returns {*} url地址
  1181. */
  1182. exports.getImgThumb = function (fileName) {
  1183. return this.getHighThumb(fileName);
  1184. };
  1185. /**
  1186. * 通过文件名获取图片模糊图缩略图url地址
  1187. * @param fileName 文件名
  1188. * @returns {*} url地址
  1189. */
  1190. exports.getBlurryImgThumb = function (fileName) {
  1191. if (this.isNull(fileName)) {
  1192. return '';
  1193. }
  1194. var url = this.getBlurryImg(fileName);
  1195. return this.getHighThumb(url);
  1196. };
  1197. /**
  1198. * 获取当前时间戳
  1199. * @returns {Number} 时间戳 秒
  1200. */
  1201. exports.time = function (str = '') {
  1202. let date = new Date();
  1203. if (!this.isNull(str)) {
  1204. let [num, dateType] = str.split(' ');
  1205. switch (dateType) {
  1206. case 'month':
  1207. date.setMonth(date.getMonth() + parseInt(num));
  1208. break;
  1209. case 'day':
  1210. date.setDate(date.getDate() + parseInt(num));
  1211. break;
  1212. }
  1213. }
  1214. return parseInt(date.getTime() / 1000);
  1215. };
  1216. /**
  1217. * 时间字符串转出时间戳
  1218. * @returns {Number} 时间戳
  1219. */
  1220. exports.strToTime = function (str) {
  1221. return parseInt(new Date(str).getTime() / 1000);
  1222. };
  1223. /**
  1224. * 根据时间戳计算,现在距离预约时间的时间
  1225. * @param time
  1226. * @returns {{d: number, h: number, m: number, s: number, difftime: number}}
  1227. */
  1228. exports.getMisTime = function (time) {
  1229. //time是服务器返回回来的时间戳,单位为妙
  1230. //本地当前时间的时间戳,单位为毫秒,需要转换为妙 /1000
  1231. var localTime = Math.floor((new Date().getTime()) / 1000);
  1232. var difftime = time - localTime;//服务器时间与本地时间的时间差
  1233. var d = Math.floor(difftime / 3600 / 24);
  1234. var h = Math.floor(difftime / 3600 % 24);
  1235. var m = Math.floor(((difftime % (3600 * 24)) % 3600) / 60);
  1236. var s = (difftime % (3600 * 24)) % 60;
  1237. var obj = {
  1238. d: d,//时间天数位数字
  1239. h: h,//时间小时位数字
  1240. m: m,//时间分位数字
  1241. s: s,//时间秒位数字
  1242. difftime: difftime//时间差,秒级
  1243. };
  1244. return obj;
  1245. }
  1246. /**
  1247. * 获取用户主播亲密度等级
  1248. * @param intimacy 亲密度值
  1249. * @returns {Number} 等级
  1250. */
  1251. exports.getIntimacyLevel = function (intimacy) {
  1252. let level = 0;
  1253. if (intimacy >= 10000 && intimacy < 100000) {
  1254. level = 1;
  1255. } else if (intimacy >= 100000 && intimacy < 500000) {
  1256. level = 2;
  1257. } else if (intimacy >= 500000 && intimacy < 2000000) {
  1258. level = 3;
  1259. } else if (intimacy >= 2000000 && intimacy < 5000000) {
  1260. level = 4;
  1261. } else if (intimacy >= 5000000) {
  1262. level = 5;
  1263. }
  1264. return level;
  1265. };
  1266. /**
  1267. * 处理逗号分隔的枚举值
  1268. * @param value 枚举值
  1269. */
  1270. exports.handleEnum = function (value) {
  1271. var statusList = [];
  1272. value = value.split(',');
  1273. for (let i = 0; i < value.length; i++) {
  1274. value[i] = parseInt(value[i]);
  1275. if (!isNaN(value[i])) {
  1276. statusList.push(value[i]);
  1277. }
  1278. }
  1279. if (this.isNull(statusList)) {
  1280. this.throwErrCode(10001);
  1281. } else {
  1282. return statusList;
  1283. }
  1284. };
  1285. exports.isTime = function (str) {
  1286. var res = str.search(/^(\d{4}|\*)\-(\d{2}|\*)\-(\d{2}|\*) (\d{2}|\*):(\d{2}|\*):(\d{2}|\*)$/);
  1287. return 0 == res;
  1288. };
  1289. exports.isInt = function (str) {
  1290. str = str.toString();
  1291. var res = str.search(/^(\d+)$/);
  1292. return 0 == res;
  1293. };
  1294. /* 返回函数执行结果
  1295. * result true,false
  1296. * data result=true:返回数据
  1297. * msg result=false:返回说明
  1298. */
  1299. exports.setFuncData = function (result, data = '') {
  1300. if (result == false) {
  1301. return {
  1302. 'result': false,
  1303. 'msg': data
  1304. };
  1305. } else {
  1306. return {
  1307. 'result': true,
  1308. 'data': data
  1309. };
  1310. }
  1311. };
  1312. /* 返回manager返回结果
  1313. * result true,false
  1314. * data result=true:返回数据
  1315. */
  1316. exports.setManagerData = function (result = true, data = '') {
  1317. if (result == false) {
  1318. return {
  1319. 'result': false,
  1320. 'errno': data.code,
  1321. 'errmsg': data.message
  1322. };
  1323. } else {
  1324. let res = {'result': true};
  1325. if (!this.isNull(data)) {
  1326. res = Object.assign(res, data);
  1327. }
  1328. return res;
  1329. }
  1330. };
  1331. /**
  1332. * 根据出生年计算年龄
  1333. * @param age
  1334. * @returns {number}
  1335. */
  1336. exports.countAge = function (age) {
  1337. var returnAge;
  1338. var birthYear = this.fDatetime('yyyy', age);
  1339. var birthMonth = this.fDatetime('MM', age);
  1340. var birthDay = this.fDatetime('dd', age);
  1341. var nowYear = this.fDatetime('yyyy');
  1342. var nowMonth = this.fDatetime('MM');
  1343. var nowDay = this.fDatetime('dd');
  1344. if (nowYear == birthYear) {
  1345. returnAge = 0;
  1346. }
  1347. else {
  1348. var ageDiff = nowYear - birthYear;
  1349. if (ageDiff > 0) {
  1350. if (nowMonth == birthMonth) {
  1351. var dayDiff = nowDay - birthDay;
  1352. if (dayDiff < 0) {
  1353. returnAge = ageDiff - 1;
  1354. }
  1355. else {
  1356. returnAge = ageDiff;
  1357. }
  1358. }
  1359. else {
  1360. var monthDiff = nowMonth - birthMonth;
  1361. if (monthDiff < 0) {
  1362. returnAge = ageDiff - 1;
  1363. }
  1364. else {
  1365. returnAge = ageDiff;
  1366. }
  1367. }
  1368. }
  1369. else {
  1370. returnAge = -1;
  1371. }
  1372. }
  1373. return returnAge;
  1374. }
  1375. /**
  1376. * 判断元素是否在数组中
  1377. * @param item
  1378. * @param array
  1379. * @returns true/false
  1380. */
  1381. exports.in_array = function (item, arr) {
  1382. return _.v.isIn(item, arr);
  1383. };
  1384. /**
  1385. * 对数组进行递归编码
  1386. * @param arr
  1387. * @returns {*}
  1388. */
  1389. exports.batchHtmlEncode = function (arr) {
  1390. if (!Array.isArray(arr)) {
  1391. return '';
  1392. }
  1393. for (let index in arr) {
  1394. if (Array.isArray(arr[index])) {
  1395. arr[index] = this.batchHtmlEncode(arr[index]);
  1396. } else {
  1397. arr[index] = this.htmlEncode(arr[index]);
  1398. }
  1399. }
  1400. return arr;
  1401. }
  1402. /**
  1403. * 删除json中的html标签
  1404. * @param data
  1405. */
  1406. exports.rmHtmlAndJsByJson = function (data) {
  1407. if (this.isNull(data)) return data;
  1408. let json_str = JSON.stringify(data);
  1409. json_str = this.rmHtmlAndJs(json_str);
  1410. return JSON.parse(json_str);
  1411. }
  1412. /**
  1413. * html编码
  1414. * @param str
  1415. * @returns {string}
  1416. */
  1417. exports.htmlEncode = function (str) {
  1418. var s = "";
  1419. if (str.length == 0) return "";
  1420. s = str.replace(/&/g, "&amp;");
  1421. s = s.replace(/</g, "&lt;");
  1422. s = s.replace(/>/g, "&gt;");
  1423. s = s.replace(/ /g, "&nbsp;");
  1424. //s = s.replace(/\'/g,"&#39;");
  1425. //s = s.replace(/\"/g,"&quot;");
  1426. return s;
  1427. }
  1428. /**
  1429. * html解码
  1430. * @param str
  1431. * @returns {string}
  1432. */
  1433. exports.htmlDecode = function (str) {
  1434. var s = "";
  1435. if (str.length == 0) return "";
  1436. s = str.replace(/&amp;/g, "&");
  1437. s = s.replace(/&lt;/g, "<");
  1438. s = s.replace(/&gt;/g, ">");
  1439. s = s.replace(/&nbsp;/g, " ");
  1440. s = s.replace(/&#39;/g, "\'");
  1441. s = s.replace(/&quot;/g, "\"");
  1442. return s;
  1443. }
  1444. /**
  1445. * 去除html标签和js代码
  1446. */
  1447. exports.rmHtmlAndJs = function (str) {
  1448. var res = str.replace(/<script>.*<\/script>/gi, "");
  1449. res = res.replace(new RegExp("<([^>]+)>", 'g'), "〈$1〉");
  1450. return res;
  1451. }
  1452. /**
  1453. * 调用模板
  1454. * @param ctx
  1455. * @param url
  1456. * @param res
  1457. */
  1458. exports.render = function* (ctx, url, res) {
  1459. var image_prefix = this.getImagePrefixByReqHost(ctx.I.real_ip, ctx.I.is_https);
  1460. var request_prefix = this.getShareHost(ctx);
  1461. res = this.replaceResJson(res, [C.pic_prefix, C.request_prefix], [image_prefix, request_prefix]);
  1462. res = this.replaceCreditStr(res, ctx.credit_type);
  1463. ctx.state = this.replaceResJson(ctx.state, [C.pic_prefix, C.request_prefix], [image_prefix, request_prefix]);
  1464. if (url == 'broadcast/index') {
  1465. //标示是否为index页面
  1466. res.isIndex = true;
  1467. } else {
  1468. res.isIndex = false;
  1469. }
  1470. //CSS和JS的版本号
  1471. res.version = '1.1.15';
  1472. res.F = this;
  1473. res.apptitleH5Page = this.isNull(res.apptitle) ? '' : res.apptitle;
  1474. yield ctx.render(url, res);
  1475. }
  1476. /**
  1477. * 获取动态视频上传的服务器类型
  1478. * @returns {number}
  1479. */
  1480. exports.getServerType = function () {
  1481. return C.is_debug ? 1 : 0;
  1482. }
  1483. /**
  1484. * 获取redis无轮询自增id
  1485. * @param redis_co redisco句柄
  1486. * @param uniid 自增id的标识
  1487. */
  1488. exports.getNextNoRoundId = function* (redis_co, uniid) {
  1489. var key = C.redisPre.pack_req_id_key;
  1490. var next_id = yield redis_co.HINCRBY(key, uniid, 1);
  1491. next_id = parseInt(next_id);
  1492. return next_id;
  1493. };
  1494. /**
  1495. * 请求验证码的key
  1496. */
  1497. exports.getCodeKey = function () {
  1498. let timestamp = this.timestamp();
  1499. let code = this.getRandom(4);
  1500. return md5.digest_s(timestamp + '_' + code);
  1501. }
  1502. /**
  1503. * 获取redis中的验证码值
  1504. * @param codeKey
  1505. */
  1506. exports.getRedisCodeKey = function (codeKey) {
  1507. return md5.digest_s(codeKey + '@#$Qw1g');
  1508. }
  1509. /**
  1510. * 豆转信用点
  1511. */
  1512. exports.getCreditByDou = function (dou) {
  1513. return dou / C.credit_coefficient;
  1514. }
  1515. /**
  1516. * 信用点转豆
  1517. */
  1518. exports.getDouByCredit = function (credit) {
  1519. return credit * C.credit_coefficient;
  1520. }
  1521. /**
  1522. * 设置信用点规则字符串
  1523. */
  1524. exports.setCreditStr = function (dou) {
  1525. return _.str.vsprintf(C.credit_dou_match_str, [dou.toString()]);
  1526. }
  1527. /**
  1528. * 替换信用点规则字符串
  1529. * #credit_%s_preg#
  1530. */
  1531. exports.replaceCreditStr = function (res, credit_type = 2) {
  1532. return false;
  1533. try {
  1534. let str = JSON.stringify(res);
  1535. let key = C.credit_dou_match_str.replace('%s', '[\\d|.|-]+');
  1536. let match_res = str.match(new RegExp(key, 'g'));
  1537. if (!this.isNull(match_res)) {
  1538. let has_set = {};
  1539. for (var i = 0; i < match_res.length; i++) {
  1540. if (this.isNull(has_set[match_res[i]])) {
  1541. let number = match_res[i].match(/[\d|.|-]+/);
  1542. number = number[0];
  1543. if (credit_type == 1) {
  1544. number = this.getCreditByDou(number);
  1545. } else {
  1546. number = Math.round(number);
  1547. }
  1548. has_set[match_res[i]] = number;
  1549. str = str.replace(new RegExp('"' + match_res[i] + '"', 'g'), number);
  1550. str = str.replace(new RegExp('\\\"' + match_res[i] + '\\\"', 'g'), number);
  1551. }
  1552. }
  1553. }
  1554. return JSON.parse(str);
  1555. } catch (e) {
  1556. this.addErrLogs(['replaceCreditStr err', res, credit_type, e.stack]);
  1557. return res;
  1558. }
  1559. };
  1560. /**
  1561. * 替换信用点单位规则字符串
  1562. * #credit_unit_preg#
  1563. */
  1564. exports.replaceCreditUnitStr = function (res, credit_type = 2) {
  1565. try {
  1566. let str = JSON.stringify(res);
  1567. let unit = credit_type == 1 ? C.credit_unit_str : C.dou_unit_str;
  1568. str = str.replace(new RegExp(C.credit_unit_match_str, 'g'), unit);
  1569. return JSON.parse(str);
  1570. } catch (e) {
  1571. this.addErrLogs(['replaceCreditUnitStr err', res, credit_type, e.stack]);
  1572. return res;
  1573. }
  1574. };
  1575. /**
  1576. * 获取请求地址
  1577. * @param ctx
  1578. * @returns {*}
  1579. */
  1580. exports.getShareHost = function (ctx) {
  1581. let protoc = 'http';
  1582. if (!this.isNull(ctx.I.is_https)) protoc = "https";
  1583. let ShareLink = this.vsprintf("%s://%s/", [protoc, ctx.I.real_ip]);
  1584. return ShareLink;
  1585. }
  1586. /**
  1587. * 获取分享地址
  1588. * @param ctx
  1589. * @returns {*}
  1590. */
  1591. exports.getShareHostIm = function (req_host, is_https) {
  1592. var proto = !this.isNull(is_https) ? "https" : "http";
  1593. return this.vsprintf("%s://%s/", [proto, req_host]);
  1594. }
  1595. exports.isCharmDate = function (ctx) {
  1596. if (this.isNull(ctx.I.real_ip)) return false;
  1597. let host = ctx.I.real_ip.split(":");
  1598. let ip = host[0];
  1599. if (ip.indexOf('.charmlive.com') >= 0) return false;
  1600. return true;
  1601. }
  1602. exports.initSession = function (ctx) {
  1603. if (typeof ctx.session.length == 'number') {
  1604. this.addLogs(['user visitorLogin session Array', ctx.session]);
  1605. ctx.session = {};
  1606. }
  1607. let cookie = {
  1608. "signed": false,
  1609. "httpOnly": false,
  1610. "path": "/",
  1611. "overwrite": true
  1612. //"maxage": 86400000,
  1613. };
  1614. if (this.isCharmDate(ctx)) cookie.maxage = 86400000;
  1615. //if (!this.isNull(ctx.I.real_ip)) cookie.domain = ctx.I.real_ip;
  1616. ctx.session.cookie = cookie;
  1617. }
  1618. /**
  1619. * 获取主机信息
  1620. * @param ctx
  1621. * @returns {{http: string, websocket: string, ip: *, port: Number}}
  1622. */
  1623. exports.getHostAndProtoc = function (ctx) {
  1624. let host = ctx.I.real_ip.split(":");
  1625. let ip = host[0];
  1626. let port = parseInt(host[1]);
  1627. if (host.length == 1) port = 80;
  1628. let http = 'http';
  1629. let websocket = 'ws';
  1630. if (!this.isNull(ctx.I.is_https)) {
  1631. if (host.length == 1) port = 443;
  1632. http = "https";
  1633. websocket = "wss";
  1634. }
  1635. return {'http': http, 'websocket': websocket, 'ip': ip, 'port': port};
  1636. }
  1637. /**
  1638. * 获取主机地址
  1639. * @param ctx
  1640. * @returns {{http: string, websocket: string, ip: *, port: Number}}
  1641. */
  1642. exports.getHostUrl = function (ctx) {
  1643. let host = ctx.I.real_ip.split(":");
  1644. let ip = host[0];
  1645. let port = parseInt(host[1]);
  1646. if (host.length == 1) port = 80;
  1647. let http = 'http';
  1648. let websocket = 'ws';
  1649. if (!this.isNull(ctx.I.is_https)) {
  1650. if (host.length == 1) port = 443;
  1651. http = "https";
  1652. websocket = "wss";
  1653. }
  1654. return this.vsprintf("%s://%s:%s", [http, ip, port]);
  1655. }
  1656. /**
  1657. * 如果变量为空则返回null
  1658. * @param parameter
  1659. * @returns {null}
  1660. */
  1661. exports.returnNull = function (parameter) {
  1662. return this.isNull(parameter) ? null : parameter;
  1663. }
  1664. /**
  1665. * judgeOrigin允许访问的URL地址集
  1666. * @type {{[demo.charmdate.com]: number, [www.charmdate.com]: number, [192.168.8.242:94]: number, [192.168.88.17:8717]: number, [192.168.88.17:8817]: number, [live.charmdate.com]: number, [demo-live.charmdate.com]: number}}
  1667. */
  1668. exports.origin_set = {
  1669. 'demo.charmdate.com': 1,
  1670. 'www.charmdate.com': 1,
  1671. '192.168.8.242:94': 1,
  1672. '192.168.88.17:8717': 1,
  1673. '192.168.88.17:8817': 1,
  1674. '192.168.88.17:3107': 1,
  1675. '192.168.88.159:9090': 1,
  1676. '192.168.88.95:9090': 1,
  1677. '192.168.88.170:9090': 1,
  1678. '192.168.88.78:9090': 1,
  1679. '192.168.88.17:8117': 1,
  1680. '192.168.88.40': 1,
  1681. 'live.charmdate.com': 1,
  1682. 'demo-live.charmdate.com': 1,
  1683. 'demo.charmlive.com': 1,
  1684. 'www.charmlive.com': 1
  1685. };
  1686. /**
  1687. * 判断请求的origin是否为指定域名
  1688. * @param ctx
  1689. * @returns {number}
  1690. */
  1691. exports.judgeOrigin = function (ctx) {
  1692. if (this.isNull(ctx.req.headers['origin'])) return true;
  1693. let origin = ctx.req.headers['origin'];
  1694. origin = origin.split("://");
  1695. let originHost = origin[1];
  1696. if (!(originHost.indexOf('192.168.88') == -1) || originHost in this.origin_set) {
  1697. return true;
  1698. } else {
  1699. this.throwErrCode(10001);
  1700. }
  1701. }
  1702. /**
  1703. * 计算字符串长度,中文算两个
  1704. * @param str
  1705. * @returns {number}
  1706. */
  1707. exports.getByteLen = function (str) {
  1708. var len = 0;
  1709. for (var i = 0; i < str.length; i++) {
  1710. var length = str.charCodeAt(i);
  1711. if (length >= 0 && length <= 128) {
  1712. len += 1;
  1713. }
  1714. else {
  1715. len += 2;
  1716. }
  1717. }
  1718. return len;
  1719. }
  1720. /**
  1721. * H5页面url控制参数
  1722. * @param ctx
  1723. * @returns {*}
  1724. */
  1725. exports.getH5UrlParameter = function (opentype, apptitle) {
  1726. opentype = this.isNull(opentype) ? 0 : opentype;
  1727. apptitle = this.isNull(apptitle) ? '' : apptitle;
  1728. return `opentype=${opentype}&apptitle=${apptitle}`;
  1729. }
  1730. /**
  1731. * 获取预约列表的预约时间
  1732. * @returns {number}
  1733. */
  1734. exports.getScheduleTime = function () {
  1735. return this.time() - 120;
  1736. }
  1737. exports.toStr = function (id) {
  1738. if (this.isNull(id)) return id;
  1739. return id.toString();
  1740. }
  1741. /**
  1742. * 去除字符串头尾的字符串
  1743. * @param str
  1744. * @param rep
  1745. * @returns {*}
  1746. */
  1747. exports.trim = function (str, rep) {
  1748. return _.str.trim(str, rep);
  1749. }
  1750. /**
  1751. * 获取day天后的7天内开始和结束时间戳
  1752. * @param day 多少天后开始
  1753. * @returns {{startTime: number, lastTime: number}}
  1754. */
  1755. exports.getWeekTimestamps = function (day = 1, span = 6) {
  1756. if (!this.isNull(C.is_debug)) {
  1757. day = 0;
  1758. }
  1759. let time = this.time();
  1760. let startTime = time + day * 24 * 3600;
  1761. startTime = this.fDatetime('yyyy-MM-dd HH', startTime * 1000);
  1762. let str = startTime + ':00:00';
  1763. startTime = this.strToTime(str);//以小时为分界线
  1764. let lastTime = startTime + span * 24 * 3600;
  1765. let lastData = this.fDatetime('yyyy-MM-dd', lastTime * 1000);
  1766. lastTime = this.strToTime(lastData + ' 24:00:00');//获取最后一天的完整时间
  1767. return {'startTime': startTime, 'lastTime': lastTime};
  1768. }
  1769. /**
  1770. * 验证我司后台修改节目状态时的key(鉴权用)
  1771. * @param key
  1772. * @param live_show_id
  1773. */
  1774. exports.verLiveShowKey = function (key, live_show_id) {
  1775. let codeKey = this.getRedisCodeKey(live_show_id);
  1776. if (key != codeKey) {
  1777. this.throwErrCode(13002);
  1778. }
  1779. }
  1780. exports.coExec = thunkify(function (cmd, cb) {
  1781. exec(cmd, function (err, stdout, stderr) {
  1782. cb(stderr, stdout);
  1783. });
  1784. });
  1785. exports.includesWithoutType = function (arr, a) {
  1786. for (let i = 0; i < arr.length; i++) {
  1787. if (a == arr[i]) return true;
  1788. }
  1789. return false;
  1790. }
  1791. /**
  1792. * 获取指定月的第一天
  1793. * @param date
  1794. * @returns {Date}
  1795. */
  1796. exports.getCurrentMonthFirst = function (date) {
  1797. var date = new Date(date);
  1798. date.setDate(1);
  1799. return date;
  1800. }
  1801. /**
  1802. * 获取指定月份的最后一天
  1803. * @param date
  1804. * @returns {Date}
  1805. */
  1806. exports.getCurrentMonthLast = function (date) {
  1807. var date = new Date(date);
  1808. var currentMonth = date.getMonth();
  1809. var nextMonth = ++currentMonth;
  1810. var nextMonthFirstDay = new Date(date.getFullYear(), nextMonth, 1);
  1811. var oneDay = 1000 * 60 * 60 * 24;
  1812. return new Date(nextMonthFirstDay - oneDay);
  1813. }
  1814. exports.cipher = function (buf) {
  1815. let algorithm = "aes-128-cbc";
  1816. var encrypted = "";
  1817. var key = new Buffer(C.aes_key);
  1818. let iv = new Buffer(C.aes_iv);
  1819. var cip = crypto.createCipheriv(algorithm, key, iv);
  1820. //cip.setAutoPadding(false);
  1821. // buf = customPadding(buf);
  1822. encrypted += cip.update(buf, 'utf8', 'base64');
  1823. encrypted += cip.final('base64');
  1824. return encrypted;
  1825. }
  1826. exports.decipher = function (encrypted) {
  1827. let algorithm = "aes-128-cbc";
  1828. var decrypted = "";
  1829. var key = new Buffer(C.aes_key);
  1830. let iv = new Buffer(C.aes_iv);
  1831. var decipher = crypto.createDecipheriv(algorithm, key, iv);
  1832. //decipher.setAutoPadding(false);
  1833. decrypted += decipher.update(encrypted, 'base64', 'utf8');
  1834. decrypted += decipher.final('utf8');
  1835. return decrypted;
  1836. }