index.js 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629
  1. // import http from '@/api/http.js'
  2. // import { downloadXlsx } from "../utils/xlsx";
  3. import { saveAs } from 'file-saver'
  4. import { apiGetExportMsg, apiGetModel, } from '../api/api'
  5. // import XLSXD from 'xlsx-style'
  6. // import Papa from 'papaparse'
  7. // import { isObject } from "xe-utils"
  8. //检查空
  9. const checkNull = val => val === undefined || val === null
  10. const until = {
  11. // 计算比率
  12. ratioCalculation(a, b) {
  13. let num = null
  14. if (a !== '-' && b !== '-') {
  15. if (a === '0.00' || a === 0) {
  16. num = 0
  17. } else if (b === '0.00' || b === 0) {
  18. num = '-'
  19. } else {
  20. num = Math.round((Number(a) / Number(b) * 100)) + '%'
  21. }
  22. } else {
  23. num = '-'
  24. }
  25. return num
  26. },
  27. // 导出所有
  28. downloadPer(url, fileName, idss, idsmo) {
  29. let params = null
  30. if (!idsmo) {
  31. params = {
  32. ids: idss ? idss.join(',') : ''
  33. }
  34. } else {
  35. params = {
  36. idsMv: idss ? idss.join(',') : '',
  37. idsBcr: idsmo ? idsmo.join(',') : '',
  38. }
  39. }
  40. apiGetExportMsg(url, params).then(datas => {
  41. let blob = new Blob([datas])
  42. saveAs(blob, fileName)
  43. }).catch((r) => {
  44. console.error(r)
  45. })
  46. },
  47. // 下载模板
  48. downloadTemplate(url, params, proName) {
  49. apiGetModel(url, params).then(datas => {
  50. let blob = new Blob([datas])
  51. saveAs(blob, proName)
  52. }).catch((r) => {
  53. console.error(r)
  54. })
  55. },
  56. getTime(date) {
  57. var y = date.getFullYear();
  58. var m = date.getMonth() + 1;
  59. m = m < 10 ? ('0' + m) : m;
  60. var d = date.getDate();
  61. d = d < 10 ? ('0' + d) : d;
  62. var h = date.getHours();
  63. h = h < 10 ? ('0' + h) : h;
  64. var minute = date.getMinutes();
  65. minute = minute < 10 ? ('0' + minute) : minute;
  66. var second = date.getSeconds();
  67. second = second < 10 ? ('0' + second) : second;
  68. return y + '-' + m + '-' + d + ' ' + h + ':' + minute + ':' + second;
  69. // timeF = y + '-' + m + '-' + d
  70. // return timeF
  71. },
  72. changePowerPickDate(val) {
  73. let endss = val.substring(val.length - 2, val.length) * 1
  74. let startTime = val.substring(0, val.length - 2)
  75. let allTime = ''
  76. if (0 <= endss && endss < 15) {
  77. allTime = startTime + '00'
  78. } else if (15 <= endss && endss < 30) {
  79. allTime = startTime + '15'
  80. } else if (30 <= endss && endss < 45) {
  81. allTime = startTime + '30'
  82. } else if (45 <= endss && endss < 60) {
  83. allTime = startTime + '45'
  84. }
  85. return allTime
  86. },
  87. changeElectricPickDate(val) {
  88. let endss = val.substring(val.length - 2, val.length) * 1
  89. let startTime = val.substring(0, val.length - 2)
  90. let allTime = ''
  91. if (0 <= endss && endss < 10) {
  92. allTime = startTime + '00'
  93. } else if (10 <= endss && endss < 20) {
  94. allTime = startTime + '10'
  95. } else if (20 <= endss && endss < 30) {
  96. allTime = startTime + '20'
  97. } else if (30 <= endss && endss < 40) {
  98. allTime = startTime + '30'
  99. } else if (40 <= endss && endss < 50) {
  100. allTime = startTime + '40'
  101. } else if (50 <= endss && endss < 60) {
  102. allTime = startTime + '50'
  103. }
  104. return allTime
  105. },
  106. oninput(str, limit, type, zero) {
  107. if (zero) {
  108. if (str.substr(0, 1) === '.' || str.substr(0, 1) === '-') {
  109. str = ''
  110. }
  111. } else {
  112. if (str.substr(0, 1) === '.' || str.substr(0, 1) === '-' || str.substr(0, 1) === '0') {
  113. str = ''
  114. }
  115. }
  116. if (type === 'float') {
  117. str = str.replace(/[^\d^\.]+/g, '') // 保留数字和小数点
  118. if (limit === 1) {
  119. str = str.replace(/^\D*([0-9]\d*\.?\d{0,1})?.*$/, '$1') // 小数点后只能输 1 位
  120. } else if (limit === 2) {
  121. str = str.replace(/^\D*([0-9]\d*\.?\d{0,2})?.*$/, '$1') // 小数点后只能输 2 位
  122. } else if (limit === 3) {
  123. str = str.replace(/^\D*([0-9]\d*\.?\d{0,3})?.*$/, '$1') // 小数点后只能输 3 位
  124. } else if (limit === 4) {
  125. str = str.replace(/^\D*([0-9]\d*\.?\d{0,4})?.*$/, '$1') // 小数点后只能输 4 位
  126. } else if (limit === 6) {
  127. str = str.replace(/^\D*([0-9]\d*\.?\d{0,6})?.*$/, '$1') // 小数点后只能输 6 位
  128. }
  129. } else {
  130. str = str.replace(/[^\d^]+/g, '')
  131. str = str.substring(0, limit)
  132. }
  133. return str
  134. },
  135. sortBy(attr, rev) {
  136. //第二个参数没有传递 默认升序排列
  137. if (rev == undefined) {
  138. rev = 1;
  139. } else {
  140. rev = (rev) ? 1 : -1;
  141. }
  142. return function (a, b) {
  143. a = a[attr];
  144. b = b[attr];
  145. if (a < b) {
  146. return rev * -1;
  147. }
  148. if (a > b) {
  149. return rev * 1;
  150. }
  151. return 0;
  152. }
  153. },
  154. /**
  155. * 字母大小写切换
  156. * @param str 要处理的字符串
  157. * @param type 1:首字母大写其余小写 2:首子母小写其余大写 3:大小写转换 4:全部大写 5:全部小写
  158. */
  159. strChangeCase(str, type) {
  160. function ToggleCase(str) {
  161. var itemText = ""
  162. str.split("").forEach(
  163. function (item) {
  164. if (/^([a-z]+)/.test(item)) {
  165. itemText += item.toUpperCase();
  166. } else if (/^([A-Z]+)/.test(item)) {
  167. itemText += item.toLowerCase();
  168. } else {
  169. itemText += item;
  170. }
  171. });
  172. return itemText;
  173. }
  174. switch (type) {
  175. case 1:
  176. return str.replace(/^(\w)(\w+)/, function (v, v1, v2) {
  177. return v1.toUpperCase() + v2.toLowerCase();
  178. });
  179. case 2:
  180. return str.replace(/^(\w)(\w+)/, function (v, v1, v2) {
  181. return v1.toLowerCase() + v2.toUpperCase();
  182. });
  183. case 3:
  184. return ToggleCase(str);
  185. case 4:
  186. return str.toUpperCase();
  187. case 5:
  188. return str.toLowerCase();
  189. default:
  190. return str;
  191. }
  192. },
  193. /*
  194. *数字每千位加逗号
  195. *
  196. */
  197. commafy(num) {
  198. return num && num.toString()
  199. .replace(/\d+/, function (s) {
  200. return s.replace(/(\d)(?=(\d{3})+$)/g, '$1,')
  201. })
  202. },
  203. /*
  204. *手机号码中间4位隐藏花号(*)显示
  205. *
  206. */
  207. hideMobile(mobile) {
  208. return mobile && mobile.toString().replace(/^(\d{3})\d{4}(\d{4})$/, "$1****$2")
  209. },
  210. /*
  211. * 验证是否为数字
  212. */
  213. isNumber(n) {
  214. return !isNaN(parseFloat(n)) && isFinite(n);
  215. },
  216. /*
  217. * 是否为数组
  218. */
  219. isArray(obj) {
  220. return Object.prototype.toString.call(obj) === '[object Array]';
  221. },
  222. /*
  223. * 递归深拷贝
  224. */
  225. deepCopy(obj) {
  226. let result = Array.isArray(obj) ? [] : {};
  227. for (let key in obj) {
  228. if (obj.hasOwnProperty(key)) {
  229. if (typeof obj[key] === 'object' && obj[key] !== null) {
  230. result[key] = deepCopy(obj[key]);
  231. } else {
  232. result[key] = obj[key];
  233. }
  234. }
  235. }
  236. return result;
  237. },
  238. exportTable(name, columnData, tableDatas) {
  239. let datalist = [];
  240. //表头数据
  241. let cluData = ''
  242. for (let i = 0; i < columnData.length; i++) {
  243. cluData += columnData[i].label + ','
  244. }
  245. cluData.slice(0, cluData.length - 1)
  246. datalist.push(cluData.split(','));
  247. //这里的tableData为你的表格数据
  248. for (let j = 0; j < tableDatas.length; j++) {
  249. let item = tableDatas[j]
  250. let tabelDatas = ''
  251. for (let k = 0; k < columnData.length; k++) {
  252. let its = columnData[k]
  253. if (item[its.value] !== null) {
  254. tabelDatas += item[its.value] + ','
  255. } else {
  256. tabelDatas += '-,'
  257. }
  258. }
  259. datalist.push(tabelDatas.split(','));
  260. }
  261. downloadXlsx(datalist, `${name}.xlsx`);
  262. // let blob = new Blob([datalist])
  263. // saveAs(blob, `${name}.xlsx`)
  264. // this.exportCsv(datalist)
  265. },
  266. exportExcel() {
  267. // let time = this.$utils.getTime(new Date())
  268. // let titleName = this.title + ' ' + time
  269. // this.$utils.exportTable(titleName,this.columData, this.tableData)
  270. let wb = XLSX.utils.book_new();
  271. let headers = {
  272. name: '姓名',
  273. age: '年龄',
  274. sex: '性别'
  275. }
  276. this.columData.unshift(headers)
  277. let contentWs = XLSX.utils.json_to_sheet(this.columData, {
  278. header: ['name', 'age', 'sex'], // 可自定义表头顺序
  279. skipHeader: true, //是否忽略表头,默认为false
  280. origin: 'A2' // 设置插入位置
  281. })
  282. contentWs['!merges'] = [{ s: { r: 0, c: 0 }, e: { r: 1, c: 0 } }, { s: { r: 0, c: 1 }, e: { r: 1, c: 1 } }]
  283. // contentWs['!merges'] = [{s:{r:1,c:2}, e:{r:2,c:2}}]
  284. // contentWs['A1'] = {
  285. // t: 's',
  286. // v: '人员',
  287. // s: {
  288. // font:{
  289. // name: '微软雅黑',
  290. // sz: 16,
  291. // bold: true,
  292. // color: {rgb: 'ffffff'}
  293. // },
  294. // alignment: {
  295. // horizontal: 'center',
  296. // vertical: 'center'
  297. // },
  298. // fill:{bgcolor: {rgb: '4472c4'}}
  299. // }
  300. // }
  301. // 设置合并单元格 !merges为一个对象数组,每个对象设定了单元格合并的规则,
  302. // {s:{r:0,c:0}, e:{r:0,c:2}}为一个规则,s:起始位置,e:结束位置,r:行,c:列
  303. // contentWs['!merges'] = [{s:{r:0,c:0}, e:{r:0,c:2}}]
  304. // contentWs['A3'] = {
  305. // t: 's',
  306. // v: '人员ss',
  307. // s: {
  308. // font:{
  309. // name: '微软雅黑',
  310. // sz: 16,
  311. // bold: true,
  312. // color: {rgb: 'ffffff'}
  313. // },
  314. // alignment: {
  315. // horizontal: 'center',
  316. // vertical: 'center'
  317. // },
  318. // fill:{bgcolor: {rgb: '4472c4'}}
  319. // }
  320. // }
  321. // contentWs['!merges'] = [{s:{r:0,c:2}, e:{r:0,c:4}}]
  322. //设置列宽
  323. contentWs['!cols'] = [{ wch: 30 }, { wch: 20 }, { wch: 40 }]
  324. XLSX.utils.book_append_sheet(wb, contentWs, '明细')
  325. // XLSX.writeFile(wb, '明细.xlsx')
  326. const tmpDown = new Blob([
  327. this.s2ab(
  328. XLSXD.write(wb, {
  329. bookType: 'xlsx',
  330. bookSST: true,
  331. type: 'binary',
  332. cellStyles: true
  333. })
  334. )
  335. ])
  336. this.downExcel(tmpDown, '明细.xlsx')
  337. },
  338. downExcel(obj, fileName) {
  339. const a_node = document.createElement('a')
  340. a_node.download = fileName
  341. if ('msSaveOrOpenBlob' in navigator) {
  342. window.navigator.msSaveOrOpenBlob(obj, fileName)
  343. } else {
  344. a_node.href = URL.createObjectURL(obj)
  345. }
  346. a_node.click()
  347. setTimeout(() => {
  348. URL.createObjectURL(obj)
  349. }, 2000)
  350. },
  351. s2ab(s) {
  352. if (typeof ArrayBuffer !== 'undefined') {
  353. const buf = new ArrayBuffer(s.length)
  354. const view = new Uint8Array(buf)
  355. for (let i = 0; i != s.length; ++i) {
  356. view[i] = s.charCodeAt(i) & 0xff
  357. }
  358. return buf
  359. } else {
  360. const buf = new Array(s.length)
  361. for (let i = 0; i != s.length; ++i) {
  362. buf[i] = s.charCodeAt(i) & 0xff
  363. }
  364. return buf
  365. }
  366. },
  367. setTooltip(myChart1, myChart2, num) {
  368. // const myChart1 = this.$echarts.init(document.getElementById(name1))
  369. // const myChart2 = this.$echarts.init(document.getElementById(name2))
  370. myChart1.getZr().on('mousemove', (params) => {
  371. const pointInPixel = [params.offsetX, params.offsetY];
  372. // 判断当前鼠标移动的位置是否在图表中
  373. if (myChart1.containPixel('grid', pointInPixel)) {
  374. //使用 convertFromPixel方法 转换像素坐标值到逻辑坐标系上的点。获取点击位置对应的x轴数据的索引值
  375. const pointInGrid = myChart1.convertFromPixel({ seriesIndex: 0 }, pointInPixel);
  376. // x轴数据的索引值
  377. const xIndex = pointInGrid[0];
  378. // 使用getOption() 获取图表的option
  379. const op = myChart1.getOption();
  380. // 获取当前点击位置要的数据
  381. const xDate = op.xAxis[0].data[xIndex];
  382. // 这里不直接用params.dataIndex是因为可能两个图表X轴的月份数据点不一致
  383. const dataIndex = op.xAxis[0].data.findIndex(x => x === xDate);
  384. myChart2.dispatchAction({
  385. type: 'showTip',
  386. seriesIndex: num,
  387. // 我用的echarts版本是4.8.0,用name而不用dataIndex时,不知道为什么tooltip不显示,所以这里用dataIndex
  388. // name: params.name
  389. dataIndex: dataIndex,
  390. position: '15%'
  391. });
  392. } else {
  393. myChart2.dispatchAction({
  394. type: 'hideTip'
  395. });
  396. }
  397. })
  398. myChart2.getZr().on('mousemove', (params) => {
  399. const pointInPixel = [params.offsetX, params.offsetY];
  400. // 判断当前鼠标移动的位置是否在图表中
  401. if (myChart2.containPixel('grid', pointInPixel)) {
  402. //使用 convertFromPixel方法 转换像素坐标值到逻辑坐标系上的点。获取点击位置对应的x轴数据的索引值
  403. const pointInGrid = myChart2.convertFromPixel({ seriesIndex: 0 }, pointInPixel);
  404. // x轴数据的索引值
  405. const xIndex = pointInGrid[0];
  406. // 使用getOption() 获取图表的option
  407. const op = myChart2.getOption();
  408. // 获取当前点击位置要的数据
  409. const xDate = op.xAxis[0].data[xIndex];
  410. // 这里不直接用params.dataIndex是因为可能两个图表X轴的月份数据点不一致
  411. const dataIndex = op.xAxis[0].data.findIndex(x => x === xDate);
  412. myChart1.dispatchAction({
  413. type: 'showTip',
  414. seriesIndex: num,
  415. // 我用的echarts版本是4.8.0,用name而不用dataIndex时,不知道为什么tooltip不显示,所以这里用dataIndex
  416. // name: params.name
  417. dataIndex: dataIndex,
  418. position: '15%'
  419. });
  420. } else {
  421. myChart1.dispatchAction({
  422. type: 'hideTip'
  423. });
  424. }
  425. })
  426. },
  427. // 数据是否为null,NaN,0的判断
  428. isHasNum(data) {
  429. let num = null
  430. if (data && data !== 0) {
  431. if (data !== 'NaN' && data !== null) {
  432. num = Number(data).toFixed(2)
  433. } else {
  434. num = '-'
  435. }
  436. } else if (data === 0) {
  437. num = 0
  438. } else {
  439. num = '-'
  440. }
  441. return num
  442. },
  443. //获取当前月天数
  444. hasYearMonthDate(a, b) {
  445. let d = new Date(a, b, 0)
  446. let de = d.getDate()
  447. return de
  448. },
  449. // ------------------------------------------------------------------------
  450. // 冒泡排序
  451. sortBubble(arr) {
  452. for (let i = 0; i < arr.length; i++) {
  453. for (let j = 0; j < arr.length - i; j++) {
  454. if (arr[j] > arr[j + 1]) {
  455. let temp = arr[j]
  456. arr[j] = arr[j + 1]
  457. arr[j + 1] = temp
  458. }
  459. }
  460. }
  461. return arr
  462. },
  463. //数组去重
  464. // 方法一
  465. //利用for 循环 搭配 indexOf 去重
  466. unique(arr) {
  467. let newArr = []
  468. for (let i = 0; i < arr.length; i++) {
  469. if (newArr.indexOf(arr[i]) === -1) {
  470. newArr.push(arr[i])
  471. }
  472. }
  473. return arr
  474. },
  475. //方法二
  476. //借助ES6提供的Set结构 new Set()
  477. // var arr = [1,9,8,8,7,2,5,3,3,3,2,3,1,4,5,444,55,22];
  478. // var arr2 = noRepeat(arr)
  479. noRepeatT(arr) {
  480. var newArr = [...new Set(arr)]; //利用了Set结构不能接收重复数据的特点
  481. return newArr
  482. },
  483. //方法三
  484. //利用 filter() 去重
  485. //eg: var arr = ['apple','apps','pear','apple','orange','apps']
  486. useFilter(arr) {
  487. return arr.filter(function (item, index) {
  488. return arr.indexOf(item) === index; // 因为indexOf 只能查找到第一个
  489. })
  490. },
  491. //方法四
  492. //将数组的每一个元素依次与其他元素做比较,发现重复元素,删除
  493. //eg: var arr = [1,9,8,8,7,2,5,3,3,3,2,3,1,4,5,444,55,22];
  494. noRepeatF(arr) {
  495. for (var i = 0; i < arr.length - 1; i++) {
  496. for (var j = i + 1; j < arr.length; j++) {
  497. if (arr[i] === arr[j]) {
  498. arr.splice(j, 1);
  499. j--;
  500. }
  501. }
  502. }
  503. return arr;
  504. },
  505. //方法五
  506. //借助新数组 通过 indexOf 方法判断当前元素在数组中的索引,如果与循环的下标相等则添加到新数组中
  507. // var arr = [1,9,8,8,7,2,5,3,3,3,2,3,1,4,5,444,55,22]
  508. noRepeatFi(arr) {
  509. var newArr = [];
  510. for (var i = 0; i < arr.length; i++) {
  511. if (arr.indexOf(arr[i]) == i) {
  512. newArr.push(arr[i]);
  513. }
  514. }
  515. return newArr;
  516. },
  517. //方法六
  518. //利用双重for循环
  519. // var arr = [1,9,8,8,7,2,5,3,3,3,2,3,1,4,5,444,55,22]
  520. noRepeatS(arr) {
  521. for (var i = 0; i < arr.length; i++) {
  522. for (var j = 0; j < arr.length; j++) {
  523. if (arr[i] == arr[j] && i != j) { //将后面重复的数删掉
  524. arr.splice(j, 1);
  525. }
  526. }
  527. }
  528. return arr;
  529. },
  530. //方法七
  531. //利用includes实现数组去重
  532. // var arr = [1,9,8,8,7,2,5,3,3,3,2,3,1,4,5,444,55,22];
  533. noRepeatSe(arr) {
  534. let newArr = [];
  535. for (i = 0; i < arr.length; i++) {
  536. if (!newArr.includes(arr[i])) {
  537. newArr.push(arr[i])
  538. }
  539. }
  540. return newArr
  541. },
  542. //把url中的参数解析为一个对象
  543. // var url = 'http://www.demo.cn/index.html?key1=val1&key2=val2'
  544. parseQueryString(argu) {
  545. let str = argu.split('?')[1]
  546. let result = {}
  547. let temp = str.split('&')
  548. for (let i = 0; i < temp.length; i++) {
  549. let temp2 = temp[i].split('=')
  550. result[temp2[0]] = temp2[1]
  551. }
  552. return result
  553. },
  554. //统计字符串中出现最多的字母
  555. // let str = 'jdjsajdjasdasdakss'
  556. countStr(str) {
  557. let json = {}
  558. //循环完毕后会得到一个对象 如{a:0,b:1,c:2}
  559. for (let i = 0; i < str.length; i++) {
  560. if (!json[str.charAt(i)]) {
  561. json[str.charAt(i)] = 1
  562. } else {
  563. json[str.charAt(i)]++
  564. }
  565. }
  566. },
  567. //对象深拷贝
  568. deepClone(obj) {
  569. if (obj instanceof Object) {
  570. let isArray = Array.isArray(obj)
  571. let cloneObj = isArray ? [] : {}
  572. for (let key in obj) {
  573. cloneObj[key] = isObject(obj[key]) ? deepClone(obj[key]) : obj[key]
  574. }
  575. return cloneObj
  576. } else {
  577. throw new Error('obj不是一个对象')
  578. }
  579. },
  580. // 防抖
  581. debounce(fn, delay) {
  582. var delay = delay || 200;
  583. var timer;
  584. return function () {
  585. var th = this;
  586. var args = arguments;
  587. if (timer) {
  588. clearTimeout(timer);
  589. }
  590. timer = setTimeout(function () {
  591. timer = null;
  592. fn.apply(th, args);
  593. }, delay);
  594. };
  595. },
  596. // 节流
  597. throttle(fn, interval) {
  598. var last;
  599. var timer;
  600. var interval = interval || 200;
  601. return function () {
  602. var th = this;
  603. var args = arguments;
  604. var now = +new Date();
  605. if (last && now - last < interval) {
  606. clearTimeout(timer);
  607. timer = setTimeout(function () {
  608. last = now;
  609. fn.apply(th, args);
  610. }, interval);
  611. } else {
  612. last = now;
  613. fn.apply(th, args);
  614. }
  615. }
  616. }
  617. }
  618. export default until