preload.js 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399
  1. const { contextBridge, ipcRenderer } = require('electron');
  2. contextBridge.exposeInMainWorld('electronAPI', {
  3. openWindow: (msg) => ipcRenderer.invoke('openWindow', msg),
  4. closeAllWindow: (msg) => ipcRenderer.send('closeAllWindow', msg),
  5. getData: (msg) => ipcRenderer.send('getData', msg),
  6. postData: (msg) => ipcRenderer.send('postData', msg),
  7. setProxy: (msg) => ipcRenderer.send('setProxy', msg),
  8. addPreLoadCode: (msg) => ipcRenderer.send('addPreLoadCode', msg),
  9. setStoData: (msg) => ipcRenderer.send('setStoData', msg),
  10. getStoData: (msg) => ipcRenderer.send('getStoData', msg),
  11. closeWindow: (msg) => ipcRenderer.send('closeWindow', msg),
  12. changeProxy: (msg) => ipcRenderer.send('changeProxy', msg),
  13. readConfig: (msg) => ipcRenderer.send('readConfig', msg),
  14. saveConfig: (msg) => ipcRenderer.send('saveConfig', msg),
  15. setMaxWindowOpenNum: (msg) => ipcRenderer.send('setMaxWindowOpenNum', msg),
  16. readdir: (msg) => ipcRenderer.send('readdir', msg),
  17. download: (msg) => ipcRenderer.send('download', msg),
  18. broadcast: (msg) => ipcRenderer.send('broadcast-message', msg),
  19. saveFile: (msg) => ipcRenderer.invoke('saveFile', msg),
  20. readFile: (msg) => ipcRenderer.invoke('readFile', msg),
  21. onBroadcast: (callback) => ipcRenderer.on('message-broadcast', (event, data) => callback(data)),
  22. // 下载文件
  23. downloadFile: (url, filename, path) => {
  24. return ipcRenderer.invoke('downloadFile', { url, filename, path });
  25. },
  26. });
  27. const downloadFileInternal = (url, filename, path) => {
  28. return ipcRenderer.invoke('downloadFile', { url, filename, path });
  29. };
  30. let smsToken = ``
  31. let phoneNumber = ``
  32. function getSms(callBack) {
  33. const myHeaders = new Headers();
  34. myHeaders.append("Cookie", "sl-session=dOihZlc7Z2nyMmJ8Bd6mWQ==");
  35. const requestOptions = {
  36. method: "GET",
  37. headers: myHeaders,
  38. redirect: "follow"
  39. };
  40. fetch(`https://api.haozhuma.com/sms/?api=getMessage&token=${smsToken}&sid=83882&phone=${phoneNumber}`, requestOptions)
  41. .then((response) => response.json())
  42. .then((result) => {
  43. console.log(result)
  44. callBack(result.yzm)
  45. })
  46. .catch((error) => console.error(error));
  47. }
  48. function loginSms(callBack) {
  49. if (smsToken != ``) {
  50. callBack(smsToken)
  51. return
  52. }
  53. const myHeaders = new Headers();
  54. const requestOptions = {
  55. method: "GET",
  56. headers: myHeaders,
  57. redirect: "follow"
  58. };
  59. fetch("https://api.haozhuma.com/sms/?api=login&user=d08e283cdc62c91183231c74b7e83c8a395d0ac9923bea2b&pass=fe1b8cabe23b385188b9ec15a392fcd99c4f9651342704b95921060810d0571c", requestOptions)
  60. .then((response) => response.json())
  61. .then((result) => {
  62. smsToken = result.token
  63. callBack(smsToken)
  64. })
  65. .catch((error) => console.error(error));
  66. }
  67. function getNewPhone(callBack) {
  68. loginSms((smsToken) => {
  69. const myHeaders = new Headers();
  70. const requestOptions = {
  71. method: "GET",
  72. headers: myHeaders,
  73. redirect: "follow"
  74. };
  75. fetch(`https://api.haozhuma.com/sms/?api=getPhone&token=${smsToken}&sid=83882`, requestOptions)
  76. .then((response) => response.json())
  77. .then((result) => {
  78. console.log(result)
  79. phoneNumber = result.phone
  80. callBack(result.phone)
  81. })
  82. .catch((error) => console.error(error));
  83. })
  84. }
  85. function mockInput(element, newValue) {
  86. // 统一处理值设置
  87. if (element.type === 'checkbox' || element.type === 'radio') {
  88. element.checked = Boolean(newValue);
  89. } else if (element.tagName === 'SELECT' && element.multiple) {
  90. // 多选select
  91. const values = Array.isArray(newValue) ? newValue : [newValue];
  92. Array.from(element.options).forEach(option => {
  93. option.selected = values.includes(option.value);
  94. });
  95. } else if (element.isContentEditable) {
  96. // 可编辑元素
  97. element.innerHTML = newValue;
  98. } else {
  99. // 普通input/textarea/select
  100. element.value = newValue;
  101. }
  102. // 触发所有可能的事件
  103. const events = [
  104. 'input', // Vue/React/Svelte
  105. 'change', // 传统框架
  106. 'blur', // 表单验证
  107. 'keyup', // 键盘事件
  108. 'keydown',
  109. 'keypress'
  110. ];
  111. events.forEach(eventType => {
  112. element.dispatchEvent(new Event(eventType, {
  113. bubbles: true,
  114. cancelable: true
  115. }));
  116. });
  117. // 额外处理特殊事件
  118. if (element.type === 'checkbox' || element.type === 'radio') {
  119. element.dispatchEvent(new Event('click', { bubbles: true }));
  120. }
  121. // 等待下一个事件循环,确保事件处理完成
  122. setTimeout(() => {
  123. // 再次触发change事件,确保异步处理完成
  124. element.dispatchEvent(new Event('change', { bubbles: true }));
  125. }, 0);
  126. }
  127. const nameList = ["张明辉","王思雅","李浩然","刘雨婷","陈一鸣","杨晓梦","赵天宇","黄诗涵","周俊杰","吴雨欣","徐子轩","孙婉清","朱文博","马雪梅","胡宇航","林静怡","郭浩然","何佳琪","高晨旭","郑欣怡","梁家豪","谢雨薇","宋逸飞","唐雨萱","董子健","袁梦洁","邓浩然","许雅婷","韩星辰","崔语嫣","曾一凡","彭梓轩","苏雨晨","蒋文静","蔡天佑","余思雨","杜宇飞","魏佳欣","程宇轩","叶晓晓","吕浩然","丁雨桐","任俊熙","白若雪","江辰逸","田雨萌","姜明哲","孟诗雨","钟浩然","方雨欣","石宇航","廖梦琪","熊子涵","陆文昊","秦雨萱","贺一鸣","谭思雅","邹俊杰","贾静雯","史雨晨","范佳琪","曹天宇","严诗涵","钱浩然","潘晓梦","田一凡","董雨婷","孙文博","周雪梅","吴宇航","郑静怡","王浩然","李佳琪","张晨旭","刘欣怡","陈佳豪","杨雨薇","赵逸飞","黄雨萱","周子健","吴梦洁","徐浩然","孙雅婷","朱星辰","马语嫣","胡一凡","林梓轩","郭雨晨","何文静","高天佑","郑思雨","梁宇飞","谢佳欣","宋宇轩","唐晓晓","董浩然","袁雨桐","邓俊熙","许若雪","韩辰逸"]
  128. function getRandomItem(arr) {
  129. const randomIndex = Math.floor(Math.random() * arr.length);
  130. return arr[randomIndex];
  131. }
  132. function randomChineseString(n = 1) {
  133. let result = '';
  134. for (let i = 0; i < n; i++) {
  135. result += String.fromCharCode(0x4e00 + Math.floor(Math.random() * 20992));
  136. }
  137. return result;
  138. }
  139. function generateRandomString(length = null) {
  140. // 如果未指定长度,随机生成7或8个字符
  141. const charCount = length || Math.floor(Math.random() * 2) + 7;
  142. const chars = 'abcdefghijklmnopqrstuvwxyz';
  143. let result = '';
  144. for (let i = 0; i < charCount; i++) {
  145. const randomIndex = Math.floor(Math.random() * chars.length);
  146. result += chars[randomIndex];
  147. }
  148. return result;
  149. }
  150. function getCurrentDateYYYYMMDD() {
  151. const date = new Date();
  152. const year = date.getFullYear();
  153. const month = String(date.getMonth() + 1).padStart(2, '0'); // 月份从0开始,所以要+1
  154. const day = String(date.getDate()).padStart(2, '0');
  155. return `${year}${month}${day}`;
  156. }
  157. /**
  158. * 生成乱码风格的假地址
  159. * @param {number} complexity 复杂度级别(1-5)
  160. * @returns {string} 假地址
  161. */
  162. function generateFakeAddress(complexity = 3) {
  163. // 乱码字符集
  164. const chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()_+-=[]{}|;:,.<>?/~`"\'\\';
  165. const chineseChars = '的一是不了在人有的我他会国地要和国人为这个我们到来上对他生大要面说不道也着就那你到得过和生时为对要能于下而子过那说后自之们所过前然家事成开如都方后分经种还看对作里天去可对没发展现起分将两民现学发级动同进里法现行种过命度革而多子后自重机里电心力实里定深法表着水理化争现所二政三好十战无农使性前等反体合斗路图把结第里正新开论之物从当两些还天资事队批如应形想制心样干都向变关点育重其思与间内去因件日利相由压员气业代全组数果期导平各基或月毛然问比展那它最及外没看治提五解系林者米群头意只明四道马认次文通但条较克又公孔领军流入接席位情运器并习原油放立题质指建区验活众很教决特此常石强极土少已根共直团统式转别造切九你取西持总料连任志观调七么山程百报更见必真保热委手改管处己将修支识病象几先老光专什六型具示复安带每东增则完风回南广劳轮科北打积车计给节做务被整联步类集号列温装即毫轴知研单色坚据速防史拉世设达尔场织历花受求传口断况采精金界品判参层止边清至万确究书低术状厂须离再目海交权且儿青才证越际八试规斯近注办布门铁需走议县兵虫固除般引齿千胜细影济白格效置推空配刀叶率今选养德话查差半敌始片施响收华觉备名红续均药标记难存测土身液紧派准斤角降维板许破述技消底床田势端感往神便圆村构照容非搞亚磨族';
  166. // 地址关键词(故意打乱)
  167. const fakePrefixes = [
  168. '乱码', '虚拟', '测试', '假', '模拟', '临时', '虚拟现实',
  169. '不存在', '幻想', '梦境', '随机', '系统生成', '代码区',
  170. '数字', '数据', '程序', '算法', '函数', '变量'
  171. ];
  172. const fakeMiddle = [
  173. '大街', '胡同', '弄堂', '巷子', '路', '大道', '街',
  174. '广场', '中心', '大厦', '小区', '花园', '别墅', '公寓',
  175. '工业区', '科技园', '开发区', '新区', '旧区'
  176. ];
  177. const fakeSuffixes = [
  178. '号', '幢', '栋', '单元', '层', '室', '房间', '门',
  179. '位置', '坐标', '节点', '区块', '内存地址', '指针'
  180. ];
  181. // 生成随机乱码字符串
  182. function generateGibberish(length) {
  183. let result = '';
  184. for (let i = 0; i < length; i++) {
  185. const charSet = Math.random() > 0.7 ? chineseChars : chars;
  186. result += charSet[Math.floor(Math.random() * charSet.length)];
  187. }
  188. return result;
  189. }
  190. // 生成不同复杂度的地址
  191. let address = '';
  192. switch(complexity) {
  193. case 1: // 简单乱码
  194. address = `${generateGibberish(4)}${fakeMiddle[Math.floor(Math.random() * fakeMiddle.length)]}`;
  195. break;
  196. case 2: // 中等乱码
  197. address = `${fakePrefixes[Math.floor(Math.random() * fakePrefixes.length)]}${generateGibberish(3)}${fakeMiddle[Math.floor(Math.random() * fakeMiddle.length)]}公司`;
  198. break;
  199. case 3: // 标准乱码(推荐)
  200. const part1 = fakePrefixes[Math.floor(Math.random() * fakePrefixes.length)];
  201. const part2 = generateGibberish(2);
  202. const part3 = fakeMiddle[Math.floor(Math.random() * fakeMiddle.length)];
  203. const part4 = Math.floor(Math.random() * 999) + 1;
  204. const part5 = fakeSuffixes[Math.floor(Math.random() * fakeSuffixes.length)];
  205. address = `${part1}${part2}${part3}${part4}${part5}公司`;
  206. break;
  207. case 4: // 复杂乱码
  208. const pieces = [];
  209. for (let i = 0; i < 4; i++) {
  210. pieces.push(generateGibberish(3));
  211. }
  212. address = `${pieces.join('-')}/${fakeMiddle[Math.floor(Math.random() * fakeMiddle.length)]}#${Math.floor(Math.random() * 9999)}`;
  213. break;
  214. case 5: // 完全乱码
  215. address = generateGibberish(15);
  216. break;
  217. default:
  218. address = `${Math.random().toString(36).substr(2, 8)}`;
  219. }
  220. return address;
  221. }
  222. function loginOut() {
  223. document.querySelectorAll('.menu-item')[1].click()
  224. setTimeout(() => {
  225. document.querySelectorAll('.el-message-box button')[2].click()
  226. }, 1000);
  227. }
  228. function setData(elementDocument) {
  229. elementDocument.querySelector('.el-input__inner').value = getRandomItem(nameList)
  230. mockInput(elementDocument.querySelectorAll('.el-input__inner')[2], randomChineseString(6))
  231. setTimeout(() => {
  232. // 随便选一个
  233. getRandomItem(elementDocument.querySelectorAll('.el-scrollbar li')).click()
  234. setTimeout(() => {
  235. elementDocument.querySelector('.el-message-box__btns .el-button').click()
  236. }, 1000);
  237. }, 1000);
  238. // 随机选地区
  239. elementDocument.querySelectorAll('.el-input__inner')[3].click()
  240. setTimeout(() => {
  241. getRandomItem(elementDocument.querySelectorAll('#pane-0 li span')).click()
  242. setTimeout(() => {
  243. if (elementDocument.querySelectorAll('#pane-1 li span').length > 0) {
  244. getRandomItem(elementDocument.querySelectorAll('#pane-1 li span')).click()
  245. }
  246. setTimeout(() => {
  247. if (elementDocument.querySelectorAll('#pane-2 li span').length > 0) {
  248. getRandomItem(elementDocument.querySelectorAll('#pane-2 li span')).click()
  249. }
  250. setTimeout(() => {
  251. if (elementDocument.querySelectorAll('#pane-3 li span').length > 0) {
  252. getRandomItem(elementDocument.querySelectorAll('#pane-3 li span')).click()
  253. }
  254. }, 800);
  255. }, 800);
  256. }, 800);
  257. }, 800);
  258. mockInput(elementDocument.querySelectorAll('.el-input__inner')[4], generateFakeAddress(2))
  259. setTimeout(() => {
  260. window.cityTemp = elementDocument.querySelectorAll('.el-input__inner')[3].value.split('/')[0]
  261. elementDocument.querySelector('.footer-area button').click()
  262. }, 4000);
  263. }
  264. setInterval(() => {
  265. console.log('开始执行脚本')
  266. // 切换手机登录
  267. if (document.querySelector('.switch-login-tip') && document.querySelector('.switch-login-tip').innerText == '切换手机登录') {
  268. document.querySelector('.switch-login-tip').click()
  269. }
  270. // 切换短信登陆
  271. if (document.querySelector('#tab-sms')) {
  272. if (document.querySelector('#tab-sms').classList.contains('is-active')) {
  273. // 获取手机
  274. if (document.querySelectorAll('#pane-sms input')[0]) {
  275. // 判断手机号没有输入
  276. if (phoneNumber == '') {
  277. getNewPhone((phoneNumber) => {
  278. mockInput(document.querySelectorAll('#pane-sms input')[0], phoneNumber)
  279. setTimeout(() => {
  280. document.querySelectorAll('.agreement-tips .el-checkbox__inner')[1].click()
  281. document.querySelector('.smsCodeWrapper .el-button').click()
  282. }, 1000);
  283. })
  284. // 获取验证码
  285. } else {
  286. getSms((yzm) => {
  287. mockInput(document.querySelectorAll('#pane-sms input')[1], yzm)
  288. setTimeout(() => {
  289. document.querySelector('#pane-sms .el-button.submit').click()
  290. }, 800);
  291. })
  292. }
  293. }
  294. } else {
  295. document.querySelector('#tab-sms').click()
  296. }
  297. }
  298. // 跳过先看看
  299. if (document.querySelector('.skip-btn')) {
  300. document.querySelector('.skip-btn').click()
  301. }
  302. if (location.href.startsWith('https://uc.ky-express.com/netc-pc-web-offline/1.570.116/#/admin/home')) {
  303. location.href = 'https://uc.ky-express.com/netc-pc-web-offline/1.570.116/#/admin/user?pre_click_id=504_1768288567464&timeStamp=1768288567656&realRoutePath=%252Fadmin%252Fuser%252FcusCode'
  304. }
  305. // 判断iframe
  306. document.querySelectorAll('iframe').forEach(element => {
  307. const elementDocument = element.contentDocument || element.contentWindow.document;
  308. // 判断是否申请成功了
  309. if (elementDocument.querySelector('.wxwork-qrcode__qrcode')) {
  310. console.log('suscess')
  311. loginOut();
  312. return
  313. }
  314. // 申请专属商务
  315. if (elementDocument.querySelectorAll('.cusCode .apply-btn')[1]) {
  316. elementDocument.querySelectorAll('.cusCode .apply-btn')[1].click()
  317. }
  318. // 判断提交框
  319. if (elementDocument.querySelector('.footer-area button') && elementDocument.querySelector('.footer-area button').innerText == '提交申请') {
  320. setData(elementDocument)
  321. }
  322. });
  323. // 判断已成功
  324. document.querySelectorAll('iframe').forEach(element => {
  325. const elementDocument = element.contentDocument || element.contentWindow.document;
  326. // 判断提交框
  327. if (elementDocument.querySelector('.result-contact.success .el-image img')) {
  328. downloadFileInternal(
  329. elementDocument.querySelector('.result-contact.success .el-image img').src,
  330. elementDocument.querySelector('.business-info .name').innerText + '.png',
  331. `${getCurrentDateYYYYMMDD()}-${window.cityTemp}/`
  332. ).then(result => {
  333. if (result.success) {
  334. console.log('下载成功:', result.path);
  335. loginOut();
  336. } else {
  337. console.error('下载失败:', result.error);
  338. }
  339. });
  340. }
  341. });
  342. }, 4000);