index.js 17 KB

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