common.js 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437
  1. import axios from "axios";
  2. export const uuid = (len = 16, radix = 10) => {
  3. const chars =
  4. "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".split("");
  5. const uuid = [];
  6. let i;
  7. radix = radix || chars.length;
  8. if (len) {
  9. // Compact form
  10. for (i = 0; i < len; i++) uuid[i] = chars[0 | (Math.random() * radix)];
  11. } else {
  12. // rfc4122, version 4 form
  13. let r;
  14. // rfc4122 requires these characters
  15. uuid[8] = uuid[13] = uuid[18] = uuid[23] = "-";
  16. uuid[14] = "4";
  17. // Fill in random data. At i==19 set the high bits of clock sequence as
  18. // per rfc4122, sec. 4.1.5
  19. for (i = 0; i < 36; i++) {
  20. if (!uuid[i]) {
  21. r = 0 | (Math.random() * 16);
  22. uuid[i] = chars[i === 19 ? (r & 0x3) | 0x8 : r];
  23. }
  24. }
  25. }
  26. return uuid.join("");
  27. };
  28. export const copy = (data) => {
  29. var copy = document.createElement("p");
  30. copy.innerText = data;
  31. document.body.append(copy);
  32. var range = document.createRange();
  33. range.selectNode(copy);
  34. var selection = window.getSelection();
  35. if (selection) {
  36. if (selection.rangeCount > 0) selection.removeAllRanges();
  37. selection.addRange(range);
  38. }
  39. document.execCommand("copy");
  40. document.body.removeChild(copy);
  41. };
  42. /**
  43. *
  44. * @param {object} positionData {
  45. * centerPosition:{x: x, y: y} 圆心坐标
  46. * originPosition:{x: x, y: y} 初始坐标
  47. * rotate: rotate 旋转角度
  48. * }
  49. * @description 根据圆心坐标、旋转角度计算旋转后的坐标
  50. */
  51. export const getRotatePosition = (positionData) => {
  52. const radian = (Math.PI / 180) * positionData.rotate;
  53. return {
  54. x:
  55. (positionData.originPosition.x - positionData.centerPosition.x) *
  56. Math.cos(radian) -
  57. (positionData.originPosition.y - positionData.centerPosition.y) *
  58. Math.sin(radian) +
  59. positionData.centerPosition.x,
  60. y:
  61. (positionData.originPosition.y - positionData.centerPosition.y) *
  62. Math.cos(radian) +
  63. (positionData.originPosition.x - positionData.centerPosition.x) *
  64. Math.sin(radian) +
  65. positionData.centerPosition.y,
  66. };
  67. };
  68. /**
  69. * @description 防抖
  70. * @param {*} fn
  71. * @param {*} wait
  72. * @returns
  73. */
  74. export function _debounce(fn, wait = 500) {
  75. let timer;
  76. return function () {
  77. const context = this;
  78. const args = arguments;
  79. if (timer) clearTimeout(timer);
  80. timer = setTimeout(() => {
  81. fn.apply(context, args);
  82. }, wait);
  83. };
  84. }
  85. /**
  86. * @description 节流
  87. * @param {*} fn
  88. * @param {*} wait
  89. * @returns
  90. */
  91. export function _throttle(fn, wait = 500) {
  92. let last, timer, now;
  93. return function () {
  94. now = Date.now();
  95. if (last && now - last < wait) {
  96. clearTimeout(timer);
  97. timer = setTimeout(function () {
  98. last = now;
  99. fn.call(this, ...arguments);
  100. }, wait);
  101. } else {
  102. last = now;
  103. fn.call(this, ...arguments);
  104. }
  105. };
  106. }
  107. /**
  108. * @param {Array} permissionList
  109. * @param {String} routerName
  110. * @description 判断是否有权限
  111. */
  112. export const hasPermission = (permissionList, routerName) => {
  113. return permissionList.some((permission) => {
  114. if (permission.code === routerName) {
  115. return true;
  116. } else {
  117. return (
  118. permission.children &&
  119. permission.children.length &&
  120. permission.children.find((child) => {
  121. if (child.code === routerName) {
  122. return true;
  123. }
  124. })
  125. );
  126. }
  127. });
  128. };
  129. export const downloadPDF = (url, fileName) => {
  130. axios({
  131. url: url,
  132. method: "GET",
  133. responseType: "blob", // 将响应类型设置为 blob
  134. })
  135. .then((response) => {
  136. const blob = new Blob([response.data], { type: "application/pdf" });
  137. const link = document.createElement("a");
  138. link.href = URL.createObjectURL(blob);
  139. link.download = fileName || "download.pdf";
  140. document.body.appendChild(link);
  141. link.click();
  142. document.body.removeChild(link);
  143. URL.revokeObjectURL(link.href); // 释放 Blob URL 资源
  144. })
  145. .catch((error) => {
  146. console.error("下载失败:", error);
  147. });
  148. };
  149. // 后端返回二进制流下载文件
  150. export const downloadBlob = (blob, fileName = "download") => {
  151. const reader = new FileReader();
  152. reader.readAsDataURL(blob);
  153. reader.onload = (e) => {
  154. const a = document.createElement("a");
  155. a.download = fileName;
  156. a.href = e.target.result;
  157. document.body.appendChild(a);
  158. a.click();
  159. document.body.removeChild(a);
  160. };
  161. };
  162. /**
  163. * @description base64下载word
  164. */
  165. export const downloadWord = (base64Data, filename) => {
  166. // 创建Blob对象
  167. var blob = base64ToBlob(
  168. base64Data,
  169. "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
  170. );
  171. // 创建下载链接
  172. var url = URL.createObjectURL(blob);
  173. var downloadLink = document.createElement("a");
  174. // 设置下载链接属性
  175. downloadLink.href = url;
  176. downloadLink.download = filename;
  177. // 触发下载
  178. document.body.appendChild(downloadLink);
  179. downloadLink.click();
  180. document.body.removeChild(downloadLink);
  181. URL.revokeObjectURL(url); // 清理
  182. };
  183. export const base64ToBlob = (base64, mimeType) => {
  184. // 解码Base64字符串
  185. var byteCharacters = atob(base64.replace(/^data:\w+\/\w+;base64,/, ""));
  186. // 将解码的字符串转换为类型化数组
  187. var byteNumbers = new Array(byteCharacters.length);
  188. for (var i = 0; i < byteCharacters.length; i++) {
  189. byteNumbers[i] = byteCharacters.charCodeAt(i);
  190. }
  191. // 创建Blob对象
  192. var byteArray = new Uint8Array(byteNumbers);
  193. return new Blob([byteArray], { type: mimeType });
  194. };
  195. export const downloadExcel = (base64Data, filename, type) => {
  196. const blobs = type
  197. ? "application/vnd.ms-excel"
  198. : "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
  199. // 创建Blob对象
  200. var blob = base64ToBlob(base64Data, blobs);
  201. // 创建下载链接
  202. var url = URL.createObjectURL(blob);
  203. var downloadLink = document.createElement("a");
  204. // 设置下载链接属性
  205. downloadLink.href = url;
  206. downloadLink.download = filename;
  207. // 触发下载
  208. document.body.appendChild(downloadLink);
  209. downloadLink.click();
  210. document.body.removeChild(downloadLink);
  211. URL.revokeObjectURL(url); // 清理
  212. };
  213. // 时间戳转化为时间
  214. export function convertTimestamp(timestamp) {
  215. const date = new Date(timestamp);
  216. const year = date.getFullYear();
  217. const month = String(date.getMonth() + 1).padStart(2, "0");
  218. const day = String(date.getDate()).padStart(2, "0");
  219. const hours = String(date.getHours()).padStart(2, "0");
  220. const minutes = String(date.getMinutes()).padStart(2, "0");
  221. const seconds = String(date.getSeconds()).padStart(2, "0");
  222. return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
  223. }
  224. // 格式化时间
  225. export function formatDate(timestamp, formate) {
  226. const date = new Date();
  227. date.setTime(parseInt(timestamp));
  228. // 传入formate形式 yyyy-MM-dd yyyy-MM-dd hh:mm
  229. formate = formate != null ? formate : "yyyy-MM-dd";
  230. const Format = function (fmt) {
  231. var o = {
  232. "M+": date.getMonth() + 1, // 月
  233. "d+": date.getDate(), // 日
  234. "h+": date.getHours(), // 小时
  235. "m+": date.getMinutes(), // 分
  236. "s+": date.getSeconds(), // 秒
  237. "q+": Math.floor((date.getMonth() + 3) / 3), // 季度
  238. S: date.getMilliseconds(), // 毫秒
  239. };
  240. if (/(y+)/.test(fmt)) {
  241. fmt = fmt.replace(
  242. RegExp.$1,
  243. (date.getFullYear() + "").substr(4 - RegExp.$1.length)
  244. );
  245. }
  246. // if (/(y+)/.test(fmt))
  247. // fmt = fmt.replace(
  248. // RegExp.$1,
  249. // (date.getFullYear() + '').substr(4 - RegExp.$1.length)
  250. // )
  251. for (var k in o) {
  252. if (new RegExp("(" + k + ")").test(fmt)) {
  253. fmt = fmt.replace(
  254. RegExp.$1,
  255. RegExp.$1.length === 1
  256. ? o[k]
  257. : ("00" + o[k]).substr(("" + o[k]).length)
  258. );
  259. }
  260. }
  261. return fmt;
  262. };
  263. return Format(formate);
  264. }
  265. export const jsonToFormData = (json) => {
  266. const formData = new FormData();
  267. for (const key in json) {
  268. if (Object.prototype.hasOwnProperty.call(json, key)) {
  269. const value = json[key];
  270. if (Array.isArray(value)) {
  271. for (let i = 0; i < value.length; i++) {
  272. let item;
  273. if (typeof value[i] === "string") {
  274. item = value[i];
  275. formData.append(`${key}[${i}]`, item);
  276. } else if (value[i] instanceof File) {
  277. item = value[i];
  278. formData.append(`${key}`, item);
  279. } else {
  280. item = JSON.stringify(value[i]);
  281. formData.append(`${key}[${i}]`, item);
  282. }
  283. }
  284. } else if (value instanceof File) {
  285. formData.append(key, value);
  286. } else {
  287. const item = typeof value === "string" ? value : JSON.stringify(value);
  288. formData.append(key, item);
  289. }
  290. }
  291. }
  292. return formData;
  293. };
  294. //下载图表json 文件
  295. export const downLoadChartsJsonFile = (selectJson) => {
  296. // 创建Blob对象,将selectJson数据转化为JSON字符串
  297. const jsonStr = JSON.stringify(selectJson, null, 2); // 格式化JSON
  298. const blob = new Blob([jsonStr], { type: "application/json" });
  299. // 创建a元素,用于下载Blob内容
  300. const link = document.createElement("a");
  301. link.href = URL.createObjectURL(blob);
  302. link.download = selectJson.layout.title + "_selected_data.json"; // 设置下载的文件名
  303. // 触发下载
  304. link.click();
  305. // 释放URL对象
  306. URL.revokeObjectURL(link.href);
  307. };
  308. //生成新的图表数据
  309. export const creatNewChartsJson = (selectedPoints, fullLayout) => {
  310. const groupedData = {};
  311. const addedPoints = {}; // 用于跟踪已添加的 (x, y) 组合
  312. selectedPoints.forEach((item) => {
  313. const { name } = item.data;
  314. if (!groupedData[name]) {
  315. groupedData[name] = {
  316. x: [],
  317. y: [],
  318. mode: item.data.mode,
  319. color: item.fullData.marker.color || item.fullData.line.color, // 获取颜色信息
  320. };
  321. }
  322. // 使用 (x, y) 作为键来跟踪是否已添加
  323. const pointKey = `${item.x}-${item.y}`;
  324. if (!addedPoints[pointKey]) {
  325. groupedData[name].x.push(item.x);
  326. groupedData[name].y.push(item.y);
  327. addedPoints[pointKey] = true;
  328. }
  329. });
  330. const newPlotlyData = Object.keys(groupedData).map((name) => ({
  331. x: groupedData[name].x,
  332. y: groupedData[name].y,
  333. mode: groupedData[name].mode,
  334. marker: { color: groupedData[name].color, size: 10 }, // 使用原始颜色
  335. line: { color: groupedData[name].color }, // 使用原始颜色
  336. name: name,
  337. }));
  338. // 配置新的图表布局
  339. const layout = {
  340. title: fullLayout.title.text,
  341. xaxis: { title: fullLayout.xaxis.title.text },
  342. yaxis: { title: fullLayout.yaxis.title.text },
  343. legend: {
  344. orientation: "h",
  345. y: -0.2,
  346. x: 0.5,
  347. xanchor: "center",
  348. },
  349. };
  350. return { newPlotlyData, layout };
  351. };
  352. export const downLoadCsvFile = (csvContent, fileName) => {
  353. // 创建 Blob 对象
  354. const blob = new Blob([csvContent], { type: "text/csv;charset=utf-8;" });
  355. // 创建下载链接
  356. const link = document.createElement("a");
  357. const url = URL.createObjectURL(blob);
  358. link.setAttribute("href", url);
  359. link.setAttribute("download", `${fileName}.csv`);
  360. link.style.visibility = "hidden";
  361. // 将链接添加到 DOM 并触发点击事件
  362. document.body.appendChild(link);
  363. link.click();
  364. // 清除 URL 和移除链接
  365. document.body.removeChild(link);
  366. URL.revokeObjectURL(url);
  367. };
  368. export const downloadDocx = (url, fileName) => {
  369. axios({
  370. url: url,
  371. method: "GET",
  372. responseType: "blob", // 将响应类型设置为 blob
  373. })
  374. .then((response) => {
  375. const blob = new Blob([response.data], {
  376. type: "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
  377. });
  378. const link = document.createElement("a");
  379. link.href = URL.createObjectURL(blob);
  380. link.download = fileName || "download.docx";
  381. document.body.appendChild(link);
  382. link.click();
  383. document.body.removeChild(link);
  384. URL.revokeObjectURL(link.href); // 释放 Blob URL 资源
  385. })
  386. .catch((error) => {
  387. console.error("下载失败:", error);
  388. });
  389. };
  390. export default {
  391. uuid,
  392. copy,
  393. jsonToFormData,
  394. getRotatePosition,
  395. _debounce,
  396. _throttle,
  397. hasPermission,
  398. downloadBlob,
  399. downloadWord,
  400. base64ToBlob,
  401. downloadExcel,
  402. convertTimestamp,
  403. formatDate,
  404. downLoadChartsJsonFile,
  405. creatNewChartsJson,
  406. downLoadCsvFile,
  407. downloadDocx,
  408. };