rsbi 4 lat temu
rodzic
commit
15180aebd1

+ 2 - 8
src/common/biConfig.js

@@ -44,14 +44,8 @@ export const ajax = (cfg, ts, loadingObj) => {
 					ts.$router.push("/");
 				//}
 			}else{
-				/** 
-				ts.$notify.error({
-					title: '系统出错',
-					message:resp.msg,
-					offset: 50
-				});
-				*/
-				Message.error({message:resp.msg, type:"error",showClose: true});
+				const h = ts.$createElement;
+				Message.error({message:h('div',[h('h5','系统错误'), h('div', resp.msg)]), type:"error",showClose: true});
 			}
 		},
 		error: function(){

+ 2 - 0
src/components/NavMenu.vue

@@ -20,8 +20,10 @@
                         <i class="fa fa-exchange"></i>
                         </span>
                         <el-dropdown-menu slot="dropdown">
+                            <!--
                         <el-dropdown-item command="flash">刷新当前页面</el-dropdown-item>
                         <el-dropdown-item command="fullScreem">全屏当前页面</el-dropdown-item>
+                        -->
                         <el-dropdown-item command="closeother">关闭其他页面</el-dropdown-item>
                         <el-dropdown-item command="closeall">关闭全部页面</el-dropdown-item>
                         </el-dropdown-menu>

+ 15 - 3
src/router/index.js

@@ -9,7 +9,9 @@ import RoleMenu from '@/view/frame/RoleMenu'
 import User from '@/view/frame/User'
 import UserMenu from '@/view/frame/UserMenu'
 import Model from '@/view/model/Index'
-import Portal from '@/view/portal/Index'
+import PortalIndex from '@/view/portal/PortalIndex'
+import PortalCustomiz from '@/view/portal/PortalCustomiz'
+import PortalView from '@/view/portal/PortalView'
 import ReportDesign from '@/view/bireport/ReportDesign'
 import BireportPrint from '@/view/bireport/Print'
 import NotFind from '@/view/NoFind'
@@ -69,8 +71,18 @@ let router = new Router({
         },
         {
           path:'/portal/Index',
-          name:'portal',
-          component:Portal
+          name:'portalIndex',
+          component:PortalIndex
+        },
+        {
+          path:'/portal/View',
+          name:'portalView',
+          component:PortalView
+        },
+        {
+          path:"/portal/Customiz",
+          name:"PortalCustomiz",
+          component:PortalCustomiz
         }
         ,
         {

+ 12 - 2
src/view/portal/CompFilter.vue

@@ -19,8 +19,7 @@
 			</el-table-column>
 		</el-table>
 		<div slot="footer" class="dialog-footer">
-			<el-button type="primary" @click="filtersSave()">确 定</el-button>
-			<el-button @click="show = false">取 消</el-button>
+			<el-button type="primary" @click="filtersSave()">关 闭</el-button>
 		</div>
 
 		<el-dialog :title="title" width="40%" :visible.sync="addShow" append-to-body>
@@ -163,7 +162,18 @@
 				}
 			},
 			filtersSave(){
+				let comp = this.comp;
 				this.show = false;
+				let c = this.$parent.$refs['mv_' + comp.id];
+				if(comp.type == 'table'){
+					c.tableView();
+				}else if(comp.type == 'chart'){
+					c.chartView();
+				}else if(comp.type === 'grid'){
+					c.gridView();
+				}else if(comp.type === 'box'){
+					c.boxView();
+				}
 			},
 			fmtvalue(row, column, cellValue, index){
 				if(row.usetype === 'param'){

+ 0 - 35
src/view/portal/Index.vue

@@ -1,35 +0,0 @@
-<template>
-  	<div class="wrapper-content-nomargin">
-      <PortalIndex v-show="showIndex" ref="indexForm"></PortalIndex>
-      <PortalIndexCustomiz v-if="!showIndex" ref="customizForm"></PortalIndexCustomiz>
-  	</div>
-</template>
-
-<script>
-import {baseUrl} from '@/common/biConfig'
-import PortalIndex from "./PortalIndex.vue"
-import PortalIndexCustomiz from "./PortalIndexCustomiz.vue"
-import 'jquery-ui-dist/jquery-ui'
-import 'jquery-ui-dist/jquery-ui.css'
-
-export default {
-  components:{PortalIndex,PortalIndexCustomiz},
-  data(){
-    return {
-      showIndex:true,
-    }
-  },
-  mounted(){
-
-  },
-  computed: {
-  },
-  methods: {
-
-  }
-}
-</script>
-
-<style lang="less" scoped>
-  @import "../../style/common";
-</style>

+ 7 - 6
src/view/portal/LayoutOptarea.vue

@@ -25,7 +25,8 @@ export default {
     pageInfo: {
       type: Object,
       required: true,
-    },
+      default:{}
+    }
   },
   render(h) {
     //在render函数执行后绑定拖拽事件
@@ -39,7 +40,7 @@ export default {
       }
     });
 
-    var json = this.pageInfo.body;
+    var json = this.pageInfo.body || {};
     var trs = [];
     for (var i = 1; true; i++) {
       var tr = json["tr" + i];
@@ -118,13 +119,13 @@ export default {
       let title = h('div', {class:"ibox-title"}, [h('div', {class:"ctit"}, [h('h5', comp.name)]), h('div', {class:"ibox-tools"}, tools)]);
       let compctx = [];
       if(comp.type === 'box'){
-        compctx.push(h('box-view',{ref:'mv_'+comp.id, attrs:{comp:comp}}));
+        compctx.push(h('box-view',{ref:'mv_'+comp.id, attrs:{comp:comp, editor:true}}));
       }else if(comp.type ==='chart'){
-        compctx.push(h('chart-view',{ref:'mv_'+comp.id, attrs:{comp:comp}}));
+        compctx.push(h('chart-view',{ref:'mv_'+comp.id, attrs:{comp:comp, editor:true}}));
       }else if(comp.type === 'grid'){
-        compctx.push(h('grid-view',{ref:'mv_'+comp.id, attrs:{comp:comp}}));
+        compctx.push(h('grid-view',{ref:'mv_'+comp.id, attrs:{comp:comp, editor:true}}));
       }else if(comp.type === 'table'){
-        compctx.push(h('table-view',{ref:'mv_'+comp.id, attrs:{comp:comp}}));
+        compctx.push(h('table-view',{ref:'mv_'+comp.id, attrs:{comp:comp, editor:true}}));
       }
       let style = {padding:"1px", width:"100%"};
       let bgcolor = comp.bgcolor;

+ 231 - 0
src/view/portal/LayoutView.vue

@@ -0,0 +1,231 @@
+<!-- 报表查看页面渲染布局器 -->
+<script>
+import { baseUrl, newGuid } from "@/common/biConfig";
+import PortalText from "./PortalText.vue"
+import ChartDailog from './ChartDailog.vue'
+import CompFilter from './CompFilter.vue'
+import $ from "jquery";
+import * as utils from './Utils'
+import BoxView from "./view/Box.vue"
+import ChartView from "./view/Chart.vue"
+import GridView from "./view/Grid.vue"
+import TableView from "./view/Table.vue"
+
+export default {
+  components: {
+    PortalText,
+    BoxView,
+    ChartView,
+    GridView,
+    TableView,
+    ChartDailog,
+    CompFilter
+  },
+  props: {
+    pageInfo: {
+      type: Object,
+      required: true,
+      default:{}
+    }
+  },
+  render(h) {
+    var json = this.pageInfo.body || {};
+    var trs = [];
+    for (var i = 1; true; i++) {
+      var tr = json["tr" + i];
+      if (!tr || tr == null) {
+        break;
+      }
+      var tds = [];
+      for (var j = 0; j < tr.length; j++) {
+        var td = tr[j];
+        
+        let cmps = [];
+        if(td.children){
+          for(var k=0; k<td.children.length; k++){
+            var comp = td.children[k];
+            cmps.push(this.renderComp(comp, h, td.id));
+          }
+        }
+
+        tds.push(
+          h("td", {
+            attrs: {
+              class: "laytd",
+              id:"layout_" + td.id,
+              height: td.height + "%",
+              width: td.width + "%",
+              colspan: td.colspan,
+              rowspan: td.rowspan,
+            },
+          }, cmps)
+        );
+      }
+      trs.push(h('tr', {}, tds));
+    }
+    let table = h('table', {attrs:{border:"0", cellspacing:"0", cellpadding:"0", class:"r_layout", id:"layout_table"}}, [h('tbody', trs)]);
+    return h("div", {attrs:{id:"optarea", class:"layout-center-body", align:"center"}}, 
+      [
+        table
+      ]
+    );
+  },
+  data() {
+    return {
+      curTmpInfo:{}  //临时对象
+    };
+  },
+  mounted() {
+    $(window).resize(()=>this.resizeChart());
+  },
+  beforeDestroy(){
+    $(window).unbind("resize");
+  },
+  computed: {},
+  methods: {
+    renderComp(comp, h, layoutId){
+      
+      let title = h('div', {class:"ibox-title"}, [h('div', {class:"ctit"}, [h('h5', comp.name)])]);
+      let compctx = [];
+      if(comp.type === 'box'){
+        compctx.push(h('box-view',{ref:'mv_'+comp.id, attrs:{comp:comp, editor:false}}));
+      }else if(comp.type ==='chart'){
+        compctx.push(h('chart-view',{ref:'mv_'+comp.id, attrs:{comp:comp, editor:false}}));
+      }else if(comp.type === 'grid'){
+        compctx.push(h('grid-view',{ref:'mv_'+comp.id, attrs:{comp:comp, editor:false}}));
+      }else if(comp.type === 'table'){
+        compctx.push(h('table-view',{ref:'mv_'+comp.id, attrs:{comp:comp, editor:false}}));
+      }
+      let style = {padding:"1px", width:"100%"};
+      let bgcolor = comp.bgcolor;
+      if(bgcolor){
+        style['background-color'] = bgcolor;
+      }
+      if(comp.height){
+        style['height'] =  comp.height + "px";
+      }
+      let bodys = {class:"ccctx", style:{}};
+      if(comp.type ==='text'){
+        bodys.domProps = {innerHTML:comp.desc.replace(/\n/g,"<br>")};
+        //处理 text 的 style
+        if(comp.style){
+          let s = comp.style;
+          let s2 = bodys.style;
+          if(s.talign){
+            s2['text-align'] = s.talign;
+          }
+          if(s.tfontsize){
+            s2['font-size'] = s.tfontsize + "px";
+          }
+          if(s.tfontcolor){
+            s2['color'] = s.tfontcolor;
+          }
+          if(s.tfontweight){
+            s2['font-weight'] = "bold";
+          }
+          if(s.titalic){
+            s2['font-style'] = 'italic';
+          }
+          if(s.tunderscore){
+            s2['text-decoration'] = 'underline';
+          }
+        }
+      }
+      let ctx = h('div', {class:"cctx ibox-content", style:style}, [h('div', bodys, comp.type=='text'?"":compctx)]);
+      return h('div', {attrs:{class:"ibox", id:"c_" + comp.id}}, [title, ctx]);
+    },
+    /**
+     * 调整图形大小,comp存在表示子调整当前组件,不存在表示调整所有组件
+     */
+    resizeChart(comp){
+      let comps = utils.findAllComps(this.pageInfo);
+      comps.forEach(m=>{
+        if(m.type === 'chart'){
+          let dom = document.getElementById("ct_"+m.id);
+          if(dom){
+            var chart = echarts.getInstanceByDom(dom);
+            if(chart){
+              let height = m.height?m.height:$(dom).height();
+              chart.resize($(dom).width(), height);
+            }
+          }
+        }
+      });
+    },
+    setCompData(datas){
+      var json = this.pageInfo.body || {};
+      for (var i = 1; true; i++) {
+        var tr = json["tr" + i];
+        if (!tr || tr == null) {
+          break;
+        }
+        for (var j = 0; j < tr.length; j++) {
+          var td = tr[j];
+          if(td.children){
+            for(var k=0; k<td.children.length; k++){
+              var comp = td.children[k];
+              if(comp.type === 'text'){
+                continue;
+              }
+              let o = this.$refs['mv_'+comp.id];
+              o.data = datas[comp.id];
+              if(comp.type === 'chart'){
+                this.$nextTick(()=>o.showChart());
+              }
+            }
+          }
+        }
+      }
+    }
+  },
+  watch:{
+   
+  }
+};
+</script>
+
+<style lang="less" scoped>
+@import "../../style/mixin";
+table.r_layout {
+	border-collapse:collapse;
+	table-layout:fixed;
+	width:100%;
+  td.laytd {
+    border: 0;
+    text-align: left;
+    vertical-align: top;
+	  background-color:#f0f3f4;
+	  min-height:100px;
+	  padding:5px;
+  }
+}
+.layout-center-body {
+	height: calc(100% - 44px);
+	overflow: auto;
+}
+.ibox-title {
+    height: 30px;
+    border-color: #edf1f2;
+    background-color: #f6f8f8;
+    color: #333;
+    font-weight: 700;
+    padding: 8px 15px 3px 15px;
+    border-bottom: 1px solid transparent;
+    display: block;
+    clear: both;
+}
+.ibox-title h5 {
+    display: inline-block;
+    font-size: 14px;
+    margin: 0 0 7px;
+    padding: 0;
+    text-overflow: ellipsis;
+    float: left;
+}
+#optarea .ibox {
+    margin-bottom: 10px !important;
+}
+.cctx {
+  overflow: hidden;
+}
+</style>

+ 12 - 6
src/view/portal/PortalIndexCustomiz.vue

@@ -51,6 +51,9 @@ import LayoutBottom from './LayoutBottom.vue'
 import $ from 'jquery'
 import "jquery-contextmenu";
 import "jquery-contextmenu/dist/jquery.contextMenu.min.css";
+import 'jquery-ui-dist/jquery-ui'
+import 'jquery-ui-dist/jquery-ui.css'
+  
 import LayoutRight from './LayoutRight.vue'
 
 export default {
@@ -109,8 +112,7 @@ export default {
     },
     handleSelect(key, keyPath){
       if(key === 'back'){
-        this.$parent.showIndex = true;
-        this.$parent.$refs['indexForm'].loadDatas();
+        this.$router.push("/portal/Index");
       }
       if(key ==='layout'){
         this.$refs['layout'].setLayout();
@@ -184,11 +186,15 @@ export default {
   watch: {
     
   },
-  filters: {
-
-  },
   mounted() {
-
+    let id =  this.$route.query.id;
+    if(id){
+      this.init(id);
+    }
+  },
+  beforeRouteLeave: function(to, from, next) {
+    this.$destroy();
+    next();
   }
 }
 </script>

+ 18 - 11
src/view/portal/PortalIndex.vue

@@ -16,7 +16,7 @@
               <h2>报表列表</h2>
             </div>
             <div class="btn-group optbtncls" role="group">
-            <button type="button" class="btn btn-outline btn-default" title="查看" @click="addUser(false)">
+            <button type="button" class="btn btn-outline btn-default" title="查看" @click="viewReport(false)">
               <i class="glyphicon glyphicon-file" aria-hidden="true"></i>
             </button>
             <button type="button" class="btn btn-outline btn-default" title="定制" @click="customization()">
@@ -97,10 +97,20 @@ export default {
 					success:function(resp){
 						ts.tableData = resp.rows;
             ts.total = resp.total;
-            ts.checked = null;
 					}
       }, this);
     },
+    viewReport(){
+      let ts = this;
+        if(!ts.checked){
+          ts.$notify.error({
+                  title: '未勾选数据',
+                  offset: 50
+                });
+          return false;
+        }
+        this.$router.push({path:"/portal/View", query:{id:ts.checked}});
+    },
     customization(){
       let ts = this;
         if(!ts.checked){
@@ -110,7 +120,7 @@ export default {
                 });
           return false;
         }
-        ts.customizationAction();
+        this.$router.push({path:"/portal/Customiz", query:{id:ts.checked}});
     },
     deleteReport(){
       let ts = this;
@@ -137,17 +147,14 @@ export default {
         }
     },
     newReport(){
-         this.$parent.showIndex = false;
-    },
-    customizationAction(){
-      this.$parent.showIndex = false;
-      this.$nextTick(()=>{
-        this.$parent.$refs['customizForm'].init(this.checked);
-      });
+      this.$router.push("/portal/Customiz");
     }
   },
   mounted(){
-    this.loadDatas();
+    //this.loadDatas();
+  },
+  beforeRouteEnter(to, from, next){
+    next(vm=>vm.loadDatas());
   },
   watch: {
 

+ 89 - 0
src/view/portal/PortalView.vue

@@ -0,0 +1,89 @@
+<template>
+  <div class="wrapper-content-nomargin">
+    <el-menu @select="handleSelect" class="el-menu-demo" background-color="#f6f8f8" text-color="#777" mode="horizontal">
+			<el-menu-item index="1"><i class="fa fa-arrow-left"></i> 返回</el-menu-item>
+      <el-menu-item index="2"><i class="fa fa-edit"></i> 定制</el-menu-item>
+			<el-submenu index="3">
+				<template slot="title"><i class="fa fa-file-excel-o"></i> 导出</template>
+				<el-menu-item index="html">HTML</el-menu-item>
+				<el-menu-item index="csv">CSV</el-menu-item>
+				<el-menu-item index="excel">EXCEL</el-menu-item>
+				<el-menu-item index="word">WORD</el-menu-item>
+				<el-menu-item index="pdf">PDF</el-menu-item>
+			</el-submenu>
+			<el-menu-item index="4"><i class="fa fa-print"></i> 打印</el-menu-item>
+		</el-menu>
+    <layout-view ref="optarea" :pageInfo="pageInfo"></layout-view>
+   
+  </div>
+</template>
+<script>
+import {baseUrl, ajax} from '@/common/biConfig'
+import { Loading } from 'element-ui'
+import LayoutView from './LayoutView.vue'
+
+export default {
+  name: "portalMain",
+  components: {
+    LayoutView
+  },
+  props: {
+
+  },
+  data() {
+    return {
+      reportId:null,
+      pageInfo:{}
+    }
+  },
+
+  methods: {
+    handleSelect(key, keyPath){
+      if(key === '1'){
+         this.$router.push("/portal/Index");
+      }else if(key === '2'){  //定制
+         this.$router.push({path:"/portal/Customiz", query:{id:this.reportId}});
+      }else if(key === '4'){  //打印
+
+      }
+    },
+    getCfg(){
+      ajax({
+        url:"portal/get.action",
+        data:{pageId:this.reportId},
+        type:"get",
+        success:(resp)=>{
+          this.pageInfo = JSON.parse(resp.rows);
+          this.getReport();
+        }
+      });
+    },
+    getReport(){
+      let loadingInstance = Loading.service({fullscreen:false, target:document.querySelector('.wrapper-content-nomargin')});
+      ajax({
+        url:"portal/view.action",
+        type:"GET",
+        data:{pageId:this.reportId},
+        success:(resp)=>{
+          //渲染组件
+          this.$refs['optarea'].setCompData(resp.rows);
+        }
+      }, this, loadingInstance);
+    }
+  },
+  mounted(){
+    this.reportId = this.$route.query.id;
+    this.getCfg();
+  },
+  watch: {
+
+  },
+  beforeRouteLeave: function(to, from, next) {
+    this.$destroy();
+    next();
+  }
+}
+</script>
+<style lang="less" scoped>
+
+</style>

+ 15 - 4
src/view/portal/view/Box.vue

@@ -17,6 +17,11 @@ export default {
         type:Object,
         required:true,
         default:{}
+      },
+      editor:{
+        type:Boolean,
+        required:true,
+        default:true
       }
   },
   render(h){
@@ -39,11 +44,17 @@ export default {
       }
       return h('div', {class:"boxcls", style:style}, this.data.value);
     }else{
-      return h('div', {attrs:{align:"center", class:"tipinfo"}, domProps:{innerHTML:"(点击<i class=\"fa fa-wrench\"></i>按钮配置"+utils.getCompTypeDesc(comp.type)+")"}});
+      if(this.editor === true){
+        return h('div', {attrs:{align:"center", class:"tipinfo"}, domProps:{innerHTML:"(点击<i class=\"fa fa-wrench\"></i>按钮配置"+utils.getCompTypeDesc(comp.type)+")"}});
+      }else{
+        return h('div','数据加载中...');
+      }
     }
   },
   mounted(){
-    this.boxView();
+    if(this.editor === true){
+      this.boxView();
+    }
   },
   computed: {
   },
