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
统计分析修改
master
1 parent
60d8907
commit
b6c237ccb48de6e7a9eb619e5bfeb5418c971b7c
hhb
authored
on 6 Dec 2022
Showing
2 changed files
project/hivuiSam/components/analysisSam/Index.vue
project/hivuiSam/components/templates/query-panel/data-list/query-style-01.js
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-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" :summary-method="getSummaries" 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" :summary-method="getSummaries" 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) arr = arr.filter(item =>{ var show = true this.analysisData.forEach(data =>{ if(data.prop == item.prop){ show = data.tableColumn } }) return show }) 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 }) } let table = model.tableprops || {} table['columns'] = columns obj.lookup = { type: "data", openstyle: 'selectgrid', bindField: item.prop, lookSelectGrid: { width: 1200, height: 600, table: table, 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 = model.tableprops table['chidren'] = 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 } lookup.returnType = "single", 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.currentPage = 1 this.doQuery(); // 当前分组加入深度分析 if(index < 0){ this.$message.error('当前分组条件不在分组字段中,请重新配置') }else{ this.$set(this.deepArr,0,this.groupFields[index]) this.curIndex = 0 } }, afterLoadData(datas){ this.data = datas // 缓存数据 this.deepArr[this.curIndex].data = datas; let ds = this.$refs.BirtWorkBook_right.dataset[this.dataset.controlId] // 总条数 this.total = ds._infcPagging.recordCount || this.total }, // 查询方法 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 this.doQuery() }, handleCurrentChange(val) { this.currentPage = val this.doQuery() }, // 切换图表 chartTypeChange(command) { this.chartType = command; }, // 打开分析列 analysisClick(){ this.analysisVisible = true }, // 分系列全选 handelCheckAll(val){ 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])); }; }, // 合计列 getSummaries(parma){ const { columns, data } = parma; const sums = []; let arr = this.analyseFields.map(item =>{ return item.prop }) columns.forEach((column, index) => { let show = true this.analysisData.forEach(item =>{ if(item.prop == column.property){ show = item.tableColumnCount } }) if(arr.includes(column.property) && show){ let values = data.map(item => Number(item[column.property])); sums[index] = values.reduce((prev, curr) => { const value = Number(curr); if (!isNaN(value)) { return prev + curr; } else { return prev; } }, 0); }else{ sums[index] = ''; } }) sums[0] = '统计' return sums; } }, 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" :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>
Ignore Space
Show notes
View
project/hivuiSam/components/templates/query-panel/data-list/query-style-01.js
/** * datalist网格查询面板布局风格1 * @param {*} form 表单配置[{colspan:1,prop:"fieldName1",label:"字段1"}] * @param {*} option.hcQueryPanel 查询面板个性化配置 * @param {*} option.hcDataList 数据列表个性化配置 * @param {*} option.row 网格行通用配置 * @param {*} option.cols 网格列配置 * @returns */ export function queryStyle01(form, option = {}) { // 初始化cols列配置, 默认3列 let cols = option.cols || [ { colWidth: "40%", }, { colWidth: "30%", }, { colWidth: "30%", } ] // 计算rows查询面板内容 let rows = {}; let curtRow = newEmptyRow(); let rIndex = 1; let colTotalCount = cols.length; let colSpanCount = 0; // 计算rows行配置 function newEmptyRow() { // 创建空行 return Object.assign({ tds: {} }, option.row || {}); } // 不足列进行补全 function fillTd(rIndex, curtColIndex, colCount, curtRow) { if (curtColIndex < colCount) { for (let m = curtColIndex; m < colCount; m++) { let mAxis = String.fromCharCode(65 + m) + rIndex; curtRow.tds[mAxis] = { colspan: 1 } } } } for (let i = 0, l = form.length; i < l; i++) { let fItem = form[i]; let colspan = fItem.colspan || 1; let tdAxis = String.fromCharCode(65 + colSpanCount); // 当前项已超本行总列数或当前是行分隔项,补全空余, 别取新行 if (colSpanCount + colspan > colTotalCount) { // 不足列进行补全 // fillTd(rIndex, colSpanCount, colTotalCount, curtRow); // 当前列添加到rows,另取新行 let rAxis = "r" + rIndex; rows[rAxis] = JSON.parse(JSON.stringify(curtRow)); curtRow = newEmptyRow(); rIndex++; colSpanCount = 0; } // 当前行curtRow添加表单项td let propAxis = tdAxis + rIndex; curtRow.tds[propAxis] = fItem; colSpanCount += colspan; } // 添加最后一行 if (colSpanCount > 0) { // 补全最后一行 // fillTd(rIndex, colSpanCount, colTotalCount, curtRow); let rAxis = "r" + rIndex; rows[rAxis] = JSON.parse(JSON.stringify(curtRow)); } // 定义dataList布局 let dataList = { controlName: "HcDataList", controlId: "HcDataList_02", width: "100%", style: "border-spacing:0px;border-collapse: collapse;table-layout:fixed;word-break:break-all;", rows: rows, cols: cols } // 应用datalist个性化配置 Object.assign(dataList, option.hcDataList); // 定义查询面板 let queryPanel = { inline: true, size: "small", children: [ dataList ], }; // 查询面板 return Object.assign(queryPanel, Option.hcQueryPanel); }
/** * datalist网格查询面板布局风格1 * @param {*} form 表单配置[{colspan:1,prop:"fieldName1",label:"字段1"}] * @param {*} option.hcQueryPanel 查询面板个性化配置 * @param {*} option.hcDataList 数据列表个性化配置 * @param {*} option.row 网格行通用配置 * @param {*} option.cols 网格列配置 * @returns */ export function queryStyle01(form, option = {}) { // 初始化cols列配置, 默认3列 let cols = option.cols || [ { colWidth: "40%", }, { colWidth: "30%", }, { colWidth: "30%", } ] // 计算rows查询面板内容 let rows = {}; let curtRow = newEmptyRow(); let rIndex = 1; let colTotalCount = cols.length; let colSpanCount = 0; // 计算rows行配置 function newEmptyRow() { // 创建空行 return Object.assign({ tds: {} }, option.row || {}); } // 不足列进行补全 function fillTd(rIndex, curtColIndex, colCount, curtRow) { if (curtColIndex < colCount) { for (let m = curtColIndex; m < colCount; m++) { let mAxis = String.fromCharCode(65 + m) + rIndex; curtRow.tds[mAxis] = { colspan: 1 } } } } for (let i = 0, l = form.length; i < l; i++) { let fItem = form[i]; let colspan = fItem.colspan || 1; let tdAxis = String.fromCharCode(65 + colSpanCount); // 当前项已超本行总列数或当前是行分隔项,补全空余, 别取新行 if (colSpanCount + colspan > colTotalCount) { // 不足列进行补全 fillTd(rIndex, colSpanCount, colTotalCount, curtRow); // 当前列添加到rows,另取新行 let rAxis = "r" + rIndex; rows[rAxis] = JSON.parse(JSON.stringify(curtRow)); curtRow = newEmptyRow(); rIndex++; colSpanCount = 0; } // 当前行curtRow添加表单项td let propAxis = tdAxis + rIndex; curtRow.tds[propAxis] = fItem; colSpanCount += colspan; } // 添加最后一行 if (colSpanCount > 0) { // 补全最后一行 fillTd(rIndex, colSpanCount, colTotalCount, curtRow); let rAxis = "r" + rIndex; rows[rAxis] = JSON.parse(JSON.stringify(curtRow)); } // 定义dataList布局 let dataList = { controlName: "HcDataList", controlId: "HcDataList_02", width: "100%", style: "border-spacing:0px;border-collapse: collapse;table-layout:fixed;word-break:break-all;", rows: rows, cols: cols } // 应用datalist个性化配置 Object.assign(dataList, option.hcDataList); // 定义查询面板 let queryPanel = { inline: true, size: "small", children: [ dataList ], }; // 查询面板 return Object.assign(queryPanel, Option.hcQueryPanel); }
Show line notes below