瀏覽代碼

解决报表设计器的三个问题:1.SQL参数过多时不显示滚动条的BUG。 2.为SQL参数添加编辑功能。 3.在右键菜单中添加设置行高列宽功能。

master
jacky6024 7 年前
父節點
當前提交
90323dec0c
  1. 34
      ureport2-js/src/dialog/ParameterDialog.js
  2. 64
      ureport2-js/src/dialog/ParameterTable.js
  3. 62
      ureport2-js/src/dialog/RowColWidthHeightDialog.js
  4. 10
      ureport2-js/src/dialog/SqlDatasetDialog.js
  5. 6
      ureport2-js/src/preview.js
  6. 3
      ureport2-js/src/table/CellRenderer.js
  7. 37
      ureport2-js/src/table/ContextMenu.js
  8. 134
      ureport2-js/src/tools/ChartTool.js
  9. 22
      ureport2-js/src/tools/MergeTool.js

34
ureport2-js/src/dialog/ParameterDialog.js

@ -14,7 +14,7 @@ export default class ParameterDialog{
×
</button>
<h4 class="modal-title">
添加参数
SQL参数
</h4>
</div>
<div class="modal-body"></div>
@ -28,14 +28,14 @@ export default class ParameterDialog{
init(body,footer){
const nameRow=$(`<div class="row" style="margin-bottom: 10px;margin-right:6px;"><div class="col-md-3" style="padding: 0 10px 0 0px;text-align:right;margin-top:5px">参数名称:</div></div>`);
const nameGroup=$(`<div class="col-md-9" style="padding: 0 10px 0 0px"></div>`);
const nameEditor=$(`<input type="text" class="form-control">`);
nameGroup.append(nameEditor);
this.nameEditor=$(`<input type="text" class="form-control">`);
nameGroup.append(this.nameEditor);
nameRow.append(nameGroup);
body.append(nameRow);
const typeRow=$(`<div class="row" style="margin-bottom: 10px;margin-right:6px;"><div class="col-md-3" style="padding: 0 10px 0 0px;text-align:right;margin-top:5px">数据类型:</div></div>`);
const typeGroup=$(`<div class="col-md-9" style="padding: 0 10px 0 0px"></div>`);
const typeEditor=$(`<select class="form-control">
this.typeEditor=$(`<select class="form-control">
<option>String</option>
<option>Integer</option>
<option>Float</option>
@ -43,14 +43,14 @@ export default class ParameterDialog{
<option>Date</option>
<option>List</option>
</select>`);
typeGroup.append(typeEditor);
typeGroup.append(this.typeEditor);
typeRow.append(typeGroup);
body.append(typeRow);
const defaultValueRow=$(`<div class="row" style="margin-bottom: 10px;margin-right:6px;"><div class="col-md-3" style="padding: 0 10px 0 0px;text-align:right;margin-top:5px">默认值:</div></div>`);
const defaultValueGroup=$(`<div class="col-md-9" style="padding: 0 10px 0 0px"></div>`);
const defaultValueEditor=$(`<input type="text" placeholder="Date类型默认值为一个格式为yyyy-MM-dd HH:mm:ss的日期值" class="form-control">`);
defaultValueGroup.append(defaultValueEditor);
this.defaultValueEditor=$(`<input type="text" placeholder="Date类型默认值为一个格式为yyyy-MM-dd HH:mm:ss的日期值" class="form-control">`);
defaultValueGroup.append(this.defaultValueEditor);
defaultValueRow.append(defaultValueGroup);
body.append(defaultValueRow);
@ -58,7 +58,7 @@ export default class ParameterDialog{
const addButton=$(`<button class="btn btn-primary">确定</button>`);
footer.append(addButton);
addButton.click(function(){
const name=nameEditor.val(),type=typeEditor.val(),defaultValue=defaultValueEditor.val();
const name=_this.nameEditor.val(),type=_this.typeEditor.val(),defaultValue=_this.defaultValueEditor.val();
if(name===''){
alert("请输入参数名!");
return;
@ -67,18 +67,26 @@ export default class ParameterDialog{
alert("请选择数据类型!");
return;
}
for(let param of _this.data){
if(param.name===name){
alert("参数["+name+"]已存在!");
return;
if(!_this.editData || name!==_this.editData.name){
for(let param of _this.data){
if(param.name===name){
alert("参数["+name+"]已存在!");
return;
}
}
}
_this.onSave.call(this,name,type,defaultValue);
_this.dialog.modal('hide');
});
}
show(onSave){
show(onSave,data){
this.onSave=onSave;
this.dialog.modal('show');
if(data){
this.editData=data;
this.nameEditor.val(data.name);
this.typeEditor.val(data.type);
this.defaultValueEditor.val(data.defaultValue);
}
}
}

64
ureport2-js/src/dialog/ParameterTable.js

@ -9,9 +9,9 @@ export default class ParameterTable{
const addButton=$(`<button type="button" class="btn btn-info">添加参数</button>`);
container.append(addButton);
const _this=this;
const table=$(`<table class="table table-bordered">
const table=$(`<table class="table table-bordered" style="margin-bottom: 0">
<thead>
<tr style="background: #f4f4f4;height: 30px;"><td style="vertical-align: middle">参数名</td><td style="vertical-align: middle"></td><td style="vertical-align: middle"></td><td style="vertical-align: middle"></td></tr>
<tr style="background: #f4f4f4;height: 30px;"><td style="vertical-align: middle">参数名</td><td style="vertical-align: middle"></td><td style="vertical-align: middle"></td><td style="vertical-align: middle;width: 80px;"></td></tr>
</thead>
</table>`);
this.body=$(`<tbody></tbody>`);
@ -23,18 +23,36 @@ export default class ParameterTable{
_this.parameterDialog.show(function(name,type,defaultValue){
const obj={name,type,defaultValue};
_this.data.push(obj);
const newTr=$(`<tr style="height: 35px;"><td style="vertical-align: middle">${name}</td><td style="vertical-align: middle">${type}</td><td style="vertical-align: middle">${defaultValue}</td></tr>`);
const removeTd=$(`<td style="vertical-align: middle"></td>`);
const removeSpan=$(`<span><a href="###"><i class="glyphicon glyphicon-trash" style="font-size: 12pt;color: #d30a16;"></a></span>`);
removeTd.append(removeSpan);
newTr.append(removeTd);
const newTr=$(`<tr style="height: 35px;"></tr>`);
const nameTd=$(`<td style="vertical-align: middle">${name}</td>`);
const typeTd=$(`<td style="vertical-align: middle">${type}</td>`);
const defaultValueTd=$(`<td style="vertical-align: middle">${defaultValue}</td>`);
newTr.append(nameTd);
newTr.append(typeTd);
newTr.append(defaultValueTd);
const opTd=$(`<td style="vertical-align: middle"></td>`);
const removeSpan=$(`<span><a href="###"><i class="glyphicon glyphicon-trash" title="删除参数" style="font-size: 12pt;color: #d30a16;"></a></span>`);
opTd.append(removeSpan);
newTr.append(opTd);
_this.body.append(newTr);
removeSpan.click(function(){
let index=_this.data.indexOf(obj);
_this.data.splice(index,1);
newTr.remove();
});
})
const editSpan=$(`<span><a href="###"><i class="glyphicon glyphicon-edit" title="修改参数" style="font-size: 12pt;color: #005fd3;margin-left: 10px"></a></span>`);
opTd.append(editSpan);
editSpan.click(function(){
_this.parameterDialog.show(function(name,type,defaultValue){
obj.name=name;
obj.type=type;
obj.defaultValue=defaultValue;
nameTd.html(name);
typeTd.html(type);
defaultValueTd.html(defaultValue);
},obj);
});
},null)
});
}
refreshData(){
@ -45,17 +63,37 @@ export default class ParameterTable{
_buildParameters(){
const _this=this;
for(let param of this.data){
const tr=$(`<tr><td>${param.name}</td><td>${param.type}</td><td>${param.defaultValue}</td></tr>`);
const deleteTd=$(`<td></td>`);
const deleteSpan=$(`<span><a href="###"><i class="glyphicon glyphicon-trash" style="font-size: 12pt;color: #d30a16;"></a></span>`);
deleteTd.append(deleteSpan);
tr.append(deleteTd);
const tr=$(`<tr style="height: 35px;"></tr>`);
const nameTd=$(`<td style="vertical-align: middle">${param.name}</td>`);
const typeTd=$(`<td style="vertical-align: middle">${param.type}</td>`);
const defaultValueTd=$(`<td style="vertical-align: middle">${param.defaultValue}</td>`);
tr.append(nameTd);
tr.append(typeTd);
tr.append(defaultValueTd);
const opTd=$(`<td style="vertical-align: middle"></td>`);
const deleteSpan=$(`<span><a href="###"><i class="glyphicon glyphicon-trash" title="删除参数" style="font-size: 12pt;color: #d30a16;"></a></span>`);
opTd.append(deleteSpan);
tr.append(opTd);
deleteSpan.click(function(){
let index=_this.data.indexOf(param);
_this.data.splice(index,1);
tr.remove();
});
this.body.append(tr);
const editSpan=$(`<span><a href="###"><i class="glyphicon glyphicon-edit" title="修改参数" style="font-size: 12pt;color: #005fd3;margin-left: 10px"></a></span>`);
opTd.append(editSpan);
editSpan.click(function(){
_this.parameterDialog.show(function(name,type,defaultValue){
param.name=name;
param.type=type;
param.defaultValue=defaultValue;
nameTd.html(name);
typeTd.html(type);
defaultValueTd.html(defaultValue);
},param);
});
}
}
}

62
ureport2-js/src/dialog/RowColWidthHeightDialog.js

@ -0,0 +1,62 @@
/**
* Created by Jacky.Gao on 2017-02-07.
*/
import {alert} from '../MsgBox.js';
import {setDirty} from '../Utils.js';
export default class RowColWidthHeightDialog{
constructor(){
this.dialog=$(`<div class="modal fade" role="dialog" aria-hidden="true" style="z-index: 11001">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">
&times;
</button>
<h4 class="modal-title row-col-wh">
行列宽高设置
</h4>
</div>
<div class="modal-body"></div>
<div class="modal-footer">
</div>
</div>
</div>
</div>`);
const body=this.dialog.find('.modal-body'),footer=this.dialog.find(".modal-footer");
this.initBody(body,footer);
}
initBody(body,footer){
const group=$(`<div class="form-group"></div>`);
this.label=$(`<label></label>`);
group.append(this.label);
this.valueEditor=$(`<input type="number" class="form-control" placeholder="请输入一个大于0的数字">`);
group.append(this.valueEditor);
body.append(group);
const button=$(`<button type="button" class="btn btn-danger">确定</button>`);
footer.append(button);
const _this=this;
button.click(function(){
const value=parseInt(_this.valueEditor.val());
if(!value){
alert("请输入一个合法的数字!");
return;
}
_this.callback.call(this,value);
_this.dialog.modal('hide');
});
}
show(callback,value,iscol){
this.dialog.modal('show');
this.callback=callback;
if(iscol){
this.label.html("设置列宽:");
$(".row-col-wh").html("设置列宽");
}else{
this.label.html("设置行高:");
$(".row-col-wh").html("设置行高");
}
this.valueEditor.val(value);
}
}

10
ureport2-js/src/dialog/SqlDatasetDialog.js

@ -10,7 +10,7 @@ export default class SqlDatasetDialog{
this.db=db;
this.datasources=db.datasources;
this.data=data;
this.dialog=$(`<div class="modal fade" role="dialog" aria-hidden="true" style="z-index: 10000">
this.dialog=$(`<div class="modal fade" role="dialog" aria-hidden="true" style="z-index: 10000;overflow: auto">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
@ -91,6 +91,14 @@ export default class SqlDatasetDialog{
footer.append(confirmButton);
confirmButton.click(function(){
const name=_this.nameEditor.val(),sql=_this.sqlEditor.val();
if(!name || name===""){
alert("数据集名称不能为空!");
return;
}
if(!sql || sql!==""){
alert("数据集SQL不能为空!");
return;
}
let check=false;
if(!_this.oldName || name!==_this.oldName){
check=true;

6
ureport2-js/src/preview.js

@ -1,6 +1,7 @@
/**
* Created by Jacky.Gao on 2017-03-17.
*/
import Chart from "chart.js";
import '../node_modules/bootstrap/dist/css/bootstrap.min.css';
import {getParameter,pointToMM,showLoading,hideLoading} from './Utils.js';
import {alert} from './MsgBox.js';
@ -110,3 +111,8 @@ function buildPrintStyle(paper){
`;
return style;
};
function _buildChart(canvasId,chartJson){
const ctx=document.getElementById(canvasId);
const chart=new Chart(ctx,chartJson);
};

3
ureport2-js/src/table/CellRenderer.js

@ -51,10 +51,11 @@ export function afterRenderer(td,row,col,prop,value,cellProperties){
if(text && text!==""){
text=text.replace(new RegExp('\r\n','gm'),'<br>');
text=text.replace(new RegExp('\n','gm'),'<br>');
text=text.replace(new RegExp(' ','gm'),'&nbsp;');
$td.html(text);
}
}
$td.css({'word-break':'break-all','line-height':'normal','white-space':'nowrap'});
$td.css({'word-break':'break-all','line-height':'normal','white-space':'nowrap',padding:'0 1px'});
if(cellDef.expand === 'Down'){
let url=window._server+"/res/asserts/icons/expr-expand-down.svg";
if(valueType==='dataset'){

37
ureport2-js/src/table/ContextMenu.js

@ -7,6 +7,7 @@ import {doInsertCol} from './operation/InsertColOperation.js';
import {doDeleteRow} from './operation/DeleteRowOperation.js';
import {doDeleteCol} from './operation/DeleteColOperation.js';
import {renderRowHeader} from './HeaderUtils.js';
import RowColWidthHeightDialog from '../dialog/RowColWidthHeightDialog.js';
import Handsontable from 'handsontable';
export const contextMenuConfigure={
@ -87,6 +88,34 @@ export const contextMenuConfigure={
}
renderRowHeader(this,context);
setDirty();
}else if(key==='row_height'){
const selected=this.getSelected();
const startRow=selected[0];
const rowHeight=this.getRowHeight(startRow);
const dialog=new RowColWidthHeightDialog();
dialog.show(function(newHeight){
const rowHeights=_this.getSettings().rowHeights;
rowHeights.splice(startRow,1,newHeight);
_this.updateSettings({
rowHeights:rowHeights,
manualRowResize:rowHeights
});
},rowHeight,false);
setDirty();
}else if(key==='col_width'){
const selected=this.getSelected();
const startCol=selected[1];
const colWidth=this.getColWidth(startCol);
const dialog=new RowColWidthHeightDialog();
dialog.show(function(newColWidth){
const colWidths=_this.getSettings().colWidths;
colWidths.splice(startCol,1,newColWidth);
_this.updateSettings({
colWidths:colWidths,
manualColumnResize:colWidths
});
},colWidth,true);
setDirty();
}
},
items: {
@ -110,6 +139,14 @@ export const contextMenuConfigure={
name: '<i class="ureport ureport-deletecolumn" style="color: #d30a16;font-size: 13px"></i> 删除列',
disabled:checkColDeleteOperationDisabled
},
"row_height": {
name: '<i class="ureport ureport-height" style="color: #d30a16;font-size: 13px;font-weight:bold"></i> 设置行高',
disabled:checkRowDeleteOperationDisabled
},
"col_width": {
name: '<i class="ureport ureport-width" style="color: #d30a16;font-size: 13px;font-weight:bold"></i> 设置列宽',
disabled:checkColDeleteOperationDisabled
},
"repeat_row_header": {
name: '<i class="ureport ureport-header-repeat" style="color: #9C27B0;font-size: 13px"></i> 重复表头',
disabled:checkRowDeleteOperationDisabled

134
ureport2-js/src/tools/ChartTool.js

@ -1,7 +1,9 @@
/**
* Created by Jacky.Gao on 2017-01-25.
*/
import undoManager from 'undo-manager';
import Tool from './Tool.js';
import {setDirty} from '../Utils.js';
export default class ChartTool extends Tool{
execute(){
@ -20,6 +22,14 @@ export default class ChartTool extends Tool{
</a>
</li>`);
ul.append(pie);
pie.click(function(){
});
const doughnut=$(`<li>
<a href="###">
<i class="ureport ureport-doughnut" style="color: #0e90d2;"></i>
</a>
</li>`);
ul.append(doughnut);
const line=$(`<li>
<a href="###">
<i class="ureport ureport-line" style="color: #0e90d2;"></i> 线
@ -68,9 +78,133 @@ export default class ChartTool extends Tool{
</a>
</li>`);
ul.append(bubble);
const mix=$(`<li>
<a href="###">
<i class="ureport ureport-mixchart" style="color: #0e90d2;"></i>
</a>
</li>`);
ul.append(mix);
group.append(mainBtn);
group.append(ul);
return group;
}
_doClick(category){
const hot=_this.context.hot;
const selected=hot.getSelected();
const startRow=selected[0],startCol=selected[1],endRow=selected[2],endCol=selected[3];
let cellDef=_this.context.getCell(startRow,startCol);
let oldValue=cellDef.value,oldCellData=hot.getDataAtCell(startRow,startCol);
hot.setDataAtCell(startRow,startCol,'');
let td=hot.getCell(startRow,startCol);
let width=_this._buildWidth(startCol,td.colSpan,hot),height=_this._buildHeight(startRow,td.rowSpan,hot);
cellDef.value={
width,
height,
type:'chart',
category:this._newChart(category),
data:''
};
hot.render();
setDirty();
Handsontable.hooks.run(hot, 'afterSelectionEnd',startRow,startCol,endRow,endCol);
const _this=this;
undoManager.add({
redo:function(){
cellDef=_this.context.getCell(startRow,startCol);
oldValue=cellDef.value,oldCellData=hot.getDataAtCell(startRow,startCol);
hot.setDataAtCell(startRow,startCol,'');
td=hot.getCell(startRow,startCol);
width=_this._buildWidth(startCol,td.colSpan,hot),height=_this._buildHeight(startRow,td.rowSpan,hot);
cellDef.value={
width,
height,
type:'chart',
category:_this._newChart(category),
data:''
};
hot.render();
setDirty();
Handsontable.hooks.run(hot, 'afterSelectionEnd',startRow,startCol,endRow,endCol);
},
undo:function(){
cellDef=_this.context.getCell(startRow,startCol);
cellDef.value=oldValue;
hot.setDataAtCell(startRow,startCol,oldCellData);
hot.render();
setDirty();
Handsontable.hooks.run(hot, 'afterSelectionEnd',startRow,startCol,endRow,endCol);
}
})
}
_newChart(category){
return {
dataset:{
type:category
}
};
/*
switch (category){
case "pie":
return {
dataset:{
type:"pie"
}
};
case "doughnut":
return {
dataset:{
type:"doughnut"
}
};
case "line":
return {
dataset:{
type:"line"
}
};
case "area":
return {type:"area"};
case "polar":
return {type:"polar"};
case "scatter":
return {type:"scatter"};
case "bar":
return {type:"bar"};
case "horizontalBar":
return {type:"horizontalBar"};
case "mix":
return {type:"mix"};
case "bubble":
return {type:"bubble"};
case "radar":
return {type:"radar"};
}
*/
}
_buildWidth(colIndex,colspan,hot){
let width=hot.getColWidth(colIndex)-3;
if(!colspan || colspan<2){
return width;
}
let start=colIndex+1,end=colIndex+colspan;
for(let i=start;i<end;i++){
width+=hot.getColWidth(i);
}
return width;
}
_buildHeight(rowIndex,rowspan,hot){
let height=hot.getRowHeight(rowIndex)-3;
if(!rowspan || rowspan<2){
return height;
}
let start=rowIndex+1,end=rowIndex+rowspan;
for(let i=start;i<end;i++){
height+=hot.getRowHeight(i);
}
return height;
}
}

22
ureport2-js/src/tools/MergeTool.js

@ -1,4 +1,4 @@
import {undoManager,setDirty} from '../Utils.js';
import {undoManager,setDirty,buildNewCellDef} from '../Utils.js';
import {alert} from '../MsgBox.js';
/**
@ -26,12 +26,13 @@ export default class MergeTool extends Tool{
endCol=startCol;
startCol=tmp;
}
doMergeCells(startRow,startCol,endRow,endCol,table);
const _this=this;
doMergeCells(startRow,startCol,endRow,endCol,table,this.context);
undoManager.add({
redo:function(){
mergeCells=table.getSettings().mergeCells || [];
oldMergeCells=mergeCells.concat([]);
doMergeCells(startRow,startCol,endRow,endCol,table);
doMergeCells(startRow,startCol,endRow,endCol,table,_this.context);
setDirty();
},
undo:function(){
@ -48,8 +49,9 @@ export default class MergeTool extends Tool{
return `<i class="ureport ureport-merge" style="color: #0e90d2;"></i>`;
}
}
function doMergeCells(startRow,startCol,endRow,endCol,table){
function doMergeCells(startRow,startCol,endRow,endCol,table,context){
let doMerge=true,doSplit=false;
const selectCell=context.getCell(startRow,startCol);
const mergeCells=table.getSettings().mergeCells || [];
for(let i=startRow;i<=endRow;i++){
for(let j=startCol;j<=endCol;j++){
@ -101,7 +103,17 @@ function doMergeCells(startRow,startCol,endRow,endCol,table){
const newMergeItem={row:startRow,col:startCol,rowspan:rowSpan,colspan:colSpan};
mergeCells.push(newMergeItem);
}else{
if(!doSplit){
if(doSplit){
for(let i=startRow;i<=endRow;i++) {
for (let j = startCol; j <= endCol; j++) {
let cellDef=context.getCell(i,j);
if(!cellDef){
cellDef=buildNewCellDef(i+1,j+1);
context.addCell(cellDef);
}
}
}
}else{
alert("请选择多个单元格后再进行此操作!");
}
}

載入中…
取消
儲存