From 3b301fdd95aeccbf6c84e22bd6d217a407259746 Mon Sep 17 00:00:00 2001 From: Gitea Date: Thu, 11 Nov 2021 15:55:51 +0800 Subject: [PATCH] modify code --- options/locale/locale_zh-CN.ini | 14 +- public/img/name.png | Bin 0 -> 5107 bytes public/img/overview.png | Bin 0 -> 1523 bytes public/img/pro.png | Bin 0 -> 1960 bytes public/img/pro.svg | 1 + routers/home.go | 9 +- routers/routes/routes.go | 1 + templates/base/head_navbar.tmpl | 1 + templates/base/head_navbar_home.tmpl | 1 + templates/explore/data_analysis.tmpl | 14 + web_src/js/components/DataAnalysis.vue | 123 ++++ web_src/js/components/ProAnalysis.vue | 923 +++++++++++++++++++++++++ web_src/js/components/UserAnalysis.vue | 415 +++++++++++ web_src/js/excel/Blob.js | 179 +++++ web_src/js/excel/Export2Excel.js | 141 ++++ web_src/js/excel/util.js | 17 + web_src/js/index.js | 25 +- 17 files changed, 1846 insertions(+), 18 deletions(-) create mode 100755 public/img/name.png create mode 100755 public/img/overview.png create mode 100755 public/img/pro.png create mode 100755 public/img/pro.svg create mode 100755 templates/explore/data_analysis.tmpl create mode 100755 web_src/js/components/DataAnalysis.vue create mode 100755 web_src/js/components/ProAnalysis.vue create mode 100755 web_src/js/components/UserAnalysis.vue create mode 100755 web_src/js/excel/Blob.js create mode 100755 web_src/js/excel/Export2Excel.js create mode 100755 web_src/js/excel/util.js diff --git a/options/locale/locale_zh-CN.ini b/options/locale/locale_zh-CN.ini index a6d40355b..035c40d92 100755 --- a/options/locale/locale_zh-CN.ini +++ b/options/locale/locale_zh-CN.ini @@ -229,6 +229,7 @@ organizations=组织 images = 云脑镜像 search=搜索 code=代码 +data_analysis=数字看板 repo_no_results=未找到匹配的项目。 dataset_no_results = 未找到匹配的数据集。 user_no_results=未找到匹配的用户。 @@ -2162,19 +2163,6 @@ repos.stars=点赞数 repos.forks=派生数 repos.issues=任务数 repos.size=大小 -repos.id=ID -repos.projectName=项目名称 -repos.isPrivate=私有 -repos.openi=OpenI指数 -repos.visit=浏览量 -repos.download=代码下载量 -repos.pr=PR数 -repos.commit=Commit数 -repos.closedIssues=已解决任务数 -repos.contributor=贡献者数 -repos.yes=是 -repos.no=否 - datasets.dataset_manage_panel=数据集管理 datasets.owner=所有者 diff --git a/public/img/name.png b/public/img/name.png new file mode 100755 index 0000000000000000000000000000000000000000..11a5c8751e587b6816c14477b49db11c66a07dfa GIT binary patch literal 5107 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 Dc9WZU literal 0 HcmV?d00001 diff --git a/public/img/overview.png b/public/img/overview.png new file mode 100755 index 0000000000000000000000000000000000000000..b704ead840b2cb65ac7a375194cd30ff7fc345ed GIT binary patch literal 1523 zcmVPx)tw}^dRCr$PTWe@tMG&6Zq(l^@0aNh_f>5kT!TQI?j|ggwCHL;!k}4>el0NJM z(}=}_VxuTntdFX#G*ya-pba^*NeZ!2N`F`s!D5vvf>0H#f?|WBRFa;NEloT*-E+^L zdv9*j^vu6xXLr8&c4l|Z?p}loT<`+-A94cn2&gjyrBdn2Fbr2CVjBS5aK`-iA~K?s z+8G4FFZF~}*AyV4l>pES09PeAdEB-$^R9Z4P&WdI=p_Jn!qc&>%)HT4w<@)1C!nLF zQ5U1MD!Q{Y;yoPj);#3LGWR;jfkECfaeo{cQf<`0m{m{^mO^upJ%?Qw1Yo*jS5xLHRY&|n?_eI>> z+pCToIr1t1*fg3Vi1othDBcbmm zX5LcCxY0gU5zyM&+SuIO+y?;59YFRV;)ZG~yHcrimx#Op05>^o>^^bg#Hxb_4~|z# zM8yOYi^ZFjQf~pk9gbY>HOAO&t|ns3XA!YGN{3^>Ltz-M85|t^x)Ng*5kN#1h|TGi zn9)&0d^EnrRRYY_M{B(q5p5|Qm)`(j9W(c5wUwCwB6TOX`m`-B3$Sv!M6?h9Z2H~i z(EDI~e7tLTc=#V5dtL-+trsDpUF>dg3_5L9S~&;W+S;0$nwo6EWy|Qe92SvP#+WbC zNJu4sh#nG=orrizbTC9bCL${;-Qv=K`L+{L4*@YSMP#X?;}&M#lm@Ea?Zsm8 zT14E1h>PR45pf_4!xhGu(X-m({~#i}uvj)1#M=H9k(I`n_v-Cj7JEcw)4`@iT)qJS zo3fuyN#*DtL}V*E>%4NXxF`sM!&$(bD_yO17b03e;u4-AVfRGCWC{?GJ+89HR!(8& z)CKcgIqb4aL{bLNMrPh>+oJ@O>j1NifJuL%1nfzuwNDc{%LwRa=4DeNptG~{qS4XO zmz7eDBC;O8ScM-lDO)wickoqBh0aL|6XRxQ30 zSl2Z`Yi&!=o`e%!5RpIa@m4MF6lNR&TI+ieai7oBipXMP%*Q^u)vjT6ivS|}#C405 z;J_hfzH_z_U~g|OpKwYX`ylPMqSUsV`t(B7Dco38;1zt<{Y9&RDJNO^lOAKpp{g`W8qF@w9f|(4Wxr9WPIT zJOz?d;OFSGb`iPN=fOdxg!+c8Pbw4&g)15w8h(xF9%tsOU40W%pj0XiiAeN?_g?_8 z%RX5%#{A#|B&w6t Z@E@88)nDGXoUs4^002ovPDHLkV1jH+%oYFu literal 0 HcmV?d00001 diff --git a/public/img/pro.png b/public/img/pro.png new file mode 100755 index 0000000000000000000000000000000000000000..7d44e180e543762d81bc9d96696ee2ed4d8c2f70 GIT binary patch literal 1960 zcmV;Z2UqxsP)Px+Vo5|nRCr$Pn|+8>RTRL_c{6LfU=q|uiBR;9S`tAdMG0CIY=wL8o5si@p%3Xx zGe6c{cURZ1w6HI?4^jH3G>u{A-C37b{J=0Mv9c{Fq$H`Vq^~7G*P5Ak;tco6ZQR*; zGxKJ4m3jZon|sea=lAYA=iYPALl^~@5aJ<3oCg3?iKsgi3U$Zh@$agk8dhVFd}Bx{ z?*#xh{H~lfe<5Nw!*Cqu&r0ezA^@b6w`s#?8OH4ZfIR^40svgb_Yv`^hR_WFR0$AO z1t6uI!c(1y<{HNA$z(E1dwP1l@a{<|muL{4euo%@Qfh0^5UK*ew(SY7>&`>O7Q=wU zmSruC$K!j4GODYq%j)m%UzgKomt|S(A3g{QL`4BaqtUUcREiB>1^{EV(mx>L(nKQh zz8@o^(P(2Tm0}Q&8tu0u;>JWGanO&9;o4LTfDqzIZTJLMfQU|6merC-B;G7V=}06p ziHOz_kudtd0RS5v$N9DtnOQ$mYR7#2gb)uPVmkm_XS7-2IL@jd#?lV-c>tK^$s?lG zb#-;!u~_W)V#f#!fDocd8-A;y#Kv$qygU|*{avhLh1yFgn*o49Tx-m*4qijVVzEr2 z{@(v(1CUbQ0s#EP?=c45W?9zqcs%~SUqwo7C#8G@0M-G(vCVHGbpqhXoLc zMCQ7#y9NLnji*X*M;y3`~m>uhxGv-03uo$ z3WYv#UH26Ln0%f)!G8f@ArXCzh&;m!&j1FXlQ01KYG0u>N<{z|@7GjBWDsZ95CBlggvfDz;(k+XfjGfJg!%vG z=H|OC%VH2yw4)3ua|(PKb5oalSF=6x)acFkTDZTQCTjGn@ML6A$bJ$do^70C-9@H#bkS zEbD;&J;!fGw}e+P+hx=NV5Ov#+0$PlnxT~XuvFvx^s50VcQ@#Va^X(0djg8AT zZ{D2pW0>DIl?0&6cGm;II76TH0|Nt{zKW!5+g?CK4B}!ffGaUu9LIUtuYrZyRRTaH z5)rQJvf&er@i(Q@>CT-ycm6T#D=>t@D5d18Zw6uM|Bn+YU@b9hpp~v!|!$sHuyu8DMtc)8K}NhE^gvTQ3LzpK1^#=kkI8VB7XpTt7@ixz(#3 zN~zC>dI&`W@Py2qIdgm{6j}-Z^9{j0`Xh+{6(bgU`r6-=90j7$=$K33F$_)8EjTK29@;c&RMm@4s7XMk50G4>H{c-#;8vH^I52qA6+ zfF+1{zcH}yWAS1E*tR{Jh&BSirFy&*+VHpi81A(R41fWG>u-1}@+WazV0ng!<~xqV zC8~KZzW}6^w*vr|=w^@I0br1bI+ao{6=QhC0Ca((><#%5$zsM6( zhJRqs%^>)@;p}I!#&yEjdmM0Gw=Lh-9znnu5demNxEc`|#4`X;Zy5BIHoPMB0VcQ+ u1z^kw4rvTxlIyx#lF8(IK|EbQGX4WYLkf;t9!vZH0000 \ No newline at end of file diff --git a/routers/home.go b/routers/home.go index dfdb030e4..d2c93c771 100755 --- a/routers/home.go +++ b/routers/home.go @@ -33,8 +33,9 @@ const ( // tplExploreOrganizations explore organizations page template tplExploreOrganizations base.TplName = "explore/organizations" // tplExploreCode explore code page template - tplExploreCode base.TplName = "explore/code" - tplExploreImages base.TplName = "explore/images" + tplExploreCode base.TplName = "explore/code" + tplExploreImages base.TplName = "explore/images" + tplExploreExploreDataAnalysis base.TplName = "explore/data_analysis" ) // Home render home page @@ -501,6 +502,10 @@ func ExploreImages(ctx *context.Context) { ctx.HTML(200, tplExploreImages) } +func ExploreDataAnalysis(ctx *context.Context) { + ctx.HTML(200, tplExploreExploreDataAnalysis) +} + // NotFound render 404 page func NotFound(ctx *context.Context) { ctx.Data["Title"] = "Page Not Found" diff --git a/routers/routes/routes.go b/routers/routes/routes.go index 383a308b6..a3de68373 100755 --- a/routers/routes/routes.go +++ b/routers/routes/routes.go @@ -325,6 +325,7 @@ func RegisterRoutes(m *macaron.Macaron) { m.Get("/organizations", routers.ExploreOrganizations) m.Get("/code", routers.ExploreCode) m.Get("/images", routers.ExploreImages) + m.Get("/data_analysis", routers.ExploreDataAnalysis) }, ignSignIn) m.Combo("/install", routers.InstallInit).Get(routers.Install). Post(bindIgnErr(auth.InstallForm{}), routers.InstallPost) diff --git a/templates/base/head_navbar.tmpl b/templates/base/head_navbar.tmpl index 57df408c9..67d8fc1b7 100755 --- a/templates/base/head_navbar.tmpl +++ b/templates/base/head_navbar.tmpl @@ -37,6 +37,7 @@ {{.i18n.Tr "explore.users"}} {{.i18n.Tr "explore.organizations"}} {{.i18n.Tr "explore.images"}} + {{.i18n.Tr "explore.data_analysis"}} {{else if .IsLandingPageHome}} diff --git a/templates/base/head_navbar_home.tmpl b/templates/base/head_navbar_home.tmpl index e6729da62..e334efba8 100644 --- a/templates/base/head_navbar_home.tmpl +++ b/templates/base/head_navbar_home.tmpl @@ -29,6 +29,7 @@ {{.i18n.Tr "explore.users"}} {{.i18n.Tr "explore.organizations"}} {{.i18n.Tr "explore.images"}} + {{.i18n.Tr "explore.data_analysis"}} {{else if .IsLandingPageHome}} diff --git a/templates/explore/data_analysis.tmpl b/templates/explore/data_analysis.tmpl new file mode 100755 index 000000000..8277dc902 --- /dev/null +++ b/templates/explore/data_analysis.tmpl @@ -0,0 +1,14 @@ +{{template "base/head" .}} +
+ + +
+ +{{template "base/footer" .}} + + diff --git a/web_src/js/components/DataAnalysis.vue b/web_src/js/components/DataAnalysis.vue new file mode 100755 index 000000000..8c632bccb --- /dev/null +++ b/web_src/js/components/DataAnalysis.vue @@ -0,0 +1,123 @@ + + + + + \ No newline at end of file diff --git a/web_src/js/components/ProAnalysis.vue b/web_src/js/components/ProAnalysis.vue new file mode 100755 index 000000000..7df0854e5 --- /dev/null +++ b/web_src/js/components/ProAnalysis.vue @@ -0,0 +1,923 @@ + + + + + \ No newline at end of file diff --git a/web_src/js/components/UserAnalysis.vue b/web_src/js/components/UserAnalysis.vue new file mode 100755 index 000000000..547a077f4 --- /dev/null +++ b/web_src/js/components/UserAnalysis.vue @@ -0,0 +1,415 @@ + + + + + \ No newline at end of file diff --git a/web_src/js/excel/Blob.js b/web_src/js/excel/Blob.js new file mode 100755 index 000000000..c43291d34 --- /dev/null +++ b/web_src/js/excel/Blob.js @@ -0,0 +1,179 @@ +/* eslint-disable */ +/* Blob.js + * A Blob implementation. + * 2014-05-27 + * + * By Eli Grey, http://eligrey.com + * By Devin Samarin, https://github.com/eboyjr + * License: X11/MIT + * See LICENSE.md + */ + +/*global self, unescape */ +/*jslint bitwise: true, regexp: true, confusion: true, es5: true, vars: true, white: true, + plusplus: true */ + +/*! @source http://purl.eligrey.com/github/Blob.js/blob/master/Blob.js */ + +(function (view) { + "use strict"; + + view.URL = view.URL || view.webkitURL; + + if (view.Blob && view.URL) { + try { + new Blob; + return; + } catch (e) {} + } + + // Internally we use a BlobBuilder implementation to base Blob off of + // in order to support older browsers that only have BlobBuilder + var BlobBuilder = view.BlobBuilder || view.WebKitBlobBuilder || view.MozBlobBuilder || (function(view) { + var + get_class = function(object) { + return Object.prototype.toString.call(object).match(/^\[object\s(.*)\]$/)[1]; + } + , FakeBlobBuilder = function BlobBuilder() { + this.data = []; + } + , FakeBlob = function Blob(data, type, encoding) { + this.data = data; + this.size = data.length; + this.type = type; + this.encoding = encoding; + } + , FBB_proto = FakeBlobBuilder.prototype + , FB_proto = FakeBlob.prototype + , FileReaderSync = view.FileReaderSync + , FileException = function(type) { + this.code = this[this.name = type]; + } + , file_ex_codes = ( + "NOT_FOUND_ERR SECURITY_ERR ABORT_ERR NOT_READABLE_ERR ENCODING_ERR " + + "NO_MODIFICATION_ALLOWED_ERR INVALID_STATE_ERR SYNTAX_ERR" + ).split(" ") + , file_ex_code = file_ex_codes.length + , real_URL = view.URL || view.webkitURL || view + , real_create_object_URL = real_URL.createObjectURL + , real_revoke_object_URL = real_URL.revokeObjectURL + , URL = real_URL + , btoa = view.btoa + , atob = view.atob + + , ArrayBuffer = view.ArrayBuffer + , Uint8Array = view.Uint8Array + ; + FakeBlob.fake = FB_proto.fake = true; + while (file_ex_code--) { + FileException.prototype[file_ex_codes[file_ex_code]] = file_ex_code + 1; + } + if (!real_URL.createObjectURL) { + URL = view.URL = {}; + } + URL.createObjectURL = function(blob) { + var + type = blob.type + , data_URI_header + ; + if (type === null) { + type = "application/octet-stream"; + } + if (blob instanceof FakeBlob) { + data_URI_header = "data:" + type; + if (blob.encoding === "base64") { + return data_URI_header + ";base64," + blob.data; + } else if (blob.encoding === "URI") { + return data_URI_header + "," + decodeURIComponent(blob.data); + } if (btoa) { + return data_URI_header + ";base64," + btoa(blob.data); + } else { + return data_URI_header + "," + encodeURIComponent(blob.data); + } + } else if (real_create_object_URL) { + return real_create_object_URL.call(real_URL, blob); + } + }; + URL.revokeObjectURL = function(object_URL) { + if (object_URL.substring(0, 5) !== "data:" && real_revoke_object_URL) { + real_revoke_object_URL.call(real_URL, object_URL); + } + }; + FBB_proto.append = function(data/*, endings*/) { + var bb = this.data; + // decode data to a binary string + if (Uint8Array && (data instanceof ArrayBuffer || data instanceof Uint8Array)) { + var + str = "" + , buf = new Uint8Array(data) + , i = 0 + , buf_len = buf.length + ; + for (; i < buf_len; i++) { + str += String.fromCharCode(buf[i]); + } + bb.push(str); + } else if (get_class(data) === "Blob" || get_class(data) === "File") { + if (FileReaderSync) { + var fr = new FileReaderSync; + bb.push(fr.readAsBinaryString(data)); + } else { + // async FileReader won't work as BlobBuilder is sync + throw new FileException("NOT_READABLE_ERR"); + } + } else if (data instanceof FakeBlob) { + if (data.encoding === "base64" && atob) { + bb.push(atob(data.data)); + } else if (data.encoding === "URI") { + bb.push(decodeURIComponent(data.data)); + } else if (data.encoding === "raw") { + bb.push(data.data); + } + } else { + if (typeof data !== "string") { + data += ""; // convert unsupported types to strings + } + // decode UTF-16 to binary string + bb.push(unescape(encodeURIComponent(data))); + } + }; + FBB_proto.getBlob = function(type) { + if (!arguments.length) { + type = null; + } + return new FakeBlob(this.data.join(""), type, "raw"); + }; + FBB_proto.toString = function() { + return "[object BlobBuilder]"; + }; + FB_proto.slice = function(start, end, type) { + var args = arguments.length; + if (args < 3) { + type = null; + } + return new FakeBlob( + this.data.slice(start, args > 1 ? end : this.data.length) + , type + , this.encoding + ); + }; + FB_proto.toString = function() { + return "[object Blob]"; + }; + FB_proto.close = function() { + this.size = this.data.length = 0; + }; + return FakeBlobBuilder; + }(view)); + + view.Blob = function Blob(blobParts, options) { + var type = options ? (options.type || "") : ""; + var builder = new BlobBuilder(); + if (blobParts) { + for (var i = 0, len = blobParts.length; i < len; i++) { + builder.append(blobParts[i]); + } + } + return builder.getBlob(type); + }; +}(typeof self !== "undefined" && self || typeof window !== "undefined" && window || this.content || this)); \ No newline at end of file diff --git a/web_src/js/excel/Export2Excel.js b/web_src/js/excel/Export2Excel.js new file mode 100755 index 000000000..3c6d022af --- /dev/null +++ b/web_src/js/excel/Export2Excel.js @@ -0,0 +1,141 @@ +/* eslint-disable */ +require('script-loader!file-saver'); +require('./Blob'); +require('script-loader!xlsx/dist/xlsx.core.min'); +function generateArray(table) { + var out = []; + var rows = table.querySelectorAll('tr'); + var ranges = []; + for (var R = 0; R < rows.length; ++R) { + var outRow = []; + var row = rows[R]; + var columns = row.querySelectorAll('td'); + for (var C = 0; C < columns.length; ++C) { + var cell = columns[C]; + var colspan = cell.getAttribute('colspan'); + var rowspan = cell.getAttribute('rowspan'); + var cellValue = cell.innerText; + if (cellValue !== "" && cellValue == +cellValue) cellValue = +cellValue; + + //Skip ranges + ranges.forEach(function (range) { + if (R >= range.s.r && R <= range.e.r && outRow.length >= range.s.c && outRow.length <= range.e.c) { + for (var i = 0; i <= range.e.c - range.s.c; ++i) outRow.push(null); + } + }); + + //Handle Row Span + if (rowspan || colspan) { + rowspan = rowspan || 1; + colspan = colspan || 1; + ranges.push({s: {r: R, c: outRow.length}, e: {r: R + rowspan - 1, c: outRow.length + colspan - 1}}); + } + ; + + //Handle Value + outRow.push(cellValue !== "" ? cellValue : null); + + //Handle Colspan + if (colspan) for (var k = 0; k < colspan - 1; ++k) outRow.push(null); + } + out.push(outRow); + } + return [out, ranges]; +}; + +function datenum(v, date1904) { + if (date1904) v += 1462; + var epoch = Date.parse(v); + return (epoch - new Date(Date.UTC(1899, 11, 30))) / (24 * 60 * 60 * 1000); +} + +function sheet_from_array_of_arrays(data, opts) { + var ws = {}; + var range = {s: {c: 10000000, r: 10000000}, e: {c: 0, r: 0}}; + for (var R = 0; R != data.length; ++R) { + for (var C = 0; C != data[R].length; ++C) { + if (range.s.r > R) range.s.r = R; + if (range.s.c > C) range.s.c = C; + if (range.e.r < R) range.e.r = R; + if (range.e.c < C) range.e.c = C; + var cell = {v: data[R][C]}; + if (cell.v == null) continue; + var cell_ref = XLSX.utils.encode_cell({c: C, r: R}); + + if (typeof cell.v === 'number') cell.t = 'n'; + else if (typeof cell.v === 'boolean') cell.t = 'b'; + else if (cell.v instanceof Date) { + cell.t = 'n'; + cell.z = XLSX.SSF._table[14]; + cell.v = datenum(cell.v); + } + else cell.t = 's'; + + ws[cell_ref] = cell; + } + } + if (range.s.c < 10000000) ws['!ref'] = XLSX.utils.encode_range(range); + return ws; +} + +function Workbook() { + if (!(this instanceof Workbook)) return new Workbook(); + this.SheetNames = []; + this.Sheets = {}; +} + +function s2ab(s) { + var buf = new ArrayBuffer(s.length); + var view = new Uint8Array(buf); + for (var i = 0; i != s.length; ++i) view[i] = s.charCodeAt(i) & 0xFF; + return buf; +} + +export function export_table_to_excel(id) { + var theTable = document.getElementById(id); + console.log('a') + var oo = generateArray(theTable); + var ranges = oo[1]; + + /* original data */ + var data = oo[0]; + var ws_name = "SheetJS"; + console.log(data); + + var wb = new Workbook(), ws = sheet_from_array_of_arrays(data); + + /* add ranges to worksheet */ + // ws['!cols'] = ['apple', 'banan']; + ws['!merges'] = ranges; + + /* add worksheet to workbook */ + wb.SheetNames.push(ws_name); + wb.Sheets[ws_name] = ws; + + var wbout = XLSX.write(wb, {bookType: 'xlsx', bookSST: false, type: 'binary'}); + + saveAs(new Blob([s2ab(wbout)], {type: "application/octet-stream"}), "test.xlsx") +} + +function formatJson(jsonData) { + console.log(jsonData) +} +export function export_json_to_excel(th, jsonData, defaultTitle) { + + /* original data */ + + var data = jsonData; + data.unshift(th); + var ws_name = "SheetJS"; + + var wb = new Workbook(), ws = sheet_from_array_of_arrays(data); + + + /* add worksheet to workbook */ + wb.SheetNames.push(ws_name); + wb.Sheets[ws_name] = ws; + + var wbout = XLSX.write(wb, {bookType: 'xlsx', bookSST: false, type: 'binary'}); + var title = defaultTitle || '列表' + saveAs(new Blob([s2ab(wbout)], {type: "application/octet-stream"}), title + ".xlsx") +} \ No newline at end of file diff --git a/web_src/js/excel/util.js b/web_src/js/excel/util.js new file mode 100755 index 000000000..b600e5e37 --- /dev/null +++ b/web_src/js/excel/util.js @@ -0,0 +1,17 @@ +export function export2Excel(columns,list,filename){ + require.ensure([], () => { + const { export_json_to_excel } = require('./Export2Excel'); + let tHeader = [] + let filterVal = [] + console.log(columns) + if(!columns){ + return; + } + columns.forEach(item =>{ + tHeader.push(item.title) + filterVal.push(item.key) + }) + const data = list.map(v => filterVal.map(j => v[j])) + export_json_to_excel(tHeader, data, filename); + }) +} \ No newline at end of file diff --git a/web_src/js/index.js b/web_src/js/index.js index 560683b7e..a6d07d0bc 100755 --- a/web_src/js/index.js +++ b/web_src/js/index.js @@ -13,7 +13,7 @@ import qs from 'qs'; import 'jquery.are-you-sure'; import './vendor/semanticdropdown.js'; import {svg} from './utils.js'; - +import echarts from 'echarts' import initContextPopups from './features/contextpopup.js'; import initGitGraph from './features/gitgraph.js'; import initClipboard from './features/clipboard.js'; @@ -35,8 +35,9 @@ import {createCodeEditor} from './features/codeeditor.js'; import MinioUploader from './components/MinioUploader.vue'; import ObsUploader from './components/ObsUploader.vue'; import EditAboutInfo from './components/EditAboutInfo.vue'; -import Images from './components/Images.vue' -import EditTopics from './components/EditTopics.vue' +import Images from './components/Images.vue'; +import EditTopics from './components/EditTopics.vue'; +import DataAnalysis from './components/DataAnalysis.vue' import Contributors from './components/Contributors.vue' Vue.use(ElementUI); @@ -44,6 +45,10 @@ Vue.prototype.$axios = axios; Vue.prototype.qs = qs; const {AppSubUrl, StaticUrlPrefix, csrf} = window.config; +Object.defineProperty(Vue.prototype, '$echarts', { + value: echarts +}) + function htmlEncode(text) { return jQuery('
') .text(text) @@ -2972,6 +2977,7 @@ $(document).ready(async () => { initVueEditTopic(); initVueContributors(); initVueImages(); + initVueDataAnalysis(); initTeamSettings(); initCtrlEnterSubmit(); initNavbarContentToggle(); @@ -3713,7 +3719,20 @@ function initVueImages() { render: h => h(Images) }); } +function initVueDataAnalysis() { + const el = document.getElementById('data_analysis'); + console.log("el",el) + + if (!el) { + return; + } + new Vue({ + el: '#data_analysis', + + render: h => h(DataAnalysis) + }); +} // 新增 function initObsUploader() { const el = document.getElementById('obsUploader');