tools.js 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552
  1. let fs = require("fs");
  2. let path = require("path");
  3. let packageCfg = require("../package.json")
  4. var http = require('http');
  5. var querystring = require('querystring');
  6. const inputType = { "text": 1, "password": 1, "number": 1, "date": 1, "color": 1, "range": 1, "month": 1, "week": 1, "time": 1, "email": 1, "search": 1, "url": 1, "textarea": 1 }
  7. let checkFsPath = new RegExp("\\.\\./", "g");
  8. let readFileQueue = []
  9. let readFileMaxCount = 50
  10. let readFileCount = 0
  11. module.exports = {
  12. // 不是输入状态是时
  13. inputTypeChk(e) {
  14. if (e.path[0]) {
  15. let type = e.path[0].type;
  16. if (inputType[type]) {
  17. return true
  18. }
  19. }
  20. },
  21. getLanguage(){
  22. return Editor.lang || window.navigator && window.navigator.language && window.navigator.language.split('-')[0];
  23. },
  24. // 更新i18翻译文本,解决creator不重启不会刷新修改问题
  25. initI18t(){
  26. let locale = this.getLanguage() || 'zh';
  27. let filePath = Editor.url('packages://simple-code/i18n/'+locale+'.js');
  28. if(!this.isFileExit(filePath)){
  29. return
  30. }
  31. let mapList = require(filePath);
  32. let converList = {}
  33. for (const key in mapList) {
  34. const converText = mapList[key];
  35. converList[packageCfg.name+'.'+key] = converText
  36. }
  37. Editor.i18n.extend(converList)
  38. },
  39. translate(key){
  40. return Editor.T(packageCfg.name+'.'+key)
  41. },
  42. translateZhAndEn(zeText,enText){
  43. return this.getLanguage() == 'zh' ? zeText : enText;
  44. },
  45. // 翻译中英文
  46. T(zeText,enText){
  47. return this.translateZhAndEn(zeText,enText);
  48. },
  49. isEmptyObject(obj){
  50. if(obj){
  51. for (const key in obj) {
  52. return false
  53. }
  54. }
  55. return true;
  56. },
  57. // 拷贝本对象方法到目标对象
  58. // newObj 子类
  59. // baseObj 父类
  60. // mergeFuncs = ["init"]; 新旧类的同名函数合并一起
  61. extendTo(newObj, baseObj, mergeFuncs = []) {
  62. if (!baseObj || !newObj) return;
  63. for (let k in baseObj) {
  64. let v = baseObj[k]
  65. if (newObj[k] == null) {
  66. newObj[k] = v
  67. }
  68. // 函数继承使用 "this._super()" 调用父类
  69. else if (typeof v == "function" && typeof newObj[k] == "function" && !newObj[k]._isExend) {
  70. let newFunc = newObj[k];
  71. newObj[k] = function () {
  72. this._super = v;
  73. let ret = newFunc.apply(this, arguments);// 执行函数并传入传参
  74. delete this._super;
  75. return ret;
  76. };
  77. newObj[k]._isExend = true
  78. }
  79. }
  80. },
  81. copyToClipboard(str) {
  82. var input = str;
  83. const el = document.createElement('textarea');
  84. el.value = input;
  85. el.setAttribute('readonly', '');
  86. el.style.contain = 'strict';
  87. el.style.position = 'absolute';
  88. el.style.left = '-9999px';
  89. el.style.fontSize = '12pt'; // Prevent zooming on iOS
  90. const selection = getSelection();
  91. var originalRange = false;
  92. if (selection.rangeCount > 0) {
  93. originalRange = selection.getRangeAt(0);
  94. }
  95. document.body.appendChild(el);
  96. el.select();
  97. el.selectionStart = 0;
  98. el.selectionEnd = input.length;
  99. var success = false;
  100. try {
  101. success = document.execCommand('copy');
  102. } catch (err) { }
  103. document.body.removeChild(el);
  104. if (originalRange) {
  105. selection.removeAllRanges();
  106. selection.addRange(originalRange);
  107. }
  108. return success;
  109. },
  110. parseJson(text){
  111. try {
  112. return JSON.parse(text)
  113. } catch (error) {
  114. return undefined;
  115. }
  116. },
  117. objectCount(obj){
  118. let len = 0
  119. for (const key in obj) {
  120. len++
  121. }
  122. return len;
  123. },
  124. // 获得import路径
  125. getImportStringPaths(codeText) {
  126. var regEx = /(require\(|import |reference path=)(.{0,}['"])(.+)['"]/g;
  127. var match = regEx.exec(codeText);
  128. var imports = []
  129. while (match) {
  130. let start = match.index + match[1].length + match[2].length;
  131. imports.push({
  132. path: match[3],
  133. start: start,
  134. length: match[3].length,
  135. })
  136. match = regEx.exec(codeText);
  137. }
  138. return imports
  139. },
  140. //将相对路径转为绝对路径
  141. relativePathTofsPath(absolutePath, relativePath) {
  142. var uplayCount = 0; // 相对路径中返回上层的次数。
  143. var m = relativePath.match(checkFsPath);
  144. if (m) uplayCount = m.length;
  145. var lastIndex = absolutePath.length - 1;
  146. var subString = absolutePath
  147. for (var i = 0; i <= uplayCount; i++) {
  148. lastIndex = subString.lastIndexOf("/", lastIndex);
  149. subString = subString.substr(0, lastIndex)
  150. }
  151. return this.normPath( subString + "/" + relativePath.substr(relativePath.lastIndexOf('./') + 2));
  152. },
  153. //将绝对路径转为相对路径
  154. fsPathToRelativePath(currPath, importPath) {
  155. let s_i = currPath.lastIndexOf('/')
  156. if (s_i != -1) currPath = currPath.substr(0, s_i);
  157. let relativePath = path.relative(currPath, importPath);
  158. if (relativePath[0] != '.') {
  159. relativePath = './' + relativePath;
  160. }
  161. return this.normPath(relativePath);
  162. },
  163. //转换相对路径
  164. converRelative(relativePath, oldFilePath, newFilePath) {
  165. let s_i = oldFilePath.lastIndexOf('/')
  166. if (s_i != -1) oldFilePath = oldFilePath.substr(0, s_i);
  167. s_i = newFilePath.lastIndexOf('/')
  168. if (s_i != -1) newFilePath = newFilePath.substr(0, s_i);
  169. let rve_to_abs = this.normPath(path.resolve(oldFilePath, relativePath));
  170. relativePath = this.normPath(path.relative(newFilePath, rve_to_abs));
  171. if (relativePath[0] != '.') {
  172. relativePath = './' + relativePath;
  173. }
  174. return relativePath;
  175. },
  176. normPath(filePath) {
  177. return filePath.replace(/\\/g, '/');
  178. },
  179. // 异步读取文件
  180. readFileAsyn(filePath,callback)
  181. {
  182. let args = {filePath,callback};
  183. readFileQueue.push(args)
  184. // 最多同时读取50个文件
  185. readFileCount++;
  186. if(readFileCount >= readFileMaxCount){
  187. // console.log("readFileAsyn:读取超出最大文件数量",readFileCount);
  188. return;
  189. }
  190. this._handleReadFileQueue()
  191. },
  192. // 处理 readFileAsyn 队列
  193. _handleReadFileQueue(){
  194. // 1 == Math.min(50,1)
  195. let len = Math.min( readFileMaxCount , readFileQueue.length );
  196. for (let i = 0; i < len; i++) {
  197. // 处理队列
  198. let args = readFileQueue.splice(0,1)[0];
  199. fs.readFile(args.filePath,(err,data)=>
  200. {
  201. readFileCount--
  202. if(readFileCount > 500){
  203. setTimeout(this._handleReadFileQueue.bind(this),100)
  204. }else{
  205. this._handleReadFileQueue()
  206. }
  207. try {
  208. args.callback(err,data);
  209. } catch (error) {
  210. console.log(error)
  211. }
  212. })
  213. }
  214. },
  215. copyFile(sourcePath, toPath) {
  216. fs.writeFileSync(toPath, fs.readFileSync(sourcePath))
  217. },
  218. // copyFile(sourcePath,toPath){
  219. // fs.readFile(sourcePath,function(err,data){
  220. // if(err) throw new Error('复制失败:'+sourcePath+" TO "+data);
  221. // fs.writeFile(toPath,data,function(err){
  222. // if(err) throw new Error('复制写入失败'+sourcePath+" TO "+data);
  223. // })
  224. // })
  225. // },
  226. moveDir(sourcePath, toPath) {
  227. if (!fs.existsSync(sourcePath)) {
  228. console.log("不存在目录:", sourcePath);
  229. return;
  230. }
  231. if (sourcePath[sourcePath.length - 1] != path.sep) {
  232. sourcePath += path.sep;// 加猴嘴
  233. }
  234. if (toPath[toPath.length - 1] != path.sep) {
  235. toPath += path.sep;// 加猴嘴
  236. }
  237. let list = this.getDirAllFiles(sourcePath, []);
  238. list.forEach((fileName, i) => {
  239. let toFilePath = fileName.replace(sourcePath, toPath);
  240. console.log("执行:", fileName, toFilePath);
  241. let dirName = path.dirname(toFilePath);
  242. this.createDir(dirName);
  243. // 移动文件
  244. fs.renameSync(fileName, toFilePath);
  245. })
  246. },
  247. createDir(dirPath) {
  248. if (fs.existsSync(dirPath)) return;
  249. let paths = dirPath.split(path.sep);//分割路径
  250. let path_ = "";
  251. // c:\
  252. let n = 0
  253. let max = paths.length
  254. if (paths[0].indexOf(":") != -1) {
  255. path_ = paths[0];
  256. n++;
  257. }
  258. if (paths[max - 1].indexOf(".") != -1) {
  259. max--;
  260. }
  261. for (n; n < max; n++) {
  262. path_ += path.sep + paths[n];
  263. if (!fs.existsSync(path_)) {
  264. fs.mkdirSync(path_);
  265. }
  266. }
  267. },
  268. // 获得文件夹列表
  269. getDirList(dirPath, result) {
  270. let files = fs.readdirSync(dirPath);
  271. files.forEach((val, index) => {
  272. let fPath = path.join(dirPath, val);
  273. if (fs.existsSync(fPath) && fs.statSync(fPath).isDirectory()) {
  274. result.push(fPath);
  275. }
  276. });
  277. return result;
  278. },
  279. // 获得文件列表
  280. getFileList(dirPath, result = []) {
  281. let files = fs.readdirSync(dirPath);
  282. files.forEach((val, index) => {
  283. let fPath = path.join(dirPath, val);
  284. if (fs.existsSync(fPath) && fs.statSync(fPath).isFile()) {
  285. result.push(fPath);
  286. }
  287. });
  288. return result;
  289. },
  290. isDirectory(fPath) {
  291. return fs.existsSync(fPath) && fs.statSync(fPath).isDirectory()
  292. },
  293. getDirAllFiles(dirPath, result = []) {
  294. let files = fs.readdirSync(dirPath);
  295. files.forEach((val, index) => {
  296. let fPath = path.join(dirPath, val);
  297. if (fs.existsSync(fPath) && fs.statSync(fPath).isDirectory()) {
  298. this.getDirAllFiles(fPath, result);
  299. } else if (fs.statSync(fPath).isFile()) {
  300. result.push(fPath);
  301. }
  302. });
  303. return result;
  304. },
  305. getFileString(fileList, options) {
  306. let curIndex = 0;
  307. let totalIndex = fileList.length;
  308. let str = {};
  309. for (let key in fileList) {
  310. let filePath = fileList[key];
  311. let b = this._isFileExit(filePath);
  312. if (b) {
  313. fs.readFile(filePath, 'utf-8', function (err, data) {
  314. if (!err) {
  315. self._collectString(data, str);
  316. } else {
  317. console.log("error: " + filePath);
  318. }
  319. self._onCollectStep(filePath, ++curIndex, totalIndex, str, options);
  320. })
  321. } else {
  322. self._onCollectStep(filePath, ++curIndex, totalIndex, str, options);
  323. }
  324. }
  325. },
  326. _onCollectStep(filePath, cur, total, str, data) {
  327. if (data && data.stepCb) {
  328. data.stepCb(filePath, cur, total);
  329. }
  330. if (cur >= total) {
  331. self._onCollectOver(str, data);
  332. }
  333. },
  334. _onCollectOver(collectObjArr, data) {
  335. let strArr = [];
  336. let str = "";
  337. for (let k in collectObjArr) {
  338. str += k;
  339. strArr.push(k);
  340. }
  341. // console.log("一共有" + strArr.length + "个字符, " + strArr);
  342. console.log("一共有" + strArr.length + "个字符");
  343. if (data && data.compCb) {
  344. data.compCb(str);
  345. }
  346. },
  347. mkDir(path) {
  348. try {
  349. fs.mkdirSync(path);
  350. } catch (e) {
  351. if (e.code !== 'EEXIST') throw e;
  352. }
  353. },
  354. isFileExit(file) {
  355. try {
  356. fs.accessSync(file, fs.F_OK);
  357. } catch (e) {
  358. return false;
  359. }
  360. return true;
  361. },
  362. async isFileExitAsync(file) {
  363. return new Promise((resolev)=>{
  364. fs.access(file,(err)=>{
  365. resolev(err == null);
  366. });
  367. });
  368. },
  369. _collectString(data, collectObject) {
  370. for (let i in data) {
  371. let char = data.charAt(i);
  372. if (collectObject[char]) {
  373. collectObject[char]++;
  374. } else {
  375. collectObject[char] = 1;
  376. }
  377. }
  378. },
  379. emptyDir(rootFile) {
  380. //删除所有的文件(将所有文件夹置空)
  381. let emptyDir = function (fileUrl) {
  382. let files = fs.readdirSync(fileUrl);//读取该文件夹
  383. for (let k in files) {
  384. let filePath = path.join(fileUrl, files[k]);
  385. let stats = fs.statSync(filePath);
  386. if (stats.isDirectory()) {
  387. emptyDir(filePath);
  388. } else {
  389. fs.unlinkSync(filePath);
  390. console.log("删除文件:" + filePath);
  391. }
  392. }
  393. };
  394. //删除所有的空文件夹
  395. let rmEmptyDir = function (fileUrl) {
  396. let files = fs.readdirSync(fileUrl);
  397. if (files.length > 0) {
  398. for (let k in files) {
  399. let rmDir = path.join(fileUrl, files[k]);
  400. rmEmptyDir(rmDir);
  401. }
  402. if (fileUrl !== rootFile) {// 不删除根目录
  403. fs.rmdirSync(fileUrl);
  404. console.log('删除空文件夹' + fileUrl);
  405. }
  406. } else {
  407. if (fileUrl !== rootFile) {// 不删除根目录
  408. fs.rmdirSync(fileUrl);
  409. console.log('删除空文件夹' + fileUrl);
  410. }
  411. }
  412. };
  413. emptyDir(rootFile);
  414. rmEmptyDir(rootFile);
  415. },
  416. /*
  417. is_fileType($('#uploadfile').val(), 'doc,pdf,txt,wps,odf,md,png,gif,jpg')
  418. * */
  419. is_fileType(filename, types) {
  420. types = types.split(',');
  421. let pattern = '\.(';
  422. for (let i = 0; i < types.length; i++) {
  423. if (0 !== i) {
  424. pattern += '|';
  425. }
  426. pattern += types[i].trim();
  427. }
  428. pattern += ')$';
  429. return new RegExp(pattern, 'i').test(filename);
  430. },
  431. getFileName(filePath) {
  432. let s_i = filePath.lastIndexOf('/');
  433. if (s_i == -1) s_i = filePath.lastIndexOf('\\');
  434. let name = filePath
  435. if (s_i != -1) name = name.substr(s_i + 1)
  436. s_i = name.lastIndexOf('.');
  437. if (s_i != -1) {
  438. name = name.substr(0, s_i)
  439. }
  440. return name;
  441. },
  442. getFileExtname(filePath) {
  443. let s_i = filePath.lastIndexOf('.');
  444. let extname = ""
  445. if (s_i != -1) {
  446. extname = filePath.substr(s_i).toLowerCase()
  447. }
  448. return extname;
  449. },
  450. getUrlInfo(url) {
  451. let s_i = url.lastIndexOf('/');
  452. if (s_i == -1) s_i = url.lastIndexOf('\\');
  453. let name = ""
  454. if (s_i != -1) name = url.substr(s_i + 1)
  455. s_i = name.lastIndexOf('.');
  456. let extname = ""
  457. if (s_i != -1) {
  458. extname = name.substr(s_i).toLowerCase()
  459. }
  460. return { name, extname, url }
  461. },
  462. httpPost(ip,path,port,args,callback){
  463. var options = {
  464. hostname: ip,
  465. port: port,
  466. path: path,
  467. method: 'POST',
  468. headers: {
  469. 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
  470. }
  471. };
  472. var req = http.request(options, function (res) {
  473. // console.log('STATUS: ' + res.statusCode);
  474. // console.log('HEADERS: ' + JSON.stringify(res.headers));
  475. res.setEncoding('utf8');
  476. res.on('data', function (chunk) {
  477. if(callback) callback(chunk);
  478. });
  479. });
  480. req.on('error', function (e) {
  481. if(callback) callback();
  482. });
  483. // write data to request body
  484. var content = querystring.stringify(args);
  485. req.write(content);
  486. req.end();
  487. },
  488. }