GitBucket
4.6.0
Toggle navigation
Sign in
Files
Branches
1
Tags
Issues
Pull Requests
Labels
Milestones
Wiki
08335
/
hivui-platform-template
hivui平台项目模板
Browse code
Jenkins commit
master
1 parent
2eef94e
commit
da12f199de5874ad2b7bf901a82205be2a928000
12896
authored
on 5 Dec 2022
Showing
4 changed files
project/hivuiLogin/index.html
project/hivuiMain/views/layout/components/Main.vue
project/hivuiSam/components/analysisSam/Index.vue
vite-plugin/vite-plugin-func.js
Ignore Space
Show notes
View
project/hivuiLogin/index.html
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width,initial-scale=1.0"> <title>EAP5-Admin-Login</title> <link id="fav_icon" rel="icon" href="" type="image/x-icon"> <% if(htmlWebpackPlugin.vite){%> <!--预览时 公共库--> <link rel="stylesheet" href="/assets_platform/element-ui/index.css"> <script src="/assets_platform/vue/vue.min.js"></script> <script src="/assets_platform/vuex/vuex.min.js"></script> <script src="/assets_platform/vue-router/vue-router.min.js"></script> <script src="/assets_platform/element-ui/index.js"></script> <script src="/assets_platform/eap/eap.umd.min.js"></script> <%}%> <% if(!htmlWebpackPlugin.vite){%> <link rel="stylesheet" href="${serverPath}/render/assets_platform/element-ui/index.css"> <script src="${serverPath}/render/assets_platform/vue/vue.min.js"></script> <script src="${serverPath}/render/assets_platform/vuex/vuex.min.js"></script> <script src="${serverPath}/render/assets_platform/vue-router/vue-router.min.js"></script> <script src="${serverPath}/render/assets_platform/element-ui/index.js"></script> <!--发布时 公共库--> <!-- <script src="${serverPath}/render/assets_platform/vendor_dll/vuelibs.dll.js"></script> --> <script src="${serverPath}/render/assets_platform/vendor_dll/vendor.dll.js"></script> <script src="${serverPath}/render/assets_platform/eap/eap.umd.min.js"></script> <%}%> <!-- <script src="/eaptpl/setting/desktop/appsetting/js/1.0.0/appsetting.js" type="text/javascript"></script> --> </head> <body> <div id="app"> <div style="padding:50px 0;text-align:center;"> <div> <img id="main_loading_logo" src="" /> </div> <div>系统初始化中...<a href="javascript:location.reload();">【点我刷新】</a></div> </div> </div> <iframe src="http://192.168.4.193:39784/eap5csxm/hivuiMain/index.html/" frameborder="0" width="900px" height="600px"></iframe> <script> let _img=window.customSysCofig&&window.customSysCofig.sysLoadLogo&&window.customSysCofig.sysLoadLogo.src; document.getElementById("main_loading_logo").src=(_img||(window._global?"./assets/logo_max.png":"./static/img/logo_max.png")); if(window.customSysCofig){ if(window.customSysCofig.syTitle){ document.title=window.customSysCofig.syTitle; } if(window.customSysCofig.favicon){ document.getElementById("fav_icon").href=window.customSysCofig.favicon; } } <% if(!htmlWebpackPlugin.vite){%> window.__loginCfg={ pageType:"${pageType}", redirect:"${redirect}", } <%}%> </script> <% if(htmlWebpackPlugin.vite==true){%> <script type="module" src="./index.js"></script> <script> //预览时判断1.5s还没有加载完,自动重刷 var _winLoadedCtrl = window.setInterval(function(){ if(document.getElementById("main_loading_logo")){ window.location.reload(); }else{ window.clearInterval(_winLoadedCtrl); } },5000) </script> <%}%> <!-- built files will be auto injected --> </body> </html>
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width,initial-scale=1.0"> <title>EAP5-Admin-Login</title> <link id="fav_icon" rel="icon" href="" type="image/x-icon"> <% if(htmlWebpackPlugin.vite){%> <!--预览时 公共库--> <link rel="stylesheet" href="/assets_platform/element-ui/index.css"> <script src="/assets_platform/vue/vue.min.js"></script> <script src="/assets_platform/vuex/vuex.min.js"></script> <script src="/assets_platform/vue-router/vue-router.min.js"></script> <script src="/assets_platform/element-ui/index.js"></script> <script src="/assets_platform/eap/eap.umd.min.js"></script> <%}%> <% if(!htmlWebpackPlugin.vite){%> <link rel="stylesheet" href="${serverPath}/render/assets_platform/element-ui/index.css"> <script src="${serverPath}/render/assets_platform/vue/vue.min.js"></script> <script src="${serverPath}/render/assets_platform/vuex/vuex.min.js"></script> <script src="${serverPath}/render/assets_platform/vue-router/vue-router.min.js"></script> <script src="${serverPath}/render/assets_platform/element-ui/index.js"></script> <!--发布时 公共库--> <!-- <script src="${serverPath}/render/assets_platform/vendor_dll/vuelibs.dll.js"></script> --> <script src="${serverPath}/render/assets_platform/vendor_dll/vendor.dll.js"></script> <script src="${serverPath}/render/assets_platform/eap/eap.umd.min.js"></script> <%}%> <!-- <script src="/eaptpl/setting/desktop/appsetting/js/1.0.0/appsetting.js" type="text/javascript"></script> --> </head> <body> <div id="app"> <div style="padding:50px 0;text-align:center;"> <div> <img id="main_loading_logo" src="" /> </div> <div>系统初始化中...<a href="javascript:location.reload();">【点我刷新】</a></div> </div> </div> <script> let _img=window.customSysCofig&&window.customSysCofig.sysLoadLogo&&window.customSysCofig.sysLoadLogo.src; document.getElementById("main_loading_logo").src=(_img||(window._global?"./assets/logo_max.png":"./static/img/logo_max.png")); if(window.customSysCofig){ if(window.customSysCofig.syTitle){ document.title=window.customSysCofig.syTitle; } if(window.customSysCofig.favicon){ document.getElementById("fav_icon").href=window.customSysCofig.favicon; } } <% if(!htmlWebpackPlugin.vite){%> window.__loginCfg={ pageType:"${pageType}", redirect:"${redirect}", } <%}%> </script> <% if(htmlWebpackPlugin.vite==true){%> <script type="module" src="./index.js"></script> <script> //预览时判断1.5s还没有加载完,自动重刷 var _winLoadedCtrl = window.setInterval(function(){ if(document.getElementById("main_loading_logo")){ window.location.reload(); }else{ window.clearInterval(_winLoadedCtrl); } },5000) </script> <%}%> <!-- built files will be auto injected --> </body> </html>
Ignore Space
Show notes
View
project/hivuiMain/views/layout/components/Main.vue
<template> <div class="pl-main"> <p-tabs ref="cmp-tabs" v-model="defTabKey" @onActiveTab="handleActiveTab" @onRemoveTab="handleRemoveTab" @onRemoveAllTab="handleRemoveAllTab" @onRemoveLeft="handleRemoveLeftTab" @onRemoveRight="handleRemoveRightTab" @onRemoveOther="handleRemoveOtherTab" @onFullScreen="handleFullScreen" :isSinglePage="sysConfig.isSinglePage" > <p-tabpanel v-for="(item,index) in tabList" :key="item.id" :close="item.close" :title.sync="item.title" :name="item.id" :url="item.url" :itemData="item" @onIframeLoad="handleIframeLoad" @onBeforeClose="handleBeforeClose" @onSelected="handleSelected" @onBeforeRefresh="handleBeforeRefresh" > <template v-if="item.type&&item.type=='home'"> <PortalSys :itemData="item" ref="protalSysHome" ></PortalSys> </template> <template v-if="item.type&&item.type=='work'"> <PortalUser :itemData="item" ref="portalUserWork" ></PortalUser> </template> </p-tabpanel> </p-tabs> <el-dialog class="miniLoginBox" width="410px" :visible.sync="isMiniLogin" :close-on-click-modal="false"> <iframe v-if="isMiniLogin" width="100%" height="380px" :src="miniLoginUrl" style="border:none;"></iframe> </el-dialog> </div> </template> <script> import {changeBz} from "@main/api/user"; import { baseURL, codeProjectName,requestUrl } from "@main/config"; import { PTabs, PTabpanel } from "@main/components/tabpanel"; import PortalUser from "@main/views/Portal/user"; import PortalSys from "@main/views/Portal/sys"; import { getUrlValue, setUrlValue,getUrlSearch,closeWindow } from "@main/utils"; import { getToken } from '@main/utils/auth' // import { type } from "os"; import md5 from "js-md5"; import { utils } from "hi-ui"; export default { inject: ["addTab", "showTab", "hideTab"], components: { PTabs, PTabpanel, PortalUser, PortalSys, }, data() { let cfg = this.$store.state.app.config || {}; let defTabs = cfg.sysDefTabs || []; let setTabs = cfg.sysSetTabs || []; let list = [], defTabKey = ""; defTabs = setTabs.concat(defTabs); defTabs.map((item, i) => { if(!window._global){//正式环境 item.url=utils.string.setUrlValue(item.url,"pn",window.HIVUI_SETTING.projectName); item.url=utils.string.setUrlValue(item.url,"access_token",getToken()); } let id = item.url ? md5(item.url) : item.id; //强转成 url md5 id // if(cfg.isSinglePage){//单页面模式 // id="123456789"; // } item.actived && (defTabKey = id); if (item.url && getUrlValue(item.url, "__tabId") == "") { //关系到用户调用,防止Scp.context.closeCurPage取不到__tabId出错 item.url = utils.string.setUrlValue(item.url, "__tabId", id); } /*if(cfg.isSinglePage){ list[0]={ title: item.title, url: item.url, close: item.close, id: id, type: item.type, }; }else*/{ list.push({ title: item.title, url: item.url, close: item.close, id: id, type: item.type, }); } }); console.log('page default open tabs :',defTabs); //系统菜单 后台默认配激活 let menusDef2Tabs = this.$store.getters.defTabs, uriStr = ""; console.log('menus default open tabs :',defTabs); menusDef2Tabs.map((item, i) => { //uriStr = baseURL + codeProjectName + item.resUrl; uriStr = item.resUrl; if(!window._global){//正式环境 uriStr=utils.string.setUrlValue(uriStr,"pn",window.HIVUI_SETTING.projectName); uriStr=utils.string.setUrlValue(uriStr,"access_token",getToken()); } if(uriStr.indexOf("http")==-1){ uriStr=location.origin+uriStr; } let id = md5(uriStr); uriStr = utils.string.setUrlValue(uriStr, "__tabId", id); list.push({ title: item.name, url: uriStr, close: true, id: id, type: item.type, }); }); // console.log('系统菜单',list); //第三方跳转过来地址自动打开功能tab let menusList = this.$store.getters.menusList; let searchObj = getUrlSearch(decodeURIComponent(this.$router.currentRoute.fullPath)); for (let i = menusList.length - 1; i >= 0; i--) { if ((menusList[i].type=="func"||menusList[i].type=="flow" )&& (searchObj.portal_func&&menusList[i].resUrl)&&searchObj.portal_func == menusList[i].resUrl) { console.log('跳转进来的功能:',searchObj.portal_func); //?portal_func=/project/rjwhzx/rjzcgl/funcdir/zcmcx.func&id=11111 delete searchObj.portal_func; // let uriStr = baseURL + codeProjectName + menusList[i].resUrl; let uriStr = menusList[i].resUrl; if(!window._global){//正式环境 uriStr=utils.string.setUrlValue(uriStr,"pn",window.HIVUI_SETTING.projectName); uriStr=utils.string.setUrlValue(uriStr,"access_token",getToken()); } if(uriStr.indexOf("http")==-1){ uriStr=location.origin+uriStr; } let id = md5(uriStr); uriStr = utils.string.setUrlValue(uriStr, "__tabId", md5(uriStr)); for(let key in searchObj){ uriStr = utils.string.setUrlValue(uriStr,key,searchObj[key]); } let inMenu = false; for (let j = list.length - 1; j >= 0; j--) { if (list[j].id == id) { inMenu = true; break; } } if (inMenu) break; defTabKey = id; list.push({ id: id, title: menusList[i].name, url: uriStr, close: true, actived:true //默认选中 }); break; } } if(cfg.isPageCache&&window.localStorage.getItem('pageCacheArr')){ JSON.parse(window.localStorage.getItem('pageCacheArr')).map((item,index)=>{ uriStr = item.url; if(!window._global){//正式环境 uriStr=utils.string.setUrlValue(uriStr,"pn",window.HIVUI_SETTING.projectName); uriStr=utils.string.setUrlValue(uriStr,"access_token",getToken()); } if(uriStr.indexOf("http")==-1){ uriStr=location.origin+uriStr; } let id = md5(uriStr); uriStr = utils.string.setUrlValue(uriStr, "__tabId", id); defTabKey = id; list.push({ title: item.title, url: uriStr, close: true, id: id, //type: item.type, }); }); } //地址栏打开标签 if(top.location.hash){ let hashTabParam={}; top.location.hash.replace("#/","").split("&zhc&").forEach((item=>{ if(item.indexOf("tabUrl=")==0){ hashTabParam.resUrl=item.replace("tabUrl=",""); }else if(item.indexOf("tabTitle=")==0){ hashTabParam.name=decodeURIComponent(item.replace("tabTitle=","")); } })); if(hashTabParam.resUrl){ if(hashTabParam.resUrl.indexOf("about:blank")==-1){//下推页面无法重新载入 //消除tabId干扰 let tabIdStr=hashTabParam.resUrl.match(/\__tabId=.*?&/)||hashTabParam.resUrl.match(/\?__tabId=.*/); if(tabIdStr&&tabIdStr[0]){ hashTabParam.resUrl=hashTabParam.resUrl.replace(tabIdStr[0],"").replace("?&","?"); } let id = md5(hashTabParam.resUrl); let existsItem=list.filter(item=>{//标签已存在 if(item.url&&hashTabParam.resUrl){ let itemMainUrl=item.url.split("?")[0]; let hashTabMainUrl=hashTabParam.resUrl.split("?")[0]; if(hashTabParam.resUrl.indexOf(itemMainUrl)!=-1){ return item; } } }); if(!existsItem[0]){ defTabKey = id; hashTabParam.resUrl = utils.string.setUrlValue(hashTabParam.resUrl, "__tabId", id); list.push({ title: hashTabParam.name, url: hashTabParam.resUrl, close: true, id: id, actived:true //默认选中 }); }else{ defTabKey=existsItem[0].id; } } } } console.log('sys default tabs :', list); return { defTabKey: defTabKey || "", tabList: list, sysConfig: this.$store.state.app.config, isFullScreen: false, isMiniLogin:false, miniLoginUrl:"", }; }, mounted() { // console.log('主界面初始化~!'); let me = this, cTabs = this.$refs["cmp-tabs"]; window.Sys = { isVue: true, addEvent(evtName, fn) { //onLoad Bus.$on(evtName, fn); }, tabPanel: { autoResize() { cTabs.resize(); }, }, getSideNavs() { return [...me.$store.getters.navs]; }, setSideNavs(data) { if (data == null && !(data instanceof Array)) return; //me.$store.dispatch("app/setQuickNav", data); }, /** * @param {} url * @param {} title * @param {} uid * @param {} onLoad //iframe 加载后 * @param {} nearest //标签页是否紧接在其右侧打开 * @param {} renderedFn //渲染回调 */ addTab(url, title, uid, onLoad, nearest, renderedFn) { // if(me.sysConfig.isSinglePage){//单页面模式 // uid="123456789"; // }else if(me.sysConfig.isPageCache){//页面标签缓存模式 let _pcarr=window.localStorage.getItem('pageCacheArr'); let cacheArr=_pcarr?JSON.parse(_pcarr):[]; cacheArr=cacheArr.filter((item)=>{ if(url!=item.url){ return item } }); cacheArr.push({ "url":url, "title":title, }); if(cacheArr.length>20){ cacheArr.shift(); } window.localStorage.setItem('pageCacheArr',JSON.stringify(cacheArr)); } if (!(url == "" || url == "about:blank")) { uid = md5(url); } if(!window._global){//正式环境 url=utils.string.setUrlValue(url,"pn",window.HIVUI_SETTING.projectName); url=utils.string.setUrlValue(url,"access_token",getToken()); } let tabs = me.tabList.filter((item, index) => { if(item.id == uid){ item.title=title; return item; } }); if (tabs.length/*&&!me.sysConfig.isSinglePage*/) { me.defTabKey = uid; me.$nextTick( (function (fn) { return function () { let tab = cTabs.getItemObj(uid); fn && fn(tab); }; })(renderedFn) ); return; } if (getUrlValue(url, "__tabId") == "") { //关系到用户调用,防止Scp.context.closeCurPage取不到__tabId出错 url = utils.string.setUrlValue(url, "__tabId", uid); } /*if(me.sysConfig.isSinglePage){ me.tabList.pop(); me.$nextTick(()=>{ me.tabList.push({ title: title, url: url, close: true, id: uid, listeners: { load: onLoad, }, }) }) }else{*/ me.tabList.push({ title: title, url: url, close: true, id: uid, listeners: { load: onLoad, }, }); //} me.defTabKey = uid; // window.____renderFunc = renderedFn; me.$nextTick( (function (fn, _uid) { return function () { let tab = cTabs.getItemObj(_uid); fn && fn(tab); }; })(renderedFn, uid) ); console.log(' addTab ',me.tabList); }, getTab(uid) { return cTabs.getItemObj(uid); }, seldTab(uid) { cTabs.defTabKey = uid; }, getSeldTab() { return cTabs.getSeldItemObj(); }, refreshTab(uid) { let tab = cTabs.getItemObj(uid); tab && tab.tabPanelIframeEl.contentWindow.window.location.reload(); }, //closeTab colseTab(uid) { cTabs.closeItem(uid); }, colseSeldTab() { cTabs.closeCurItem(); }, }; window.SysPage={ newPage : function(title, url, params, method, target) { var uid = md5((params&¶ms._ftaskguid)?(url+"?tguid="+params._ftaskguid):url), tab; function formSubmit(cfg){ cfg.autoDestroy = true; var form = me.creatForm(cfg); form.submit(); } if(method=="get"){ //get 不刷新 var tab = top.Sys.getTab(uid); if(tab){ top.Sys.seldTab(uid); return; } } if(target=="opening"){ var cfg = { url : utils.string.setUrlValue(url,"__tabId",uid), data : params, target : '_blank', method : method || "get" }; formSubmit(cfg); //打开新标签 return; }else if(target=="me"){ //本页:框架页的本页面 var cfg = { url : url, data : params, target : '_self', method : method || "get" }; formSubmit(cfg); }else{ if (target == "_self"){ tab = top.Sys.getSeldTab(); if(top.Sys.isVue){ var titleEl = tab.tabEl.querySelector('.pl-tabs-itemTxt'); titleEl.innerText = ""; }else{ tab.tabEl.find('.sys-tab-item-text').html(""); } }else{ /*** * uid 让框架页可以关闭自己 closeCurPage */ if(top.Sys.isVue){ //6个参数,第7个是vue渲染后回调 if(target == "_blank"){ uid+=utils.string.id(4); } top.Sys.addTab("about:blank",title,uid,null,true,function(tab){ if(!window._global){//正式环境 url=utils.string.setUrlValue(url,"pn",window.HIVUI_SETTING.projectName); url=utils.string.setUrlValue(url,"access_token",getToken()); } var cfg = { url : utils.string.setUrlValue(url,"__tabId",uid), data : params, target : null, method : method || "get" }; //var titleEl = tab.tabEl.querySelector('.pl-tabs-itemTxt'); //titleEl.innerText = ""; cfg.target = tab.tabPanelIframeEl.getAttribute('name'); formSubmit(cfg); }); }else{ var cfg = { url : utils.string.setUrlValue(url,"__tabId",uid), data : params, target : null, method : method || "get" }; //Sys.addTab(url, title, uid, callback) tab = top.Sys.addTab("about:blank",title,uid); tab.tabEl.find('.sys-tab-item-text').html(""); cfg.target = tab.tabPanelIframeEl.getAttribute('name'); formSubmit(cfg); } } } }, /** * 通过url 进行对应的目标功能 调用目标页的callback方法 * @param id * @param url */ closePage : function(id,url) { if (!top.Sys) { closeWindow() return; } var uid = md5(url||""), tab; if(!window.parent.Sys){ return; } var tab = window.parent.Sys.getTab(uid); if(tab){ window.parent.Sys.seldTab(uid); //var _scp = tab.tabPanelIframeEl.contentWindow.window.Scp; //if(_scp){ // _scp.context&&_scp.context.callback&&_scp.context.callback.call(_scp.context); //} }else{ if(url&&url.trim()!=""){ var tab = window.parent.Sys.addTab(url,"",null,null,true); } } if (id) { window.parent.Sys.colseTab(id); }else{ window.parent.Sys.colseSeldTab(); } }, closeCurPage:function(){ if(!window.parent.Sys){ return; } var id = getUrlValue(window.location.search,'__tabId'); window.parent.Sys.colseTab(id); }, setPageTitle:function(title){ if(!window.parent.Sys){ return; } var openway = getUrlValue('','openway'); if(openway=="openwin")return; var tab = window.parent.Sys.getSeldTab(); if(title!=""){ tab.tabEl.find('.sys-tab-item-text').html(title); window.parent.Sys.tabPanel.autoResize(); } }, //小登录弹窗打开 openMiniLogin:function(isRefresh){ if(window.HIVUI_SETTING.isSingleLogin||me.isMiniLogin){ return; } me.isMiniLogin=true; let params="questType=ajax"+(isRefresh?"&isRefresh=true":"")+"#"; let __login=window.HIVUI_SETTING.loginUrl.split("#"); me.miniLoginUrl=__login[0]+(__login[0].indexOf("?")==-1?"?":"&")+params+(__login[1]||"")+"miniLogin"; }, //小登录弹窗关闭 closeMiniLogin:function(isRefresh){ me.isMiniLogin=false; changeBz({ bzid:me.$store.state.user.userInfo.fbzid }); let tabId=location.href.match(/\?__tabId=.*?&/)[0].replace("?__tabId=","").replace("&",""); if(isRefresh&&tabId){ document.querySelector("iframe[name='iframe"+tabId+"']").contentWindow.location.reload(); } }, }; if (this.defTabKey == "" && this.tabList.length) this.defTabKey = this.tabList[0].id; //默认如果指向下面两个的话,标识一下已经加载过 if (this.$refs["protalSysHome"]) { //this.$store.dispatch("portal/loadSysList"); //重新加载系统门户列表 // console.log('加载系统门户列表~!'); let itemData = this.$refs["protalSysHome"][0].itemData; if (itemData.id == this.defTabKey) { this.$refs["protalSysHome"][0].actived = true; } } if (this.$refs["portalUserWork"]) { //this.$store.dispatch("portal/loadList"); //重新加载工作台门户列表 // console.log('加载工作台门户列表~!'); let itemData = this.$refs["portalUserWork"][0].itemData; if (itemData.id == this.defTabKey) { this.$refs["portalUserWork"][0].actived = true; } } let events = this.sysConfig.events; if (events) { this.$nextTick((r) => { events.onLoad && events.onLoad(); }); } }, methods: { //将框架页里头的a 标签进行转换 initATagUrl(el) { let aList = el.querySelectorAll("a"); aList.forEach(function (aTag, i) { if (aTag.href) { var httpUrl = new RegExp( "^((https|http|ftp|rtsp|mms)?://)" ); if ( httpUrl.test( aTag.href.replace(window.location.origin, "") ) ) { return false; } if (!aTag.onclick) { if (aTag.target == "_blank") { aTag.addEventListener("click", function (evt) { evt.preventDefault(); evt.stopPropagation(); var tabTitle = ""; if (aTag.title) { tabTitle = aTag.title; } var url = this.getAttribute("href"); var reg = /^\//gi; Sys.addTab(url, tabTitle, "", "", true); return false; }); } } } }); window.Sys.tabPanel.autoResize(); }, handleBeforeRefresh(panel, evt) { //if (panel.itemData.type == "home") { // this.$store.state.app.sysList=[]; //this.$store.dispatch("portal/loadSysList"); //重新加载系统门户列表 //return false; //} if (panel.itemData.type == "work") { // this.$store.state.app.list=[]; //this.$store.dispatch("portal/loadList"); //重新加载工作台门户列表 return false; } }, handleIframeLoad(panelCmp, evt) { let me = this, key = panelCmp.name; let ifm = panelCmp.$refs["iframe"]; let tabData = panelCmp.itemData; if (tabData.listeners) { tabData.listeners.load && tabData.listeners.load(); } //转换A标签 me.initATagUrl(ifm.contentWindow.document.body); window.__UserInfo = { orgId: "", operator: "", }; if (panelCmp.title == null || panelCmp.title == "") { let cTabs = me.$refs["cmp-tabs"]; cTabs.resize(); } }, handleBeforeClose(panel, evt) { let ifm = panel.$refs["iframe"]; try { let flag = ifm.contentWindow.Scp.context.beforeunloadFn(evt, 1); return flag; } catch (e) { !document.all && window.console.log( "iframe : Scp.context.beforeunloadFn();" ); } }, handleActiveTab(panel) { if (!panel) return; top.location.hash="#/tabUrl="+panel.url+"&zhc&tabTitle="+panel.title; if (panel.itemData.type == "home") { this.$refs["protalSysHome"][0].doRender(); } if (panel.itemData.type == "work") { this.$refs["portalUserWork"][0].doRender(); } try { let tab = this.$refs["cmp-tabs"].getItemObj(panel.name); //tab.tabPanelIframeEl.contentDocument.trigger("iframeActiving", [panel.name]); tab.tabPanelIframeEl.contentDocument.dispatchEvent( new CustomEvent('iframeActiving', { detail:[panel.name] } ) ); } catch (e) { console.log("iframeActiving error!"); } }, //面板上面的事件特别处理,现在暂时没用 handleSelected(item) { return; let key = item.id; let ifm = this.$refs["dom-iframe" + key][0]; try { let __orgId = ifm.contentWindow.Scp.User.getId(); let __operator = ifm.contentWindow.Scp.User.getOperator(); window.__UserInfo = { orgId: __orgId, operator: __operator, }; } catch (e) {} }, handleRemoveTab(targetName) { let tabs = this.tabList; let activeName = this.defTabKey; if (activeName === targetName) { tabs.forEach((tab, index) => { if (tab.close && tab.id === targetName) { let nextTab = tabs[index + 1] || tabs[index - 1]; if (nextTab) { activeName = nextTab.id; } } }); } this.defTabKey = activeName; tabs = tabs.filter((tab) => { return tab.close == false || tab.id !== targetName; }); console.log('handleRemoveTab') this.$set(this, "tabList", tabs); if (this.tabList.length == 0) { this.defTabKey = "tabPanel_home"; } }, handleRemoveAllTab() { let tabs = this.tabList; this.tabList = tabs.filter((tab) => { return !tab.close; }); let l = this.tabList.length; this.defTabKey = l ? this.tabList[l - 1].id : ""; }, handleRemoveLeftTab(name, index) { let tabs = this.tabList; let defTabKey = this.defTabKey; this.tabList = tabs.filter((tab, i) => { if (tab.id == defTabKey && i < index) { //当前的选中,是在关闭区内 defTabKey = name; } return tab.close == false || i >= index; }); this.defTabKey = defTabKey; }, handleRemoveRightTab(name, index) { let tabs = this.tabList; let defTabKey = this.defTabKey; this.tabList = tabs.filter((tab, i) => { if (tab.id == defTabKey && i > index) { //当前的选中,是在关闭区内 defTabKey = name; } return tab.close == false || i <= index; }); this.defTabKey = defTabKey; }, handleRemoveOtherTab(name, index) { let tabs = this.tabList; tabs = tabs.filter((tab, i) => { return tab.close == false || i == index; }); this.$set(this, "tabList", tabs); this.defTabKey = name; }, handleFullScreen() { this.$emit("onFullScreen"); // screenfull.toggle() }, creatForm(opt){ let that=this; var _opt={ autoShow:false, cancelAction:false, url:null, target:null, action:null, method:null, params:null, data:null, autoDestroy:false, _id:utils.string.id(8), }; Object.assign(_opt,opt); var _formTpl=`<form style="display:none;" id="${_opt._id}"><input type="submit" value="submit" id="submit_${_opt._id}"/></form>`; var _el=document.createElement("div"); _el.innerHTML=_formTpl; document.getElementsByTagName("body")[0].appendChild(_el); var _form=_el.getElementsByTagName("form")[0]; this.setTarget=(str)=>{ _opt.target = str; _form.setAttribute('target',str); } this.setUrl=(str)=>{ this.formateUrl(str); var url = utils.string.setUrlValue(_opt.url,"_____r",new Date().getTime()); _form.setAttribute('action',url); } this.setMethod=(str)=>{ _opt.method = str||'get'; _form.setAttribute('method',str); } this.setParams=(params)=>{ _opt.params = params; } this.setData=(obj)=>{ _opt.data = obj||{}; if(_opt.method=="get"&&_opt.url!=null){ var parms =_opt.url.split("?")[1], item,i=0,len; if(parms!=null){ parms = parms.split("&"); for(i=0,len=parms.length;i<len;i++){ item = parms[i].split("="); _opt.data[item[0]]=item[1]; } } } _.each(_opt.data,function(value,key){ if(_.isObject(value)){ value = JSON.stringify(value); } var _hiddenInput=document.createElement("input"); _hiddenInput.setAttribute("type","hidden"); _form.appendChild(_hiddenInput); _hiddenInput.setAttribute('name',key); _hiddenInput.setAttribute('value',value); }); } this.removeData=()=>{ _opt.data = null; _form.children().remove(); } this.addData=(data)=>{ _opt.data = _.extend({},_opt.data||{},data||{}); _form.children().remove(); this.setData(_opt.data); } this.delData=(keys)=>{ _.each(keys||[],function(val,i){ if((val in _opt.data)){ delete _opt.data[val]; } }); _form.children().remove(); this.setData(_opt.data); } this.formateUrl=(url)=>{ var params= this.formateParams(_opt.params); if(!url)return; _opt.url = url; if(params){ if(_opt.url.indexOf('?')>0){ _opt.url+='&'+params; }else{ _opt.url+='?'+params; } } } this.formateParams=(obj)=>{ if(obj==null) return null; return $.param(obj||{}); } this.submit=()=>{ if(_opt.cancelAction) return; _opt.cancelAction = false; if(_opt.autoDestroy){ setTimeout(function(){ _form.submit() //_form.find('#submit'+me.id).click();//谷歌下面要用 按钮才有效果 },0); setTimeout(function(){that.destroy();},1000); }else{ _form.submit(); } } this.destroy=()=>{ _el.remove(); } this.setTarget(_opt.target); this.setMethod(_opt.method); this.setUrl(_opt.url); this.setData(_opt.data); return that; }, }, }; </script> <style lang="less" scoped> .miniLoginBox{ ::v-deep .el-dialog__body{ padding-top:0; } } </style>
<template> <div class="pl-main"> <p-tabs ref="cmp-tabs" v-model="defTabKey" @onActiveTab="handleActiveTab" @onRemoveTab="handleRemoveTab" @onRemoveAllTab="handleRemoveAllTab" @onRemoveLeft="handleRemoveLeftTab" @onRemoveRight="handleRemoveRightTab" @onRemoveOther="handleRemoveOtherTab" @onFullScreen="handleFullScreen" :isSinglePage="sysConfig.isSinglePage" > <p-tabpanel v-for="(item,index) in tabList" :key="item.id" :close="item.close" :title.sync="item.title" :name="item.id" :url="item.url" :itemData="item" @onIframeLoad="handleIframeLoad" @onBeforeClose="handleBeforeClose" @onSelected="handleSelected" @onBeforeRefresh="handleBeforeRefresh" > <template v-if="item.type&&item.type=='home'"> <PortalSys :itemData="item" ref="protalSysHome" ></PortalSys> </template> <template v-if="item.type&&item.type=='work'"> <PortalUser :itemData="item" ref="portalUserWork" ></PortalUser> </template> </p-tabpanel> </p-tabs> <el-dialog class="miniLoginBox" width="410px" :visible.sync="isMiniLogin" :close-on-click-modal="false"> <iframe v-if="isMiniLogin" width="100%" height="380px" :src="miniLoginUrl" style="border:none;"></iframe> </el-dialog> </div> </template> <script> import {changeBz} from "@main/api/user"; import { baseURL, codeProjectName,requestUrl } from "@main/config"; import { PTabs, PTabpanel } from "@main/components/tabpanel"; import PortalUser from "@main/views/Portal/user"; import PortalSys from "@main/views/Portal/sys"; import { getUrlValue, setUrlValue,getUrlSearch,closeWindow } from "@main/utils"; import { getToken } from '@main/utils/auth' // import { type } from "os"; import md5 from "js-md5"; import { utils } from "hi-ui"; export default { inject: ["addTab", "showTab", "hideTab"], components: { PTabs, PTabpanel, PortalUser, PortalSys, }, data() { let cfg = this.$store.state.app.config || {}; let defTabs = cfg.sysDefTabs || []; let setTabs = cfg.sysSetTabs || []; let list = [], defTabKey = ""; defTabs = setTabs.concat(defTabs); defTabs.map((item, i) => { if(!window._global){//正式环境 item.url=utils.string.setUrlValue(item.url,"pn",window.HIVUI_SETTING.projectName); item.url=utils.string.setUrlValue(item.url,"access_token",getToken()); } let id = item.url ? md5(item.url) : item.id; //强转成 url md5 id // if(cfg.isSinglePage){//单页面模式 // id="123456789"; // } item.actived && (defTabKey = id); if (item.url && getUrlValue(item.url, "__tabId") == "") { //关系到用户调用,防止Scp.context.closeCurPage取不到__tabId出错 item.url = utils.string.setUrlValue(item.url, "__tabId", id); } /*if(cfg.isSinglePage){ list[0]={ title: item.title, url: item.url, close: item.close, id: id, type: item.type, }; }else*/{ list.push({ title: item.title, url: item.url, close: item.close, id: id, type: item.type, }); } }); console.log('page default open tabs :',defTabs); //系统菜单 后台默认配激活 let menusDef2Tabs = this.$store.getters.defTabs, uriStr = ""; console.log('menus default open tabs :',defTabs); menusDef2Tabs.map((item, i) => { //uriStr = baseURL + codeProjectName + item.resUrl; uriStr = item.resUrl; if(!window._global){//正式环境 uriStr=utils.string.setUrlValue(uriStr,"pn",window.HIVUI_SETTING.projectName); uriStr=utils.string.setUrlValue(uriStr,"access_token",getToken()); } if(uriStr.indexOf("http")==-1){ uriStr=location.origin+uriStr; } let id = md5(uriStr); uriStr = utils.string.setUrlValue(uriStr, "__tabId", id); list.push({ title: item.name, url: uriStr, close: true, id: id, type: item.type, }); }); // console.log('系统菜单',list); //第三方跳转过来地址自动打开功能tab let menusList = this.$store.getters.menusList; let searchObj = getUrlSearch(decodeURIComponent(this.$router.currentRoute.fullPath)); for (let i = menusList.length - 1; i >= 0; i--) { if ((menusList[i].type=="func"||menusList[i].type=="flow" )&& (searchObj.portal_func&&menusList[i].resUrl)&&searchObj.portal_func == menusList[i].resUrl) { console.log('跳转进来的功能:',searchObj.portal_func); //?portal_func=/project/rjwhzx/rjzcgl/funcdir/zcmcx.func&id=11111 delete searchObj.portal_func; // let uriStr = baseURL + codeProjectName + menusList[i].resUrl; let uriStr = menusList[i].resUrl; if(!window._global){//正式环境 uriStr=utils.string.setUrlValue(uriStr,"pn",window.HIVUI_SETTING.projectName); uriStr=utils.string.setUrlValue(uriStr,"access_token",getToken()); } if(uriStr.indexOf("http")==-1){ uriStr=location.origin+uriStr; } let id = md5(uriStr); uriStr = utils.string.setUrlValue(uriStr, "__tabId", md5(uriStr)); for(let key in searchObj){ uriStr = utils.string.setUrlValue(uriStr,key,searchObj[key]); } let inMenu = false; for (let j = list.length - 1; j >= 0; j--) { if (list[j].id == id) { inMenu = true; break; } } if (inMenu) break; defTabKey = id; list.push({ id: id, title: menusList[i].name, url: uriStr, close: true, actived:true //默认选中 }); break; } } if(cfg.isPageCache&&window.localStorage.getItem('pageCacheArr')){ JSON.parse(window.localStorage.getItem('pageCacheArr')).map((item,index)=>{ uriStr = item.url; if(!window._global){//正式环境 uriStr=utils.string.setUrlValue(uriStr,"pn",window.HIVUI_SETTING.projectName); uriStr=utils.string.setUrlValue(uriStr,"access_token",getToken()); } if(uriStr.indexOf("http")==-1){ uriStr=location.origin+uriStr; } let id = md5(uriStr); uriStr = utils.string.setUrlValue(uriStr, "__tabId", id); defTabKey = id; list.push({ title: item.title, url: uriStr, close: true, id: id, //type: item.type, }); }); } //地址栏打开标签 if(top.location.hash){ let hashTabParam={}; top.location.hash.replace("#/","").split("&zhc&").forEach((item=>{ if(item.indexOf("tabUrl=")==0){ hashTabParam.resUrl=item.replace("tabUrl=",""); }else if(item.indexOf("tabTitle=")==0){ hashTabParam.name=decodeURIComponent(item.replace("tabTitle=","")); } })); if(hashTabParam.resUrl){ if(hashTabParam.resUrl.indexOf("about:blank")==-1){//下推页面无法重新载入 //消除tabId干扰 let tabIdStr=hashTabParam.resUrl.match(/\__tabId=.*?&/)||hashTabParam.resUrl.match(/\?__tabId=.*/); if(tabIdStr&&tabIdStr[0]){ hashTabParam.resUrl=hashTabParam.resUrl.replace(tabIdStr[0],"").replace("?&","?"); } let id = md5(hashTabParam.resUrl); let existsItem=list.filter(item=>{//标签已存在 if(item.url&&hashTabParam.resUrl){ let itemMainUrl=item.url.split("?")[0]; let hashTabMainUrl=hashTabParam.resUrl.split("?")[0]; if(hashTabParam.resUrl.indexOf(itemMainUrl)!=-1){ return item; } } }); if(!existsItem[0]){ defTabKey = id; hashTabParam.resUrl = utils.string.setUrlValue(hashTabParam.resUrl, "__tabId", id); list.push({ title: hashTabParam.name, url: hashTabParam.resUrl, close: true, id: id, actived:true //默认选中 }); }else{ defTabKey=existsItem[0].id; } } } } console.log('sys default tabs :', list); return { defTabKey: defTabKey || "", tabList: list, sysConfig: this.$store.state.app.config, isFullScreen: false, isMiniLogin:false, miniLoginUrl:"", }; }, mounted() { // console.log('主界面初始化~!'); let me = this, cTabs = this.$refs["cmp-tabs"]; window.Sys = { isVue: true, addEvent(evtName, fn) { //onLoad Bus.$on(evtName, fn); }, tabPanel: { autoResize() { cTabs.resize(); }, }, getSideNavs() { return [...me.$store.getters.navs]; }, setSideNavs(data) { if (data == null && !(data instanceof Array)) return; //me.$store.dispatch("app/setQuickNav", data); }, /** * @param {} url * @param {} title * @param {} uid * @param {} onLoad //iframe 加载后 * @param {} nearest //标签页是否紧接在其右侧打开 * @param {} renderedFn //渲染回调 */ addTab(url, title, uid, onLoad, nearest, renderedFn) { // if(me.sysConfig.isSinglePage){//单页面模式 // uid="123456789"; // }else if(me.sysConfig.isPageCache){//页面标签缓存模式 let _pcarr=window.localStorage.getItem('pageCacheArr'); let cacheArr=_pcarr?JSON.parse(_pcarr):[]; cacheArr=cacheArr.filter((item)=>{ if(url!=item.url){ return item } }); cacheArr.push({ "url":url, "title":title, }); if(cacheArr.length>20){ cacheArr.shift(); } window.localStorage.setItem('pageCacheArr',JSON.stringify(cacheArr)); } if (!(url == "" || url == "about:blank")) { uid = md5(url); } if(!window._global){//正式环境 url=utils.string.setUrlValue(url,"pn",window.HIVUI_SETTING.projectName); url=utils.string.setUrlValue(url,"access_token",getToken()); } let tabs = me.tabList.filter((item, index) => { if(item.id == uid){ item.title=title; return item; } }); if (tabs.length/*&&!me.sysConfig.isSinglePage*/) { me.defTabKey = uid; me.$nextTick( (function (fn) { return function () { let tab = cTabs.getItemObj(uid); fn && fn(tab); }; })(renderedFn) ); return; } if (getUrlValue(url, "__tabId") == "") { //关系到用户调用,防止Scp.context.closeCurPage取不到__tabId出错 url = utils.string.setUrlValue(url, "__tabId", uid); } /*if(me.sysConfig.isSinglePage){ me.tabList.pop(); me.$nextTick(()=>{ me.tabList.push({ title: title, url: url, close: true, id: uid, listeners: { load: onLoad, }, }) }) }else{*/ me.tabList.push({ title: title, url: url, close: true, id: uid, listeners: { load: onLoad, }, }); //} me.defTabKey = uid; // window.____renderFunc = renderedFn; me.$nextTick( (function (fn, _uid) { return function () { let tab = cTabs.getItemObj(_uid); fn && fn(tab); }; })(renderedFn, uid) ); console.log(' addTab ',me.tabList); }, getTab(uid) { return cTabs.getItemObj(uid); }, seldTab(uid) { cTabs.defTabKey = uid; }, getSeldTab() { return cTabs.getSeldItemObj(); }, refreshTab(uid) { let tab = cTabs.getItemObj(uid); tab && tab.tabPanelIframeEl.contentWindow.window.location.reload(); }, //closeTab colseTab(uid) { cTabs.closeItem(uid); }, colseSeldTab() { cTabs.closeCurItem(); }, }; window.SysPage={ newPage : function(title, url, params, method, target) { var uid = md5((params&¶ms._ftaskguid)?(url+"?tguid="+params._ftaskguid):url), tab; function formSubmit(cfg){ cfg.autoDestroy = true; var form = me.creatForm(cfg); form.submit(); } if(method=="get"){ //get 不刷新 var tab = top.Sys.getTab(uid); if(tab){ top.Sys.seldTab(uid); return; } } if(target=="opening"){ var cfg = { url : utils.string.setUrlValue(url,"__tabId",uid), data : params, target : '_blank', method : method || "get" }; formSubmit(cfg); //打开新标签 return; }else if(target=="me"){ //本页:框架页的本页面 var cfg = { url : url, data : params, target : '_self', method : method || "get" }; formSubmit(cfg); }else{ if (target == "_self"){ tab = top.Sys.getSeldTab(); if(top.Sys.isVue){ var titleEl = tab.tabEl.querySelector('.pl-tabs-itemTxt'); titleEl.innerText = ""; }else{ tab.tabEl.find('.sys-tab-item-text').html(""); } }else{ /*** * uid 让框架页可以关闭自己 closeCurPage */ if(top.Sys.isVue){ //6个参数,第7个是vue渲染后回调 if(target == "_blank"){ uid+=utils.string.id(4); } top.Sys.addTab("about:blank",title,uid,null,true,function(tab){ if(!window._global){//正式环境 url=utils.string.setUrlValue(url,"pn",window.HIVUI_SETTING.projectName); url=utils.string.setUrlValue(url,"access_token",getToken()); } var cfg = { url : utils.string.setUrlValue(url,"__tabId",uid), data : params, target : null, method : method || "get" }; //var titleEl = tab.tabEl.querySelector('.pl-tabs-itemTxt'); //titleEl.innerText = ""; cfg.target = tab.tabPanelIframeEl.getAttribute('name'); formSubmit(cfg); }); }else{ var cfg = { url : utils.string.setUrlValue(url,"__tabId",uid), data : params, target : null, method : method || "get" }; //Sys.addTab(url, title, uid, callback) tab = top.Sys.addTab("about:blank",title,uid); tab.tabEl.find('.sys-tab-item-text').html(""); cfg.target = tab.tabPanelIframeEl.getAttribute('name'); formSubmit(cfg); } } } }, /** * 通过url 进行对应的目标功能 调用目标页的callback方法 * @param id * @param url */ closePage : function(id,url) { if (!top.Sys) { closeWindow() return; } var uid = md5(url||""), tab; if(!window.parent.Sys){ return; } var tab = window.parent.Sys.getTab(uid); if(tab){ window.parent.Sys.seldTab(uid); //var _scp = tab.tabPanelIframeEl.contentWindow.window.Scp; //if(_scp){ // _scp.context&&_scp.context.callback&&_scp.context.callback.call(_scp.context); //} }else{ if(url&&url.trim()!=""){ var tab = window.parent.Sys.addTab(url,"",null,null,true); } } if (id) { window.parent.Sys.colseTab(id); }else{ window.parent.Sys.colseSeldTab(); } }, closeCurPage:function(){ if(!window.parent.Sys){ return; } var id = getUrlValue(window.location.search,'__tabId'); window.parent.Sys.colseTab(id); }, setPageTitle:function(title){ if(!window.parent.Sys){ return; } var openway = getUrlValue('','openway'); if(openway=="openwin")return; var tab = window.parent.Sys.getSeldTab(); if(title!=""){ tab.tabEl.find('.sys-tab-item-text').html(title); window.parent.Sys.tabPanel.autoResize(); } }, //小登录弹窗打开 openMiniLogin:function(isRefresh){ if(window.HIVUI_SETTING.isSingleLogin||me.isMiniLogin){ return; } me.isMiniLogin=true; let params="questType=ajax"+(isRefresh?"&isRefresh=true":"")+"#"; let __login=window.HIVUI_SETTING.loginUrl.split("#"); me.miniLoginUrl=__login[0]+(__login[0].indexOf("?")==-1?"?":"&")+params+(__login[1]||"")+"miniLogin"; }, //小登录弹窗关闭 closeMiniLogin:function(isRefresh){ me.isMiniLogin=false; changeBz({ bzid:me.$store.state.user.userInfo.fbzid }); let tabId=location.href.match(/\?__tabId=.*?&/)[0].replace("?__tabId=","").replace("&",""); if(isRefresh&&tabId){ document.querySelector("iframe[name='iframe"+tabId+"']").contentWindow.location.reload(); } }, }; if (this.defTabKey == "" && this.tabList.length) this.defTabKey = this.tabList[0].id; //默认如果指向下面两个的话,标识一下已经加载过 if (this.$refs["protalSysHome"]) { //this.$store.dispatch("portal/loadSysList"); //重新加载系统门户列表 // console.log('加载系统门户列表~!'); let itemData = this.$refs["protalSysHome"][0].itemData; if (itemData.id == this.defTabKey) { this.$refs["protalSysHome"][0].actived = true; } } if (this.$refs["portalUserWork"]) { //this.$store.dispatch("portal/loadList"); //重新加载工作台门户列表 // console.log('加载工作台门户列表~!'); let itemData = this.$refs["portalUserWork"][0].itemData; if (itemData.id == this.defTabKey) { this.$refs["portalUserWork"][0].actived = true; } } let events = this.sysConfig.events; if (events) { this.$nextTick((r) => { events.onLoad && events.onLoad(); }); } }, methods: { //将框架页里头的a 标签进行转换 initATagUrl(el) { let aList = el.querySelectorAll("a"); aList.forEach(function (aTag, i) { if (aTag.href) { var httpUrl = new RegExp( "^((https|http|ftp|rtsp|mms)?://)" ); if ( httpUrl.test( aTag.href.replace(window.location.origin, "") ) ) { return false; } if (!aTag.onclick) { if (aTag.target == "_blank") { aTag.addEventListener("click", function (evt) { evt.preventDefault(); evt.stopPropagation(); var tabTitle = ""; if (aTag.title) { tabTitle = aTag.title; } var url = this.getAttribute("href"); var reg = /^\//gi; Sys.addTab(url, tabTitle, "", "", true); return false; }); } } } }); window.Sys.tabPanel.autoResize(); }, handleBeforeRefresh(panel, evt) { if (panel.itemData.type == "home") { // this.$store.state.app.sysList=[]; //this.$store.dispatch("portal/loadSysList"); //重新加载系统门户列表 return false; } if (panel.itemData.type == "work") { // this.$store.state.app.list=[]; //this.$store.dispatch("portal/loadList"); //重新加载工作台门户列表 return false; } }, handleIframeLoad(panelCmp, evt) { let me = this, key = panelCmp.name; let ifm = panelCmp.$refs["iframe"]; let tabData = panelCmp.itemData; if (tabData.listeners) { tabData.listeners.load && tabData.listeners.load(); } //转换A标签 me.initATagUrl(ifm.contentWindow.document.body); window.__UserInfo = { orgId: "", operator: "", }; if (panelCmp.title == null || panelCmp.title == "") { let cTabs = me.$refs["cmp-tabs"]; cTabs.resize(); } }, handleBeforeClose(panel, evt) { let ifm = panel.$refs["iframe"]; try { let flag = ifm.contentWindow.Scp.context.beforeunloadFn(evt, 1); return flag; } catch (e) { !document.all && window.console.log( "iframe : Scp.context.beforeunloadFn();" ); } }, handleActiveTab(panel) { if (!panel) return; top.location.hash="#/tabUrl="+panel.url+"&zhc&tabTitle="+panel.title; if (panel.itemData.type == "home") { this.$refs["protalSysHome"][0].doRender(); } if (panel.itemData.type == "work") { this.$refs["portalUserWork"][0].doRender(); } try { let tab = this.$refs["cmp-tabs"].getItemObj(panel.name); //tab.tabPanelIframeEl.contentDocument.trigger("iframeActiving", [panel.name]); tab.tabPanelIframeEl.contentDocument.dispatchEvent( new CustomEvent('iframeActiving', { detail:[panel.name] } ) ); } catch (e) { console.log("iframeActiving error!"); } }, //面板上面的事件特别处理,现在暂时没用 handleSelected(item) { return; let key = item.id; let ifm = this.$refs["dom-iframe" + key][0]; try { let __orgId = ifm.contentWindow.Scp.User.getId(); let __operator = ifm.contentWindow.Scp.User.getOperator(); window.__UserInfo = { orgId: __orgId, operator: __operator, }; } catch (e) {} }, handleRemoveTab(targetName) { let tabs = this.tabList; let activeName = this.defTabKey; if (activeName === targetName) { tabs.forEach((tab, index) => { if (tab.close && tab.id === targetName) { let nextTab = tabs[index + 1] || tabs[index - 1]; if (nextTab) { activeName = nextTab.id; } } }); } this.defTabKey = activeName; tabs = tabs.filter((tab) => { return tab.close == false || tab.id !== targetName; }); console.log('handleRemoveTab') this.$set(this, "tabList", tabs); if (this.tabList.length == 0) { this.defTabKey = "tabPanel_home"; } }, handleRemoveAllTab() { let tabs = this.tabList; this.tabList = tabs.filter((tab) => { return !tab.close; }); let l = this.tabList.length; this.defTabKey = l ? this.tabList[l - 1].id : ""; }, handleRemoveLeftTab(name, index) { let tabs = this.tabList; let defTabKey = this.defTabKey; this.tabList = tabs.filter((tab, i) => { if (tab.id == defTabKey && i < index) { //当前的选中,是在关闭区内 defTabKey = name; } return tab.close == false || i >= index; }); this.defTabKey = defTabKey; }, handleRemoveRightTab(name, index) { let tabs = this.tabList; let defTabKey = this.defTabKey; this.tabList = tabs.filter((tab, i) => { if (tab.id == defTabKey && i > index) { //当前的选中,是在关闭区内 defTabKey = name; } return tab.close == false || i <= index; }); this.defTabKey = defTabKey; }, handleRemoveOtherTab(name, index) { let tabs = this.tabList; tabs = tabs.filter((tab, i) => { return tab.close == false || i == index; }); this.$set(this, "tabList", tabs); this.defTabKey = name; }, handleFullScreen() { this.$emit("onFullScreen"); // screenfull.toggle() }, creatForm(opt){ let that=this; var _opt={ autoShow:false, cancelAction:false, url:null, target:null, action:null, method:null, params:null, data:null, autoDestroy:false, _id:utils.string.id(8), }; Object.assign(_opt,opt); var _formTpl=`<form style="display:none;" id="${_opt._id}"><input type="submit" value="submit" id="submit_${_opt._id}"/></form>`; var _el=document.createElement("div"); _el.innerHTML=_formTpl; document.getElementsByTagName("body")[0].appendChild(_el); var _form=_el.getElementsByTagName("form")[0]; this.setTarget=(str)=>{ _opt.target = str; _form.setAttribute('target',str); } this.setUrl=(str)=>{ this.formateUrl(str); var url = utils.string.setUrlValue(_opt.url,"_____r",new Date().getTime()); _form.setAttribute('action',url); } this.setMethod=(str)=>{ _opt.method = str||'get'; _form.setAttribute('method',str); } this.setParams=(params)=>{ _opt.params = params; } this.setData=(obj)=>{ _opt.data = obj||{}; if(_opt.method=="get"&&_opt.url!=null){ var parms =_opt.url.split("?")[1], item,i=0,len; if(parms!=null){ parms = parms.split("&"); for(i=0,len=parms.length;i<len;i++){ item = parms[i].split("="); _opt.data[item[0]]=item[1]; } } } _.each(_opt.data,function(value,key){ if(_.isObject(value)){ value = JSON.stringify(value); } var _hiddenInput=document.createElement("input"); _hiddenInput.setAttribute("type","hidden"); _form.appendChild(_hiddenInput); _hiddenInput.setAttribute('name',key); _hiddenInput.setAttribute('value',value); }); } this.removeData=()=>{ _opt.data = null; _form.children().remove(); } this.addData=(data)=>{ _opt.data = _.extend({},_opt.data||{},data||{}); _form.children().remove(); this.setData(_opt.data); } this.delData=(keys)=>{ _.each(keys||[],function(val,i){ if((val in _opt.data)){ delete _opt.data[val]; } }); _form.children().remove(); this.setData(_opt.data); } this.formateUrl=(url)=>{ var params= this.formateParams(_opt.params); if(!url)return; _opt.url = url; if(params){ if(_opt.url.indexOf('?')>0){ _opt.url+='&'+params; }else{ _opt.url+='?'+params; } } } this.formateParams=(obj)=>{ if(obj==null) return null; return $.param(obj||{}); } this.submit=()=>{ if(_opt.cancelAction) return; _opt.cancelAction = false; if(_opt.autoDestroy){ setTimeout(function(){ _form.submit() //_form.find('#submit'+me.id).click();//谷歌下面要用 按钮才有效果 },0); setTimeout(function(){that.destroy();},1000); }else{ _form.submit(); } } this.destroy=()=>{ _el.remove(); } this.setTarget(_opt.target); this.setMethod(_opt.method); this.setUrl(_opt.url); this.setData(_opt.data); return that; }, }, }; </script> <style lang="less" scoped> .miniLoginBox{ ::v-deep .el-dialog__body{ padding-top:0; } } </style>
Ignore Space
Show notes
View
project/hivuiSam/components/analysisSam/Index.vue
<template> <div class="container"> <!-- 工具条 --> <div class="btn-toolbar"> <!-- 后退 --> <el-dropdown split-button :size="size" :class="{disabled: backDisabled}" :disabled="backDisabled" @command="backCommand" @click="backClick"> <i class="el-icon-back"></i>后退 <el-dropdown-menu slot="dropdown"> <el-dropdown-item v-for="(item,index) in deepArr" :key="item.prop" :command="index" v-if="index < curIndex">{{ item.label }}</el-dropdown-item> </el-dropdown-menu> </el-dropdown> <!-- 前进 --> <el-dropdown split-button :size="size" :class="{disabled: goDisabled}" :disabled="goDisabled" @command="goCommand" @click="goClick"> <i class="el-icon-right"></i>前进 <el-dropdown-menu slot="dropdown"> <el-dropdown-item v-for="(item,index) in deepArr" :key="item.prop" :command="index" v-if="index > curIndex">{{ item.label }}</el-dropdown-item> </el-dropdown-menu> </el-dropdown> <!-- 排序 --> <el-dropdown split-button :size="size" class="sort" @command="sortClick"> <i class="el-icon-sort"></i>排序 <el-dropdown-menu slot="dropdown"> <el-dropdown-item :command="-1">不排序</el-dropdown-item> <el-dropdown-item v-for="(item, index) in sortArr" :key="item.prop" :command="index">{{ item.label }} <i class="el-icon-sort-down" :class="{ sortActive: index == sortIndex && sortType =='desc' }" @click="sortDown"></i> <i class="el-icon-sort-up" :class="{ sortActive: index == sortIndex && sortType =='asc' }" @click="sortUp"></i> </el-dropdown-item> </el-dropdown-menu> </el-dropdown> <!-- 分析列设置 --> <el-button icon="el-icon-setting" :size="size" @click="analysisClick">分析列设置</el-button> <el-dropdown :size="size" @command="chartTypeChange"> <el-button :size="size"> <i class="el-icon-s-data"></i> 图表<i class="el-icon-arrow-down el-icon--right"></i> </el-button> <el-dropdown-menu slot="dropdown"> <el-dropdown-item command="table">表格</el-dropdown-item> <el-dropdown-item command="pie">饼图</el-dropdown-item> <el-dropdown-item command="bar">柱图</el-dropdown-item> <el-dropdown-item command="line">线图</el-dropdown-item> <el-dropdown-item command="area">区域图</el-dropdown-item> </el-dropdown-menu> </el-dropdown> <!-- 刷新 --> <el-button icon="el-icon-refresh" :size="size" @click="refresh">刷新</el-button> <!-- 分析记录 --> <el-button icon="el-icon-edit-outline" :size="size" >分析记录</el-button> <!-- 叠加 --> <el-checkbox v-model="superposition" label="叠加" border :size="size" ></el-checkbox> <!-- 透视 --> <el-checkbox v-model="perspective" label="直接透视" border :size="size" ></el-checkbox> <el-button icon="el-icon-download" :size="size" :disabled="this.data && this.data.length == 0" :loading="exportLoading" @click="exportExcel">导出excel</el-button> </div> <!-- 内容区 --> <hi-layout :is-fit="true" style="heiht: 100%;"> <!-- 右侧查询面板 --> <hi-layout-right size="300" title="过滤条件"> <birt-work-book style="height: calc( 100% - 142px );border-bottom: 1px dashed #3179de;overflow: auto;" :conf="birtModelRight" :ref="birtModelRight.controlId" class="birtModelRight" ></birt-work-book> <el-form @submit.native.prevent ref="groupForm" style="padding: 10px 10px 0 0;" :model="groupForm" label-width="80px" > <el-form-item label="分组条件" prop="prop"> <i class="el-icon-edit" @click="showtransfer"></i> <el-select v-model="groupForm.prop" style="width: 100%;" placeholder="请选择分组条件"> <el-option v-for="item in groupFields" :label="item.label" :value="item.prop" :key="item.prop" ></el-option> </el-select> </el-form-item> <el-form-item> <el-button type="primary" size="mini" :loading="loading" @click="doCount" >执行查询</el-button > <el-button size="mini" @click="reset">重置</el-button> </el-form-item> </el-form> </hi-layout-right> <!-- 图表展示区 --> <hi-layout-center style="heiht: 100%;"> <div class="depth-analysis"> <span>深度分析:</span> <el-breadcrumb separator-class="el-icon-arrow-right" style="padding: 0 0 0 10px;" > <el-breadcrumb-item v-for="(item,index) in deepArr" :key="item.prop"> <span v-if="item.label.includes(',')" @click="breadcrumbClick(item.prop)" :class="{ deepActive: index == curIndex }" style="cursor: pointer;"> <span v-for="(it, i) in item.label.split(',')"> {{ it }} <span style="color: rgb(255, 102, 0);margin-left:2px;" v-if="index < curIndex">{{ item.selectVal.split(',')[i] }}</span> </span> </span> <span v-else @click="breadcrumbClick(item.prop)" :class="{ deepActive: index == curIndex }" style="cursor: pointer;"> {{ item.label }} <span style="color: rgb(255, 102, 0);margin-left:2px;" v-if="index < curIndex">{{ item.selectVal }}</span> </span> </el-breadcrumb-item> </el-breadcrumb> </div> <div v-if="showDetail" style="height: calc( 100% - 100px )"> <el-table :data="data" ref="table" height="100%" border stripe :show-summary="showSummary" header-row-class-name="tableHeader" style="width: 100%" > <el-table-column v-for="item in tableColumns" :key="item.prop" :prop="item.prop" :label="item.label" > </el-table-column> </el-table> <el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page="currentPage" :page-sizes="[10, 20, 50, 100]" :page-size="pageSize" layout="total, sizes, prev, pager, next, jumper" :total="total" > </el-pagination> </div> <div v-if="!showDetail && chartType == 'table'" style="height: calc( 100% - 100px )"> <el-table :data="data" ref="table" height="100%" border stripe :show-summary="showSummary" header-row-class-name="tableHeader" style="width: 100%" > <el-table-column v-for="item in tableColumns" :key="item.prop" :prop="item.prop" :label="item.label" > </el-table-column> </el-table> <el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page="currentPage" :page-sizes="[10, 20, 50, 100]" :page-size="pageSize" layout="total, sizes, prev, pager, next, jumper" :total="total" > </el-pagination> </div> <Pie-chart style="height: calc( 100% - 100px )" v-else-if="!showDetail && chartType == 'pie'" ref="chartConf" :conf="chartConf" ></Pie-chart> <Bar-chart style="height: calc( 100% - 100px )" v-else-if="!showDetail && chartType == 'bar'" ref="chartConf" :conf="chartConf" ></Bar-chart> <Line-chart style="height: calc( 100% - 100px )" v-else-if="!showDetail && chartType == 'line'" ref="chartConf" :conf="chartConf" ></Line-chart> <Line-chart style="height: calc( 100% - 100px )" v-else-if="!showDetail && chartType == 'area'" ref="chartConf" :conf="chartConf" ></Line-chart> </hi-layout-center> </hi-layout> <!-- 分析列 --> <el-dialog :visible.sync="analysisVisible" title="分析列设置" :height="500"> <el-table :data="analysisData" size="small" :height="400"> <el-table-column prop="countField" label="统计字段"> </el-table-column> <el-table-column prop="tableColumn" label="网格列" align="center"> <template slot="header" slot-scope="{row}"> <el-checkbox v-model="tableColumnCheck" @change="handelCheckAll('tableColumn')" label="网格列"></el-checkbox> </template> <template slot-scope="{row}"> <el-checkbox v-model="row.tableColumn"></el-checkbox> </template> </el-table-column> <el-table-column prop="tableColumn" label="网格合计列" align="center"> <template slot="header" slot-scope="{row}"> <el-checkbox v-model="tableColumnCountCheck" @change="handelCheckAll('tableColumnCount')" label="网格合计列"></el-checkbox> </template> <template slot-scope="{row}"> <el-checkbox v-model="row.tableColumnCount"></el-checkbox> </template> </el-table-column> <el-table-column prop="tableColumn" label="图表列" align="center"> <template slot="header" slot-scope="{row}"> <el-checkbox v-model="chartColumnCheck" @change="handelCheckAll('chartColumn')" label="图表列"></el-checkbox> </template> <template slot-scope="{row}"> <el-checkbox v-model="row.chartColumn"></el-checkbox> </template> </el-table-column> <el-table-column prop="chartColumnCount" label="图表列汇总" align="center"> <template slot="header" slot-scope="{row}"> <el-checkbox v-model="chartColumnCountCheck" @change="handelCheckAll('chartColumnCount')" label="图表列汇总"></el-checkbox> </template> <template slot-scope="{row}"> <el-checkbox v-model="row.chartColumnCount"></el-checkbox> </template> </el-table-column> </el-table> </el-dialog> <!-- 分析字段 --> <el-dialog :visible.sync="analysisFieldsVisible" title="选择分析字段" :height="500"> <Pie-chart style="height: 400px;" ref="analysisChart" :conf="analysisChartConf" ></Pie-chart> </el-dialog> <!-- 穿梭框(修改分组字段) --> <el-dialog :visible.sync="transferVisible" title="选择分组字段" :height="500" width="640px" center @close="transferClose"> <el-transfer class="sam" v-model="groupFieldsEdit" :data="conf.groupFields" :titles="['来源字段', '目标字段']" target-order="push" :props="{ key: 'prop', label: 'label' }" style="width: 100%;padding: 20px;"> <span slot-scope="{ option }">{{ option.label }} <el-button style="margin-left: 10px;" icon="el-icon-top" type="primary" size="mini" circle @click.stop="transferUp(option)"></el-button> <el-button icon="el-icon-bottom" type="primary" size="mini" circle @click.stop="transferDown(option)"></el-button> </span> </el-transfer> <span slot="footer" class="dialog-footer"> <el-button @click="transferClose" size="small">取 消</el-button> <el-button type="primary" size="small" @click="transferConfirm">确 定</el-button> </span> </el-dialog> </div> </template> <script> import { QueryStyleFactory } from "../templates/query-panel/QueryStyleFactory"; import { GridSingleSelect } from "../templates/GridSingleSelect"; import _ from 'lodash' export default { name: "AnalysisSam", props:{ conf:{ type: Object, } }, computed: { // 后退 backDisabled(){ return this.curIndex === 0 }, // 前进 goDisabled(){ return this.curIndex == this.deepArr.length - 1 }, // 表格列 tableColumns() { if(this.showDetail){ return this.dataFields }else{ // 组合分组条件分成多个列 let list = this.curGroupField.split(',') // 获取当前分组列 let curGroupArr = this.groupFields.filter(item =>{ return list.includes(item.prop) }) // 当前分组列+分析列 let arr = curGroupArr.concat(this.analyseFields) if(arr && arr.length){ this.sortArr = arr } return arr } }, // 网格是否显示合计行 showSummary(){ let flag = false this.analysisData.some(item =>{ flag = item.tableColumnCount return flag }) return flag }, // 数据列 dataFields(){ return this.conf && this.conf.dataFields || [] }, // 图表配置 chartConf() { debugger let groupBy = this.curGroupField; let calcFields = [] calcFields = this.analyseFields.map(item =>{ let obj = { name: item.prop, title: item.label } return obj }) let controlName = '' let datas = this.data // 组合分组条件时,数据添加组合列 if(groupBy.includes(',')){ let keyArr = groupBy.split(','); datas = datas.map(item =>{ let label = [] for(let key of keyArr){ label.push(item[key]) } label=label.join(); item[groupBy] = label return item }) } controlName = this.chartType == "pie" ? "PieChart" : this.chartType == "bar" ? "BarChart" : this.chartType == "line" ? "LineChart" : this.chartType == "area" ? "LineChart" : 'PieChart' // 区域图 let areaSeries = calcFields.map(item =>{ return { smooth: true, areaStyle: { normal: { color: new this.$echarts.graphic.LinearGradient(0, 0, 0, 1, [{ offset: 0, color: "rgba(30, 231, 231, 0.3)" },{ offset: 1, color: "rgba(30, 231, 231, 0.1)" }]), }, }, label: { show: false, position: "outside", }, } }) // 饼图 var pieSeries = [] if(this.chartType == "pie"){ let len = calcFields.length switch(len){ case 1: pieSeries = []; break; case 2: pieSeries = [ { radius: ["50%"], center: ["25%", "50%"], }, { radius: ["50%"], center: ["75%", "50%"], }, ] break; case 3: pieSeries = [ { radius: ["50%"], center: ["25%", "50%"], }, { radius: ["35%"], center: ["75%", "30%"], }, { radius: ["35%"], center: ["75%", "70%"], }, ] break; case 4: pieSeries = [ { radius: ["35%"], center: ["25%", "30%"], }, { radius: ["35%"], center: ["25%", "70%"], }, { radius: ["35%"], center: ["75%", "30%"], }, { radius: ["35%"], center: ["75%", "70%"], }, ] break; } } // 其他 var series = [] const conf = { controlName: controlName, controlId: "chart_controlid", height: "100%", isGroupData: true, groupBy: groupBy, datas: datas, calcFields: calcFields, option: { legend: { show: true }, series: this.chartType == "area" ? areaSeries : this.chartType == "pie" ? pieSeries : series }, events:{ click(row){ let _this = this.$parent.$parent.$parent; _this.currentObj = row.data _this.currentObj.prop = _this.curGroupField; if(_this.perspective){ var index = -1 _this.deepArr.forEach((item,i)=>{ if(item.prop == _this.curGroupField){ index = i } }) if(index > -1 && index < _this.deepArr.length - 1){ _this.analysisFieldsVisible = false _this.curIndex = _this.curIndex + 1 _this.currentObj = _this.deepArr[_this.curIndex]; _this.data = _this.currentObj.data _this.curGroupField = _this.currentObj.prop; }else{ _this.analysisChartConf.datas = _this.deepAnalysisFields _this.analysisFieldsVisible = true } }else{ _this.analysisChartConf.datas = _this.deepAnalysisFields _this.analysisFieldsVisible = true } } } }; return conf }, // 深度分析字段列表 deepAnalysisFields(){ let fields = this.groupFields if(fields && fields.length == 0){ return [] } let analysisFields = fields.map((item) => { item.value = 1 return item }); // 排除已经统计的分析列 if(this.deepArr && this.deepArr.length > 0){ let arrnew = this.deepArr.slice(0, this.curIndex + 1).map((item) => { return item.prop }); analysisFields = analysisFields.filter(item =>{ return arrnew.indexOf(item.prop) < 0 }) } // 添加详情 analysisFields.push( { prop: 'detail', label: "详情", value: 1 } ) return analysisFields }, // 查询字段 queryFields(){ let queryFields = [] let fields = this.conf && this.conf.queryFields if(!fields || fields.length == 0){ queryFields = [] }else{ queryFields = fields.map(item =>{ let obj = {} obj.prop = item.prop if(item.props && item.props.lookup){ let model = item.props.lookup if(item.element === 'hi-select-grid'){ var columns = [] if(model && model.columns && model.columns.length){ columns = model.columns.map(item =>{ item.prop = item.name return item }) } obj.lookup = { type: "data", openstyle: 'selectgrid', bindField: item.prop, lookSelectGrid: { width: 1200, height: 600, table: { columns: columns, }, bindField: item.prop, tableData: model && model.sourceDatas, }, } obj.dbtype = 'dbString' }else if(item.element === 'hi-data-select'){ var columns = [] if(model && model.columns && model.columns.length){ columns = model.columns.map(item =>{ item.prop = item.name return item }) } let queryOptionFields = model.queryOption.fields let store = model.storeCfg || model.sourceDsCfg let modelFilePath =store.modelFile let fields = store.fields let rows = queryOptionFields.map(item =>{ return {children:[ { prop: item.name, label: item.label } ]} }); let cols = queryOptionFields.map(item =>{ return { colWidth: 100} }); let queryPanel = { rows: rows, cols: cols }; let tableColumn = model.columns.map(item =>{ return { prop: item.name, label: item.label } }) let table = { children:tableColumn } let ds = { controlName: "HcDataset", controlId: modelFilePath, name: model.entityDs, modelFilePath: modelFilePath, _infcPagging: { pageSize: 10, pageNum: 1, returnCount: true }, _infcLoad: { autoActive: true, }, fields: fields, data: [], } obj.lookup = { type: "data", openstyle: 'dialog', birtModel: GridSingleSelect({ mainDataset: ds, hcQueryPanel: queryPanel, hcTable: table }), lookDataset: { modelFilePath: modelFilePath, // 数据模型路径 }, lookDialog: { title: "", width: 900, height: 600, }, bindField: item.prop, sourceDsId: model.sourceDsId } obj.dbtype = 'dbString' } } return obj }) } return queryFields }, // 数据集字段 fields(){ let fields = this.conf.dataset && this.conf.dataset.config.fields for(let key in this.queryFields){ let prop = this.queryFields[key].prop if(fields[prop] && fields[prop].lookup){ let lookup = Object.assign(fields[prop].lookup, this.queryFields[key].lookup) // 下拉枚举查找 if(lookup.label && lookup.returnFields){ for(let key in lookup.returnFields){ if(lookup.returnFields[key] == lookup.label){ lookup.bindShowField = key lookup.lookSelectGrid.bindShowField = key } if(lookup.lookSelectGrid && lookup.lookSelectGrid.tableData){ let data = lookup.lookSelectGrid.tableData for(let i in data){ if(data[i][lookup.returnFields[key]]){ data[i][key] = data[i][lookup.returnFields[key]] } } } } } // 数据模型查找 if(lookup.fieldPair && lookup.sourceDsId){ lookup.returnFields = lookup.fieldPair[lookup.sourceDsId].returnFields } fields[prop]['lookup'] = lookup } } // 应用默认填充表达式 for(let key in fields){ if(fields[key].default && fields[key].default.exps){ fields[key].default['expr'] = fields[key].default.exps } } return fields }, // 数据集 dataset(){ var dataset = {} if(this.conf && this.conf.dataset){ let ds = this.conf.dataset dataset = { controlName: ds.controlName, controlId: ds.controlId, name: ds.name, modelFilePath: ds.modelFilePath, fields: this.fields, _infcLoad: { autoActive: false }, _infcPagging: { returnCount: true, pageSize: 100, pageNum: 1 }, data: [], } } return dataset }, // 查询面板 birtModelRight(){ let rows = this.queryFields.map(item =>{ return {children:[item],colspan: 6} }) let cols = this.queryFields.map(item =>{ return { colWidth: 60 } }) const queryPanel = { rows: rows, cols: cols }; let hcQueryPanel = { controlName: "HcQueryPanel", controlId: "HcQueryPanel_sam", inline: false, dataset: this.dataset && this.dataset.controlId || "dsSam", size: "small", hideBtn: true, style: "width: 100%;", children: [], }; Object.assign(hcQueryPanel, QueryStyleFactory.buildForm(queryPanel) || {}); let birtModelRight = { controlName: "BirtWorkBook", controlId: "BirtWorkBook_right", style: "border-bottom: 1px solid #eee;", showToolBar: false, children: [ { controlName: "BirtSheet", controlId: "BirtSheet_right", name: "sheet0", pageIndex: 0, dataSets: [].concat(this.dataset ? this.dataset : []), children: [ { controlName: "BirtFormSheet", controlId: "BirtFormSheet_01", children: [hcQueryPanel] } ] } ], }; return birtModelRight }, // 分组条件(统计字段) groupFields(){ let groupFields = this.conf && _.cloneDeep(this.conf.groupFields) || [] // 组合分组条件 if(this.curTransferVal && this.curTransferVal.length){ let obj = {} let curTransferLabel = this.curTransferVal.map(item =>{ for(var field of groupFields){ if(field.prop == item){ return field.label } } }) obj = { prop: this.curTransferVal.join(), label: curTransferLabel.join() } groupFields.push(obj) } return groupFields }, // 分析字段 analyseFields(){ return this.conf && this.conf.analyseFields || [] }, // 显示详情 showDetail(){ return this.currentObj.prop == 'detail' }, }, watch:{ conf:{ deep: true, handler: function(val){ if(val && val.groupFields && !this.groupForm.prop){ this.groupForm.prop = val.groupFields[0] && val.groupFields[0].prop this.curGroupField = this.groupForm.prop } if(val && val.analyseFields && val.analyseFields.length){ this.analysisData=val.analyseFields.map(item =>{ let obj = { prop: item.prop, countField: item.label, tableColumn: true, tableColumnCount: true, chartColumn: true, chartColumnCount: true, } return obj }) } } }, }, data() { return { size: 'small', superposition: false, perspective: false, chartType: "table", groupForm: { prop: "" }, loading: false, currentPage: 1, pageSize: 100, total: 0, data: [], // 排序 sortArr:[], sortIndex:-1, sortType: '', // 分析列 analysisVisible: false, analysisData:[], tableColumnCheck: true, tableColumnCountCheck: true, chartColumnCheck: true, chartColumnCountCheck: true, // 分析字段 analysisFieldsVisible: false, analysisFieldsArr:[], analysisChartConf:{ controlName: "PieChart", controlId: "chart_analysis", height: "100%", isGroupData: true, groupBy: "label", datas: [], calcFields: [ { name: "value", title: "" } ], option: { legend: { show: true } }, events:{ click(row){ debugger; var _this = this.$parent.$parent; _this.analysisChartConf.datas = _this.deepAnalysisFields let data = JSON.parse(JSON.stringify(row.data)) delete data.emphasis // 删除当前分析以后的深度分析 _this.deepArr.splice(_this.curIndex+1, _this.deepArr.length - _this.curIndex - 1) let obj = _this.deepArr[_this.deepArr.length -1] obj.selectVal = _this.currentObj.name _this.$set(_this.deepArr,_this.curIndex,obj) _this.$set(_this.deepArr,_this.curIndex + 1, data) _this.curGroupField = data.prop; _this.currentObj = data; _this.curIndex = _this.curIndex + 1; _this.doQuery(); _this.analysisFieldsVisible = false; } } }, // 深度分析 deepArr:[], conf:{}, // 图表当前选中对象 currentObj:{}, // 当前分组字段 curGroupField: '', // 深度分析当前环节下标 curIndex: 0, exportLoading: false, // 穿梭框 transferVisible: false, curTransferVal: [], groupFieldsEdit: [], } }, updated() { this.$nextTick(() => { this.$refs["table"] && this.$refs["table"].doLayout(); }); }, methods: { // 排序 sortClick(val) { this.sortIndex = val }, sortDown(){ this.sortType = 'desc' }, sortUp(){ this.sortType = 'asc' }, // 前进 goCommand(val){ let index = this.curIndex + val; this.curIndex = index; this.currentObj = this.deepArr[index]; this.curGroupField = this.currentObj.prop; this.data = this.currentObj.data }, goClick:_.debounce(function(){ if(this.curIndex < this.deepArr.length - 1){ this.curIndex = this.curIndex + 1; this.currentObj = this.deepArr[this.curIndex]; this.curGroupField = this.currentObj.prop; this.data = this.currentObj.data } },500), // 后退 backCommand(val){ this.curIndex = val this.currentObj = this.deepArr[val]; this.curGroupField = this.currentObj.prop; this.data = this.currentObj.data }, backClick:_.debounce(function(){ if(this.curIndex > 0){ this.curIndex = this.curIndex - 1 this.currentObj = this.deepArr[this.curIndex]; this.curGroupField = this.currentObj.prop; this.data = this.currentObj.data } },500), // 深度分析 breadcrumbClick(val) { this.curGroupField = val let arrnew = this.deepArr.map(item =>{ return item.prop }) this.curIndex = arrnew.indexOf(val) this.currentObj = this.deepArr[this.curIndex]; // 数据替换成缓存的数据 this.data = this.currentObj.data }, // 点击查询 doCount() { debugger; // 监听数据集 if(this.dataset && this.deepArr.length == 0){ let ds = this.$refs.BirtWorkBook_right.dataset[this.dataset.controlId] ds && ds.on("afterLoadData", this.afterLoadData); } this.loading = true; let prop = this.groupForm.prop; let fields = this.groupFields.map(item =>{ return item.prop }) this.curGroupField = prop; let index = fields.indexOf(prop) if(this.deepArr.length){ // 如果切换了分组条件,清空深度分析 if(this.deepArr[0] && this.deepArr[0].prop !== prop){ this.deepArr = [] this.currentObj = this.groupFields[index] }else{ this.currentObj = this.deepArr[0] } } this.doQuery(); // 当前分组加入深度分析 if(index < 0){ this.$message.error('当前分组条件不在分组字段中,请重新配置') }else{ this.$set(this.deepArr,0,this.groupFields[index]) this.curIndex = 0 } }, afterLoadData(datas){ debugger this.data = datas // 缓存数据 this.deepArr[this.curIndex].data = datas; let ds = this.$refs.BirtWorkBook_right.dataset[this.dataset.controlId] this.total = ds._infcPagging.recordCount }, // 查询方法 doQuery(){ let ds = this.$refs.BirtWorkBook_right.dataset[this.dataset.controlId] if(this.showDetail){ ds._infcPagging = { _isPagging: true, pageSize: this.pageSize, pageNum: this.currentPage, returnCount: true }; ds._infcStat = {} ds._infcSort = {} }else{ ds._infcPagging = { _isPagging: true, pageSize: this.pageSize, pageNum: this.currentPage, returnCount: true }; ds._infcStat = { isGroupData: true, groupBy: this.curGroupField, } if(this.sortIndex > -1){ let obj = this.sortArr[this.sortIndex] ds._infcSort.orderBy =[{ name: obj.prop, desc: obj.label, type: this.sortType || 'desc' }] }else{ ds._infcSort.orderBy = [] } } ds.query(); this.loading = false; }, // 重置 reset() { this.$refs.groupForm.resetFields(); this.curTransferVal = [] this.groupForm.prop = this.groupFields[0] && this.groupFields[0].prop; var queryPanel = this.$refs.BirtWorkBook_right.$children[0].$children[0].$children[0].$children[0].$children[0].$children[0]; queryPanel.reset(); let ds = this.$refs.BirtWorkBook_right.dataset[this.dataset.controlId] ds._infcLoad.queryModel={} }, handleSizeChange(val) { this.pageSize = val }, handleCurrentChange(val) { this.currentPage = val }, // 切换图表 chartTypeChange(command) { this.chartType = command; }, // 打开分析列 analysisClick(){ this.analysisVisible = true }, // 分系列全选 handelCheckAll(val){ debugger let _this = this this.analysisData = this.analysisData.map(item => { if(val == 'tableColumn') { item.tableColumn = _this.tableColumnCheck } if(val == 'tableColumnCount') { item.tableColumnCount = _this.tableColumnCountCheck } if(val == 'chartColumn') { item.chartColumn = _this.chartColumnCheck } if(val == 'chartColumnCount') { item.chartColumnCount = _this.chartColumnCountCheck } return item }) }, // 刷新 refresh(){ this.doQuery(); this.$refs.chartConf && this.$refs.chartConf.refreshChart(); }, // 导出 exportExcel() { let param = { pageNum: -1, pageSize: -1, __slaveExport: false, }; let __body = {}; let ds = this.$refs.BirtWorkBook_right.dataset[this.dataset.controlId] var cdion = ds.lastLoadCdion console.log('cdion', cdion) if (cdion) { __body['queryCdions'] = JSON.parse(cdion); } param['modelFilePath'] = ds['modelFilePath']; param['__funcpath'] = ds['__funcpath']; param.__body = __body let sheetStyle = {} let cells = [] let columns = [] this.tableColumns.forEach(item => { cells.push({ title: item.label, colspan: 1, rowspan: 1 }) columns.push({ fields: item.prop, width: 70 }) }); sheetStyle = { name: '统计分析', titleRows: [ { cells: cells } ], columns: columns } param.__sheetStyle = sheetStyle var data = { __sheetDatas: JSON.stringify([param]) } var url = this.$HI.exportUrl this.exportLoading = true this.$HI.request.post(url,data).then((res) =>{ console.log('res', res) this.exportLoading = false if(res.status == 200){ let token = getToken(); var url = this.$HI.download + `?path=${res.dataPack.path}&access_token=${token}` url = url.replace(/\\/g,"/") const a = document.createElement('a') //创建a标签 a.style.display = 'none' a.href = url // 指定下载链接 // a.download = '用户信息.xlsx' //指定下载文件名 a.click() //触发下载 } }).catch((e) =>{ this.exportLoading = false }) }, // 打开穿梭框 showtransfer(){ this.groupFieldsEdit = JSON.parse(JSON.stringify(this.curTransferVal)) this.transferVisible = true }, transferConfirm(){ if(this.groupFieldsEdit && this.groupFieldsEdit.length > 1){ this.curTransferVal = JSON.parse(JSON.stringify(this.groupFieldsEdit)) this.groupForm.prop = this.curTransferVal.join(); this.curGroupField = this.groupForm.prop; this.transferVisible = false }else{ this.$message.error("该分组选项已存在") } }, transferClose(){ this.transferVisible = false this.groupFieldsEdit = JSON.parse(JSON.stringify(this.curTransferVal)) }, transferUp(option){ let arr = this.groupFieldsEdit let index = this.groupFieldsEdit.indexOf(option.prop) if(index > 0){ arr.splice(index - 1, 1, ...arr.splice(index, 1, arr[index - 1])); } }, transferDown(option){ let arr = this.groupFieldsEdit let index = this.groupFieldsEdit.indexOf(option.prop) if(index < arr.length){ arr.splice(index, 1, ...arr.splice(index + 1, 1, arr[index])); }; }, }, mounted() { } }; </script> <style> .birtModelRight .el-main{ padding: 5px !important; } .birtModelRight table.zhc-birt-data-list{ table-layout: auto !important; border-collapse: initial !important; border-spacing: revert !important; } .el-transfer.sam .el-transfer-panel:nth-child(1) button{ display: none; } .el-dropdown.disabled .el-button, .el-dropdown.disabled .el-button:hover{ cursor: not-allowed; color: #C0C4CC; cursor: not-allowed; background-image: none; background-color: #FFF; border-color: #EBEEF5; } .tableHeader th, .tableHeader tr{ background: linear-gradient(0deg,rgba(224,240,255,1), rgba(240,247,255,1)); } </style> <style lang="scss" scoped> .container { position: relative; display: flex; flex-direction: column; height: 100%; padding: 20px; } .btn-toolbar { * + * { margin-left: 10px; margin-right: 0; } } .el-dropdown-menu__item { min-width: 90px; } .center-content { height: 100%; width: 100%; padding: 10px; box-sizing: border-box; } .depth-analysis { display: flex; align-items: center; padding: 10px; } .el-breadcrumb__item a { cursor: pointer !important; } .deepActive{ color: #06c; font-weight: 600; } .sortActive{ color: rgb(33, 235, 141); font-weight: 600; } >>>.el-dropdown-menu__item:focus, .el-dropdown-menu__item:not(.is-disabled):hover{ background: initial; color: initial; } .el-dropdown-menu__item i{ font-weight: 600; margin: 0 0 0 5px; } .el-dropdown-menu__item i:hover { color: rgb(33, 235, 141); } .birtModelRight .el-main{ padding: 5px !important; } .el-icon-edit{ right: 30px; position: absolute; z-index: 1; line-height: 30px; cursor: pointer; } >>>.el-dropdown.disabled .el-button, >>>.el-dropdown.disabled .el-button:hover{ cursor: not-allowed; color: #C0C4CC; cursor: not-allowed; background-image: none; background-color: #FFF; border-color: #EBEEF5; } </style>
<template> <div class="container"> <!-- 工具条 --> <div class="btn-toolbar"> <!-- 后退 --> <el-dropdown split-button :size="size" :disabled="backDisabled" @command="backCommand" @click="backClick"> <i class="el-icon-back"></i>后退 <el-dropdown-menu slot="dropdown"> <el-dropdown-item v-for="(item,index) in deepArr" :key="item.prop" :command="index" v-if="index < curIndex">{{ item.label }}</el-dropdown-item> </el-dropdown-menu> </el-dropdown> <!-- 前进 --> <el-dropdown split-button :size="size" :disabled="goDisabled" @command="goCommand" @click="goClick"> <i class="el-icon-right"></i>前进 <el-dropdown-menu slot="dropdown"> <el-dropdown-item v-for="(item,index) in deepArr" :key="item.prop" :command="index" v-if="index > curIndex">{{ item.label }}</el-dropdown-item> </el-dropdown-menu> </el-dropdown> <!-- 排序 --> <el-dropdown split-button :size="size" class="sort" @command="sortClick"> <i class="el-icon-sort"></i>排序 <el-dropdown-menu slot="dropdown"> <el-dropdown-item :command="-1">不排序</el-dropdown-item> <el-dropdown-item v-for="(item, index) in sortArr" :key="item.prop" :command="index">{{ item.label }} <i class="el-icon-sort-down" :class="{ sortActive: index == sortIndex && sortType =='desc' }" @click="sortDown"></i> <i class="el-icon-sort-up" :class="{ sortActive: index == sortIndex && sortType =='asc' }" @click="sortUp"></i> </el-dropdown-item> </el-dropdown-menu> </el-dropdown> <!-- 分析列设置 --> <el-button icon="el-icon-setting" :size="size" @click="analysisClick">分析列设置</el-button> <el-dropdown :size="size" @command="chartTypeChange"> <el-button :size="size"> <i class="el-icon-s-data"></i> 图表<i class="el-icon-arrow-down el-icon--right"></i> </el-button> <el-dropdown-menu slot="dropdown"> <el-dropdown-item command="table">表格</el-dropdown-item> <el-dropdown-item command="pie">饼图</el-dropdown-item> <el-dropdown-item command="bar">柱图</el-dropdown-item> <el-dropdown-item command="line">线图</el-dropdown-item> <el-dropdown-item command="area">区域图</el-dropdown-item> </el-dropdown-menu> </el-dropdown> <!-- 刷新 --> <el-button icon="el-icon-refresh" :size="size" @click="refresh">刷新</el-button> <!-- 分析记录 --> <!-- <el-button icon="el-icon-edit-outline" :size="size" >分析记录</el-button> --> <!-- 叠加 --> <!-- <el-checkbox v-model="superposition" label="叠加" border :size="size" ></el-checkbox> --> <!-- 透视 --> <!-- <el-checkbox v-model="perspective" label="直接透视" border :size="size" ></el-checkbox> --> <el-button icon="el-icon-download" :size="size" :disabled="this.data && this.data.length == 0" :loading="exportLoading" @click="exportExcel">导出excel</el-button> </div> <hi-layout :is-fit="true" style="heiht: 100%;"> <!-- 右侧查询面板 --> <hi-layout-right size="300" title="过滤条件"> <birt-work-book style="height: calc( 100% - 142px );border-bottom: 1px dashed #3179de;overflow: auto;" :conf="birtModelRight" :ref="birtModelRight.controlId" class="birtModelRight" ></birt-work-book> <el-form @submit.native.prevent ref="groupForm" style="padding: 10px 10px 0 0;" :model="groupForm" label-width="80px" > <el-form-item label="分组条件" prop="prop"> <i class="el-icon-edit" @click="showtransfer"></i> <el-select v-model="groupForm.prop" style="width: 100%;" placeholder="请选择分组条件"> <el-option v-for="item in groupFields" :label="item.label" :value="item.prop" :key="item.prop" ></el-option> </el-select> </el-form-item> <el-form-item> <el-button type="primary" size="mini" :loading="loading" @click="doCount" >执行查询</el-button > <el-button size="mini" @click="reset">重置</el-button> </el-form-item> </el-form> </hi-layout-right> <!-- 图表展示区 --> <hi-layout-center style="heiht: 100%;"> <div class="depth-analysis"> <span>深度分析:</span> <el-breadcrumb separator-class="el-icon-arrow-right" style="padding: 0 0 0 10px;" > <el-breadcrumb-item v-for="(item,index) in deepArr" :key="item.prop"><span @click="breadcrumbClick(item.prop)" :class="{ deepActive: index == curIndex }" style="cursor: pointer;">{{ item.label }}<span style="color: rgb(255, 102, 0);margin-left:2px;" v-if="index < curIndex">{{ item.selectVal }}</span></span></el-breadcrumb-item> </el-breadcrumb> </div> <div v-if="showDetail" style="height: calc( 100% - 100px )"> <el-table :data="data" ref="table" height="100%" border :show-summary="showSummary" style="width: 100%" > <el-table-column v-for="item in tableColumns" :key="item.prop" :prop="item.prop" :label="item.label" > </el-table-column> </el-table> <el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page="currentPage" :page-sizes="[10, 20, 50, 100]" :page-size="10" layout="total, sizes, prev, pager, next, jumper" :total="total" > </el-pagination> </div> <div v-if="!showDetail && chartType == 'table'" style="height: calc( 100% - 100px )"> <el-table :data="data" ref="table" height="100%" border :show-summary="showSummary" style="width: 100%" > <el-table-column v-for="item in tableColumns" :key="item.prop" :prop="item.prop" :label="item.label" > </el-table-column> </el-table> <el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page="currentPage" :page-sizes="[10, 20, 50, 100]" :page-size="pageSize" layout="total, sizes, prev, pager, next, jumper" :total="total" > </el-pagination> </div> <Pie-chart style="height: calc( 100% - 100px )" v-else-if="!showDetail && chartType == 'pie'" ref="chartConf" :conf="chartConf" ></Pie-chart> <Bar-chart style="height: calc( 100% - 100px )" v-else-if="!showDetail && chartType == 'bar'" ref="chartConf" :conf="chartConf" ></Bar-chart> <Line-chart style="height: calc( 100% - 100px )" v-else-if="!showDetail && chartType == 'line'" ref="chartConf" :conf="chartConf" ></Line-chart> <Line-chart style="height: calc( 100% - 100px )" v-else-if="!showDetail && chartType == 'area'" ref="chartConf" :conf="chartConf" ></Line-chart> </hi-layout-center> </hi-layout> <!-- 分析列 --> <el-dialog :visible.sync="analysisVisible" title="分析列设置" :height="500"> <el-table :data="analysisData" size="small" :height="400"> <el-table-column prop="countField" label="统计字段"> </el-table-column> <el-table-column prop="tableColumn" label="网格列" align="center"> <template slot="header" slot-scope="{row}"> <el-checkbox v-model="tableColumnCheck" @change="handelCheckAll('tableColumn')" label="网格列"></el-checkbox> </template> <template slot-scope="{row}"> <el-checkbox v-model="row.tableColumn"></el-checkbox> </template> </el-table-column> <el-table-column prop="tableColumn" label="网格合计列" align="center"> <template slot="header" slot-scope="{row}"> <el-checkbox v-model="tableColumnCountCheck" @change="handelCheckAll('tableColumnCount')" label="网格合计列"></el-checkbox> </template> <template slot-scope="{row}"> <el-checkbox v-model="row.tableColumnCount"></el-checkbox> </template> </el-table-column> <el-table-column prop="tableColumn" label="图表列" align="center"> <template slot="header" slot-scope="{row}"> <el-checkbox v-model="chartColumnCheck" @change="handelCheckAll('chartColumn')" label="图表列"></el-checkbox> </template> <template slot-scope="{row}"> <el-checkbox v-model="row.chartColumn"></el-checkbox> </template> </el-table-column> <el-table-column prop="chartColumnCount" label="图表列汇总" align="center"> <template slot="header" slot-scope="{row}"> <el-checkbox v-model="chartColumnCountCheck" @change="handelCheckAll('chartColumnCount')" label="图表列汇总"></el-checkbox> </template> <template slot-scope="{row}"> <el-checkbox v-model="row.chartColumnCount"></el-checkbox> </template> </el-table-column> </el-table> </el-dialog> <!-- 分析字段 --> <el-dialog :visible.sync="analysisFieldsVisible" title="选择分析字段" :height="500"> <Pie-chart style="height: 400px;" ref="analysisChart" :conf="analysisChartConf" ></Pie-chart> </el-dialog> <!-- 穿梭框(修改分组字段) --> <el-dialog :visible.sync="transferVisible" title="选择分组字段" :height="500" width="640px" center @close="transferClose"> <el-transfer class="sam" v-model="groupFieldsEdit" :data="conf.groupFields" :titles="['来源字段', '目标字段']" target-order="push" :props="{ key: 'prop', label: 'label' }" style="width: 100%;padding: 20px;"> <span slot-scope="{ option }">{{ option.label }} <el-button style="margin-left: 10px;" icon="el-icon-top" type="primary" size="mini" circle @click.stop="transferUp(option)"></el-button> <el-button icon="el-icon-bottom" type="primary" size="mini" circle @click.stop="transferDown(option)"></el-button> </span> </el-transfer> <span slot="footer" class="dialog-footer"> <el-button @click="transferClose" size="small">取 消</el-button> <el-button type="primary" size="small" @click="transferConfirm">确 定</el-button> </span> </el-dialog> </div> </template> <script> import { QueryStyleFactory } from "../templates/query-panel/QueryStyleFactory"; import { GridSingleSelect } from "../templates/GridSingleSelect"; import _ from 'lodash' export default { name: "AnalysisSam", props:{ conf:{ type: Object, } }, computed: { // 后退 backDisabled(){ return this.curIndex === 0 }, // 前进 goDisabled(){ return this.curIndex == this.deepArr.length - 1 || this.curIndex === 0 }, // 表格列 tableColumns() { if(this.showDetail){ return this.dataFields }else{ // 获取当前分组列 let curGroupArr = this.groupFields.filter(item =>{ return item.prop == this.curGroupField }) // 当前分组列+分系列 let arr = curGroupArr.concat(this.analyseFields) if(arr && arr.length){ this.sortArr = arr } return arr } }, // 网格是否显示合计行 showSummary(){ let flag = false this.analysisData.some(item =>{ flag = item.tableColumnCount return flag }) return flag }, // 数据列 dataFields(){ return this.conf && this.conf.dataFields || [] }, // 图表配置 chartConf() { let groupBy = this.curGroupField; let calcFields = [] calcFields = this.analyseFields.map(item =>{ let obj = { name: item.prop, title: item.label } return obj }) let controlName = '' let datas = this.data controlName = this.chartType == "pie" ? "PieChart" : this.chartType == "bar" ? "BarChart" : this.chartType == "line" ? "LineChart" : this.chartType == "area" ? "LineChart" : 'PieChart' let pieSeries = [ { smooth: true, areaStyle: { normal: { color: new this.$echarts.graphic.LinearGradient(0, 0, 0, 1, [{ offset: 0, color: "rgba(30, 231, 231, 0.3)" },{ offset: 1, color: "rgba(30, 231, 231, 0.1)" }]), }, }, label: { show: false, position: "outside", }, }, { smooth: true, areaStyle: { normal: { color: new this.$echarts.graphic.LinearGradient(0, 0, 0, 1, [{ offset: 0, color: "rgba(30, 231, 231, 0.3)" },{ offset: 1, color: "rgba(30, 231, 231, 0.1)" }]), }, }, label: { show: false, position: "outside", }, }, ]; let series = [] const conf = { controlName: controlName, controlId: "chart_controlid", height: "100%", isGroupData: true, groupBy: groupBy, datas: datas, calcFields: calcFields, option: { legend: { show: true }, series: this.chartType == "area" ? pieSeries : series }, events:{ click(row){ debugger let _this = this.$parent.$parent.$parent; _this.currentObj = row.data _this.currentObj.prop = _this.curGroupField; _this.analysisChartConf.datas = _this.deepAnalysisFields _this.analysisFieldsVisible = true } } }; return conf }, // 深度分析字段列表 deepAnalysisFields(){ debugger let fields = this.groupFields if(fields && fields.length == 0){ return [] } let analysisFields = fields.map((item) => { item.value = 1 return item }); // 排除已经统计的分析列 if(this.deepArr && this.deepArr.length > 0){ let arrnew = this.deepArr.slice(0, this.curIndex + 1).map((item) => { return item.prop }); analysisFields = analysisFields.filter(item =>{ return arrnew.indexOf(item.prop) < 0 }) } // 添加详情 analysisFields.push( { prop: 'detail', label: "详情", value: 1 } ) return analysisFields }, // 查询字段 queryFields(){ let queryFields = [] let fields = this.conf && this.conf.queryFields if(!fields || fields.length == 0){ queryFields = [] }else{ queryFields = fields.map(item =>{ let obj = {} obj.prop = item.prop if(item.props && item.props.lookup){ let model = item.props.model if(item.element === 'hi-select-grid'){ var columns = [] if(model && model.columns && model.columns.length){ columns = model.columns.map(item =>{ item.prop = item.name return item }) } obj.lookup = { type: "data", openstyle: 'selectgrid', bindField: item.prop, lookSelectGrid: { width: 1200, height: 600, table: { columns: columns, }, bindField: item.prop, tableData: model && model.sourceDatas, }, } obj.dbtype = 'dbString' }else if(item.element === 'hi-data-select'){ var columns = [] if(model && model.columns && model.columns.length){ columns = model.columns.map(item =>{ item.prop = item.name return item }) } let store = model.storeCfg || model.sourceDsCfg let index =store.lastIndexOf('|') let modelFilePath =store.substring(0,index); let fields = {} let queryOptionFields = model.queryOption.fields for(let key of queryOptionFields){ if(key.name){ fields[key.name] = key; fields[key.name].dbtype = 'dbString' } } let rows = queryOptionFields.map(item =>{ return {children:[ { prop: item.name, label: item.label } ]} }); let cols = queryOptionFields.map(item =>{ return { colWidth: 100} }); let queryPanel = { rows: rows, cols: cols }; let tableColumn = model.columns.map(item =>{ return { prop: item.name, label: item.label } }) let table = { children:tableColumn } let ds = { controlName: "HcDataset", controlId: modelFilePath, name: model.entityDs, modelFilePath: modelFilePath, _infcPagging: { pageSize: 10, pageNum: 1, returnCount: true }, _infcLoad: { autoActive: true, }, fields: fields, data: [], } obj.lookup = { type: "data", openstyle: 'dialog', birtModel: GridSingleSelect({ mainDataset: ds, hcQueryPanel: queryPanel, hcTable: table }), lookDataset: { modelFilePath: modelFilePath, // 数据模型路径 }, lookDialog: { title: "", width: 900, height: 600, }, bindField: item.prop, sourceDsId: model.sourceDsId } obj.dbtype = 'dbString' } } return obj }) } return queryFields }, // 数据集字段 fields(){ let fields = this.conf.dataset && this.conf.dataset.config.fields for(let key in this.queryFields){ let prop = this.queryFields[key].prop if(fields[prop] && fields[prop].lookup){ let lookup = Object.assign(fields[prop].lookup, this.queryFields[key].lookup) // 下拉枚举查找 if(lookup.label && lookup.returnFields){ for(let key in lookup.returnFields){ if(lookup.returnFields[key] == lookup.label){ lookup.bindShowField = key lookup.lookSelectGrid.bindShowField = key } if(lookup.lookSelectGrid && lookup.lookSelectGrid.tableData){ let data = lookup.lookSelectGrid.tableData for(let i in data){ if(data[i][lookup.returnFields[key]]){ data[i][key] = data[i][lookup.returnFields[key]] } } } } } // 数据模型查找 if(lookup.fieldPair && lookup.sourceDsId){ lookup.returnFields = lookup.fieldPair[lookup.sourceDsId].returnFields } fields[prop]['lookup'] = lookup } } return fields }, // 数据集 dataset(){ var dataset = {} if(this.conf && this.conf.dataset){ let ds = this.conf.dataset dataset = { controlName: ds.controlName, controlId: ds.controlId, name: ds.name, modelFilePath: ds.modelFilePath, fields: this.fields, _infcLoad: { autoActive: false }, _infcPagging: { returnCount: true, pageSize: 100, pageNum: 1 }, data: [], } } return dataset }, // 查询面板 birtModelRight(){ let rows = this.queryFields.map(item =>{ return {children:[item],colspan: 6} }) let cols = this.queryFields.map(item =>{ return { colWidth: 60 } }) const queryPanel = { rows: rows, cols: cols }; let hcQueryPanel = { controlName: "HcQueryPanel", controlId: "HcQueryPanel_sam", inline: false, dataset: this.dataset && this.dataset.controlId || "dsSam", size: "small", hideBtn: true, style: "width: 100%;", children: [], }; Object.assign(hcQueryPanel, QueryStyleFactory.buildForm(queryPanel) || {}); let birtModelRight = { controlName: "BirtWorkBook", controlId: "BirtWorkBook_right", style: "border-bottom: 1px solid #eee;", showToolBar: false, children: [ { controlName: "BirtSheet", controlId: "BirtSheet_right", name: "sheet0", pageIndex: 0, dataSets: [].concat(this.dataset ? this.dataset : []), children: [ { controlName: "BirtFormSheet", controlId: "BirtFormSheet_01", children: [hcQueryPanel] } ] } ], }; return birtModelRight }, // 分组条件(统计字段) groupFields(){ debugger let groupFields = this.conf && _.cloneDeep(this.conf.groupFields) || [] if(this.curTransferVal && this.curTransferVal.length){ let obj = {} let curTransferLabel = this.curTransferVal.map(item =>{ for(var field of groupFields){ if(field.prop == item){ return field.label } } }) obj = { prop: this.curTransferVal.join(), label: curTransferLabel.join() } groupFields.push(obj) } return groupFields }, // 分析字段 analyseFields(){ return this.conf && this.conf.analyseFields || [] }, // 显示详情 showDetail(){ return this.currentObj.prop == 'detail' }, }, watch:{ conf:{ deep: true, handler: function(val){ debugger if(val && val.groupFields && !this.groupForm.prop){ this.groupForm.prop = val.groupFields[0] && val.groupFields[0].prop this.curGroupField = this.groupForm.prop } if(val && val.analyseFields && val.analyseFields.length){ this.analysisData=val.analyseFields.map(item =>{ let obj = { prop: item.prop, countField: item.label, tableColumn: true, tableColumnCount: true, chartColumn: true, chartColumnCount: true, } return obj }) } } } }, data() { return { size: 'small', superposition: false, perspective: false, chartType: "table", groupForm: { prop: "" }, loading: false, currentPage: 1, pageSize: 100, total: 0, data: [], // 排序 sortArr:[], sortIndex:-1, sortType: '', // 分析列 analysisVisible: false, analysisData:[], tableColumnCheck: true, tableColumnCountCheck: true, chartColumnCheck: true, chartColumnCountCheck: true, // 分析字段 analysisFieldsVisible: false, analysisFieldsArr:[], analysisChartConf:{ controlName: "PieChart", controlId: "chart_analysis", height: "100%", isGroupData: true, groupBy: "label", datas: [], calcFields: [ { name: "value", title: "" } ], option: { legend: { show: true } }, events:{ click(row){ debugger; var _this = this.$parent.$parent; _this.analysisChartConf.datas = _this.deepAnalysisFields let data = JSON.parse(JSON.stringify(row.data)) delete data.emphasis // 删除当前分析以后的深度分析 _this.deepArr.splice(_this.curIndex+1, _this.deepArr.length - _this.curIndex - 1) let obj = _this.deepArr[_this.deepArr.length -1] obj.selectVal = _this.currentObj.name _this.$set(_this.deepArr,_this.curIndex,obj) _this.$set(_this.deepArr,_this.curIndex + 1, data) _this.curGroupField = data.prop; _this.currentObj = data; _this.curIndex = _this.curIndex + 1; _this.doQuery(); _this.analysisFieldsVisible = false; } } }, // 深度分析 deepArr:[], conf:{}, // 图表当前选中对象 currentObj:{}, // 当前分组字段 curGroupField: '', // 深度分析当前环节下标 curIndex: 0, exportLoading: false, // 穿梭框 transferVisible: false, curTransferVal: [], groupFieldsEdit: [], } }, updated() { this.$nextTick(() => { this.$refs["table"] && this.$refs["table"].doLayout(); }); }, methods: { // 排序 sortClick(val) { this.sortIndex = val }, sortDown(){ this.sortType = 'desc' }, sortUp(){ this.sortType = 'asc' }, // 前进 goCommand(val){ let index = this.curIndex + val; this.curIndex = index; this.currentObj = this.deepArr[index]; this.curGroupField = this.currentObj.prop; this.data = this.currentObj.data }, goClick:_.debounce(function(){ if(this.curIndex < this.deepArr.length - 1){ this.curIndex = this.curIndex + 1; this.currentObj = this.deepArr[this.curIndex]; this.curGroupField = this.currentObj.prop; this.data = this.currentObj.data } },500), // 后退 backCommand(val){ this.curIndex = val this.currentObj = this.deepArr[val]; this.curGroupField = this.currentObj.prop; this.data = this.currentObj.data }, backClick:_.debounce(function(){ if(this.curIndex > 0){ this.curIndex = this.curIndex - 1 this.currentObj = this.deepArr[val]; this.curGroupField = this.currentObj.prop; this.data = this.currentObj.data } },500), // 深度分析 breadcrumbClick(val) { debugger this.curGroupField = val let arrnew = this.deepArr.map(item =>{ return item.prop }) this.curIndex = arrnew.indexOf(val) this.currentObj = this.deepArr[this.curIndex]; // 数据替换成缓存的数据 this.data = this.currentObj.data }, // 点击查询 doCount() { debugger; this.loading = true; this.doQuery(); let prop = this.groupForm.prop; let fields = this.groupFields.map(item =>{ return item.prop }) this.curGroupField = prop; let index = fields.indexOf(prop) if(this.deepArr.length){ // 如果切换了分组条件,清空深度分析 if(this.deepArr[0] && this.deepArr[0].prop !== prop){ this.deepArr = [] this.currentObj = this.groupFields[index] }else{ this.currentObj = this.deepArr[0] } } // 当前分组加入深度分析 if(index < 0){ this.$message.error('当前分组条件不在分组字段中,请重新配置') }else{ this.$set(this.deepArr,0,this.groupFields[index]) this.curIndex = 0 } // 监听数据集 if(this.dataset){ let ds = this.$refs.BirtWorkBook_right.dataset[this.dataset.controlId] this.$nextTick(() =>{ ds && ds.on("afterLoadData", afterLoadData); ds.vm = this function afterLoadData(datas){ this.vm.data = datas // 缓存数据 this.vm.deepArr[this.vm.curIndex].data = datas } }) } }, // 查询方法 doQuery(){ let ds = this.$refs.BirtWorkBook_right.dataset[this.dataset.controlId] if(this.showDetail){ ds._infcPagging = { pageSize: this.pageSize, pageNum: this.currentPage }; ds._infcStat = {} ds._infcSort = {} }else{ ds._infcPagging = { pageSize: this.pageSize, pageNum: this.currentPage }; ds._infcStat = { isGroupData: true, groupBy: this.curGroupField, } if(this.sortIndex > -1){ let obj = this.sortArr[this.sortIndex] ds._infcSort.orderBy =[{ name: obj.prop, desc: obj.label, type: this.sortType || 'desc' }] }else{ ds._infcSort.orderBy = [] } } ds.query(); this.loading = false; }, // 重置 reset() { this.$refs.groupForm.resetFields(); this.groupForm.prop = this.groupFields[0] && this.groupFields[0].prop; var queryPanel = this.$refs.BirtWorkBook_right.$children[0].$children[0].$children[0].$children[0].$children[0].$children[0]; queryPanel.reset(); }, handleSizeChange(val) { this.pageSize = val }, handleCurrentChange(val) { this.currentPage = val }, // 切换图表 chartTypeChange(command) { this.chartType = command; }, // 打开分析列 analysisClick(){ this.analysisVisible = true }, // 分系列全选 handelCheckAll(val){ debugger let _this = this this.analysisData = this.analysisData.map(item => { if(val == 'tableColumn') { item.tableColumn = _this.tableColumnCheck } if(val == 'tableColumnCount') { item.tableColumnCount = _this.tableColumnCountCheck } if(val == 'chartColumn') { item.chartColumn = _this.chartColumnCheck } if(val == 'chartColumnCount') { item.chartColumnCount = _this.chartColumnCountCheck } return item }) }, // 刷新 refresh(){ this.doQuery(); this.$refs.chartConf && this.$refs.chartConf.refreshChart(); }, // 导出 exportExcel() { let param = { pageNum: -1, pageSize: -1, __slaveExport: false, }; let __body = {}; let ds = this.$refs.BirtWorkBook_right.dataset[this.dataset.controlId] var cdion = ds.lastLoadCdion console.log('cdion', cdion) if (cdion) { __body['queryCdions'] = JSON.parse(cdion); } param['modelFilePath'] = ds['modelFilePath']; param['__funcpath'] = ds['__funcpath']; param.__body = __body let sheetStyle = {} let cells = [] let columns = [] this.tableColumns.forEach(item => { cells.push({ title: item.label, colspan: 1, rowspan: 1 }) columns.push({ fields: item.prop, width: 70 }) }); sheetStyle = { name: '统计分析', titleRows: [ { cells: cells } ], columns: columns } param.__sheetStyle = sheetStyle var data = { __sheetDatas: JSON.stringify([param]) } var url = this.$HI.exportUrl this.exportLoading = true this.$HI.request.post(url,data).then((res) =>{ console.log('res', res) this.exportLoading = false if(res.status == 200){ let token = getToken(); var url = this.$HI.download + `?path=${res.dataPack.path}&access_token=${token}` url = url.replace(/\\/g,"/") const a = document.createElement('a') //创建a标签 a.style.display = 'none' a.href = url // 指定下载链接 // a.download = '用户信息.xlsx' //指定下载文件名 a.click() //触发下载 } }).catch((e) =>{ this.exportLoading = false }) }, // 打开穿梭框 showtransfer(){ this.groupFieldsEdit = JSON.parse(JSON.stringify(this.curTransferVal)) this.transferVisible = true }, transferConfirm(){ if(this.groupFieldsEdit && this.groupFieldsEdit.length > 1){ this.curTransferVal = JSON.parse(JSON.stringify(this.groupFieldsEdit)) this.groupForm.prop = this.curTransferVal.join(); this.curGroupField = this.groupForm.prop; this.transferVisible = false }else{ this.$message.error("该分组选项已存在") } }, transferClose(){ this.transferVisible = false this.groupFieldsEdit = JSON.parse(JSON.stringify(this.curTransferVal)) }, transferUp(option){ let arr = this.groupFieldsEdit let index = this.groupFieldsEdit.indexOf(option.prop) if(index > 0){ arr.splice(index - 1, 1, ...arr.splice(index, 1, arr[index - 1])); } }, transferDown(option){ let arr = this.groupFieldsEdit let index = this.groupFieldsEdit.indexOf(option.prop) if(index < arr.length){ arr.splice(index, 1, ...arr.splice(index + 1, 1, arr[index])); }; }, }, mounted() { } }; </script> <style> .birtModelRight .el-main{ padding: 5px !important; } .birtModelRight table.zhc-birt-data-list{ table-layout: auto !important; border-collapse: initial !important; border-spacing: revert !important; } .el-transfer.sam .el-transfer-panel:nth-child(1) button{ display: none; } </style> <style lang="scss" scoped> .container { position: relative; display: flex; flex-direction: column; height: 100%; padding: 20px; } .btn-toolbar { * + * { margin-left: 10px; margin-right: 0; } } .el-dropdown-menu__item { min-width: 90px; } .center-content { height: 100%; width: 100%; padding: 10px; box-sizing: border-box; } .depth-analysis { display: flex; align-items: center; padding: 10px; } .el-breadcrumb__item a { cursor: pointer !important; } .deepActive{ color: #06c; font-weight: 600; } .sortActive{ color: rgb(33, 235, 141); font-weight: 600; } >>>.el-dropdown-menu__item:focus, .el-dropdown-menu__item:not(.is-disabled):hover{ background: initial; color: initial; } .el-dropdown-menu__item i{ font-weight: 600; margin: 0 0 0 5px; } .el-dropdown-menu__item i:hover { color: rgb(33, 235, 141); } .birtModelRight .el-main{ padding: 5px !important; } .el-icon-edit{ right: 30px; position: absolute; z-index: 1; line-height: 30px; cursor: pointer; } </style>
Ignore Space
Show notes
View
vite-plugin/vite-plugin-func.js
var querystring = require('querystring'); var url = require('url'); const fs = require('fs') var https = require('https'); var request = require('request'); var ejs = require('ejs'); function myPlugin(rawOptions) { let projectName = process.env.VITE_APP_PN.split("/")[0]; var previewPath = `${projectName}/setting/studio/preview.json` var setting try { let settingContent = fs.readFileSync(previewPath, { encoding: 'utf8' }); setting = JSON.parse(settingContent) } catch (e) { console.log("preview数据有错!") } var VITE_APP_BASE_API, VITE_APP_SERVER; if (setting) { VITE_APP_BASE_API = (setting.server || {}).VITE_APP_BASE_API || process.env.VITE_APP_BASE_API; VITE_APP_SERVER = (setting.server || {}).VITE_APP_SERVER || process.env.VITE_APP_SERVER; } else { VITE_APP_BASE_API = process.env.VITE_APP_BASE_API; VITE_APP_SERVER = process.env.VITE_APP_SERVER; } const options = { isProduction: process.env.NODE_ENV === 'production', ...rawOptions, VITE_APP_BASE_API: VITE_APP_BASE_API, VITE_APP_SERVER: VITE_APP_SERVER, root: process.cwd(), }; let postData; let config; return { name: 'vite-plugin-func', // 必须的,将会显示在 warning 和 error 中 configResolved(resolvedConfig) { // 存储最终解析的配置 config = resolvedConfig }, configureServer(server) { server.middlewares.use((req, res, next) => { function isFlow(type) { return type.endsWith(".flow") || type.endsWith(".flowc"); } // 接口 function isInfc(type) { return type.endsWith(".infc") } function isFunc(type) { return type.endsWith(".func") } // 渲染页面 function renderHtml(pcform, isGuest, body) { let content; try { content = fs.readFileSync(pcform, { encoding: 'utf8' }) } catch (e) { res.writeHead(404, { "Content-Type": "application/json;charset=UTF-8" }); res.end("pcform:" + pcform + "文件异常!"); return; } const statusCode = 200; if (!body) throw new Error(`No body text found for the ${statusCode} status code`); try { var html = ejs.render(content, options); } catch (e) { res.end(e.message); return; } let postDataStr = JSON.stringify(postData || {}); let varName = options.varName || 'viteRequestData'; let varGlobal = JSON.stringify(options.global || {}); let funcName = new Date().valueOf(); let queryScript = ` function _viteGetQuery${funcName}() { var url = window.location.search; var theRequest = new Object(); if (url.indexOf("?") != -1) { var str = url.substr(1); strs = str.split("&"); for(var i = 0; i < strs.length; i ++) { theRequest[strs[i].split("=")[0]]=decodeURI(strs[i].split("=")[1]); } } return theRequest; }` let titleStr = html.match(/<head(.*?)>/g)[0] || ""; html = html.replace( /<head(.*?)>/g, `${titleStr}<script>${queryScript};window.isGuest=${isGuest};window.${varName} = Object.assign(_viteGetQuery${funcName}(),${postDataStr}); window._global=${varGlobal}</script>` ) res.writeHead(statusCode, { "serverInfo": `${VITE_APP_BASE_API},${VITE_APP_SERVER}`, // 'Content-Length': html.length, 'Content-Type': 'html' }); res.write(html) res.end(); } var serverPath = VITE_APP_BASE_API + VITE_APP_SERVER; if (req.url.indexOf("/development.js") != -1) { let content; try { content = fs.readFileSync(req.url.substr(1), { encoding: 'utf8' }) } catch (e) { res.writeHead(404, { "Content-Type": "application/json;charset=UTF-8" }); res.end("获取", req.url + "文件异常!"); return; } try { var html = ejs.render(content, options); } catch (e) { res.end(e.message); return; } res.end(html); return; } let pathname = req._parsedUrl.pathname; //console.log(new Date(), 'req.url:', req.url) if (isFlow(pathname) || isFunc(pathname) || isInfc(pathname)) { // let url = req.url; let post = ''; postData = ''; let path; let fmodelpath = pathname;// url.split("?")[0]; var post_data = {}; // var param = req.url.split("?")[1]; var param = req._parsedUrl.query; var result = {}; if (param) { let values = param.split("&"); for (let i = 0; i < values.length; i++) { const element = values[i]; let _val = element.split("="); result[_val[0]] = _val[1]; } } if (isFlow(fmodelpath)) { var fversion = ""; var ftaskguid = ""; if (param) { fversion = result["_version"] || result["version"]; ftaskguid = result["_ftaskguid"] || result["ftaskguid"]; } post_data = { fmodelpath: fmodelpath, fversion, ftaskguid } path = serverPath + "/flow/open?pn="; } else if (isInfc(fmodelpath)) { path = serverPath + fmodelpath + "?pn="; } else { var viewItemId = "" if (param) { viewItemId = result["__viewItemId"] || result["viewItemId"] || ""; } path = serverPath + fmodelpath + "?skip=false&viewItemId=" + viewItemId + "&pn=" } // let pn = url.split("/")[1]; const TokenKey = 'EAP-Token'; function handleFunc() { var Cookies = {}; if (req.headers.cookie != null) { req.headers.cookie.split(';').forEach(l => { var parts = l.split('='); Cookies[parts[0].trim()] = (parts[1] || '').trim(); }); } let token = Cookies[TokenKey]; let requestUrl = path + process.env.VITE_APP_PN; if (param) { requestUrl = requestUrl + "&" + param; } console.log("----requestUrl:", requestUrl, "token:", token); Object.assign(post_data, postData); var requestOption = { url: requestUrl, method: "POST", json: true, body: post_data, headers: { "token": token, "Authorization": "Bearer " + token, "Content-Type": "application/json;charset=UTF-8" } } if (isFlow(pathname)) { requestOption["body"] = post_data; } else if (isFunc(pathname)) {//页面流用表单提交 requestOption["form"] = post_data; } request(requestOption, function (error, response, body) { //console.log(error, response, body); if (!error && response.statusCode == 200) { let pcform; let designPath; let isGuest = false; if (body) { if (isFlow(fmodelpath) && body.outParameter) { pcform = body.outParameter.task.bizpcform; } else if (isFunc(fmodelpath) || isInfc(fmodelpath)) { if (body && body.logicflow || isInfc(fmodelpath)) { //逻辑流 let statusCode = body.status || response.statusCode; res.writeHead(statusCode, { "Content-Type": "application/json;charset=UTF-8" }); res.end(JSON.stringify(body)); return; } else if (body.dataPack) { pcform = body.dataPack.path; designPath = body.dataPack.designPath; isGuest = body.dataPack.isGuest; } } } if (!pcform) { res.writeHead(500, { "serverInfo": `${VITE_APP_BASE_API},${VITE_APP_SERVER}`, "Content-Type": "application/json;charset=UTF-8" }); res.end(JSON.stringify(body)); return; } if (designPath && (designPath.endsWith(".vm") || designPath.endsWith(".dvm"))) { res.writeHead(200, { 'Content-Type': 'html' }); let projectName = process.env.VITE_APP_PN.split("/")[0]; var pn = `pn=${process.env.VITE_APP_PN}` if (req.url.indexOf("?") == -1) { pn = "?" + pn; } else { pn = "&" + pn; } let accessToken = "" if (token) { accessToken = `&access_token=${token}`; } let html = ` <script src="/assets_platform/eap/eap.umd.min.js"></script> <script> window._global ={ env :"dev" } </script> <script src="/${projectName}/setting/desktop/development.js" type="text/javascript"></script> <script> window.location.href="${serverPath}${req.url}${pn}${accessToken}"; </script> ` res.end(html); return; } // var fullPath = "eaptpl/12112/mokuai/shitumulu/biaodan/dtv/1.0.0/desktop/index.html"; renderHtml(pcform, isGuest, body); } else { if (response && response.statusCode == 401) { res.writeHead(200, { "serverInfo": `${VITE_APP_BASE_API},${VITE_APP_SERVER}`, 'Content-Type': 'html' }); let projectName = process.env.VITE_APP_PN.split("/")[0]; let html = ` <script src="/assets_platform/eap/eap.umd.min.js"></script> <script> window._global ={ env :"dev" } </script> <script src="/${projectName}/setting/desktop/development.js" type="text/javascript"></script> <script> if(top.window.SysPage&&top.window.SysPage.openMiniLogin){//小窗口 top.window.SysPage.openMiniLogin(true); }else{ window.location.href=window.HIVUI_SETTING.loginUrl; } </script> ` res.end(html); } else { res.writeHead(500, { "serverInfo": `${VITE_APP_BASE_API},${VITE_APP_SERVER}`, "Content-Type": "application/json;charset=UTF-8" }); res.end(JSON.stringify(body)); } //res.end(requestUrl + ":" + JSON.stringify(error) + JSON.stringify(body)); } }, (msg) => { res.writeHead(404, { "Content-Type": "application/json;charset=UTF-8" }); res.end(JSON.stringify(msg)); // console.log(msg) }); } req.on('data', (chunk) => { post += chunk; postData = querystring.parse(post); }); req.on('end', (chunk) => { handleFunc() }); return; } else if (pathname.endsWith("studio.html")) {//动态流程 let projectName = process.env.VITE_APP_PN.split("/")[0]; let pcform = `${projectName}/hivuiStudio/index.html` renderHtml(pcform, false, {}) } else { next(); } }) }, } } export default myPlugin;
var querystring = require('querystring'); var url = require('url'); const fs = require('fs') var https = require('https'); var request = require('request'); var ejs = require('ejs'); function myPlugin(rawOptions) { let projectName = process.env.VITE_APP_PN.split("/")[0]; var previewPath = `${projectName}/setting/studio/preview.json` var setting try { let settingContent = fs.readFileSync(previewPath, { encoding: 'utf8' }); setting = JSON.parse(settingContent) } catch (e) { console.log("preview数据有错!") } var VITE_APP_BASE_API, VITE_APP_SERVER; if (setting) { VITE_APP_BASE_API = (setting.server || {}).VITE_APP_BASE_API || process.env.VITE_APP_BASE_API; VITE_APP_SERVER = (setting.server || {}).VITE_APP_SERVER || process.env.VITE_APP_SERVER; } else { VITE_APP_BASE_API = process.env.VITE_APP_BASE_API; VITE_APP_SERVER = process.env.VITE_APP_SERVER; } const options = { isProduction: process.env.NODE_ENV === 'production', ...rawOptions, VITE_APP_BASE_API: VITE_APP_BASE_API, VITE_APP_SERVER: VITE_APP_SERVER, root: process.cwd(), }; let postData; let config; return { name: 'vite-plugin-func', // 必须的,将会显示在 warning 和 error 中 configResolved(resolvedConfig) { // 存储最终解析的配置 config = resolvedConfig }, configureServer(server) { server.middlewares.use((req, res, next) => { function isFlow(type) { return type.endsWith(".flow") || type.endsWith(".flowc"); } // 渲染页面 function renderHtml(pcform, isGuest, body) { let content; try { content = fs.readFileSync(pcform, { encoding: 'utf8' }) } catch (e) { res.writeHead(404, { "Content-Type": "application/json;charset=UTF-8" }); res.end("pcform:" + pcform + "文件异常!"); return; } const statusCode = 200; if (!body) throw new Error(`No body text found for the ${statusCode} status code`); try { var html = ejs.render(content, options); } catch (e) { res.end(e.message); return; } let postDataStr = JSON.stringify(postData || {}); let varName = options.varName || 'viteRequestData'; let varGlobal = JSON.stringify(options.global || {}); let funcName = new Date().valueOf(); let queryScript = ` function _viteGetQuery${funcName}() { var url = window.location.search; var theRequest = new Object(); if (url.indexOf("?") != -1) { var str = url.substr(1); strs = str.split("&"); for(var i = 0; i < strs.length; i ++) { theRequest[strs[i].split("=")[0]]=decodeURI(strs[i].split("=")[1]); } } return theRequest; }` let titleStr = html.match(/<head(.*?)>/g)[0] || ""; html = html.replace( /<head(.*?)>/g, `${titleStr}<script>${queryScript};window.isGuest=${isGuest};window.${varName} = Object.assign(_viteGetQuery${funcName}(),${postDataStr}); window._global=${varGlobal}</script>` ) res.writeHead(statusCode, { "serverInfo": `${VITE_APP_BASE_API},${VITE_APP_SERVER}`, // 'Content-Length': html.length, 'Content-Type': 'html' }); res.write(html) res.end(); } var serverPath = VITE_APP_BASE_API + VITE_APP_SERVER; if (req.url.indexOf("/development.js") != -1) { let content; try { content = fs.readFileSync(req.url.substr(1), { encoding: 'utf8' }) } catch (e) { res.writeHead(404, { "Content-Type": "application/json;charset=UTF-8" }); res.end("获取", req.url + "文件异常!"); return; } try { var html = ejs.render(content, options); } catch (e) { res.end(e.message); return; } res.end(html); return; } let pathname = req._parsedUrl.pathname; //console.log(new Date(), 'req.url:', req.url) if (isFlow(pathname) || pathname.endsWith(".func")) { // let url = req.url; let post = ''; postData = ''; let path; let fmodelpath = pathname;// url.split("?")[0]; var post_data = {}; // var param = req.url.split("?")[1]; var param = req._parsedUrl.query; var result = {}; if (param) { let values = param.split("&"); for (let i = 0; i < values.length; i++) { const element = values[i]; let _val = element.split("="); result[_val[0]] = _val[1]; } } if (isFlow(fmodelpath)) { var fversion = ""; var ftaskguid = ""; if (param) { fversion = result["_version"] || result["version"]; ftaskguid = result["_ftaskguid"] || result["ftaskguid"]; } post_data = { fmodelpath: fmodelpath, fversion, ftaskguid } path = serverPath + "/flow/open?pn="; } else { var viewItemId = "" if (param) { viewItemId = result["__viewItemId"] || result["viewItemId"] || ""; } path = serverPath + fmodelpath + "?skip=false&viewItemId=" + viewItemId + "&pn=" } // let pn = url.split("/")[1]; const TokenKey = 'EAP-Token'; function handleFunc() { var Cookies = {}; if (req.headers.cookie != null) { req.headers.cookie.split(';').forEach(l => { var parts = l.split('='); Cookies[parts[0].trim()] = (parts[1] || '').trim(); }); } let token = Cookies[TokenKey]; let requestUrl = path + process.env.VITE_APP_PN; requestUrl = requestUrl + "&" + param; console.log("----requestUrl:", requestUrl, "token:", token); Object.assign(post_data, postData); request({ url: requestUrl, method: "POST", json: true, body: post_data, headers: { "token": token, "Authorization": "Bearer " + token, "Content-Type": "application/json;charset=UTF-8" } }, function (error, response, body) { //console.log(error, response, body); if (!error && response.statusCode == 200) { let pcform; let designPath; let isGuest = false; if (body) { if (isFlow(fmodelpath) && body.outParameter) { pcform = body.outParameter.task.bizpcform; } else if (fmodelpath.endsWith(".func")) { if (body && body.logicflow) { //逻辑流 let statusCode = body.status || response.statusCode; res.writeHead(statusCode, { "Content-Type": "application/json;charset=UTF-8" }); res.end(JSON.stringify(body)); return; } else if (body.dataPack) { pcform = body.dataPack.path; designPath = body.dataPack.designPath; isGuest = body.dataPack.isGuest; } } } if (!pcform) { res.writeHead(500, { "serverInfo": `${VITE_APP_BASE_API},${VITE_APP_SERVER}`, "Content-Type": "application/json;charset=UTF-8" }); res.end(JSON.stringify(body)); return; } if (designPath && (designPath.endsWith(".vm") || designPath.endsWith(".dvm"))) { res.writeHead(200, { 'Content-Type': 'html' }); let projectName = process.env.VITE_APP_PN.split("/")[0]; var pn = `pn=${process.env.VITE_APP_PN}` if (req.url.indexOf("?") == -1) { pn = "?" + pn; } else { pn = "&" + pn; } let accessToken = "" if (token) { accessToken = `&access_token=${token}`; } let html = ` <script src="/assets_platform/eap/eap.umd.min.js"></script> <script> window._global ={ env :"dev" } </script> <script src="/${projectName}/setting/desktop/development.js" type="text/javascript"></script> <script> window.location.href="${serverPath}${req.url}${pn}${accessToken}"; </script> ` res.end(html); return; } // var fullPath = "eaptpl/12112/mokuai/shitumulu/biaodan/dtv/1.0.0/desktop/index.html"; renderHtml(pcform, isGuest, body); } else { if (response && response.statusCode == 401) { res.writeHead(200, { "serverInfo": `${VITE_APP_BASE_API},${VITE_APP_SERVER}`, 'Content-Type': 'html' }); let projectName = process.env.VITE_APP_PN.split("/")[0]; let html = ` <script src="/assets_platform/eap/eap.umd.min.js"></script> <script> window._global ={ env :"dev" } </script> <script src="/${projectName}/setting/desktop/development.js" type="text/javascript"></script> <script> if(top.window.SysPage&&top.window.SysPage.openMiniLogin){//小窗口 top.window.SysPage.openMiniLogin(true); }else{ window.location.href=window.HIVUI_SETTING.loginUrl; } </script> ` res.end(html); } else { res.writeHead(500, { "serverInfo": `${VITE_APP_BASE_API},${VITE_APP_SERVER}`, "Content-Type": "application/json;charset=UTF-8" }); res.end(JSON.stringify(body)); } //res.end(requestUrl + ":" + JSON.stringify(error) + JSON.stringify(body)); } }, (msg) => { res.writeHead(404, { "Content-Type": "application/json;charset=UTF-8" }); res.end(JSON.stringify(msg)); // console.log(msg) }); } req.on('data', (chunk) => { post += chunk; postData = querystring.parse(post); }); req.on('end', (chunk) => { handleFunc() }); return; } else if (pathname.endsWith("studio.html")) {//动态流程 let projectName = process.env.VITE_APP_PN.split("/")[0]; let pcform = `${projectName}/hivuiStudio/index.html` renderHtml(pcform, false, {}) } else { next(); } }) }, } } export default myPlugin;
Show line notes below