tools.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372
  1. const crypto = require('crypto');
  2. const config = require('./etc/config.json');
  3. const { default: axios } = require('axios');
  4. const http = require('http');
  5. const moment = require('moment');
  6. const mysql = require('mysql2/promise');
  7. const JSONbig = require('json-bigint')
  8. class tools {
  9. constructor(redis_help){
  10. this.redis_help = redis_help
  11. }
  12. init(){
  13. }
  14. distributorId = 1814786227164169;
  15. secretKey = 'CN6KQ8Bauo8JXg5fFPk86EHdRFIUVnyV';
  16. heiyan_config(){
  17. return { //黑岩配置
  18. chang_pian_user:{
  19. userName:"康帅",
  20. password:"Ks25666"
  21. },
  22. duan_pian_user:{
  23. userName:"王海泉",
  24. password:"My20240088"
  25. },
  26. default_user:{
  27. userName:"zhuoyue003",
  28. password:"Xuan2026@123"
  29. },
  30. }
  31. }
  32. unixTimestampToDate = function(timestamp) {
  33. const date = new Date(timestamp * 1000); // Unix时间戳是秒,JavaScript的Date对象需要毫秒
  34. return date.getTime();
  35. }
  36. dateToUnixTimestamp = function (date) {
  37. return Math.floor(date.getTime() / 1000); // 将毫秒转换为秒
  38. }
  39. calculateTimestampDifference = function(timestamp1, timestamp2) {
  40. return Math.abs(timestamp1 - timestamp2);
  41. }
  42. formatUnixTimestamp = function(timestamp, format = 'YYYY-MM-DD HH:mm:ss') {
  43. const date = new Date(timestamp * 1000);
  44. const year = date.getFullYear();
  45. const month = String(date.getMonth() + 1).padStart(2, '0'); // 月份从0开始,需要+1
  46. const day = String(date.getDate()).padStart(2, '0');
  47. const hours = String(date.getHours()).padStart(2, '0');
  48. const minutes = String(date.getMinutes()).padStart(2, '0');
  49. const seconds = String(date.getSeconds()).padStart(2, '0');
  50. const formattedDate = format
  51. .replace('YYYY', year)
  52. .replace('MM', month)
  53. .replace('DD', day)
  54. .replace('HH', hours)
  55. .replace('mm', minutes)
  56. .replace('ss', seconds);
  57. return formattedDate;
  58. }
  59. getCurrentUnixTimestamp = function() {
  60. return Math.floor(Date.now() / 1000)
  61. }
  62. getCurrentUnixTimestamp = function() {
  63. return Math.floor(Date.now() / 1000)
  64. }
  65. generateCryptoNumericUUID= function(length = 10) {
  66. return crypto.randomInt(Math.pow(10, length - 1), Math.pow(10, length)).toString();
  67. }
  68. generateQMSignature = function(url, secretKey) {
  69. const urlObj = new URL(url);
  70. const params = Array.from(urlObj.searchParams.entries())
  71. .sort(([keyA], [keyB]) => keyA.localeCompare(keyB))
  72. .map(([key, value]) => `${key}=${value}`)
  73. .join('&');
  74. // 拼接secret key
  75. const stringToSign = params + secretKey;
  76. console.log("stringToSign:",stringToSign)
  77. // 计算MD5
  78. const md5Hash = crypto.createHash('md5')
  79. .update(stringToSign)
  80. .digest('hex');
  81. return md5Hash;
  82. }
  83. getSign = function(distributorId,secretKey) {
  84. const params = [distributorId, secretKey, tools.getCurrentUnixTimestamp()];
  85. // 将参数数组中的每个元素转换为字符串并连接成一个单一的字符串
  86. const paramStr = params.map(String).join('');
  87. // 使用 MD5 算法生成哈希值
  88. const hash = crypto.createHash('md5');
  89. hash.update(paramStr);
  90. // 返回哈希值的十六进制表示
  91. return hash.digest('hex');
  92. }
  93. setHyToken(token){
  94. this.redis_help.setKeyValue("hei_yan_token",token)
  95. }
  96. async getHyToken (){
  97. return await this.redis_help.getKeyValue("hei_yan_token")
  98. }
  99. async getQMToken (){
  100. return await this.redis_help.getKeyValue("qi_mao_token")
  101. }
  102. async getQMMFToken (){
  103. return await this.redis_help.getKeyValue("qi_mao_mf_token")
  104. }
  105. getSupdate(){ //插入素材域名
  106. return config.isDebug?config.debug_supdate_config:config.release_supdate_config
  107. }
  108. getCheckDataBaseConfig(){
  109. return config.isDebug?config.debug_check_mysql:config.release_chekc_mysql
  110. }
  111. getDataBaseConfig(){
  112. return config.isDebug?config.debug_mysql:config.release_mysql
  113. }
  114. getTaskDataBaseConfig(){
  115. return config.isDebug?config.debug_task_mysql:config.release_task_mysql
  116. }
  117. getRandomElement(array) {
  118. const randomIndex = Math.floor(Math.random() * array.length);
  119. return array[randomIndex];
  120. }
  121. async getFqSidtt() {
  122. let sidtt = '01e060d0cc506bf1340dcb004aea1161'
  123. let list = await this.redis_help.getKeyValue("all_fq_key")
  124. if(list == null){
  125. return sidtt
  126. }
  127. list = JSON.parse(list)
  128. if(list.length<=0){
  129. return sidtt
  130. }
  131. let temp = []
  132. for (let index = 0; index < list.length; index++) {
  133. const sidtt = list[index];
  134. if(sidtt.canUse==1){
  135. temp.push(sidtt.sid_tt)
  136. }
  137. }
  138. return this.getRandomElement(temp)
  139. }
  140. async getFqMfSidtt() {
  141. let sidtt = '01e060d0cc506bf1340dcb004aea1161'
  142. let list = await this.redis_help.getKeyValue("all_fq_mf_key")
  143. if(list == null){
  144. return sidtt
  145. }
  146. list = JSON.parse(list)
  147. if(list.length<=0){
  148. return sidtt
  149. }
  150. let temp = []
  151. for (let index = 0; index < list.length; index++) {
  152. const sidtt = list[index];
  153. if(sidtt.canUse==1){
  154. temp.push(sidtt.sid_tt)
  155. }
  156. }
  157. return this.getRandomElement(temp)
  158. }
  159. async getYwOPENSESSID() {
  160. let open_sessid = '9077ffcc5ca974e2c0e78502a24c9053'
  161. let list = await this.redis_help.getKeyValue("all_yw_key")
  162. if(list == null){
  163. return open_sessid
  164. }
  165. list = JSON.parse(list)
  166. if(list.length<=0){
  167. return open_sessid
  168. }
  169. for (let index = 0; index < list.length; index++) {
  170. const yw_data = list[index];
  171. const old_time = yw_data.create_time;
  172. const current_time = moment();
  173. const past_time = moment(old_time);
  174. // 计算时间差(小时)
  175. const diff_hours = current_time.diff(past_time, 'hours');
  176. // 判断是否小于7小时
  177. const isLessThan7Hours = diff_hours < 7;
  178. if(isLessThan7Hours){
  179. this.redis_help.setKeyValue("OPENSESSID",yw_data.open_sessid)
  180. }else{
  181. this.redis_help.setKeyValue("OPENSESSID","")
  182. }
  183. return open_sessid
  184. }
  185. }
  186. getOneNewClinetBuffer(headers=null){
  187. return axios.create({
  188. timeout: 30000,
  189. headers:headers||{},
  190. responseType:"arraybuffer",
  191. // 使用独立的 agent,不影响其他连接
  192. httpAgent: new http.Agent({
  193. keepAlive: true,
  194. maxSockets: 5, // 允许适度的并发
  195. maxFreeSockets: 2,
  196. timeout: 30000
  197. }),
  198. validateStatus: function (status) {
  199. return status >= 200 && status < 300;
  200. }
  201. });
  202. }
  203. getOneNewClinet(headers=null){
  204. return axios.create({
  205. timeout: 30000,
  206. headers:headers||{},
  207. // 使用独立的 agent,不影响其他连接
  208. httpAgent: new http.Agent({
  209. keepAlive: true,
  210. maxSockets: 5, // 允许适度的并发
  211. maxFreeSockets: 2,
  212. timeout: 30000
  213. }),
  214. validateStatus: function (status) {
  215. return status >= 200 && status < 300;
  216. },
  217. transformResponse: [data => {
  218. try {
  219. // 将大数字存储为字符串
  220. return JSONbig({ storeAsString: true }).parse(data);
  221. // 或者使用 BigInt 类型(需要环境支持)
  222. // return JSONbig({ useNativeBigInt: true }).parse(data);
  223. } catch (e) {
  224. console.error('JSON 解析错误:', e);
  225. return data;
  226. }
  227. }]
  228. });
  229. }
  230. async getAppletProductDataByButlerId(butler_id,product_id,main_id){
  231. const taskdbConfig = config.isDebug?config.debug_task_mysql:config.release_task_mysql
  232. let connection = null
  233. try{
  234. connection = await mysql.createConnection({
  235. ...taskdbConfig,
  236. multipleStatements: true
  237. });
  238. const [rows] = await connection.execute(
  239. `SELECT * FROM video_applet_product_${butler_id} WHERE product_id = '${product_id}' AND main_id = ${main_id} LIMIT 1`
  240. );
  241. if(rows.length<=0){
  242. return null
  243. }
  244. return rows[0]
  245. }catch(e){
  246. console.error(e)
  247. return null
  248. }finally{
  249. if(connection!=null){
  250. await connection.end();
  251. }
  252. }
  253. }
  254. async setDzCookie(cookit){
  255. return this.redis_help.setKeyValue("DZ_COOKIT",cookit)
  256. }
  257. async getDzCookit(){
  258. return this.redis_help.getKeyValue("DZ_COOKIT")
  259. }
  260. zh_sign(body, app_secret) {
  261. // 1. 处理输入参数
  262. let requestBody = body;
  263. if (typeof body === 'string') {
  264. try {
  265. requestBody = JSON.parse(body);
  266. } catch (e) {
  267. throw new Error('Invalid JSON string');
  268. }
  269. }
  270. // 2. 获取所有参数名并排序
  271. const keys = Object.keys(requestBody).sort();
  272. // 3. 拼接键值对
  273. let s1 = '';
  274. keys.forEach(key => {
  275. // 处理值:如果是对象/数组则转为JSON字符串,否则直接使用
  276. const value = typeof requestBody[key] === 'object'
  277. ? JSON.stringify(requestBody[key])
  278. : String(requestBody[key]);
  279. s1 += key + value;
  280. });
  281. // 4. 追加app_secret
  282. const x1 = s1 + app_secret;
  283. console.log('拼接后的字符串 x1:', x1); // 调试用
  284. // 5. HmacSha256 签名
  285. const hmac = crypto.createHmac('sha256', app_secret);
  286. hmac.update(x1);
  287. const b1 = hmac.digest();
  288. // 6. Base64 编码
  289. const s2 = b1.toString('base64');
  290. // 7. 转为大写
  291. const signature = s2.toUpperCase();
  292. return signature;
  293. }
  294. isObject(value) {
  295. return typeof value === 'object' && value !== null;
  296. }
  297. getOriginVideoId(url){
  298. const match = url.match(/\/video\/(\d+)/);
  299. // 2. 提取结果
  300. const videoId = match ? match[1] : null;
  301. return videoId
  302. }
  303. getPreviousDay(dateString) {
  304. // 将传入的字符串转换为 Date 对象
  305. const date = new Date(dateString);
  306. // 获取前一天的日期
  307. const previousDay = new Date(date);
  308. previousDay.setDate(date.getDate() - 1);
  309. // 格式化为 YYYY-MM-DD 字符串
  310. const year = previousDay.getFullYear();
  311. const month = String(previousDay.getMonth() + 1).padStart(2, '0');
  312. const day = String(previousDay.getDate()).padStart(2, '0');
  313. return `${year}-${month}-${day}`;
  314. }
  315. }
  316. module.exports = new tools(require('./src/use_redis'));