@@ -60,10 +71,10 @@ export default {
             data:JSON.stringify(json),
             postJSON:true,
             success:(resp)=>{
-              ts.data = resp.rows[0];
+              ts.data = resp.rows;
               loadingInstance.close();
             }
-          }, this);
+          }, this, loadingInstance);
       }
     }
   },

+ 14 - 3
src/view/portal/view/Chart.vue

@@ -18,6 +18,11 @@ export default {
         type:Object,
         required:true,
         default:{}
+      },
+      editor:{
+        type:Boolean,
+        required:true,
+        default:true
       }
   },
   render(h){
@@ -27,11 +32,17 @@ export default {
       let height = comp && comp.height?comp.height:250;
       return h('div', {attrs:{id:"ct_"+comp.id}, style:{width:'100%', height: height + "px"}});
     }else{
-      return h('div', {attrs:{align:"center", class:"tipinfo"}, domProps:{innerHTML:"(点击<i class=\"fa fa-wrench\"></i>按钮配置"+utils.getCompTypeDesc(comp.type)+")"}});
+      if(this.editor === true){
+        return h('div', {attrs:{align:"center", class:"tipinfo"}, domProps:{innerHTML:"(点击<i class=\"fa fa-wrench\"></i>按钮配置"+utils.getCompTypeDesc(comp.type)+")"}});
+      }else{
+        return h('div','数据加载中...');
+      }
     }
   },
   mounted(){
-    this.chartView();
+    if(this.editor === true){
+      this.chartView();
+    }
     //放入window对象
     window.echartsUtils = echartsUtils;
     var echarts = require('echarts');
@@ -68,7 +79,7 @@ export default {
           //ts.$forceUpdate();
           ts.$nextTick(()=>ts.showChart());
         }
-      }, this);
+      }, this, loadingInstance);
     },
     /**
      * 调用echarts渲染图形

+ 14 - 3
src/view/portal/view/Grid.vue

@@ -17,6 +17,11 @@ export default {
         type:Object,
         required:true,
         default:{}
+      },
+      editor:{
+        type:Boolean,
+        required:true,
+        default:true
       }
   },
   render(h){
@@ -100,10 +105,16 @@ export default {
       return h('div', {class:"lock-dg", attrs:{id:comp.id}}, cld);
       
     }
-    return h('div', {attrs:{align:"center", class:"tipinfo"}, domProps:{innerHTML:"(点击<i class=\"fa fa-wrench\"></i>按钮配置"+utils.getCompTypeDesc(comp.type)+")"}});
+     if(this.editor === true){
+        return h('div', {attrs:{align:"center", class:"tipinfo"}, domProps:{innerHTML:"(点击<i class=\"fa fa-wrench\"></i>按钮配置"+utils.getCompTypeDesc(comp.type)+")"}});
+     }else{
+        return h('div','数据加载中...');
+     }
   },
   mounted(){
-    this.gridView();
+    if(this.editor === true){
+      this.gridView();
+    }
   },
   computed: {
   },
@@ -132,7 +143,7 @@ export default {
               loadingInstance.close();
               ts.$nextTick(()=>ts.bindScrollEvent());
             }
-          }, this);
+          }, this, loadingInstance);
       }
     }
   },

+ 14 - 3
src/view/portal/view/Table.vue

@@ -17,6 +17,11 @@ export default {
         type:Object,
         required:true,
         default:{}
+      },
+      editor:{
+        type:Boolean,
+        required:true,
+        default:true
       }
   },
   render(h){
@@ -57,11 +62,17 @@ export default {
       return h('div', {class:"lock-dg", attrs:{id:comp.id}}, cld);
 
     }else{
-      return h('div', {attrs:{align:"center", class:"tipinfo"}, domProps:{innerHTML:"(点击<i class=\"fa fa-wrench\"></i>按钮配置"+utils.getCompTypeDesc(comp.type)+")"}});
+      if(this.editor === true){
+        return h('div', {attrs:{align:"center", class:"tipinfo"}, domProps:{innerHTML:"(点击<i class=\"fa fa-wrench\"></i>按钮配置"+utils.getCompTypeDesc(comp.type)+")"}});
+      }else{
+        return h('div','数据加载中...');
+      }
     }
   },
   mounted(){
-    this.tableView();
+    if(this.editor === true){
+      this.tableView();
+    }
   },
   computed: {
   },
@@ -90,7 +101,7 @@ export default {
               loadingInstance.close();
               ts.$nextTick(()=>ts.bindScrollEvent());
             }
-          }, this);
+          }, this, loadingInstance);
       }
     }
   },