|
|
|
|
|
(function (win) {
|
|
|
|
|
|
/////////////////////////////////////////////
|
|
|
///global variable
|
|
|
////////////////////////////////////////////
|
|
|
|
|
|
var ID_PROPERTY = '$id';
|
|
|
var ROW_SELECT_COLNAME = '$is_sel';
|
|
|
var Global = win.Store;
|
|
|
|
|
|
var hasValue = function (o) {
|
|
|
if (o !== 0 && !o) {
|
|
|
return false;
|
|
|
}
|
|
|
return true;
|
|
|
};
|
|
|
|
|
|
var getFormatter = function (name) {
|
|
|
if (Slick && Slick.Formatters) {
|
|
|
return Slick.Formatters[name];
|
|
|
}
|
|
|
return null;
|
|
|
};
|
|
|
|
|
|
var toStrLines = function (arr) {
|
|
|
var msgs = [];
|
|
|
for (var i = 0, len = arr.length; i < len; i++) {
|
|
|
var elem = arr[i];
|
|
|
if (msgs.indexOf(elem) === -1) {
|
|
|
msgs.push(elem);
|
|
|
}
|
|
|
}
|
|
|
return arr.join('<br>').replace(/\n/g, '<br>');
|
|
|
};
|
|
|
|
|
|
var serialEnumValues = function (data, sep) {
|
|
|
if (!data) return [];
|
|
|
var result = []
|
|
|
sep = sep || '';
|
|
|
for (var name in data) {
|
|
|
var item = {
|
|
|
key: name,
|
|
|
value: name + sep + data[name]
|
|
|
}
|
|
|
result.push(item);
|
|
|
}
|
|
|
|
|
|
return _.sortBy(result, 'key');
|
|
|
};
|
|
|
|
|
|
var isObjectValueEqual = function (a, b) {
|
|
|
var aProps = Object.getOwnPropertyNames(a);
|
|
|
var bProps = Object.getOwnPropertyNames(b);
|
|
|
|
|
|
if (aProps.length != bProps.length) {
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
for (var i = 0; i < aProps.length; i++) {
|
|
|
var propName = aProps[i];
|
|
|
if (a[propName] !== b[propName]) {
|
|
|
return false;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
var checkDuplicate = function (datas, data) {
|
|
|
var flag = false;
|
|
|
for (var i = 0, length = datas.length; i < length; i++) {
|
|
|
if (isObjectValueEqual(datas[i], data)) {
|
|
|
flag = true;
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
return flag;
|
|
|
}
|
|
|
|
|
|
function equalIgnoreCase(a, b) {
|
|
|
a = String(a).toUpperCase()
|
|
|
b = String(b).toUpperCase()
|
|
|
|
|
|
return a === b
|
|
|
}
|
|
|
|
|
|
function toUpperKey(o) {
|
|
|
if (!o || Object.keys(o).length === 0) {
|
|
|
return {}
|
|
|
}
|
|
|
|
|
|
var result = {}
|
|
|
Object.keys(o).forEach(k => {
|
|
|
result[k.toUpperCase()] = o[k]
|
|
|
})
|
|
|
|
|
|
return result
|
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////
|
|
|
///DataColumn 数据列
|
|
|
/**
|
|
|
* 数据列,用于表示数据源上的列
|
|
|
* @param {Object} dataSrc 数据源
|
|
|
*/
|
|
|
function DataColumn(dataSrc) {
|
|
|
var self = this;
|
|
|
self.dataSrc = dataSrc;
|
|
|
self.isDataColumn = true;
|
|
|
self.isInit = false;
|
|
|
Global.eventuality(self);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 数据列初始化,主要是初始化相应的字典属性,只执行一遍
|
|
|
* @param {Object} dictCol 服务器返回的字典信息
|
|
|
* @return {[type]} [description]
|
|
|
*/
|
|
|
DataColumn.prototype.init = function (dictCol) {
|
|
|
if (self.isInit) {
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
var col = this;
|
|
|
//数据相关
|
|
|
col.fieldName = dictCol.fieldName;
|
|
|
col.dataRightCode = dictCol.dataRightCode;
|
|
|
col.dataRightType = dictCol.dataRightType;
|
|
|
col.defaultValue = dictCol.defaultValue;
|
|
|
col.paraValue = dictCol.defaultValue;
|
|
|
col.isEmptyField = dictCol.isEmptyField;
|
|
|
col.isQrySele = dictCol.isQrySele;
|
|
|
col.isStrictRef = dictCol.isStrictRef;
|
|
|
col.isCalc = dictCol.isCalc;
|
|
|
col.isRequired = dictCol.isRequired;
|
|
|
col.isEditLimit = dictCol.isEditLimit;
|
|
|
col.isEditable = dictCol.isEditable;
|
|
|
col.match = dictCol.match;
|
|
|
col.refObj = dictCol.refObj;
|
|
|
col.refField = dictCol.refField;
|
|
|
col.refFieldName = dictCol.refFieldName;
|
|
|
col.refSeparator = dictCol.refSeparator;
|
|
|
col.refType = dictCol.refType;
|
|
|
col.refEditWhere = dictCol.refEditWhere;
|
|
|
col.setRule = dictCol.setRule;
|
|
|
col.statType = dictCol.statType;
|
|
|
col.extParams = dictCol.extParams;
|
|
|
col.dataType = col.isCalc ? '1' : dictCol.dataType;
|
|
|
col.dataWidth = dictCol.dataWidth || 0;
|
|
|
col.dataDec = dictCol.dataDec || 0;
|
|
|
col.procParaType = dictCol.procParaType;
|
|
|
col.isPrimaryKey = dictCol.isPrimaryKey;
|
|
|
|
|
|
//界面相关
|
|
|
col.dispScale = dictCol.dispScale;
|
|
|
col.dispFormat = dictCol.dispFormat;
|
|
|
col.dispName = dictCol.dispName;
|
|
|
col.dispIndex = dictCol.dispIndex;
|
|
|
col.dispPosition = dictCol.dispPosition;
|
|
|
col.dispWidth = dictCol.dispWidth;
|
|
|
col.headerWidth = dictCol.headerWidth;
|
|
|
col.labelWidth = dictCol.labelWidth;
|
|
|
col.hint = dictCol.hint;
|
|
|
col.editStyle = dictCol.editStyle;
|
|
|
col.isZeroSpace = dictCol.isZeroSpace;
|
|
|
col.pageId = dictCol.pageId;
|
|
|
col.refCols = dictCol.refCols;
|
|
|
col.isReadonly = false; //是否只读列
|
|
|
col.header = dictCol.header;
|
|
|
|
|
|
col.precision = dictCol.precision;
|
|
|
col.keyBoardType = dictCol.keyBoardType;
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 设置属性值
|
|
|
* @param {[type]} property [description]
|
|
|
* @param {[type]} value [description]
|
|
|
*/
|
|
|
DataColumn.prototype.set = function (property, value) {
|
|
|
this[property] = value;
|
|
|
this.onPropertyChanged(property);
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 获取属性值
|
|
|
* @param {[type]} property [description]
|
|
|
* @return {[type]} [description]
|
|
|
*/
|
|
|
DataColumn.prototype.get = function (property) {
|
|
|
return this[property];
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 属性改变通知
|
|
|
* @param {String} property 属性名
|
|
|
* @return {[type]} [description]
|
|
|
*/
|
|
|
DataColumn.prototype.onPropertyChanged = function (property) {
|
|
|
this.fire('onPropertyChanged', {
|
|
|
propertyName: property
|
|
|
});
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 获取列是否只读
|
|
|
*/
|
|
|
DataColumn.prototype.getReadOnly = function () {
|
|
|
return !this.isEditable || this.isReadonly;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 校验数据
|
|
|
* @param {DataRow} row 所在行
|
|
|
* @param {Object} value 新值
|
|
|
* @return {Boolean} 是否通过
|
|
|
*/
|
|
|
DataColumn.prototype.validator = function (row, value) {
|
|
|
if (row && row.validator) {
|
|
|
return row.validator(this, value);
|
|
|
}
|
|
|
|
|
|
return true;
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 获取显示内容
|
|
|
* @param {DataRow} row 所在行
|
|
|
* @return {string} 显示内容
|
|
|
*/
|
|
|
DataColumn.prototype.getText = function (row) {
|
|
|
if (!row) return null;
|
|
|
|
|
|
var name = this.fieldName;
|
|
|
var value = row[name];
|
|
|
var refValue = row[name + '$'];
|
|
|
|
|
|
if (hasValue(refValue) && this.refType != Global.Enums.RefType.NONE) {
|
|
|
var sep = this.refSeparator || '';
|
|
|
return value + sep + refValue;
|
|
|
} else {
|
|
|
if (value instanceof Date) {
|
|
|
return TypeUtil.toDateString(value)
|
|
|
}
|
|
|
return hasValue(value) ? value.toString() : '';
|
|
|
}
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 按照列的配置,获取value对应的实际值
|
|
|
* @param {[type]} value [description]
|
|
|
* @return {String} [description]
|
|
|
*/
|
|
|
DataColumn.prototype.getValue = function (value) {
|
|
|
//null或者undefined,则直接返回null
|
|
|
if (value !== '' && !hasValue(value)) {
|
|
|
return null;
|
|
|
}
|
|
|
|
|
|
//数字处理逻辑
|
|
|
if (this.dataType == Global.Enums.DataType.NUMBER) {
|
|
|
if (typeof value === 'string') {
|
|
|
value = value.trim();
|
|
|
//处理分隔符
|
|
|
if (this.refSeparator) {
|
|
|
let index = value.indexOf(this.refSeparator);
|
|
|
if (index > -1) {
|
|
|
value = value.slice(0, index);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
return Number(value) || 0;
|
|
|
}
|
|
|
|
|
|
//非数字处理逻辑
|
|
|
if (typeof value !== 'string') {
|
|
|
value = value.toString();
|
|
|
}
|
|
|
|
|
|
value = value.trim();
|
|
|
//处理分隔符
|
|
|
if (this.refSeparator && this.refObj &&
|
|
|
this.dataType != Store.Enums.DataType.DATETIME &&
|
|
|
this.editStyle != Store.Enums.EditStyle.DATE) {
|
|
|
let index = value.indexOf(this.refSeparator);
|
|
|
if (index > -1) {
|
|
|
value = value.slice(0, index);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if (this.dataType == Store.Enums.DataType.DATETIME && value && value.length <= 10 && value.indexOf('-') > -1) {
|
|
|
value = value + ' 00:00:00';
|
|
|
}
|
|
|
|
|
|
return value;
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 是否是表参照,包括属性参照和表参照
|
|
|
* @returns {boolean}
|
|
|
*/
|
|
|
DataColumn.prototype.isTableRef = function () {
|
|
|
return this.refType == Global.Enums.RefType.TABLE || this.refType == Global.Enums.RefType.PROP;
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 是否是枚举参照
|
|
|
* @returns {boolean}
|
|
|
*/
|
|
|
DataColumn.prototype.isEnumRef = function () {
|
|
|
return this.refType == Global.Enums.RefType.ENUM;
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 是否是无参照
|
|
|
* @returns {boolean}
|
|
|
*/
|
|
|
DataColumn.prototype.isNoneRef = function () {
|
|
|
return this.refType == Global.Enums.RefType.NONE;
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 设置dr上当前列的参照值
|
|
|
* @param {Object} dr dataRow
|
|
|
*/
|
|
|
DataColumn.prototype.setRefValue = function (dr, value) {
|
|
|
var item = this.getRefItem();
|
|
|
if (item) {
|
|
|
//表参照处理
|
|
|
if (this.isTableRef() && this.refFieldName) {
|
|
|
dr[this.fieldName + '$'] = item[this.refFieldName.toUpperCase()];
|
|
|
}
|
|
|
|
|
|
//枚举参照处理
|
|
|
if (this.isEnumRef()) {
|
|
|
var refValue = item[value];
|
|
|
dr[this.fieldName + '$'] = refValue;
|
|
|
}
|
|
|
} else {
|
|
|
if (dr.hasOwnProperty(this.fieldName + '$')) {
|
|
|
dr[this.fieldName + '$'] = null;
|
|
|
}
|
|
|
}
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 获取参照值
|
|
|
* @param {null|String} name
|
|
|
* @return {null|String}
|
|
|
*/
|
|
|
DataColumn.prototype.getRefValue = function (name) {
|
|
|
if (this.refItem) {
|
|
|
if (!name) {
|
|
|
name = this.refField || '';
|
|
|
}
|
|
|
|
|
|
let refValue = this.refItem[name.toUpperCase()]
|
|
|
if (refValue === undefined) {
|
|
|
refValue = null
|
|
|
}
|
|
|
return refValue;
|
|
|
} else {
|
|
|
return null;
|
|
|
}
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 获取列的默认显示格式
|
|
|
* @return {[type]} 显示格式,已预置
|
|
|
*/
|
|
|
DataColumn.prototype.getFormatter = function () {
|
|
|
var defaultFormatter = null;
|
|
|
switch (this.editStyle) {
|
|
|
case Global.Enums.EditStyle.CHECKBOX:
|
|
|
defaultFormatter = getFormatter('Checkbox');
|
|
|
break;
|
|
|
case Global.Enums.EditStyle.TEXT:
|
|
|
defaultFormatter = getFormatter('Text');
|
|
|
break;
|
|
|
case Global.Enums.EditStyle.REFERENCE:
|
|
|
defaultFormatter = getFormatter('Reference');
|
|
|
break;
|
|
|
case Global.Enums.EditStyle.DECIMAL:
|
|
|
defaultFormatter = getFormatter('Decimal');
|
|
|
break;
|
|
|
case Global.Enums.EditStyle.DATETIME:
|
|
|
defaultFormatter = getFormatter('DateTime');
|
|
|
break;
|
|
|
default:
|
|
|
break;
|
|
|
//预留
|
|
|
}
|
|
|
|
|
|
defaultFormatter = getFormatter(this.dispFormat) || defaultFormatter;
|
|
|
var formatter = this.dataSrc.onGetColumnFormatter(this, defaultFormatter);
|
|
|
return formatter || null;
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 获取参照内容。枚举值获取的是数据,表参照获取的是行集合
|
|
|
* @param {DataRow} row 数据行
|
|
|
* @param {Boolean} ignoreValue 忽略当前value的约束
|
|
|
* @return {*} [description]
|
|
|
*
|
|
|
*/
|
|
|
DataColumn.prototype.loadRefData = function (row, value, ignoreValue, isEdit) {
|
|
|
//如果当前参照内容未发生改变,则不再重复获取数据
|
|
|
//只有在值处理时,才会需要跳过
|
|
|
if (!ignoreValue && this.refField &&
|
|
|
this.refItem &&
|
|
|
this.refItem.$owner === row[ID_PROPERTY] &&
|
|
|
this.getRefValue() == value) {
|
|
|
return;
|
|
|
}
|
|
|
this.dataSrc.loadDefaultRefData(row, this, value, ignoreValue, isEdit);
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 获取参照数据
|
|
|
* @returns {*|Array}
|
|
|
*/
|
|
|
DataColumn.prototype.getRefData = function () {
|
|
|
return this.refData;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 设置参照数据
|
|
|
* @param {null|Array} data
|
|
|
*/
|
|
|
DataColumn.prototype.setRefData = function (data) {
|
|
|
if (data) {
|
|
|
this.refData = data;
|
|
|
} else {
|
|
|
this.refData = [];
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 获取参照列表
|
|
|
* @param {DataColumn} col
|
|
|
* @return {[Array]}
|
|
|
*/
|
|
|
function getRefTableList(col) {
|
|
|
var self = col,
|
|
|
result = [];
|
|
|
|
|
|
if (self.refData && self.refField) {
|
|
|
for (var i = 0; i < self.refData.length; i++) {
|
|
|
var row = self.refData[i];
|
|
|
var text = row[self.refField.toUpperCase()];
|
|
|
var item = {
|
|
|
key: text
|
|
|
};
|
|
|
if (self.refFieldName) {
|
|
|
var sep = self.refSeparator || '';
|
|
|
text = text + sep + row[self.refFieldName.toUpperCase()];
|
|
|
}
|
|
|
item.value = text;
|
|
|
result.push(item);
|
|
|
}
|
|
|
}
|
|
|
return result;
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 获取参照显示列表
|
|
|
* @return Array [description]
|
|
|
*/
|
|
|
DataColumn.prototype.getRefList = function () {
|
|
|
var self = this;
|
|
|
|
|
|
//枚举
|
|
|
if (self.isEnumRef()) {
|
|
|
return serialEnumValues(self.refData, self.refSeparator);
|
|
|
}
|
|
|
//表参照
|
|
|
if (self.isTableRef()) {
|
|
|
return getRefTableList(self);
|
|
|
}
|
|
|
return [];
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 获取当前参照信息
|
|
|
* @returns {null|*}
|
|
|
*/
|
|
|
DataColumn.prototype.getRefItem = function () {
|
|
|
return this.refItem;
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 设置参照信息
|
|
|
* @param {null|*} item
|
|
|
* @param {DataRow} [dr]
|
|
|
*/
|
|
|
DataColumn.prototype.setRefItem = function (item, dr) {
|
|
|
if (item) {
|
|
|
this.refItem = item;
|
|
|
if (dr) {
|
|
|
this.refItem.$owner = dr[ID_PROPERTY];
|
|
|
}
|
|
|
} else {
|
|
|
this.refItem = null;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 获取参照表的字典编码
|
|
|
* @returns {String}
|
|
|
*/
|
|
|
DataColumn.prototype.getRefObjCode = function () {
|
|
|
if (this.refType == Global.Enums.RefType.TABLE) {
|
|
|
return this.refObj;
|
|
|
}
|
|
|
|
|
|
if (this.refType == Global.Enums.RefType.PROP) {
|
|
|
var refObjCol = this.dataSrc.getColumn(this.refObj);
|
|
|
if (refObjCol) {
|
|
|
return refObjCol.getRefObjCode();
|
|
|
}
|
|
|
}
|
|
|
return '';
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 展示弹出窗体
|
|
|
* @param {DataRow} row
|
|
|
* @param {String} text
|
|
|
* @param {Boolean} isEdit
|
|
|
* @param {Function} callback
|
|
|
* @return {*}
|
|
|
*/
|
|
|
DataColumn.prototype.showDlg = function (dr, text, isEdit, callback) {
|
|
|
var args = {
|
|
|
dataSrc: this.dataSrc,
|
|
|
row: dr,
|
|
|
col: this,
|
|
|
text: text,
|
|
|
refParam: this.getRefParam(dr, text, isEdit, true),
|
|
|
isEdit: isEdit,
|
|
|
callback: callback
|
|
|
};
|
|
|
|
|
|
return this.dataSrc.onUserRefDlg(args);
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 展示多选弹出窗体
|
|
|
* @param {DataRow} row
|
|
|
* @param {String} text
|
|
|
* @param {Boolean} isEdit
|
|
|
* @param {Function} callback
|
|
|
* @return {*}
|
|
|
*/
|
|
|
DataColumn.prototype.showMultiDlg = function (dr, text, isEdit, callback) {
|
|
|
var args = {
|
|
|
dataSrc: this.dataSrc,
|
|
|
row: dr,
|
|
|
col: this,
|
|
|
text: text,
|
|
|
refParam: this.getRefParam(dr, text, isEdit, true),
|
|
|
isEdit: isEdit,
|
|
|
callback: callback
|
|
|
};
|
|
|
|
|
|
return this.dataSrc.onUserMultiRefDlg(args);
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 获取参照查询参数
|
|
|
* @param {DataRow} dr [description]
|
|
|
* @param {Object} value [description]
|
|
|
* @param {Boolean} isEdit
|
|
|
* @param {Boolean} ignoreValue
|
|
|
* @return {{fieldName: *, uiObjCode: *, refField: *, refFieldName: *, refType: *, refObj: *, userRefWhere, value: Object, D: *, ignoreValue: boolean}} [description]
|
|
|
*/
|
|
|
DataColumn.prototype.getRefParam = function (dr, value, isEdit, ignoreValue) {
|
|
|
var self = this;
|
|
|
var refParam = {
|
|
|
fieldName: self.fieldName,
|
|
|
refCols: self.refCols,
|
|
|
uiObjCode: self.dataSrc.uiObjCode,
|
|
|
userRefWhere: self.dataSrc.onGetUserRefColumnWhere(dr, self, isEdit),
|
|
|
value: value,
|
|
|
D: isEdit && dr ? dr.getData() : {},
|
|
|
ignoreValue: !!ignoreValue
|
|
|
};
|
|
|
|
|
|
if (self.dataSrc._parentRelation) {
|
|
|
var masterRow = self.dataSrc._parentRelation.master.currentRow;
|
|
|
refParam.M = masterRow ? masterRow.getData() : {};
|
|
|
}
|
|
|
|
|
|
return refParam;
|
|
|
};
|
|
|
|
|
|
///////////////////////////////////////////////////////////////
|
|
|
///DataRow 数据行
|
|
|
/**
|
|
|
* 数据行,用于数据源存放数据
|
|
|
* @param {Object} dataSrc 数据源
|
|
|
* @param {Boolean} nodefault 是否处理默认值
|
|
|
*/
|
|
|
function DataRow(dataSrc, nodefault) {
|
|
|
this.isDataRow = true;
|
|
|
this.dataSrc = dataSrc;
|
|
|
this.dataRowState = Global.Enums.DataRowState.DETACHED;
|
|
|
this._origin = {};
|
|
|
this._prevValues = {}
|
|
|
this._updating = false;
|
|
|
this._valueLocking = {};
|
|
|
this[ID_PROPERTY] = Date.now();
|
|
|
this._errors = {
|
|
|
data: [],
|
|
|
//获取列错误
|
|
|
getError: function (colName) {
|
|
|
var len = this.data.length;
|
|
|
for (var i = 0; i < len; i++) {
|
|
|
if (this.data[i].column == colName) {
|
|
|
return this.data[i].errMsg;
|
|
|
}
|
|
|
}
|
|
|
return null;
|
|
|
},
|
|
|
//设置列错误
|
|
|
setError: function (colName, value) {
|
|
|
var index = -1,
|
|
|
len = this.data.length;
|
|
|
|
|
|
for (var i = 0; i < len; i++) {
|
|
|
if (this.data[i].column == colName) {
|
|
|
index = i;
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if (index < 0) {
|
|
|
var err = {
|
|
|
column: colName,
|
|
|
errMsg: value,
|
|
|
id: colName + Date.now()
|
|
|
}
|
|
|
this.data.push(err);
|
|
|
} else {
|
|
|
this.data[index].id = colName + Date.now();
|
|
|
this.data[index].errMsg = value;
|
|
|
}
|
|
|
|
|
|
},
|
|
|
//清空错误
|
|
|
clearError: function (colName) {
|
|
|
var index = -1,
|
|
|
len = this.data.length;
|
|
|
|
|
|
for (var i = 0; i < len; i++) {
|
|
|
if (this.data[i].column == colName) {
|
|
|
index = i;
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if (index >= 0) {
|
|
|
this.data.splice(index, 1);
|
|
|
}
|
|
|
},
|
|
|
//清空所有错误
|
|
|
clearAll: function () {
|
|
|
this.data = [];
|
|
|
},
|
|
|
//获取错误数
|
|
|
getLength: function () {
|
|
|
return this.data.length;
|
|
|
},
|
|
|
/**
|
|
|
* 检查当前错误集合是否已经减少
|
|
|
* @param errs 旧错误集合
|
|
|
* @returns {boolean}
|
|
|
*/
|
|
|
less: function (errs) {
|
|
|
if (this.getLength() == 0) {
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
if (errs.getLength() < this.getLength()) {
|
|
|
return false;
|
|
|
} else if (errs.getLength() == this.getLength()) {
|
|
|
for (let i = 0; i < this.data.length; i++) {
|
|
|
let err = this.data[i],
|
|
|
err1 = errs.data[i];
|
|
|
if (err.id !== err1.id) {
|
|
|
return false;
|
|
|
}
|
|
|
}
|
|
|
} else {
|
|
|
for (let i = 0; i < this.data.length; i++) {
|
|
|
let err = this.data[i];
|
|
|
let hit = false;
|
|
|
//检测是否能在errs找到原错误,找到则继续查找下一个错误
|
|
|
for (let j = 0; j < errs.data.length; j++) {
|
|
|
if (errs.data[j].id === err.id) {
|
|
|
hit = true;
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
//找不到错误,则认为错误发生了变化
|
|
|
if (!hit) {
|
|
|
return false;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
return true;
|
|
|
}
|
|
|
};
|
|
|
|
|
|
this.init(nodefault);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 比较r是否是当前行
|
|
|
* @param {[type]} r [description]
|
|
|
* @return {[type]} [description]
|
|
|
*/
|
|
|
DataRow.prototype.equals = function (r) {
|
|
|
return this === r;
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 初始化数据源,默认根据列数生成属性
|
|
|
* @param {[type]} nodefault [description]
|
|
|
* @return {[type]} [description]
|
|
|
*/
|
|
|
DataRow.prototype.init = function (nodefault) {
|
|
|
if (nodefault) {
|
|
|
for (var i = 0; i < this.dataSrc.columns.length; i++) {
|
|
|
var col = this.dataSrc.columns[i];
|
|
|
this[col.fieldName] = null;
|
|
|
}
|
|
|
} else {
|
|
|
this.setDefaultValue();
|
|
|
}
|
|
|
};
|
|
|
|
|
|
DataRow.prototype.beginUpdate = function () {
|
|
|
this._updating = true;
|
|
|
};
|
|
|
|
|
|
DataRow.prototype.endUpdate = function () {
|
|
|
this._updating = false;
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 设置默认值
|
|
|
*/
|
|
|
DataRow.prototype.setDefaultValue = function () {
|
|
|
for (var i = 0; i < this.dataSrc.columns.length; i++) {
|
|
|
var col = this.dataSrc.columns[i];
|
|
|
this[col.fieldName] = col.dataType === Global.Enums.DataType.NUMBER ? 0 : null;
|
|
|
}
|
|
|
|
|
|
for (var i = 0; i < this.dataSrc.columns.length; i++) {
|
|
|
var col = this.dataSrc.columns[i];
|
|
|
//获取默认值,会经过业务类的处理
|
|
|
var dfValue = this.dataSrc.getDefaultValue(this, col);
|
|
|
if (dfValue || dfValue === 0) {
|
|
|
this.setColumnText(col, dfValue);
|
|
|
}
|
|
|
}
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 加载数据,数据来自于data,通常是服务获取来的数据
|
|
|
* @param {DataRow|Object} data 数据
|
|
|
* @return {[type]} [description]
|
|
|
*/
|
|
|
DataRow.prototype.loadData = function (data) {
|
|
|
var self = this;
|
|
|
data = toUpperKey(data)
|
|
|
//服务器返回的数据,列名都是小写
|
|
|
for (var j = 0; j < self.dataSrc.columns.length; j++) {
|
|
|
var col = self.dataSrc.columns[j];
|
|
|
|
|
|
if (data.hasOwnProperty(col.fieldName.toUpperCase())) {
|
|
|
self[col.fieldName] = data[col.fieldName.toUpperCase()];
|
|
|
}
|
|
|
|
|
|
if (data.hasOwnProperty(col.fieldName.toUpperCase() + '$')) {
|
|
|
self[col.fieldName + '$'] = data[col.fieldName.toUpperCase() + '$'];
|
|
|
}
|
|
|
|
|
|
|
|
|
if (self[col.fieldName] && col.dataType === Global.Enums.DataType.DATETIME) {
|
|
|
self[col.fieldName] = new Date(Number(self[col.fieldName]))
|
|
|
}
|
|
|
}
|
|
|
if (self.dataSrc) {
|
|
|
var ds = self.dataSrc;
|
|
|
ds.onCollectChanged(Global.Enums.CollectionChangedAction.REPLACE, this);
|
|
|
ds.columns.forEach(function (col) {
|
|
|
ds.updateParent(col);
|
|
|
});
|
|
|
}
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
* 接受当前对行的增加、修改
|
|
|
* @return {DataRow}
|
|
|
*/
|
|
|
DataRow.prototype.acceptChanges = function () {
|
|
|
var self = this;
|
|
|
//接受操作,具体内容:
|
|
|
//1、修改行状态为UNCHANGED无修改状态
|
|
|
//2、备份数据,作为原始数据
|
|
|
//3、删除行做accept没有意义
|
|
|
if (this.dataRowState == Global.Enums.DataRowState.DELETED) {
|
|
|
return this;
|
|
|
}
|
|
|
this.dataRowState = Global.Enums.DataRowState.UNCHANGED;
|
|
|
|
|
|
//find out dataSrc originRow
|
|
|
var dataSrcOriginRow = this.dataSrc._originRows[self[ID_PROPERTY]];
|
|
|
|
|
|
this._origin = {};
|
|
|
for (var i = 0; i < this.dataSrc.columns.length; i++) {
|
|
|
var c = this.dataSrc.columns[i];
|
|
|
this._origin[c.fieldName] = this[c.fieldName];
|
|
|
this._origin[c.fieldName + '$'] = this[c.fieldName + '$'];
|
|
|
if (dataSrcOriginRow) {
|
|
|
dataSrcOriginRow[c.fieldName] = this[c.fieldName];
|
|
|
dataSrcOriginRow[c.fieldName + '$'] = this[c.fieldName + '$'];
|
|
|
}
|
|
|
}
|
|
|
return this;
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 丢弃
|
|
|
* @return {[type]} [description]
|
|
|
*/
|
|
|
DataRow.prototype.rejectChanges = function () {
|
|
|
//丢弃修改
|
|
|
//放弃所有的修改,只对修改行有用
|
|
|
if (this.dataRowState == Global.Enums.DataRowState.MODIFIED) {
|
|
|
this.dataRowState = Global.Enums.DataRowState.UNCHANGED;
|
|
|
for (var i = 0; i < this.dataSrc.columns.length; i++) {
|
|
|
var c = this.dataSrc.columns[i];
|
|
|
this[c.fieldName] = this._origin[c.fieldName];
|
|
|
this[c.fieldName + '$'] = this._origin[c.fieldName + '$'];
|
|
|
}
|
|
|
}
|
|
|
|
|
|
this._errors.clearAll();
|
|
|
return this;
|
|
|
};
|
|
|
|
|
|
DataRow.prototype.beginTransaction = function () {
|
|
|
if (!this.transData) {
|
|
|
this.transData = $.extend(true, {}, this);
|
|
|
return 0;
|
|
|
}
|
|
|
return 1;
|
|
|
};
|
|
|
|
|
|
DataRow.prototype.getPrevValue = function (fieldName) {
|
|
|
if (fieldName === null || fieldName === undefined) { return undefined }
|
|
|
|
|
|
return this._prevValues[fieldName]
|
|
|
};
|
|
|
|
|
|
|
|
|
DataRow.prototype.commit = function (id) {
|
|
|
if (id === 0) {
|
|
|
this.transData = null;
|
|
|
}
|
|
|
};
|
|
|
|
|
|
DataRow.prototype.rollBack = function (id) {
|
|
|
if (id !== 0) {
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
//丢弃修改
|
|
|
//放弃某个节点之后的修改
|
|
|
let originRow = this.transData;
|
|
|
for (var i = 0; i < this.dataSrc.columns.length; i++) {
|
|
|
var c = this.dataSrc.columns[i];
|
|
|
this[c.fieldName] = originRow[c.fieldName];
|
|
|
this._prevValues = origin._prevValues || {}
|
|
|
this[c.fieldName + '$'] = originRow[c.fieldName + '$'];
|
|
|
}
|
|
|
this._errors = originRow._errors;
|
|
|
this.dataRowState = originRow.dataRowState;
|
|
|
this.dataSrc.onCollectChanged(Global.Enums.CollectionChangedAction.REPLACE, this);
|
|
|
this.transData = null;
|
|
|
return this;
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 获取行上某列的错误信息
|
|
|
* @param {String} colName 列名
|
|
|
* @return {[type]} [description]
|
|
|
*/
|
|
|
DataRow.prototype.getColumnError = function (colName) {
|
|
|
if (typeof colName === 'object') {
|
|
|
colName = colName.fieldName;
|
|
|
}
|
|
|
return this._errors.getError(colName);
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 设置行上某列的错误信息
|
|
|
* @param {[type]} colName [description]
|
|
|
* @param {[type]} errMsg [description]
|
|
|
*/
|
|
|
DataRow.prototype.setColumnError = function (colName, errMsg, noShow) {
|
|
|
|
|
|
//赋值错误也作为行修改的标识
|
|
|
if (this.dataRowState == Global.Enums.DataRowState.UNCHANGED) {
|
|
|
this.dataRowState = Global.Enums.DataRowState.MODIFIED;
|
|
|
}
|
|
|
|
|
|
if (typeof colName === 'object') {
|
|
|
colName = colName.fieldName;
|
|
|
}
|
|
|
|
|
|
console.log(errMsg);
|
|
|
this._errors.setError(colName, errMsg);
|
|
|
if (!this._updating && !noShow) {
|
|
|
setTimeout(function () {
|
|
|
//如果页面已经有了提示框则不弹提示框
|
|
|
if (!$(".messager-window").length) {
|
|
|
Global.messager.err(errMsg)
|
|
|
}
|
|
|
|
|
|
}, 120);
|
|
|
}
|
|
|
|
|
|
return this;
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 清除行上某列的错误
|
|
|
* @param {[type]} colName [description]
|
|
|
* @return {[type]} [description]
|
|
|
*/
|
|
|
DataRow.prototype.clearColumnError = function (colName) {
|
|
|
if (typeof colName === 'object') {
|
|
|
colName = colName.fieldName;
|
|
|
}
|
|
|
this._errors.clearError(colName);
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 获取行上是否存在错误
|
|
|
* @return {Boolean} [description]
|
|
|
*/
|
|
|
DataRow.prototype.hasError = function () {
|
|
|
return this._errors.getLength() > 0;
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 设置列值,不会触发校验,仍然触发值改变通知
|
|
|
* @param {String} col [description]
|
|
|
* @param {Object} value [description]
|
|
|
*/
|
|
|
DataRow.prototype.setColumnValue = function (col, value) {
|
|
|
var dc = this.dataSrc.getColumn(col);
|
|
|
|
|
|
if (dc === null) {
|
|
|
Global.throwException(Global.MSG.COL_NOT_FOUND, 'setColumnValue');
|
|
|
}
|
|
|
|
|
|
//修改状态, 还原状态,通知内容修改
|
|
|
this._prevValues[dc.fieldName] = this[dc.fieldName]
|
|
|
this[dc.fieldName] = value;
|
|
|
|
|
|
this.clearColumnError(dc);
|
|
|
if (this.dataRowState == Global.Enums.DataRowState.UNCHANGED) {
|
|
|
this.dataRowState = Global.Enums.DataRowState.MODIFIED;
|
|
|
}
|
|
|
this.dataSrc.onValueChanged(this, dc);
|
|
|
// 更新子表合计
|
|
|
if (this.dataRowState != Global.Enums.DataRowState.DETACHED) {
|
|
|
this.dataSrc.updateParent(col);
|
|
|
}
|
|
|
return this;
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 设置列的参照名称
|
|
|
* @param {[type]} col 列名或者列
|
|
|
* @param {string} refValue 参照名称
|
|
|
*/
|
|
|
DataRow.prototype.setColumnRefValue = function (col, refValue) {
|
|
|
var dc = this.dataSrc.getColumn(col);
|
|
|
|
|
|
if (dc === null) {
|
|
|
Global.throwException(Global.MSG.COL_NOT_FOUND, 'setColumnRefValue');
|
|
|
}
|
|
|
|
|
|
this[dc.fieldName + '$'] = refValue;
|
|
|
return this;
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 判断值改变
|
|
|
* @param newValue 新值
|
|
|
* @param oldValue 旧值
|
|
|
*/
|
|
|
function isValueChanged(newValue, oldValue) {
|
|
|
if (newValue == oldValue) {
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
if (newValue == null && oldValue == '') {
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
if (oldValue == null && newValue == '') {
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 检查器,完成值校验、赋值、赋值后处理
|
|
|
* @param {DataColumn} col [description]
|
|
|
* @param {Object} value [description]
|
|
|
* @return {Boolean} [description]
|
|
|
*/
|
|
|
DataRow.prototype.validator = function (col, value, callback) {
|
|
|
if (typeof col === 'string') {
|
|
|
col = this.dataSrc.getColumn(col);
|
|
|
}
|
|
|
|
|
|
try {
|
|
|
//检查值是否锁定,锁定则退出
|
|
|
var lock = this._valueLocking[col.fieldName];
|
|
|
if (lock) return true;
|
|
|
this._valueLocking[col.fieldName] = true;
|
|
|
|
|
|
//获取需要保存的值,如果未改变则退出
|
|
|
value = col.getValue(value);
|
|
|
var err = this.getColumnError(col);
|
|
|
if (!err && !isValueChanged(value, this.getColumnValue(col))) {
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
//基本校验,包括参照内容的获取
|
|
|
var bRet = this.dataSrc.validateColumn(this, col, value);
|
|
|
if (bRet) {
|
|
|
//赋值以及相关值
|
|
|
return this.calcColumnValue(col, value);
|
|
|
}
|
|
|
|
|
|
return false;
|
|
|
} finally {
|
|
|
delete this._valueLocking[col.fieldName];
|
|
|
}
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 处理与col列相关联的列的值
|
|
|
* @param {DataColumn} col
|
|
|
* @param {Object} value 新值
|
|
|
* @return {Boolean} [description]
|
|
|
*/
|
|
|
DataRow.prototype.calcColumnValue = function (col, value) {
|
|
|
try {
|
|
|
var id = this.beginTransaction();
|
|
|
|
|
|
//参照值
|
|
|
col.setRefValue(this, value);
|
|
|
//带出其他字段
|
|
|
this.setColumnValue(col, value);
|
|
|
|
|
|
var isOk = true;
|
|
|
//关联参照,处理属性参照和属性参照的表参照
|
|
|
if (col.refType === Global.Enums.RefType.TABLE || (col.refType === Global.Enums.RefType.PROP && col.isStrictRef)) {
|
|
|
for (var i = 0; i < this.dataSrc.columns.length; i++) {
|
|
|
var c = this.dataSrc.columns[i];
|
|
|
|
|
|
//处理属性参照
|
|
|
//或处理属性参照的表参照
|
|
|
if ((c.refType == Global.Enums.RefType.PROP && c.refObj === col.fieldName) ||
|
|
|
(col.refType == Global.Enums.RefType.PROP && col.refObj === c.fieldName)) {
|
|
|
var value = col.getRefValue(c.refField);
|
|
|
c.setRefData(col.getRefData());
|
|
|
c.setRefItem(col.getRefItem());
|
|
|
this.setColumnText(c, value);
|
|
|
var err = this.getColumnError(c);
|
|
|
if (err) {
|
|
|
isOk = false;
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if (!isOk) {
|
|
|
//回滚
|
|
|
this.rollBack(id);
|
|
|
return false;
|
|
|
}
|
|
|
this.dataSrc.onFieldChanged(this, col);
|
|
|
if (!this._errors.less(this.transData._errors)) {
|
|
|
col.$colErr = this.getColumnError(col);
|
|
|
this.rollBack(id);
|
|
|
if (col.$colErr) {
|
|
|
this.setColumnError(col, col.$colErr, true);
|
|
|
delete col.$colErr;
|
|
|
}
|
|
|
return false;
|
|
|
}
|
|
|
this.commit(id);
|
|
|
if (this.dataRowState != Global.Enums.DataRowState.DETACHED) {
|
|
|
this.dataSrc.updateParent(col);
|
|
|
}
|
|
|
return true;
|
|
|
} catch (ex) {
|
|
|
this.setColumnError(col, ex.toString());
|
|
|
this.rollBack(id);
|
|
|
return false;
|
|
|
}
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 设置校验值,触发业务校验,通知界面更新
|
|
|
* @param {String|DataColumn} col
|
|
|
* @param {Object} value
|
|
|
*/
|
|
|
DataRow.prototype.setColumnText = function (col, value) {
|
|
|
if (typeof col === 'string') {
|
|
|
col = this.dataSrc.getColumn(col);
|
|
|
}
|
|
|
if (!col)
|
|
|
Global.throwException(Global.MSG.COL_NOT_FOUND, 'setColumnText');
|
|
|
return this.validator(col, value);
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 获取列显示值
|
|
|
* @param {DataColumn} col ,支持列名
|
|
|
* @return {String} code-name
|
|
|
*/
|
|
|
DataRow.prototype.getColumnText = function (col) {
|
|
|
if (typeof col === 'string') {
|
|
|
col = this.dataSrc.getColumn(col);
|
|
|
if (col === null) {
|
|
|
return '';
|
|
|
}
|
|
|
}
|
|
|
|
|
|
return col.getText(this);
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 获取列值
|
|
|
* @param {String} col 列名
|
|
|
* @return {[type]} [description]
|
|
|
*/
|
|
|
DataRow.prototype.getColumnValue = function (col) {
|
|
|
return typeof col === 'string' ? this[col] : this[col.fieldName];
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 删除该行
|
|
|
* @param needConfirm 是否需要询问
|
|
|
*/
|
|
|
DataRow.prototype.delete = function (needConfirm) {
|
|
|
return this.dataSrc.deleteRow(this, needConfirm);
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 获取打印用的行数据
|
|
|
* 1.主要区别getData方法是添加了枚举的value-description展示
|
|
|
* @return {[type]} [description]
|
|
|
*/
|
|
|
DataRow.prototype.getPrintData = function () {
|
|
|
var data = {};
|
|
|
for (var i = 0; i < this.dataSrc.columns.length; i++) {
|
|
|
var col = this.dataSrc.columns[i];
|
|
|
// if (Global.Enums.RefType.ENUM == col.refType) {
|
|
|
if (this[col.fieldName + '$']) {
|
|
|
data[col.fieldName] = this[col.fieldName] + col.refSeparator + this[col.fieldName + '$'];
|
|
|
} else {
|
|
|
data[col.fieldName] = this[col.fieldName] == null ? '' : this[col.fieldName];
|
|
|
}
|
|
|
data['old_' + col.fieldName] = this._origin[col.fieldName];
|
|
|
data['$state'] = this.dataRowState;
|
|
|
}
|
|
|
return data;
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 获取带有行原始值的数据对象,不会带有方法
|
|
|
* @return {type}
|
|
|
*/
|
|
|
DataRow.prototype.getData = function () {
|
|
|
var data = {};
|
|
|
for (var i = 0; i < this.dataSrc.columns.length; i++) {
|
|
|
var col = this.dataSrc.columns[i];
|
|
|
data[col.fieldName] = this[col.fieldName] instanceof Date ? this[col.fieldName].getTime() : this[col.fieldName];
|
|
|
data['old_' + col.fieldName] = this._origin[col.fieldName] instanceof Date ? this._origin[col.fieldName].getTime() : this._origin[col.fieldName];
|
|
|
data['$state'] = this.dataRowState;
|
|
|
}
|
|
|
return data;
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 行校验
|
|
|
* @param {Function} onerror 错误回调
|
|
|
* @return {boolean} 是否通过
|
|
|
*/
|
|
|
DataRow.prototype.validate = function (onerror) {
|
|
|
return this.dataSrc.validateDataRow(this, onerror);
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 检查必填字段
|
|
|
* @return {boolean} 是否通过
|
|
|
*/
|
|
|
DataRow.prototype.checkRequired = function () {
|
|
|
for (var i = 0; i < this.dataSrc.columns.length; i++) {
|
|
|
var col = this.dataSrc.columns[i];
|
|
|
if (col.isRequired && (this[col.fieldName] === null || this[col.fieldName] === '')) {
|
|
|
this.setColumnError(col.fieldName, col.dispName + Global.MSG.VALUE_REQUIRE);
|
|
|
}
|
|
|
};
|
|
|
return !this.hasError();
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 获取行上所有错误的文本信息
|
|
|
* @return {string}
|
|
|
*/
|
|
|
DataRow.prototype.getErrors = function () {
|
|
|
var msg = '';
|
|
|
for (var i = 0; i < this._errors.data.length; i++) {
|
|
|
var err = this._errors.data[i].errMsg;
|
|
|
msg = msg + err + '\n';
|
|
|
}
|
|
|
return msg;
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 获取该行上对应于某列的显示格式,通常用于网格使用
|
|
|
* @param {DataColumn} col
|
|
|
* @return {All}
|
|
|
*/
|
|
|
DataRow.prototype.getFormatter = function (col) {
|
|
|
return this.dataSrc.onGetRowFormatter(this, col);
|
|
|
};
|
|
|
|
|
|
DataRow.prototype.isEmpty = function () {
|
|
|
for (var i = 0; i < this.dataSrc.columns.length; i++) {
|
|
|
var col = this.dataSrc.columns[i];
|
|
|
if (col.isEmptyField && !hasValue(this[col.fieldName])) {
|
|
|
return true;
|
|
|
}
|
|
|
};
|
|
|
|
|
|
return false;
|
|
|
};
|
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
|
///主从关系类
|
|
|
|
|
|
/**
|
|
|
* 主从关系类
|
|
|
* @param {DataSource} master [description]
|
|
|
* @param {DataSource} detail [description]
|
|
|
* @param {String} masterColunmsStr [description]
|
|
|
* @param {String} detailColumnsStr [description]
|
|
|
*/
|
|
|
function DataRelation(master, detail, masterColunmsStr, detailColumnsStr) {
|
|
|
var self = this;
|
|
|
var masterColunms = typeof masterColunmsStr === 'string' ? masterColunmsStr.split(',') : null;
|
|
|
var detailColumns = typeof detailColumnsStr === 'string' ? detailColumnsStr.split(',') : null;
|
|
|
if (!masterColunms || !detailColumns || masterColunms.length != detailColumns.length) {
|
|
|
Global.throwException(Global.MSG.MASTERDETAIL_KEYERR, 'DataRelation');
|
|
|
}
|
|
|
this.master = master;
|
|
|
this.detail = detail;
|
|
|
this.masterColunms = masterColunms;
|
|
|
this.detailColumns = detailColumns;
|
|
|
|
|
|
//检查子表合计
|
|
|
this._totalMap = {};
|
|
|
this.master.columns.forEach(function (col) {
|
|
|
if (col.refType == Global.Enums.RefType.TOTAL && col.refObj == self.detail.uiObjCode) {
|
|
|
self._totalMap[col.refField] = col.fieldName;
|
|
|
}
|
|
|
});
|
|
|
|
|
|
/**
|
|
|
* 获取主从关系
|
|
|
* @return {[type]} [description]
|
|
|
*/
|
|
|
function getSchema(args) {
|
|
|
var schema = {
|
|
|
masterKey: self.masterColunms.toString(),
|
|
|
detailKey: self.detailColumns.toString(),
|
|
|
detail: self.detail.getSchemaData(args)
|
|
|
};
|
|
|
return schema;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 获取从表约束
|
|
|
* @param {[type]} dr [description]
|
|
|
* @return {[type]} [description]
|
|
|
*/
|
|
|
function getParams(dr) {
|
|
|
var p = {};
|
|
|
for (var i = 0; i < self.detailColumns.length; i++) {
|
|
|
var col = self.detailColumns[i];
|
|
|
p[col] = dr[self.masterColunms[i]];
|
|
|
}
|
|
|
return p;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 获取从表对应值
|
|
|
* @return {[type]} [description]
|
|
|
*/
|
|
|
function getDetailValue(detailCol) {
|
|
|
if (typeof detailCol !== 'string') {
|
|
|
detailCol = detailCol.fieldName;
|
|
|
}
|
|
|
|
|
|
//检查是否是关系键
|
|
|
var index = self.detailColumns.indexOf(detailCol);
|
|
|
if (index < 0) {
|
|
|
return null;
|
|
|
}
|
|
|
|
|
|
//检查主表当前行是否为空
|
|
|
if (!self.master.currentRow) {
|
|
|
return null;
|
|
|
}
|
|
|
return self.master.currentRow[self.masterColunms[index]];
|
|
|
}
|
|
|
|
|
|
function updateRelationValue(dr) {
|
|
|
if (dr.dataSrc !== self.master) {
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
for (var j = 0, len = self.detail.rows.length; j < len; j++) {
|
|
|
var row = self.detail.rows[j];
|
|
|
for (var i = 0; i < self.detailColumns.length; i++) {
|
|
|
var detailCol = self.detailColumns[i];
|
|
|
var masterCol = self.masterColunms[i];
|
|
|
// 添加判断在增加时更新从表主键值。
|
|
|
var fieldValue = row[detailCol];
|
|
|
if (fieldValue == null || fieldValue == '' || fieldValue == '*'
|
|
|
|| row.dataRowState == Global.Enums.DataRowState.ADDED) {
|
|
|
row.setColumnText(detailCol, dr[masterCol]);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 字表合计
|
|
|
* @param {String|DataColumn} detailColName
|
|
|
*/
|
|
|
var aggregateDetail = function (detailColName) {
|
|
|
try {
|
|
|
if (detailColName instanceof DataColumn) {
|
|
|
detailColName = detailColName.fieldName;
|
|
|
}
|
|
|
|
|
|
var masterColName = self._totalMap[detailColName];
|
|
|
if (!masterColName) {
|
|
|
return;
|
|
|
}
|
|
|
var curRow = self.master.currentRow;
|
|
|
if (curRow) {
|
|
|
curRow.setColumnText(masterColName, getTotalValue(detailColName));
|
|
|
}
|
|
|
} catch (ex) {
|
|
|
console.log(ex);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 获取明细的合计值
|
|
|
* @param {String} colName
|
|
|
*/
|
|
|
function getTotalValue(colName) {
|
|
|
//遍历明细,赋值,以最后一个为准
|
|
|
var result = 0;
|
|
|
self.detail.rows.forEach(function (row) {
|
|
|
result = BigNumber.add(result, TypeUtil.toFloat(row[colName]));
|
|
|
});
|
|
|
return result;
|
|
|
}
|
|
|
|
|
|
_.extend(this, {
|
|
|
'getDetailValue': getDetailValue,
|
|
|
'getParams': getParams,
|
|
|
'getSchema': getSchema,
|
|
|
'updateRelationValue': updateRelationValue,
|
|
|
'aggregateDetail': aggregateDetail
|
|
|
});
|
|
|
}
|
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////
|
|
|
///数据源
|
|
|
|
|
|
/**
|
|
|
* 数据源,用于进行操作业务数据,影响界面和后台
|
|
|
* @param {[type]} opts [description]
|
|
|
*/
|
|
|
function DataSource(opts) {
|
|
|
this.columns = [];
|
|
|
this.rows = [];
|
|
|
this.currentRow = null;
|
|
|
this._deletedRows = [];
|
|
|
this._originRows = {};
|
|
|
this._childRelations = [];
|
|
|
this._parentRelation = null;
|
|
|
this._needUpdateTotalRows = true; //是否更新总行
|
|
|
this._totalRows = -1;
|
|
|
this._pageSize = -1;
|
|
|
this._pagenum = 0;
|
|
|
this._isOpened = true;
|
|
|
this._idSequence = {};
|
|
|
this._editable = false;
|
|
|
this._requireDetail = false;
|
|
|
|
|
|
this.isDataSource = true;
|
|
|
this.onlySaveCurrent = false;
|
|
|
this.fixQuery = {};
|
|
|
this.queryParamPlugin = null;
|
|
|
this._followMaster = true
|
|
|
|
|
|
Global.eventuality(this);
|
|
|
|
|
|
var defaultOpts = {
|
|
|
funcObjName: '',
|
|
|
funcObjCode: '',
|
|
|
allowDel: true,
|
|
|
allowEdit: true,
|
|
|
allowInsert: true,
|
|
|
detailkey: '',
|
|
|
fixedSearch: '',
|
|
|
isMaster: false,
|
|
|
isMultiPage: false,
|
|
|
isSaveRefresh: false,
|
|
|
isShowSelCol: false,
|
|
|
masterKey: '',
|
|
|
parentFuncObjName: '',
|
|
|
isShow: true
|
|
|
};
|
|
|
|
|
|
_.extend(defaultOpts, opts);
|
|
|
this.initFuncObj(defaultOpts);
|
|
|
}
|
|
|
|
|
|
////////////////
|
|
|
//Property Begin
|
|
|
|
|
|
/**
|
|
|
* 获取明细是否必填
|
|
|
* @return {Number} [description]
|
|
|
*/
|
|
|
DataSource.prototype.getRequireDetail = function () {
|
|
|
return this._requireDetail;
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 设置是否明细是否必填
|
|
|
* @param {Boolean} value
|
|
|
*/
|
|
|
DataSource.prototype.setRequireDetail = function (value) {
|
|
|
this._requireDetail = value;
|
|
|
this.onPropertyChanged('RequireDetail');
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 获取是否需要更新总行数
|
|
|
* @return {Number} [description]
|
|
|
*/
|
|
|
DataSource.prototype.getNeedUpdateTotalRows = function () {
|
|
|
return this._needUpdateTotalRows;
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 设置是否更新总行数属性
|
|
|
* @param {[type]} value [description]
|
|
|
*/
|
|
|
DataSource.prototype.setNeedUpdateTotalRows = function (value) {
|
|
|
this._needUpdateTotalRows = value;
|
|
|
this.onPropertyChanged('NeedUpdateTotalRows');
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 获取数据总行数
|
|
|
* @return {number}
|
|
|
*/
|
|
|
DataSource.prototype.getTotalRows = function () {
|
|
|
if (this._totalRows <= 0 && this.rows.length > 0) {
|
|
|
return this.rows.length
|
|
|
}
|
|
|
return this._totalRows < 0 ? 0 : this._totalRows;
|
|
|
};
|
|
|
|
|
|
DataSource.prototype.setTotalRows = function (value) {
|
|
|
this._totalRows = value;
|
|
|
this.onPropertyChanged('TotalRows');
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 获取每页行树,用于分页
|
|
|
* @return {number}
|
|
|
*/
|
|
|
DataSource.prototype.getPageSize = function () {
|
|
|
return this._pageSize;
|
|
|
};
|
|
|
|
|
|
DataSource.prototype.setPageSize = function (value) {
|
|
|
this._pageSize = value;
|
|
|
this.onPropertyChanged('PageSize');
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 获取当前页号,查看数据所在的页号
|
|
|
* @return {number}
|
|
|
*/
|
|
|
DataSource.prototype.getPagenum = function () {
|
|
|
return this._pagenum;
|
|
|
};
|
|
|
|
|
|
DataSource.prototype.setPagenum = function (value) {
|
|
|
this._pagenum = value;
|
|
|
this.onPropertyChanged('Pagenum');
|
|
|
};
|
|
|
|
|
|
DataSource.prototype.getEditable = function () {
|
|
|
return this._editable;
|
|
|
};
|
|
|
|
|
|
DataSource.prototype.setEditable = function (value) {
|
|
|
this._editable = value;
|
|
|
this.onPropertyChanged('Editable');
|
|
|
};
|
|
|
|
|
|
// 设置数据源最终搜索时用到的物理表名
|
|
|
DataSource.prototype.setSearchTableName = function (name) {
|
|
|
this._searchTableName = name;
|
|
|
};
|
|
|
|
|
|
DataSource.prototype.getSearchTableName = function () {
|
|
|
return this._searchTableName;
|
|
|
};
|
|
|
|
|
|
DataSource.prototype.setFollowMaster = function (value) {
|
|
|
this._followMaster = !!value
|
|
|
}
|
|
|
|
|
|
DataSource.prototype.getFollowMaster = function () {
|
|
|
return this._followMaster
|
|
|
}
|
|
|
|
|
|
//Property End
|
|
|
/////////////////////////////
|
|
|
|
|
|
/**
|
|
|
* 初始化功能对象字典
|
|
|
* @param {object} dict 服务器传过来的字典对象
|
|
|
* @return {object} this
|
|
|
*/
|
|
|
DataSource.prototype.initFuncObj = function (dict) {
|
|
|
this.funcCode = dict.funcCode;
|
|
|
this.name = dict.funcObjName;
|
|
|
this.uiObjCode = dict.funcObjCode;
|
|
|
this.allowDel = dict.allowDel;
|
|
|
this.allowEdit = dict.allowEdit;
|
|
|
this.allowInsert = dict.allowInsert;
|
|
|
this.detailKey = dict.detailKey;
|
|
|
this.fixedSearch = dict.fixedSearch;
|
|
|
this.isMaster = dict.isMaster;
|
|
|
this.isMultiPage = dict.isMultiPage;
|
|
|
this.isSaveRefresh = dict.isSaveRefresh;
|
|
|
this.isShowSelCol = dict.isShowSelCol;
|
|
|
this.isShow = dict.isShow;
|
|
|
this.masterKey = dict.masterKey;
|
|
|
this.parentObjName = dict.parentFuncObjName;
|
|
|
return this;
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 初始化界面字典
|
|
|
* @param {object} dict 服务器传来的字典或者uiObjCode
|
|
|
* @return {object} this
|
|
|
*/
|
|
|
DataSource.prototype.initUIObj = function (dict) {
|
|
|
|
|
|
this.defaultOrder = dict.defaultOrder;
|
|
|
this.dataObjType = dict.dataObjType;
|
|
|
this.multiFields = dict.multiFields;
|
|
|
this.multiMsg = dict.multiMsg;
|
|
|
this.multiType = dict.multiType;
|
|
|
this.treeField = dict.treeField;
|
|
|
this.uiObjName = dict.uiObjName;
|
|
|
this.headers = dict.headers;
|
|
|
this.datasetName = dict.datasetName;
|
|
|
this.columns.names = {};
|
|
|
for (var i = 0; i < dict.columns.length; i++) {
|
|
|
var col = new DataColumn(this);
|
|
|
var dictCol = dict.columns[i];
|
|
|
col.init(dictCol);
|
|
|
this.columns.push(col);
|
|
|
this.columns.names[col.fieldName] = i;
|
|
|
}
|
|
|
return this;
|
|
|
};
|
|
|
|
|
|
function serialize(ds, type) {
|
|
|
var data = {
|
|
|
uiObjCode: ds.uiObjCode,
|
|
|
uiObjName: ds.uiObjName,
|
|
|
isMaster: ds.isMaster,
|
|
|
fieldList: [],
|
|
|
forPrint: []
|
|
|
};
|
|
|
|
|
|
for (var i = 0; i < ds.columns.length; i++) {
|
|
|
var col = ds.columns[i];
|
|
|
data.fieldList.push({
|
|
|
fieldName: col.fieldName,
|
|
|
fieldDes: col.dispName,
|
|
|
dataType: col.dataType,
|
|
|
dataWidth: col.dataWidth,
|
|
|
dataDec: col.dataDec,
|
|
|
hasRefColumn: (col.isTableRef() || col.isEnumRef()) ? '1' : '0'
|
|
|
});
|
|
|
}
|
|
|
|
|
|
if (type === '0') {
|
|
|
if (ds.currentRow) {
|
|
|
data.forPrint.push(ds.currentRow.getPrintData())
|
|
|
}
|
|
|
} else if (type === '1') {
|
|
|
for (var k = 0; k < ds.rows.length; k++) {
|
|
|
var row = ds.rows[k];
|
|
|
data.forPrint.push(row.getPrintData());
|
|
|
}
|
|
|
} else if (type === '2') {
|
|
|
for (var i = 0; i < ds.rows.length; i++) {
|
|
|
var row = ds.rows[i];
|
|
|
if (row.$is_sel) {
|
|
|
data.forPrint.push(row.getPrintData());
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
return data;
|
|
|
};
|
|
|
|
|
|
|
|
|
/**
|
|
|
* 获取打印数据
|
|
|
* @return {Array}
|
|
|
*/
|
|
|
DataSource.prototype.getPrintData = function () {
|
|
|
var self = this,
|
|
|
printData = [];
|
|
|
printData.push(serialize(self, '0'));
|
|
|
for (var j = 0; j < self.getDetailRelations().length; j++) {
|
|
|
var r = self.getDetailRelations()[j];
|
|
|
printData.push(serialize(r.detail, '1'));
|
|
|
}
|
|
|
|
|
|
return printData;
|
|
|
};
|
|
|
|
|
|
DataSource.prototype.getPrintAllSelectData = function () {
|
|
|
var self = this,
|
|
|
printData = [];
|
|
|
printData.push(serialize(self, '2'));
|
|
|
|
|
|
return printData;
|
|
|
};
|
|
|
/**
|
|
|
* 获取打印变量
|
|
|
* @return {Object}
|
|
|
*/
|
|
|
DataSource.prototype.getPrintVariables = function () {
|
|
|
var self = this;
|
|
|
return self.onGetPrintVariables();
|
|
|
};
|
|
|
|
|
|
|
|
|
/**
|
|
|
* 获取数据源上的指定列
|
|
|
* @param {DataColumn} col 列名,如果传入的是DataColumn,则直接返回
|
|
|
* @return {DataColumn|null} DataColumn或者null
|
|
|
*/
|
|
|
DataSource.prototype.getColumn = function (col) {
|
|
|
if (col) {
|
|
|
if (typeof col == 'string' && this.columns.names && this.columns.names.hasOwnProperty(col)) {
|
|
|
return this.columns[this.columns.names[col]];
|
|
|
}
|
|
|
|
|
|
if (col.isDataColumn && this.columns.indexOf(col) >= 0) {
|
|
|
return col;
|
|
|
}
|
|
|
}
|
|
|
return null;
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 创建基于当前DataSource的行
|
|
|
* @return {[type]} [description]
|
|
|
*/
|
|
|
DataSource.prototype.newRow = function (noDefault) {
|
|
|
return new DataRow(this, noDefault);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 增加行到当前数据源,如果dr未指定,则自动添加一行
|
|
|
* @param {DataRow} [dr]
|
|
|
* @param noDefault 是否不需要m默认值
|
|
|
*/
|
|
|
DataSource.prototype.addRow = function (dr, noDefault) {
|
|
|
if (dr === undefined) {
|
|
|
dr = this.newRow(noDefault);
|
|
|
}
|
|
|
|
|
|
if (!this._maxId) {
|
|
|
this._maxId = 1;
|
|
|
}
|
|
|
|
|
|
dr[ID_PROPERTY] = this._maxId++;
|
|
|
this.rows.push(dr);
|
|
|
dr.dataRowState = Global.Enums.DataRowState.ADDED;
|
|
|
|
|
|
if (this._isOpened) {
|
|
|
this.onCollectChanged(Global.Enums.CollectionChangedAction.ADD, dr);
|
|
|
this.setCurrentRow(dr);
|
|
|
this.onRowAdded(dr);
|
|
|
var self = this;
|
|
|
this.columns.forEach(function (col) {
|
|
|
self.updateParent(col);
|
|
|
});
|
|
|
}
|
|
|
|
|
|
return dr;
|
|
|
}
|
|
|
|
|
|
DataSource.prototype.removeRow = function (dr) {
|
|
|
var self = this;
|
|
|
var index = self.rows.indexOf(dr);
|
|
|
if (index < 0) {
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
this.rows.splice(index, 1);
|
|
|
this.columns.forEach(function (col) {
|
|
|
self.updateParent(col);
|
|
|
});
|
|
|
if (self._isOpened) {
|
|
|
self.onRowRemoved(dr);
|
|
|
self.onCollectChanged(Global.Enums.CollectionChangedAction.REMOVE, dr);
|
|
|
index = index - 1;
|
|
|
index = index > -1 ? index : 0;
|
|
|
self.setCurrentRow(index);
|
|
|
}
|
|
|
|
|
|
return self;
|
|
|
}
|
|
|
|
|
|
|
|
|
/**
|
|
|
* 删除行
|
|
|
* @param {DataRow} dr 要删除的行
|
|
|
* @param needConfirm 是否需要确认
|
|
|
*/
|
|
|
DataSource.prototype.deleteRow = function (dr, needConfirm) {
|
|
|
var index = this.rows.indexOf(dr);
|
|
|
if (index < 0) {
|
|
|
return null;
|
|
|
}
|
|
|
|
|
|
var self = this;
|
|
|
this.onRowDeleting(dr, needConfirm, function () {
|
|
|
dr.rejectChanges();
|
|
|
self.removeRow(dr);
|
|
|
for (var j = 0; j < self._childRelations.length; j++) {
|
|
|
var r = self._childRelations[j];
|
|
|
if (dr.hasOwnProperty(r.detail.name)) {
|
|
|
for (var i = 0; i < dr[r.detail.name].rows.length; i++) {
|
|
|
dr[r.detail.name].rows[i].dataRowState = Global.Enums.DataRowState.DELETED;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
if (dr.dataRowState == Global.Enums.DataRowState.MODIFIED ||
|
|
|
dr.dataRowState == Global.Enums.DataRowState.UNCHANGED) {
|
|
|
dr.dataRowState = Global.Enums.DataRowState.DELETED;
|
|
|
self._deletedRows.push(dr);
|
|
|
}
|
|
|
|
|
|
self.onRowDeleted(dr);
|
|
|
});
|
|
|
};
|
|
|
|
|
|
DataSource.prototype.deleteAll = function () {
|
|
|
for (var i = this.rows.length; i > 0; i--) {
|
|
|
this.rows[i - 1].delete();
|
|
|
}
|
|
|
};
|
|
|
|
|
|
|
|
|
/**
|
|
|
* 清空数据。注意,clear后,所有数据都会销毁,包括删除的数据和原始数据
|
|
|
* 无法通过rejectChange操作还原
|
|
|
* @return {[type]} [description]
|
|
|
*/
|
|
|
DataSource.prototype.clear = function () {
|
|
|
//if (this.rows.length > 0) {
|
|
|
this.rows.splice(0);
|
|
|
|
|
|
//清空原始数据和删除数据
|
|
|
this._idSequence = {};
|
|
|
this._originRows = {};
|
|
|
this._deletedRows.splice(0);
|
|
|
this.setTotalRows(-1);
|
|
|
//this.setPagenum(0);
|
|
|
//this.setPageSize(-1);
|
|
|
this.setCurrentRow(null);
|
|
|
this.onCleared();
|
|
|
this.onCollectChanged(Global.Enums.CollectionChangedAction.RESET);
|
|
|
|
|
|
return this;
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 接受修改
|
|
|
* @return {[type]} [description]
|
|
|
*/
|
|
|
DataSource.prototype.acceptChanges = function () {
|
|
|
this._originRows = {};
|
|
|
for (var i = 0, len = this.rows.length; i < len; i++) {
|
|
|
var dr = this.rows[i];
|
|
|
//主从从表数据
|
|
|
for (var j = 0, len1 = this._childRelations.length; j < len1; j++) {
|
|
|
var rel = this._childRelations[j];
|
|
|
delete dr[rel.detail.name];
|
|
|
}
|
|
|
dr.acceptChanges();
|
|
|
this._originRows[dr[ID_PROPERTY]] = _.clone(dr);
|
|
|
}
|
|
|
|
|
|
this._deletedRows.splice(0);
|
|
|
return this;
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 快照当前数据,用于后续reset
|
|
|
* @return {[type]} [description]
|
|
|
*/
|
|
|
DataSource.prototype.snapData = function () {
|
|
|
var data = {};
|
|
|
data.origin = _.clone(this._originRows);
|
|
|
data.deleted = _.clone(this._deletedRows);
|
|
|
data.rows = _.clone(this.rows);
|
|
|
return data;
|
|
|
};
|
|
|
/**
|
|
|
* 获取变动行,包含删除行
|
|
|
* @param {Function} iteratee 处理方法
|
|
|
* @return {[type]} [description]
|
|
|
*/
|
|
|
DataSource.prototype.getChanges = function (iteratee) {
|
|
|
var self = this;
|
|
|
var changes = [];
|
|
|
|
|
|
this.ii = this.ii ? this.ii : 0;
|
|
|
|
|
|
//删除行数据
|
|
|
for (var k = 0; k < self._deletedRows.length; k++) {
|
|
|
var delRow = self._deletedRows[k];
|
|
|
changes.push(delRow);
|
|
|
if (iteratee) {
|
|
|
iteratee(delRow);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
//本身修改数据
|
|
|
for (var i = 0; i < self.rows.length; i++) {
|
|
|
var row = self.rows[i]
|
|
|
if (row.dataRowState != Global.Enums.DataRowState.UNCHANGED && row.dataRowState != Global.Enums.DataRowState.DETACHED) {
|
|
|
changes.push(row);
|
|
|
if (iteratee) {
|
|
|
iteratee(row);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
//检查父数据是否有需要提交的内容
|
|
|
var pr = self.getParentRelation();
|
|
|
if (pr) {
|
|
|
var masterRows = pr.master.getAllRows();
|
|
|
for (var j = 0; j < masterRows.length; j++) {
|
|
|
var mrow = masterRows[j];
|
|
|
if (mrow.hasOwnProperty(pr.detail.name)) {
|
|
|
for (var l = 0; l < mrow[pr.detail.name].rows.length; l++) {
|
|
|
var drow = mrow[pr.detail.name].rows[l];
|
|
|
if (drow.dataRowState != Global.Enums.DataRowState.UNCHANGED && drow.dataRowState != Global.Enums.DataRowState.DETACHED) {
|
|
|
changes.push(drow);
|
|
|
if (iteratee) {
|
|
|
iteratee(drow);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
//删除行
|
|
|
if (mrow[pr.detail.name].deleted.length > 0) {
|
|
|
for (var l = 0; l < mrow[pr.detail.name].deleted.length; l++) {
|
|
|
var dDelRow = mrow[pr.detail.name].deleted[l];
|
|
|
if (dDelRow.dataRowState == Global.Enums.DataRowState.DELETED) {
|
|
|
changes.push(dDelRow);
|
|
|
if (iteratee) {
|
|
|
iteratee(dDelRow);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
return changes;
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 获取实际的数据,通常与rows一致,只有在多级从表情况下才会导致不一致。
|
|
|
* @param {[type]} first_argument [description]
|
|
|
* @return {[type]} [description]
|
|
|
*/
|
|
|
DataSource.prototype.getAllRows = function () {
|
|
|
var self = this;
|
|
|
var data = [];
|
|
|
|
|
|
//删除行数据
|
|
|
for (var k = 0; k < self._deletedRows.length; k++) {
|
|
|
var delRow = self._deletedRows[k];
|
|
|
data.push(delRow);
|
|
|
}
|
|
|
|
|
|
//本身修改数据
|
|
|
for (var i = 0; i < self.rows.length; i++) {
|
|
|
var row = self.rows[i]
|
|
|
data.push(row);
|
|
|
}
|
|
|
|
|
|
//检查父数据是否有需要提交的内容
|
|
|
var pr = self.getParentRelation();
|
|
|
if (pr) {
|
|
|
var masterRows = pr.master.getAllRows();
|
|
|
for (var j = 0; j < masterRows.length; j++) {
|
|
|
var mrow = masterRows[j];
|
|
|
if (mrow.hasOwnProperty(pr.detail.name)) {
|
|
|
for (var l = 0; l < mrow[pr.detail.name].rows.length; l++) {
|
|
|
var drow = mrow[pr.detail.name].rows[l];
|
|
|
data.push(drow);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
return data;
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 获取选择行
|
|
|
* @returns {Array}
|
|
|
*/
|
|
|
DataSource.prototype.getSelectedRows = function () {
|
|
|
var selected = [];
|
|
|
this.rows.forEach(function (item) {
|
|
|
if (item[ROW_SELECT_COLNAME]) {
|
|
|
selected.push(item);
|
|
|
}
|
|
|
});
|
|
|
|
|
|
return selected;
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 放弃修改数据,取消修改
|
|
|
* @param {[type]} deep 是否深还原,即还原明细数据
|
|
|
* @return {[type]} [description]
|
|
|
*/
|
|
|
DataSource.prototype.rejectChanges = function (deep) {
|
|
|
this.rows = [];
|
|
|
var curIndex = -1;
|
|
|
var curRow = null;
|
|
|
|
|
|
//记录当前行的坐标
|
|
|
if (this.currentRow && (this.currentRow.dataRowState == Global.Enums.DataRowState.MODIFIED || this.currentRow.dataRowState == Global.Enums.DataRowState.UNCHANGED)) {
|
|
|
curIndex = this.currentRow[ID_PROPERTY];
|
|
|
}
|
|
|
|
|
|
//重置当前行
|
|
|
this.currentRow = null;
|
|
|
|
|
|
//还原数据
|
|
|
if (this._originRows) {
|
|
|
for (var i in this._originRows) {
|
|
|
var originRow = this._originRows[i];
|
|
|
var row = _.clone(originRow);
|
|
|
if (curIndex === row[ID_PROPERTY]) {
|
|
|
curRow = row;
|
|
|
}
|
|
|
row.rejectChanges();
|
|
|
this.rows.push(row);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
this._deletedRows.splice(0);
|
|
|
|
|
|
//还原当前行,如果curIndex为-1,则还原后的当前行仍为null
|
|
|
this.currentRow = curRow;
|
|
|
this.onCollectChanged(Global.Enums.CollectionChangedAction.RESET);
|
|
|
|
|
|
if (deep) {
|
|
|
for (var i = 0; i < this._childRelations.length; i++) {
|
|
|
var r = this._childRelations[i];
|
|
|
r.detail.rejectChanges(deep);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
//如果当前行为null,同时存在行数据,则设置当前行为首行
|
|
|
if (!this.currentRow && this.rows.length > -1) {
|
|
|
this.setCurrentRow(this.rows[0]);
|
|
|
}
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 增加主从关系
|
|
|
* @param {DataSource} detail [description]
|
|
|
* @param {String} masterColunms [description]
|
|
|
* @param {String} detailColumns [description]
|
|
|
*/
|
|
|
DataSource.prototype.addRelation = function (detail, masterColunms, detailColumns) {
|
|
|
for (var i = 0; i < this._childRelations.length; i++) {
|
|
|
var r = this._childRelations[i];
|
|
|
if (r.detail === detail) {
|
|
|
return;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
var relation = new DataRelation(this, detail, masterColunms, detailColumns);
|
|
|
if (detail._parentRelation != null)
|
|
|
throw '明细表已存在主表对象';
|
|
|
detail._parentRelation = relation;
|
|
|
this._childRelations.push(relation);
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 获取第一个明细
|
|
|
* @return {[type]} [description]
|
|
|
*/
|
|
|
DataSource.prototype.getFirstDetail = function () {
|
|
|
if (this._childRelations.length > 0) {
|
|
|
return this._childRelations[0].detail;
|
|
|
}
|
|
|
|
|
|
return null;
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 获取所有明细
|
|
|
* @param {String} [uiObjCode]
|
|
|
* @return {Array[DataSource]} [description]
|
|
|
*/
|
|
|
DataSource.prototype.getDetails = function (uiObjCode) {
|
|
|
var details = [];
|
|
|
for (var i = 0; i < this._childRelations.length; i++) {
|
|
|
var d = this._childRelations[i];
|
|
|
if (!uiObjCode || d.detail.uiObjCode == uiObjCode) {
|
|
|
details.push(d.detail);
|
|
|
}
|
|
|
}
|
|
|
return details;
|
|
|
};
|
|
|
|
|
|
DataSource.prototype.getMaster = function () {
|
|
|
if (this._parentRelation) {
|
|
|
return this._parentRelation.master;
|
|
|
}
|
|
|
return null;
|
|
|
};
|
|
|
|
|
|
DataSource.prototype.getDetailRelations = function () {
|
|
|
return this._childRelations;
|
|
|
};
|
|
|
|
|
|
DataSource.prototype.getParentRelation = function () {
|
|
|
return this._parentRelation;
|
|
|
};
|
|
|
|
|
|
DataSource.prototype.setSchemaData = function (schemaData) {
|
|
|
var rows = schemaData.rows;
|
|
|
var columns = schemaData.columns;
|
|
|
var totalRows = schemaData.totalRows;
|
|
|
|
|
|
//总行数
|
|
|
if (totalRows) {
|
|
|
this.setTotalRows(totalRows);
|
|
|
}
|
|
|
|
|
|
//列值
|
|
|
if (columns) {
|
|
|
for (var col in columns) {
|
|
|
var index = this.columns.names[col];
|
|
|
if (index == undefined) {
|
|
|
continue;
|
|
|
}
|
|
|
|
|
|
this.columns[index].paraValue = columns[col];
|
|
|
}
|
|
|
}
|
|
|
|
|
|
//数据
|
|
|
if (rows) {
|
|
|
this.loadData(rows);
|
|
|
}
|
|
|
};
|
|
|
|
|
|
DataSource.prototype.loadRows = function (rows) {
|
|
|
this.clear();
|
|
|
|
|
|
if (!rows || rows.length == 0) {
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
this._isOpened = false;
|
|
|
var self = this;
|
|
|
try {
|
|
|
rows.forEach(rowData => {
|
|
|
var row = new DataRow(this, true);
|
|
|
for (var j = 0; j < self.columns.length; j++) {
|
|
|
var col = self.columns[j];
|
|
|
|
|
|
if (rowData.hasOwnProperty(col.fieldName)) {
|
|
|
row[col.fieldName] = rowData[col.fieldName];
|
|
|
}
|
|
|
|
|
|
if (rowData.hasOwnProperty(col.fieldName + '$')) {
|
|
|
row[col.fieldName + '$'] = rowData[col.fieldName + '$'];
|
|
|
}
|
|
|
}
|
|
|
|
|
|
self.addRow(row);
|
|
|
});
|
|
|
|
|
|
this.acceptChanges();
|
|
|
|
|
|
this.onCollectChanged(Global.Enums.CollectionChangedAction.RESET);
|
|
|
} finally {
|
|
|
this._isOpened = true;
|
|
|
}
|
|
|
|
|
|
this.moveTo(0);
|
|
|
}
|
|
|
|
|
|
DataSource.prototype.loadData = function (rows) {
|
|
|
if (!rows || !(rows instanceof Array)) return;
|
|
|
this.onBeforeDataSrcLoadData(rows);
|
|
|
|
|
|
this._isOpened = false;
|
|
|
try {
|
|
|
for (var i = 0; i < rows.length; i++) {
|
|
|
var rowData = toUpperKey(rows[i]);
|
|
|
var row = new DataRow(this, true);
|
|
|
for (var j = 0; j < this.columns.length; j++) {
|
|
|
var col = this.columns[j];
|
|
|
if (rowData.hasOwnProperty(col.fieldName.toUpperCase())) {
|
|
|
row[col.fieldName] = rowData[col.fieldName.toUpperCase()];
|
|
|
}
|
|
|
|
|
|
if (rowData.hasOwnProperty(col.fieldName.toUpperCase() + '$')) {
|
|
|
row[col.fieldName + '$'] = rowData[col.fieldName.toUpperCase() + '$'];
|
|
|
}
|
|
|
|
|
|
if (row[col.fieldName] && col.dataType === Global.Enums.DataType.DATETIME) {
|
|
|
row[col.fieldName] = new Date(Number(row[col.fieldName]))
|
|
|
}
|
|
|
}
|
|
|
|
|
|
this.addRow(row);
|
|
|
}
|
|
|
|
|
|
this.acceptChanges();
|
|
|
this._isOpened = true;
|
|
|
this.onCollectChanged(Global.Enums.CollectionChangedAction.RESET);
|
|
|
this.onAfterDataSrcLoadData(true);
|
|
|
} catch (e) {
|
|
|
this._isOpened = true;
|
|
|
this.onAfterDataSrcLoadData(false);
|
|
|
throw e;
|
|
|
}
|
|
|
|
|
|
this.setCurrentRow(this.rows[0]);
|
|
|
};
|
|
|
|
|
|
DataSource.prototype.sort = function (fieldName) {
|
|
|
this._isOpened = false;
|
|
|
try {
|
|
|
var isNumber = this.getColumn(fieldName).dataType === Global.Enums.DataType.NUMBER
|
|
|
this.rows.sort((r1, r2) => {
|
|
|
var a = r1[fieldName]
|
|
|
var b = r2[fieldName]
|
|
|
if (isNumber) {
|
|
|
return Number(a) - Number(b)
|
|
|
}
|
|
|
|
|
|
if (!a && !b) {
|
|
|
return 0
|
|
|
}
|
|
|
|
|
|
if (!a && b) {
|
|
|
return 1
|
|
|
}
|
|
|
|
|
|
if (a && !b) {
|
|
|
return -1
|
|
|
}
|
|
|
|
|
|
return a.localeCompare(b)
|
|
|
})
|
|
|
|
|
|
|
|
|
} finally {
|
|
|
this._isOpened = true
|
|
|
}
|
|
|
|
|
|
this.onCollectChanged(Global.Enums.CollectionChangedAction.RESET);
|
|
|
}
|
|
|
|
|
|
DataSource.prototype.resetData = function (data) {
|
|
|
this._isOpened = false;
|
|
|
try {
|
|
|
this._idSequence = {};
|
|
|
this.rows = data.rows;
|
|
|
this._originRows = data.origin;
|
|
|
this._deletedRows = data.deleted;
|
|
|
this.currentRow = this.rows[0] || null;
|
|
|
this.onCollectChanged(Global.Enums.CollectionChangedAction.RESET);
|
|
|
} catch (e) {
|
|
|
console.log(e);
|
|
|
}
|
|
|
this._isOpened = true;
|
|
|
};
|
|
|
|
|
|
DataSource.prototype.removeEmptyRow = function () {
|
|
|
var self = this;
|
|
|
//移除空行
|
|
|
for (var j = this.rows.length - 1; j > -1; j--) {
|
|
|
var row = this.rows[j];
|
|
|
if (row.isEmpty()) {
|
|
|
row.delete();
|
|
|
}
|
|
|
|
|
|
var details = self.getDetails();
|
|
|
for (var i = 0; i < details.length; i++) {
|
|
|
var d = details[i];
|
|
|
if (row[d.name]) {
|
|
|
self.removeDetailEmptyRow(row[d.name].rows);
|
|
|
}
|
|
|
};
|
|
|
|
|
|
};
|
|
|
};
|
|
|
|
|
|
DataSource.prototype.removeDetailEmptyRow = function (rows) {
|
|
|
for (var j = rows.length - 1; j > -1; j--) {
|
|
|
var row = rows[j];
|
|
|
if (row.isEmpty()) {
|
|
|
rows.splice(j, 1);
|
|
|
}
|
|
|
}
|
|
|
};
|
|
|
|
|
|
DataSource.prototype.validate = function (deep) {
|
|
|
var msgs = [];
|
|
|
//先移除空行,再校验
|
|
|
this.removeEmptyRow();
|
|
|
this.getChanges(function (row) {
|
|
|
if (row.dataRowState !== Global.Enums.DataRowState.DELETED) {
|
|
|
|
|
|
row.validate(function (err) {
|
|
|
msgs.push(err);
|
|
|
});
|
|
|
}
|
|
|
});
|
|
|
|
|
|
if (msgs.length > 0) {
|
|
|
Global.messager.err(toStrLines(msgs));
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
if (msgs.length == 0 && deep) {
|
|
|
for (var i = 0; i < this._childRelations.length; i++) {
|
|
|
var rel = this._childRelations[i];
|
|
|
|
|
|
//先移除空行,再校验
|
|
|
if (!rel.detail.validate(true)) {
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
//明细必填检查
|
|
|
if (this.getRequireDetail() && rel.detail.isEmpty()) {
|
|
|
Global.messager.err(Global.format(Global.MSG.DS_REQUIREDETAIL, rel.detail.uiObjName));
|
|
|
return false;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
return true;
|
|
|
};
|
|
|
|
|
|
function acceptChanges(dataSrc, deep) {
|
|
|
dataSrc.acceptChanges();
|
|
|
if (deep) {
|
|
|
for (var i = 0; i < dataSrc._childRelations.length; i++) {
|
|
|
var rel = dataSrc._childRelations[i];
|
|
|
acceptChanges(rel.detail, true);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 设置保存扩展类,用于调用服务器的保存操作
|
|
|
* @param {[type]} className [description]
|
|
|
*/
|
|
|
DataSource.prototype.setServerBiz = function (className) {
|
|
|
this.serverBiz = className;
|
|
|
};
|
|
|
|
|
|
|
|
|
/**
|
|
|
* 获取包含结构信息的保存操作数据
|
|
|
* @return {Object} 数据
|
|
|
*/
|
|
|
DataSource.prototype.getSchemaData = function (args, cb) {
|
|
|
if (!args) {
|
|
|
args = {};
|
|
|
}
|
|
|
|
|
|
var self = this;
|
|
|
|
|
|
//结构
|
|
|
var table = {
|
|
|
funcCode: self.funcCode,
|
|
|
uiObjCode: this.uiObjCode,
|
|
|
serverBiz: this.serverBiz,
|
|
|
dataObjType: self.dataObjType,
|
|
|
pageSize: args.updateRow ? 0 : self._pageSize,
|
|
|
pageIndex: self._pagenum,
|
|
|
totalRows: self._totalRows,
|
|
|
queryParams: self.getQueryParams(args),
|
|
|
columnParams: self.getColumnParams(),
|
|
|
isMaster: self.isMaster,
|
|
|
detailRelation: [],
|
|
|
searchTableName: self._searchTableName,
|
|
|
rows: [],
|
|
|
state: self.state
|
|
|
};
|
|
|
|
|
|
if (args.deep) {
|
|
|
for (var i = 0; i < self._childRelations.length; i++) {
|
|
|
var r = self._childRelations[i];
|
|
|
if (r.detail._followMaster) {
|
|
|
table.detailRelation.push(r.getSchema({
|
|
|
deep: args.deep,
|
|
|
nodata: args.nodata
|
|
|
}));
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
//存储过程不需要数据
|
|
|
if (self.dataObjType == Global.Enums.DataObjType.STOREDPROC) {
|
|
|
args.nodata = true;
|
|
|
}
|
|
|
|
|
|
//数据
|
|
|
if (!args.nodata) {
|
|
|
if (args.onlyOne) {
|
|
|
var curRow = self.currentRow;
|
|
|
var rowData = curRow.getData();
|
|
|
table.rows.push(rowData);
|
|
|
} else {
|
|
|
self.getChanges(function (row) {
|
|
|
if (row.dataRowState == Global.Enums.DataRowState.DELETED ||
|
|
|
row.dataRowState == Global.Enums.DataRowState.MODIFIED ||
|
|
|
row.dataRowState == Global.Enums.DataRowState.ADDED) {
|
|
|
var _rowData = row.getData();
|
|
|
table.rows.push(_rowData);
|
|
|
}
|
|
|
|
|
|
var _prow = self.getParentRelaventRow(row);
|
|
|
_prow && (cb ? cb(_prow, args.oldSchema) : '');
|
|
|
});
|
|
|
}
|
|
|
|
|
|
if (self.isMaster && table.rows.length === 0) {
|
|
|
if (!self.currentRow) {
|
|
|
throw new Error('保存时,未指定主表当前行')
|
|
|
}
|
|
|
table.rows.push(self.currentRow.getData())
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if (args.deleteCur) {
|
|
|
var __curRow = self.currentRow;
|
|
|
if (!__curRow) { throw new Error('delete row not found'); }
|
|
|
|
|
|
var __rowData = __curRow.getData();
|
|
|
__rowData.$state = Global.Enums.DataRowState.DELETED;
|
|
|
table.rows.push(__rowData);
|
|
|
}
|
|
|
|
|
|
return table;
|
|
|
};
|
|
|
|
|
|
DataSource.prototype.getParentRelaventRow = function (row) {
|
|
|
var self = this;
|
|
|
var _row = null;
|
|
|
var curMasterRow = null;
|
|
|
// 如果从表数据有改动,强制添加当前从表对应的主表行到保存数据中
|
|
|
if (self.isMaster === false && self.getMaster() !== null) {
|
|
|
var curMaster = self.getMaster();
|
|
|
var paRelation = self.getParentRelation();
|
|
|
for (var jj = 0; jj < curMaster.rows.length; jj++) {
|
|
|
curMasterRow = curMaster.rows[jj];
|
|
|
var filt = true;
|
|
|
for (var ii = 0; ii < paRelation.masterColunms.length; ii++) {
|
|
|
var curColumn = paRelation.masterColunms[ii];
|
|
|
// 添加对主从关联键只有一个键并且主从关联键名称不一致的情况的支持。
|
|
|
var detailColumn = paRelation.detailColumns[ii];
|
|
|
if (paRelation.masterColunms.length > 1) {
|
|
|
detailColumn = curColumn;
|
|
|
}
|
|
|
if (curMasterRow[curColumn] != row[detailColumn]) {
|
|
|
filt = false;
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
if (filt) {
|
|
|
_row = curMasterRow.getData();
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
return _row ? {
|
|
|
row: curMasterRow,
|
|
|
_row: _row
|
|
|
} : null;
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 主动提交编辑状态
|
|
|
* @returns {boolean}
|
|
|
*/
|
|
|
DataSource.prototype.commitEdit = function() {
|
|
|
if (!this.onCommitEdit()) {
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
DataSource.prototype.save = function (callback, deep) {
|
|
|
var self = this;
|
|
|
|
|
|
if (!this.commitEdit()) {
|
|
|
saveCallBack(this, false, callback)
|
|
|
}
|
|
|
|
|
|
var allow = this.onBeforeDataSrcSave();
|
|
|
if (!allow) {
|
|
|
saveCallBack(this, false, callback)
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
//检查业务逻辑是否通过
|
|
|
if (this.validate(deep) == false) {
|
|
|
saveCallBack(this, false, callback)
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
//存储过程的保存需要处理入参
|
|
|
if (self.dataObjType == Global.Enums.DataObjType.STOREDPROC) {
|
|
|
self.onSetStoredProcParas();
|
|
|
}
|
|
|
|
|
|
var postData = {
|
|
|
beforeProc: '',
|
|
|
afterProc: '',
|
|
|
saveData: {},
|
|
|
serverBiz: self.serverBiz
|
|
|
};
|
|
|
|
|
|
postData.saveData[this.uiObjCode] = self.getSchemaData({
|
|
|
deep: deep,
|
|
|
onlyOne: self.onlySaveCurrent
|
|
|
});
|
|
|
if (Object.keys(postData.saveData).length == 0) {
|
|
|
saveCallBack(self, true, callback);
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
|
|
|
if (self.beforeSaveProc && self.beforeSaveProc.isDataSource) {
|
|
|
postData.beforeProc = self.beforeSaveProc.uiObjCode;
|
|
|
postData.saveData[postData.beforeProc] = self.beforeSaveProc.getSchemaData({
|
|
|
nodata: true
|
|
|
});
|
|
|
}
|
|
|
|
|
|
if (self.beforeSaveProc && self.beforeSaveProc.isDataSource) {
|
|
|
postData.afterProc = self.beforeSaveProc.uiObjCode;
|
|
|
postData.saveData[postData.afterProc] = self.beforeSaveProc.getSchemaData({
|
|
|
nodata: true
|
|
|
});
|
|
|
}
|
|
|
|
|
|
Global.services.saveData(postData, function (isOk, data) {
|
|
|
if (isOk) {
|
|
|
var schemaData = data[self.uiObjCode];
|
|
|
self.setSchemaData(schemaData);
|
|
|
acceptChanges(self, deep);
|
|
|
if (self.isMaster) {
|
|
|
self.updateRow();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
saveCallBack(self, isOk, callback);
|
|
|
});
|
|
|
};
|
|
|
|
|
|
function saveCallBack(ds, result, callback) {
|
|
|
if (callback) {
|
|
|
callback(result);
|
|
|
}
|
|
|
|
|
|
ds.onAfterDataSrcSave(result);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 删除当前行到服务器
|
|
|
* @return {[type]} [description]
|
|
|
*/
|
|
|
DataSource.prototype.delete = function (callback) {
|
|
|
if (this.currentRow) {
|
|
|
var self = this;
|
|
|
var postData = {
|
|
|
beforeProc: '',
|
|
|
afterProc: '',
|
|
|
saveData: {},
|
|
|
serverBiz: self.serverBiz
|
|
|
};
|
|
|
|
|
|
postData.saveData[self.uiObjCode] = self.getSchemaData({
|
|
|
deep: true,
|
|
|
onlyOne: self.onlySaveCurrent,
|
|
|
nodata: true,
|
|
|
deleteCur: true
|
|
|
});
|
|
|
|
|
|
if (self.beforeDeleteProc && self.beforeDeleteProc.isDataSource) {
|
|
|
postData.beforeProc = self.beforeDeleteProc.uiObjCode;
|
|
|
//self.beforeProc.getSaveSchemaData(false, postData.saveData);
|
|
|
postData.saveData[postData.beforeProc] = self.beforeDeleteProc.getSchemaData({
|
|
|
nodata: true
|
|
|
});
|
|
|
}
|
|
|
|
|
|
if (self.beforeDeleteProc && self.beforeDeleteProc.isDataSource) {
|
|
|
postData.afterProc = self.beforeDeleteProc.uiObjCode;
|
|
|
//self.afterProc.getSaveSchemaData(false, postData.saveData);
|
|
|
postData.saveData[postData.afterProc] = self.beforeDeleteProc.getSchemaData({
|
|
|
nodata: true
|
|
|
});
|
|
|
}
|
|
|
|
|
|
Global.services.saveData(postData, function (isOk, data) {
|
|
|
if (isOk) {
|
|
|
var row = self.currentRow;
|
|
|
self.deleteRow(row);
|
|
|
var clearChild = function (dataSrc) {
|
|
|
for (var i = 0; i < dataSrc._childRelations.length; i++) {
|
|
|
var r = dataSrc._childRelations[i];
|
|
|
r.detail.clear();
|
|
|
clearChild(r.detail);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
clearChild(self);
|
|
|
self.acceptChanges();
|
|
|
if (!self.currentRow) {
|
|
|
self.moveToPrev();
|
|
|
}
|
|
|
}
|
|
|
if (callback) {
|
|
|
callback(isOk);
|
|
|
}
|
|
|
});
|
|
|
|
|
|
|
|
|
}
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* @param {DataSource} ds 数据源
|
|
|
* @param {DataRow} masterRow 主表行
|
|
|
* @param {DataRow} curRow 当前行
|
|
|
*/
|
|
|
DataSource.prototype.getQueryParams = function (args) {
|
|
|
var params = {},
|
|
|
ds = this;
|
|
|
if (args.updateRow) {
|
|
|
params.fixQuery = {};
|
|
|
for (var i = 0; i < ds.columns.length; i++) {
|
|
|
var col = ds.columns[i];
|
|
|
if (col.isPrimaryKey) {
|
|
|
params.fixQuery[col.fieldName] = args.updateRow[col.fieldName];
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if (Object.keys(params.fixQuery).length === 0) {
|
|
|
throw new Error('主键未找到')
|
|
|
}
|
|
|
|
|
|
} else {
|
|
|
params = {
|
|
|
refQuery: ds.refQuery,
|
|
|
searchQuery: ds.searchQuery,
|
|
|
fixQuery: {},
|
|
|
defaultQuery: {
|
|
|
funcObjCode: ds.name,
|
|
|
funcCode: ds.funcCode
|
|
|
},
|
|
|
projectQuery: {},
|
|
|
treeQuery: ds.treeQuery,
|
|
|
userExtSqlQuery: ds.queryParamPlugin
|
|
|
};
|
|
|
|
|
|
_.extend(params.fixQuery, ds.fixQuery);
|
|
|
|
|
|
if (ds.linkQuery) {
|
|
|
params['linkQuery'] = ds.linkQuery;
|
|
|
ds.linkQuery = null;
|
|
|
}
|
|
|
|
|
|
if (ds.cautionQuery) {
|
|
|
params['cautionQuery'] = ds.cautionQuery;
|
|
|
ds.cautionQuery = null;
|
|
|
}
|
|
|
|
|
|
if (ds.defaultOrder && ds.defaultOrder.length > 0) {
|
|
|
var _order = {};
|
|
|
try {
|
|
|
var orderList = ds.defaultOrder.split(',');
|
|
|
orderList.forEach(function (item, index) {
|
|
|
var itemArray = item.split(' ');
|
|
|
if (!itemArray[1]) {
|
|
|
_order[itemArray[0]] = 0;
|
|
|
} else {
|
|
|
_order[itemArray[0]] = itemArray[1].toLowerCase() === 'desc' ? 1 : 0;
|
|
|
}
|
|
|
})
|
|
|
} catch (e) {
|
|
|
console.log(e);
|
|
|
}
|
|
|
params.order = _order;
|
|
|
}
|
|
|
|
|
|
if (args.masterRow) {
|
|
|
_.extend(params.fixQuery, ds._parentRelation.getParams(args.masterRow))
|
|
|
}
|
|
|
|
|
|
this.onGetQueryParams(params);
|
|
|
}
|
|
|
|
|
|
if (ds._parentRelation) {
|
|
|
var masterRow = ds._parentRelation.master.currentRow;
|
|
|
params.M = masterRow ? masterRow.getData() : {};
|
|
|
}
|
|
|
|
|
|
params.state = this.state
|
|
|
return params;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 获取列值传输对象,用于服务器处理存储过程入参
|
|
|
* @param {DataSource} ds
|
|
|
* @return {Object}
|
|
|
*/
|
|
|
DataSource.prototype.getColumnParams = function () {
|
|
|
var params = {},
|
|
|
ds = this;
|
|
|
if (ds.dataObjType == Global.Enums.DataObjType.STOREDPROC) {
|
|
|
for (var i = 0; i < ds.columns.length; i++) {
|
|
|
var col = ds.columns[i];
|
|
|
if (col.procParaType == Global.Enums.ProcParaType.IN || col.procParaType == Global.Enums.ProcParaType.INOUT) {
|
|
|
params[col.fieldName] = col.paraValue;
|
|
|
}
|
|
|
};
|
|
|
}
|
|
|
return params;
|
|
|
}
|
|
|
|
|
|
|
|
|
/**
|
|
|
* 刷新数据源数据
|
|
|
* @param {Function} callback 参数isOk,DataSource
|
|
|
* @return {undefined}
|
|
|
*/
|
|
|
DataSource.prototype.search = function (callback, args) {
|
|
|
var self = this;
|
|
|
args = args || {}
|
|
|
|
|
|
if (Global) {
|
|
|
if (!args || args.reset) {
|
|
|
self.setPagenum(0);
|
|
|
self.setTotalRows(-1);
|
|
|
}
|
|
|
|
|
|
if (!self.onBeforeSearch()) return;
|
|
|
|
|
|
if (self.dataObjType == Global.Enums.DataObjType.STOREDPROC) {
|
|
|
self.onSetStoredProcParas();
|
|
|
}
|
|
|
|
|
|
var postData = {
|
|
|
beforeProc: self.beforeSearchProc,
|
|
|
afterProc: self.afterSearchProc,
|
|
|
searchData: {},
|
|
|
serverBiz: self.serverBiz,
|
|
|
sync: args.sync || false
|
|
|
};
|
|
|
|
|
|
// 明细分页search条件支持
|
|
|
var schemaArgs = { nodata: true };
|
|
|
if (!self.isMaster && self._parentRelation) {
|
|
|
schemaArgs = {
|
|
|
masterRow: self._parentRelation.master.currentRow
|
|
|
}
|
|
|
}
|
|
|
|
|
|
postData.searchData[self.uiObjCode] = self.getSchemaData(schemaArgs);
|
|
|
|
|
|
Global.services.searchData(postData, function (isOk, result) {
|
|
|
if (isOk) {
|
|
|
//优先清除数据,保证数据的实时性
|
|
|
self.clear();
|
|
|
var schemaData = result[self.uiObjCode];
|
|
|
self.setSchemaData(schemaData);
|
|
|
acceptChanges(self);
|
|
|
}
|
|
|
if (callback) {
|
|
|
callback(isOk, self);
|
|
|
}
|
|
|
});
|
|
|
}
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 更新某一行的数据
|
|
|
* @param {DataRow} [dr]
|
|
|
* @return
|
|
|
*/
|
|
|
DataSource.prototype.updateRow = function (dr) {
|
|
|
var self = this;
|
|
|
|
|
|
if (Global) {
|
|
|
if (self.dataObjType == Global.Enums.DataObjType.STOREDPROC) {
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
if (!dr) {
|
|
|
dr = self.currentRow;
|
|
|
}
|
|
|
|
|
|
if (!dr) {
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
if (dr.dataRowState !== Global.Enums.DataRowState.UNCHANGED) {
|
|
|
Global.showError("数据已修改,请先保存再更新");
|
|
|
}
|
|
|
|
|
|
var postData = {
|
|
|
beforeProc: null,
|
|
|
afterProc: null,
|
|
|
searchData: {},
|
|
|
sync: true
|
|
|
};
|
|
|
postData.searchData[self.uiObjCode] = self.getSchemaData({
|
|
|
updateRow: dr,
|
|
|
nodata: true
|
|
|
});
|
|
|
var isCurrentRow = dr == this.currentRow;
|
|
|
|
|
|
Global.services.searchData(postData, function (isOk, result) {
|
|
|
if (isOk) {
|
|
|
var schemaData = result[self.uiObjCode];
|
|
|
if (schemaData.rows && schemaData.rows.length === 1) {
|
|
|
dr.loadData(schemaData.rows[0]);
|
|
|
} else {
|
|
|
Global.showError(Global.MSG.UPDATEROW_ERR);
|
|
|
}
|
|
|
dr.acceptChanges();
|
|
|
if (isCurrentRow) {
|
|
|
self.onCurrentChanged(dr, dr);
|
|
|
}
|
|
|
return;
|
|
|
}
|
|
|
});
|
|
|
}
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 根据主表行,刷新当前明细
|
|
|
* @param {[type]} dr [description]
|
|
|
* @param {Function} callback [description]
|
|
|
* @return {[type]} [description]
|
|
|
*/
|
|
|
DataSource.prototype.searchByMaster = function (dr, callback) {
|
|
|
var self = this;
|
|
|
self.clear();
|
|
|
if (!dr || dr.dataRowState == Global.Enums.DataRowState.ADDED) {
|
|
|
if (callback) {
|
|
|
callback(true, self);
|
|
|
}
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
if (self._parentRelation === null || self._parentRelation.master != dr.dataSrc) {
|
|
|
throw 'searchByMaster:' + Global.MSG.SEARCH_MASTER_ROW_ERROR;
|
|
|
}
|
|
|
|
|
|
if (self.dataObjType == Global.Enums.DataObjType.STOREDPROC) {
|
|
|
Global.throwException(Global.MSG.SEARCH_ERROR_DETAIL, 'searchByMaster');
|
|
|
}
|
|
|
|
|
|
if (Global) {
|
|
|
var postData = {
|
|
|
beforeProc: self.beforeSearchProc,
|
|
|
afterProc: self.afterSearchProc,
|
|
|
searchData: {}
|
|
|
};
|
|
|
|
|
|
self.setPagenum(0);
|
|
|
postData.searchData[self.uiObjCode] = self.getSchemaData({
|
|
|
masterRow: dr
|
|
|
});
|
|
|
|
|
|
Global.services.searchData(postData, function (isOk, result) {
|
|
|
if (isOk) {
|
|
|
//优先清除数据,保证数据的实时性
|
|
|
self.clear();
|
|
|
var schemaData = result[self.uiObjCode];
|
|
|
self.setSchemaData(schemaData);
|
|
|
}
|
|
|
if (callback) {
|
|
|
callback(isOk, self);
|
|
|
}
|
|
|
});
|
|
|
}
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 加载相关明细
|
|
|
* @param {Function} callback 回调
|
|
|
* @return {[type]} [description]
|
|
|
*/
|
|
|
DataSource.prototype.loadDetails = function (callback) {
|
|
|
var postData = {
|
|
|
beforeProc: null,
|
|
|
afterProc: null,
|
|
|
searchData: {}
|
|
|
};
|
|
|
|
|
|
var dr = this.currentRow;
|
|
|
_.extend(postData.searchData, this.getDetailsParams(dr, function (ds) {
|
|
|
ds.clear();
|
|
|
}));
|
|
|
|
|
|
if (postData.length == 0) {
|
|
|
if (callback) {
|
|
|
callback(true);
|
|
|
}
|
|
|
} else {
|
|
|
var self = this;
|
|
|
Global.services.searchData(postData, function (isOk, data) {
|
|
|
for (var j = 0; j < self._childRelations.length; j++) {
|
|
|
var d = self._childRelations[j];
|
|
|
if (isOk && data.hasOwnProperty(d.detail.uiObjCode)) {
|
|
|
var result = data[d.detail.uiObjCode];
|
|
|
d.detail.clear();
|
|
|
d.detail.setSchemaData(result);
|
|
|
acceptChanges(d.detail);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if (callback) {
|
|
|
callback(isOk, self);
|
|
|
}
|
|
|
});
|
|
|
}
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 获取从表查询约束
|
|
|
* @param {当前行} dr 主表行
|
|
|
* @param {function} fn 每个明细的处理 fn(ds){}
|
|
|
* @return {array} 参数集合
|
|
|
*/
|
|
|
DataSource.prototype.getDetailsParams = function (dr, cb) {
|
|
|
var searchData = {};
|
|
|
|
|
|
for (var i = 0; i < this._childRelations.length; i++) {
|
|
|
var r = this._childRelations[i];
|
|
|
if (cb) {
|
|
|
cb(r.detail);
|
|
|
}
|
|
|
|
|
|
if (dr && dr.dataRowState !== Global.Enums.DataRowState.ADDED) {
|
|
|
searchData[r.detail.uiObjCode] = r.detail.getSchemaData({
|
|
|
masterRow: dr
|
|
|
});
|
|
|
}
|
|
|
}
|
|
|
|
|
|
return searchData;
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 获取字符串字节长度
|
|
|
* @param str
|
|
|
* @returns {number}
|
|
|
*/
|
|
|
var getLength = function (str) {
|
|
|
if (str === null || str === undefined) return 0;
|
|
|
var realLength = 0;
|
|
|
for (var i = 0; i < str.length; i++) {
|
|
|
var charCode = str.charCodeAt(i);
|
|
|
if (charCode >= 0 && charCode <= 128)
|
|
|
realLength += 1;
|
|
|
else
|
|
|
realLength += 3;
|
|
|
}
|
|
|
return realLength;
|
|
|
};
|
|
|
|
|
|
function getScaleLength(val) {
|
|
|
if (!val) {
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
var str = String(val)
|
|
|
var dotIndex = str.indexOf('.');
|
|
|
var len = str.length;
|
|
|
return dotIndex > 0 ? len - dotIndex - 1 : 0;
|
|
|
}
|
|
|
|
|
|
function getIntegerLength(val) {
|
|
|
if (!val) {
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
var str = String(val)
|
|
|
var dotIndex = str.indexOf('.');
|
|
|
var len = str.length;
|
|
|
return dotIndex > 0 ? dotIndex : len;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 校验列值宽度
|
|
|
* @param dr
|
|
|
* @param dc
|
|
|
* @param value
|
|
|
* @returns {bool}
|
|
|
*/
|
|
|
var validateColumnWidth = function (dr, dc, value) {
|
|
|
if (dc.isCalc || (!value && value !== 0)) {
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
if (dc.dataType == Global.Enums.DataType.STRING || dc.dataType == Global.Enums.DataType.TEXT) {
|
|
|
var len = getLength(value);
|
|
|
if (len > dc.dataWidth) {
|
|
|
dr.setColumnError(dc, dc.dataSrc.onGetDataWidthErr(dr, dc, Global.format(Global.MSG.VALIDATE_LENGTH, dc.dispName, dc.dataWidth)));
|
|
|
return false;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if (dc.dataType == Global.Enums.DataType.NUMBER) {
|
|
|
var scale = getScaleLength(value);
|
|
|
var integer = getIntegerLength(value);
|
|
|
var realInteger = dc.dataWidth - dc.dataDec;
|
|
|
var realScale = dc.dataSrc.onGetPrecision(dr, dc);
|
|
|
realInteger = realInteger > 0 ? realInteger : 0;
|
|
|
if (scale > realScale || integer > realInteger) {
|
|
|
dr.setColumnError(dc, dc.dataSrc.onGetDataWidthErr(dr, dc, Global.format(Global.MSG.VALIDATE_LENGTH_NUM, dc.dispName, realInteger, realScale)));
|
|
|
return false;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
return true;
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 校验列类型
|
|
|
* @param dr
|
|
|
* @param dc
|
|
|
* @param value
|
|
|
* @returns {bool}
|
|
|
*/
|
|
|
var validateColumnType = function (dr, dc, value) {
|
|
|
if (dc.isCalc || (!value && value !== 0)) {
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
var bRet = false;
|
|
|
switch (dc.dataType.toString()) {
|
|
|
case Global.Enums.DataType.DATETIME:
|
|
|
bRet = !isNaN(Date.parse(value));
|
|
|
if (!bRet) {
|
|
|
var regDate = /^(?:(?!0000)[0-9]{4}-(?:(?:0[1-9]|1[0-2])-(?:0[1-9]|1[0-9]|2[0-8])|(?:0[13-9]|1[0-2])-(?:29|30)|(?:0[13578]|1[02])-31)|(?:[0-9]{2}(?:0[48]|[2468][048]|[13579][26])|(?:0[48]|[2468][048]|[13579][26])00)-02-29)([ T][0-2]?[0-9]:[0-5]?[0-9]:[0-5]?[0-9])?$/;
|
|
|
var regTime = /[0-9]{2}:[0-9]{2}:[0-9]{2}/;
|
|
|
bRet = regDate.test(value) || regTime.test(value);
|
|
|
}
|
|
|
break;
|
|
|
default:
|
|
|
bRet = true;
|
|
|
}
|
|
|
if (!bRet) {
|
|
|
dr.setColumnError(dc, dc.dataSrc.onGetDataTypeErr(dr, dc, Global.format(Global.MSG.VALIDATE_TYPE, dc.dispName, value)));
|
|
|
}
|
|
|
return bRet;
|
|
|
};
|
|
|
|
|
|
var valiateColumnRule = function (dr, dc, value) {
|
|
|
if (!dc.setRule) return true;
|
|
|
var reg = new RegExp(dc.setRule);
|
|
|
if (!reg.test(value)) {
|
|
|
dr.setColumnError(dc, dc.dataSrc.onGetDataRuleErr(dr, dc, Global.format(Global.MSG.VAILIDATE_RULE, dc.dispName, value)));
|
|
|
}
|
|
|
};
|
|
|
|
|
|
var validateColumnStrictRef = function (dr, dc, value) {
|
|
|
if (dc.isTableRef() || dc.isEnumRef()) {
|
|
|
//获取参照内容
|
|
|
dc.loadRefData(dr, value, false, true);
|
|
|
|
|
|
if (value != dc.match && (value || value === 0)) {
|
|
|
//严格校验,只有表参照和枚举生效
|
|
|
if (dc.isStrictRef && !dc.getRefItem()) {
|
|
|
dr.setColumnError(dc,
|
|
|
dc.dataSrc.onGetDataStrictErr(dr, dc, Global.format(Global.MSG.VALIDTE_STRICTREF, dc.dispName, value)));
|
|
|
return false;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 校验列值,调用业务类
|
|
|
* @param {DataRow} dr [description]
|
|
|
* @param {DataColumn} dc [description]
|
|
|
* @param {Object} value [description]
|
|
|
* @return {bool} [description]
|
|
|
*/
|
|
|
DataSource.prototype.validateColumn = function (dr, dc, value, callback) {
|
|
|
//类型校验
|
|
|
if (!validateColumnType(dr, dc, value)) return false;
|
|
|
//长度校验
|
|
|
if (!validateColumnWidth(dr, dc, value)) return false;
|
|
|
//严格校验
|
|
|
if (!validateColumnStrictRef(dr, dc, value)) return false;
|
|
|
//自定义校验
|
|
|
return this.onDataColumnValidate(dr, dc, value);
|
|
|
};
|
|
|
|
|
|
|
|
|
/**
|
|
|
* 校验多选列值,调用业务类
|
|
|
* @param {DataRow} dr [description]
|
|
|
* @param {DataColumn} dc [description]
|
|
|
* @param {Object} value [description]
|
|
|
* @return {bool} [description]
|
|
|
*/
|
|
|
DataSource.prototype.validateQueryMultiColumn = function (dc, value, callback) {
|
|
|
//自定义校验
|
|
|
return this.onQueryDataColumnValidate(dr, dc, value);
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 检查重复校验字段
|
|
|
* @param {Object} ds 数据源
|
|
|
* @param {Object} dr 行
|
|
|
* @return {Object} 两个属性valid和msg
|
|
|
*/
|
|
|
DataSource.prototype.checkMultiField = function (ds, dr) {
|
|
|
|
|
|
//检查行重复
|
|
|
if (ds.multiFields && ds.multiFields.length > 0) {
|
|
|
var cols = ds.multiFields.split(',');
|
|
|
//检查校验字段是否存在
|
|
|
for (var i = 0; i < cols.length; i++) {
|
|
|
if (!ds.getColumn(cols[i])) {
|
|
|
return {
|
|
|
valid: false,
|
|
|
msg: Global.MSG.MULTIFIELD_MISS
|
|
|
};
|
|
|
}
|
|
|
}
|
|
|
//获取行标识,用于辨别重复
|
|
|
var getTag = function (r) {
|
|
|
var tag = '';
|
|
|
for (var i = 0; i < cols.length; i++) {
|
|
|
var col = cols[i];
|
|
|
tag = tag + '_' + r[col];
|
|
|
}
|
|
|
|
|
|
return tag;
|
|
|
}
|
|
|
|
|
|
var curTag = getTag(dr);
|
|
|
for (var j = 0; j < ds.rows.length; j++) {
|
|
|
var row = ds.rows[j];
|
|
|
if (row === dr) {
|
|
|
continue;
|
|
|
} else {
|
|
|
var tag = getTag(row);
|
|
|
if (tag === curTag) {
|
|
|
var index = _.findIndex(row.dataSrc.rows, row) + 1;
|
|
|
var msg = "";
|
|
|
if (ds.isMaster === true) {
|
|
|
msg = ds.onGetMultiMsg(dr);
|
|
|
} else {
|
|
|
var cur = row.dataSrc.rows[index - 1];
|
|
|
var msg = ds.onGetMultiMsg(dr);
|
|
|
var cnt = 0;
|
|
|
//查询有多少个占位符
|
|
|
msg.replace(/\{(\w+)\}/g, function () {
|
|
|
cnt++;
|
|
|
});
|
|
|
//获得占位符字段,并进行替换
|
|
|
for (var n = 0; n < cnt; n++) {
|
|
|
var field = msg.substr(msg.indexOf('{') + 1, msg.indexOf('}') - (msg.indexOf('{') + 1));
|
|
|
msg = msg.replace('{' + field + '}', cur[field]);
|
|
|
}
|
|
|
//如果没有占位符 直接提示平台原始信息
|
|
|
if (cnt === 0)
|
|
|
msg = Global.MSG.LINE + index + ': ' + ds.onGetMultiMsg(dr);
|
|
|
}
|
|
|
return {
|
|
|
valid: false,
|
|
|
msg: msg
|
|
|
};
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
return {
|
|
|
valid: true,
|
|
|
msg: null
|
|
|
};
|
|
|
}
|
|
|
|
|
|
|
|
|
/**
|
|
|
* 校验行操作
|
|
|
* @param {DataRow} dr [description]
|
|
|
* @return {[type]} [description]
|
|
|
*/
|
|
|
DataSource.prototype.validateDataRow = function (dr, onerror) {
|
|
|
var self = this,
|
|
|
error = function (errmsg) {
|
|
|
if (onerror) {
|
|
|
onerror(errmsg);
|
|
|
}
|
|
|
},
|
|
|
ret;
|
|
|
// 处理更新字段并检查行必填
|
|
|
for (var k = 0; k < self.columns.length; k++) {
|
|
|
var col = self.columns[k];
|
|
|
self.onUpdateValue(dr, col);
|
|
|
if (col.isRequired && (!dr[col.fieldName] && dr[col.fieldName] !== 0)) {
|
|
|
dr.setColumnError(col.fieldName, col.dispName + Global.MSG.VALUE_REQUIRE, true);
|
|
|
}
|
|
|
}
|
|
|
//检查空行
|
|
|
if (dr.isEmpty()) {
|
|
|
setTimeout(function () {
|
|
|
dr.delete();
|
|
|
}, 120);
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
if (dr.hasError()) {
|
|
|
error(toStrLines([dr.getErrors()]));
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
//检查行重复
|
|
|
var result = this.checkMultiField(self, dr);
|
|
|
if (!result.valid && dr == this.currentRow) {
|
|
|
error(result.msg);
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
return self.onDataRowValidate(dr, error);
|
|
|
};
|
|
|
/**
|
|
|
* 获取默认值
|
|
|
* @param {[type]} dr [description]
|
|
|
* @param {[type]} col [description]
|
|
|
* @return {[type]} [description]
|
|
|
*/
|
|
|
DataSource.prototype.getDefaultValue = function (dr, col) {
|
|
|
if (typeof col === 'string') {
|
|
|
col = this.getColumn(col);
|
|
|
}
|
|
|
|
|
|
if (col) {
|
|
|
var relationValue = this._parentRelation ? this._parentRelation.getDetailValue(col) : null;
|
|
|
var dfValue = relationValue === null ? col.defaultValue : relationValue;
|
|
|
return this.onGetDefaultValue(dr, col, dfValue);
|
|
|
}
|
|
|
|
|
|
return null;
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 获取列相关的参照内容
|
|
|
* @param {DataRow} row [description]
|
|
|
* @param {DataColumn} column [description]
|
|
|
* @param {Object} value [description]
|
|
|
* @param {Function} callback [description]
|
|
|
* @return {bool} 是否有数据
|
|
|
*/
|
|
|
DataSource.prototype.loadDefaultRefData = function (row, column, value, ignoreValue, isEdit) {
|
|
|
isEdit = isEdit ? !!isEdit : this.getEditable();
|
|
|
column.setRefData();
|
|
|
column.setRefItem();
|
|
|
|
|
|
if (column.refType == Global.Enums.RefType.ENUM) {
|
|
|
var result = Global.getEnumValue(column.refObj);
|
|
|
if (!result) {
|
|
|
Global.throwException(Global.MSG.NONE_ENUM, column.refObj);
|
|
|
}
|
|
|
|
|
|
if (isEdit && column.refEditWhere) {
|
|
|
var items = column.refEditWhere.split(',');
|
|
|
var enumValues = {};
|
|
|
|
|
|
for (var i = 0; i < items.length; i++) {
|
|
|
var item = items[i];
|
|
|
enumValues[item] = result[item];
|
|
|
}
|
|
|
result = enumValues;
|
|
|
}
|
|
|
|
|
|
result = this.onGetUserRefData(row, column, result);
|
|
|
if (result.hasOwnProperty(value)) {
|
|
|
column.setRefItem(result);
|
|
|
}
|
|
|
column.setRefData(result);
|
|
|
}
|
|
|
|
|
|
if (column.isTableRef()) {
|
|
|
//行不为空,表示进行严格校验,如果值为空或者为通配符,则跳出校验
|
|
|
if (!ignoreValue && !value && value !== 0) {
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
if (!ignoreValue && value == column.match) {
|
|
|
var item = {};
|
|
|
this.columns.forEach(function (c) {
|
|
|
item[c.fieldName.toUpperCase()] = c.defaultValue;
|
|
|
});
|
|
|
item[column.fieldName.toUpperCase()] = column.match;
|
|
|
column.setRefItem(item, row);
|
|
|
column.setRefData([item]);
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
//同步访问服务器,获取参照数据
|
|
|
var postData = {
|
|
|
funcCode: this.funcCode || '*',
|
|
|
searchData: {},
|
|
|
sync: true
|
|
|
};
|
|
|
|
|
|
postData.searchData[column.getRefObjCode()] = {
|
|
|
pageSize: 0,
|
|
|
pageIndex: 0,
|
|
|
totalRows: -1,
|
|
|
uiObjCode: column.getRefObjCode(),
|
|
|
queryParams: {
|
|
|
refQuery: column.getRefParam(row, value, isEdit, ignoreValue)
|
|
|
}
|
|
|
};
|
|
|
|
|
|
var result = Global.services.searchData(postData);
|
|
|
if (!result) {
|
|
|
Global.throwException(Global.MSG.NONE_REFDATA, column.refObj);
|
|
|
}
|
|
|
|
|
|
var schemaData = result[column.getRefObjCode()];
|
|
|
var refRows = schemaData ? schemaData.rows : [];
|
|
|
result = this.onGetUserRefData(row, column, refRows);
|
|
|
if (_.isArray(result) && result.length > 0) {
|
|
|
column.setRefItem(result[0], row);
|
|
|
}
|
|
|
column.setRefData(result);
|
|
|
}
|
|
|
};
|
|
|
|
|
|
DataSource.prototype.getNextId = function (dc) {
|
|
|
if (dc.dataType != Global.Enums.DataType.NUMBER) {
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
if (this._idSequence.hasOwnProperty(dc.fieldName)) {
|
|
|
if (this.rows.length == 0) {
|
|
|
this._idSequence[dc.fieldName] = 0;
|
|
|
}
|
|
|
return ++this._idSequence[dc.fieldName];
|
|
|
} else {
|
|
|
var maxNum = 0;
|
|
|
for (var i = 0; i < this.rows.length; i++) {
|
|
|
var num = parseInt(this.rows[i][dc.fieldName]) || 0;
|
|
|
if (maxNum < num) {
|
|
|
maxNum = num;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
this._idSequence[dc.fieldName] = maxNum + 1;
|
|
|
return maxNum + 1;
|
|
|
}
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 重置NextId种子,Clear方法会默认执行该方法
|
|
|
* @param {DataColumn} [dc]
|
|
|
*/
|
|
|
DataSource.prototype.resetNextId = function (dc) {
|
|
|
if (dc) {
|
|
|
if (this._idSequence.hasOwnProperty(dc.fieldName)) {
|
|
|
delete this._idSequence[dc.fieldName];
|
|
|
}
|
|
|
} else {
|
|
|
this._idSequence = {};
|
|
|
}
|
|
|
};
|
|
|
|
|
|
DataSource.prototype.isEmpty = function () {
|
|
|
for (var i = 0; i < this.rows.length; i++) {
|
|
|
var row = this.rows[i];
|
|
|
if (!row.isEmpty()) {
|
|
|
return false;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
return true;
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 更新父数据
|
|
|
* @param col 明细列
|
|
|
*/
|
|
|
DataSource.prototype.updateParent = function (col) {
|
|
|
var parentRlt = this.getParentRelation();
|
|
|
if (parentRlt) {
|
|
|
parentRlt.aggregateDetail(col);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
/****当前行操作-开始****/
|
|
|
|
|
|
/**
|
|
|
* 设置当前行,引起行变换事件
|
|
|
* @param {Object} row DataRow,也可以为数字,指行在当前数据源中的位置
|
|
|
*/
|
|
|
DataSource.prototype.setCurrentRow = function (row) {
|
|
|
if (this._isOpened) {
|
|
|
if (typeof row === 'number') {
|
|
|
row = this.rows[row];
|
|
|
}
|
|
|
|
|
|
var oldRow = this.currentRow;
|
|
|
this.currentRow = row === undefined ? null : row;
|
|
|
if (oldRow !== row) {
|
|
|
this.onCurrentChanged(row, oldRow);
|
|
|
}
|
|
|
}
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 求列和
|
|
|
* @param {[type]} col [列]
|
|
|
* @param {[type]} start [开始位置]
|
|
|
* @param {[type]} end [终止位置]
|
|
|
* @return {[type]} [列值之和]
|
|
|
*/
|
|
|
DataSource.prototype.sumColValue = function (col, start, end) {
|
|
|
var sum = 0;
|
|
|
var i = null;
|
|
|
if (typeof col === 'string') {
|
|
|
col = this.getColumn(col);
|
|
|
}
|
|
|
|
|
|
if (col.isDataColumn && col.dataType == Global.Enums.DataType.NUMBER) {
|
|
|
for (i = start; i <= end; i++) {
|
|
|
if (this.rows.length > 0) {
|
|
|
if (!this.rows[i]) continue;
|
|
|
sum = BigNumber.add(sum, parseFloat(this.rows[i][col.fieldName]) || 0);
|
|
|
}
|
|
|
}
|
|
|
sum = sum.toFixed(parseInt(col.dispScale));
|
|
|
} else {
|
|
|
sum = '';
|
|
|
}
|
|
|
return sum;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 求平均值
|
|
|
* @param {[type]} col [列]
|
|
|
* @param {[type]} start [开始位置]
|
|
|
* @param {[type]} end [终止位置]
|
|
|
* @return {[type]} [列值之平均值]
|
|
|
*/
|
|
|
DataSource.prototype.averageColValue = function (col, start, end) {
|
|
|
var average = null;
|
|
|
var sum = null;
|
|
|
if (typeof col === 'string') {
|
|
|
col = this.getColumn(col);
|
|
|
}
|
|
|
if (col.isDataColumn && col.dataType == Global.Enums.DataType.NUMBER) {
|
|
|
sum = this.sumColValue(col, start, end);
|
|
|
if (sum === '') {
|
|
|
average = '';
|
|
|
} else {
|
|
|
average = (sum / (end - start + 1)).toFixed(parseInt(col.dispScale));
|
|
|
}
|
|
|
} else {
|
|
|
average = '';
|
|
|
}
|
|
|
return average;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 获取特定范围内列的最大值
|
|
|
* @param {[type]} col [列]
|
|
|
* @param {[type]} start [开始位置]
|
|
|
* @param {[type]} end [终止位置]
|
|
|
* @return {[type]} [列最大值]
|
|
|
*/
|
|
|
DataSource.prototype.getColMaxValue = function (col, start, end) {
|
|
|
var max = 0;
|
|
|
var i = null;
|
|
|
if (typeof col === 'string') {
|
|
|
col = this.getColumn(col);
|
|
|
}
|
|
|
if (col.isDataColumn && col.dataType == Global.Enums.DataType.NUMBER) {
|
|
|
for (i = start; i <= end; i++) {
|
|
|
if (!this.rows[i]) continue;
|
|
|
var _temp = parseFloat(this.rows[i][col.fieldName]) || 0;
|
|
|
max = max >= _temp ? max : _temp;
|
|
|
}
|
|
|
} else {
|
|
|
max = '';
|
|
|
}
|
|
|
return max;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 获取特定范围内列的最小值
|
|
|
* @param {[type]} col [列]
|
|
|
* @param {[type]} start [开始位置]
|
|
|
* @param {[type]} end [终止位置]
|
|
|
* @return {[type]} [列最小值]
|
|
|
*/
|
|
|
DataSource.prototype.getColMinValue = function (col, start, end) {
|
|
|
var min = 0;
|
|
|
var i = null;
|
|
|
if (typeof col === 'string') {
|
|
|
col = this.getColumn(col);
|
|
|
}
|
|
|
if (col.isDataColumn && col.dataType == Global.Enums.DataType.NUMBER) {
|
|
|
for (i = start; i <= end; i++) {
|
|
|
if (!this.rows[i]) continue;
|
|
|
var _temp = parseFloat(this.rows[i][col.fieldName]) || 0;
|
|
|
min = min <= _temp ? min : _temp;
|
|
|
}
|
|
|
} else {
|
|
|
min = '';
|
|
|
}
|
|
|
return min;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 移动到指定位置
|
|
|
* @param {Number} position 行位置
|
|
|
* @return {[type]} [description]
|
|
|
*/
|
|
|
DataSource.prototype.moveTo = function (position) {
|
|
|
if (this.dataView) {
|
|
|
this.dataView.moveTo(position);
|
|
|
} else {
|
|
|
var row = this.rows[position];
|
|
|
row = row == undefined ? null : row;
|
|
|
this.setCurrentRow(row);
|
|
|
}
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 向下移动一行
|
|
|
* @return {[type]} [description]
|
|
|
*/
|
|
|
DataSource.prototype.moveToNext = function () {
|
|
|
var position = this.rows.indexOf(this.currentRow);
|
|
|
position++;
|
|
|
if (position >= this.rows.length) {
|
|
|
position = this.rows.length;
|
|
|
}
|
|
|
|
|
|
if (position < 0) {
|
|
|
position = 0;
|
|
|
}
|
|
|
|
|
|
this.moveTo(position);
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 向上移动一行
|
|
|
* @return {[type]} [description]
|
|
|
*/
|
|
|
DataSource.prototype.moveToPrev = function () {
|
|
|
var position = this.rows.indexOf(this.currentRow);
|
|
|
position--;
|
|
|
this.moveTo(position < 0 ? 0 : position);
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 移动到首行
|
|
|
* @return {[type]} [description]
|
|
|
*/
|
|
|
DataSource.prototype.moveToFirst = function () {
|
|
|
this.moveTo(0);
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 移动到最后一行
|
|
|
* @return {[type]} [description]
|
|
|
*/
|
|
|
DataSource.prototype.moveToLast = function () {
|
|
|
this.moveTo(this.rows.length - 1);
|
|
|
};
|
|
|
|
|
|
DataSource.prototype.beforeAddFirstRow = function () {
|
|
|
if (this.rows.length > 0) {
|
|
|
return true
|
|
|
}
|
|
|
|
|
|
return this.onBeforeAddFirstRow()
|
|
|
}
|
|
|
|
|
|
/****当前行操作-结束****/
|
|
|
|
|
|
/****事件-开始****/
|
|
|
|
|
|
DataSource.prototype.onBeforeAddFirstRow = function () {
|
|
|
var args = {
|
|
|
cancel: false
|
|
|
}
|
|
|
|
|
|
this.fire('onBeforeAddFirstRow', args)
|
|
|
return !args.cancel
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 获取某行某列的精度
|
|
|
* @param dr
|
|
|
* @param dc
|
|
|
*/
|
|
|
DataSource.prototype.onGetPrecision = function (dr, dc) {
|
|
|
var args = {
|
|
|
row: dr,
|
|
|
col: dc,
|
|
|
precision: dc.dataDec
|
|
|
};
|
|
|
this.fire('onGetPrecision', args);
|
|
|
return args.precision;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 数据发生变化事件
|
|
|
* @param {[type]} row [description]
|
|
|
* @param {[type]} col [description]
|
|
|
* @return {[type]} [description]
|
|
|
*/
|
|
|
DataSource.prototype.onFieldChanged = function (row, col) {
|
|
|
var args = {
|
|
|
row: row,
|
|
|
col: col,
|
|
|
valid: true,
|
|
|
err: ''
|
|
|
}
|
|
|
this.fire('onFieldChanged', args);
|
|
|
return args;
|
|
|
};
|
|
|
|
|
|
DataSource.prototype.onBeforeSearch = function () {
|
|
|
var params = {
|
|
|
isCancel: false
|
|
|
}
|
|
|
this.fire('onBeforeSearch', params);
|
|
|
return !params.isCancel;
|
|
|
};
|
|
|
|
|
|
DataSource.prototype.onGetQueryParams = function (params) {
|
|
|
this.fire('onGetQueryParams', params);
|
|
|
return params;
|
|
|
};
|
|
|
|
|
|
DataSource.prototype.onCollectChanged = function (type, dr) {
|
|
|
this.fire('onCollectChanged', {
|
|
|
action: type,
|
|
|
row: dr
|
|
|
});
|
|
|
};
|
|
|
|
|
|
DataSource.prototype.onGetColumnFormatter = function (dc, fmt) {
|
|
|
var args = {
|
|
|
col: dc,
|
|
|
formatter: fmt
|
|
|
};
|
|
|
this.fire('onGetColumnFormatter', args);
|
|
|
return args.formatter;
|
|
|
};
|
|
|
|
|
|
DataSource.prototype.onUserRefDlg = function (args) {
|
|
|
this.fire('onUserRefDlg', args);
|
|
|
};
|
|
|
|
|
|
DataSource.prototype.onUserMultiRefDlg = function (args) {
|
|
|
this.fire('onUserMultiRefDlg', args);
|
|
|
};
|
|
|
|
|
|
DataSource.prototype.onGetUserRefColumnWhere = function (dr, dc, isEdit) {
|
|
|
var args = {
|
|
|
row: dr,
|
|
|
col: dc,
|
|
|
isEdit: isEdit,
|
|
|
where: {}
|
|
|
};
|
|
|
this.fire('onGetUserRefColumnWhere', args);
|
|
|
return args.where;
|
|
|
};
|
|
|
|
|
|
DataSource.prototype.onGetRowFormatter = function (dr, dc) {
|
|
|
var args = {
|
|
|
row: dr,
|
|
|
col: dc,
|
|
|
formatter: null
|
|
|
};
|
|
|
this.fire('onGetRowFormatter', args);
|
|
|
return args.formatter
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 获取类型错误信息
|
|
|
* @param {DataRow} dr
|
|
|
* @param {DataColumn} dc
|
|
|
* @returns {*}
|
|
|
*/
|
|
|
DataSource.prototype.onGetDataTypeErr = function (dr, dc, err) {
|
|
|
var args = {
|
|
|
row: dr,
|
|
|
col: dc,
|
|
|
err: err
|
|
|
};
|
|
|
this.fire('onGetDataTypeErr', args);
|
|
|
return args.err;
|
|
|
};
|
|
|
|
|
|
DataSource.prototype.onGetDataWidthErr = function (dr, dc, err) {
|
|
|
var args = {
|
|
|
row: dr,
|
|
|
col: dc,
|
|
|
err: err
|
|
|
};
|
|
|
this.fire('onGetDataWidthErr', args);
|
|
|
return args.err;
|
|
|
};
|
|
|
|
|
|
DataSource.prototype.onGetDataRuleErr = function (dr, dc, err) {
|
|
|
var args = {
|
|
|
row: dr,
|
|
|
col: dc,
|
|
|
err: err
|
|
|
};
|
|
|
this.fire('onGetDataRuleErr', args);
|
|
|
return args.err;
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 属性改变通知
|
|
|
* @param {string} property 属性名称
|
|
|
* @return {undefined}
|
|
|
*/
|
|
|
DataSource.prototype.onPropertyChanged = function (property) {
|
|
|
this.fire('onPropertyChanged', {
|
|
|
propertyName: property
|
|
|
});
|
|
|
};
|
|
|
|
|
|
DataSource.prototype.onGetMultiMsg = function (dr) {
|
|
|
var args = {
|
|
|
row: dr,
|
|
|
err: this.multiMsg
|
|
|
};
|
|
|
this.fire('onGetMultiMsg', args);
|
|
|
return args.err;
|
|
|
};
|
|
|
|
|
|
DataSource.prototype.onGetDataStrictErr = function (dr, dc, err) {
|
|
|
var args = {
|
|
|
row: dr,
|
|
|
col: dc,
|
|
|
err: err
|
|
|
};
|
|
|
this.fire('onGetDataStrictErr', args);
|
|
|
return args.err;
|
|
|
};
|
|
|
|
|
|
DataSource.prototype.getFieldReadOnly = function (dr, dc) {
|
|
|
var args = {
|
|
|
row: dr,
|
|
|
col: dc,
|
|
|
readOnly: dc.getReadOnly()
|
|
|
};
|
|
|
|
|
|
if (!args.readOnly &&
|
|
|
this._parentRelation &&
|
|
|
this._parentRelation.detailColumns.indexOf(dc.fieldName) > -1) {
|
|
|
args.readOnly = true;
|
|
|
}
|
|
|
|
|
|
if (!args.readOnly &&
|
|
|
this.isMaster &&
|
|
|
dc.isPrimaryKey &&
|
|
|
dr.dataRowState != Global.Enums.DataRowState.ADDED) {
|
|
|
args.readOnly = true;
|
|
|
}
|
|
|
|
|
|
this.fire('onGetFieldReadOnly', args);
|
|
|
return args.readOnly;
|
|
|
};
|
|
|
|
|
|
DataSource.prototype.onGetContextMenus = function (source) {
|
|
|
var args = {
|
|
|
source: source,
|
|
|
items: []
|
|
|
};
|
|
|
this.fire('onGetContextMenus', args);
|
|
|
return args.items;
|
|
|
};
|
|
|
|
|
|
DataSource.prototype.onGetPrintVariables = function () {
|
|
|
var args = {
|
|
|
variables: {}
|
|
|
};
|
|
|
this.fire('onGetPrintVariables', args);
|
|
|
return args.variables;
|
|
|
};
|
|
|
|
|
|
DataSource.prototype.onBeforeDataSrcLoadData = function (data) {
|
|
|
this.fire('onBeforeDataSrcLoadData', {
|
|
|
data: data
|
|
|
});
|
|
|
};
|
|
|
|
|
|
DataSource.prototype.onAfterDataSrcLoadData = function (result) {
|
|
|
this.fire('onAfterDataSrcLoadData', {
|
|
|
result: result
|
|
|
});
|
|
|
};
|
|
|
|
|
|
DataSource.prototype.onSetStoredProcParas = function () {
|
|
|
this.fire('onSetStoredProcParas', {});
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 删除行前询问
|
|
|
* @param dr 删除行
|
|
|
* @return {bool}
|
|
|
*/
|
|
|
DataSource.prototype.onRowDeleting = function (dr, needConfirm, fn) {
|
|
|
var self = this;
|
|
|
var del = function () {
|
|
|
//删除前询问
|
|
|
var args = {
|
|
|
dataSrc: this,
|
|
|
row: dr,
|
|
|
isCancel: false
|
|
|
};
|
|
|
self.fire('onRowDeleting', args);
|
|
|
if (!args.isCancel) {
|
|
|
fn();
|
|
|
}
|
|
|
};
|
|
|
|
|
|
if (needConfirm) {
|
|
|
Global.messager.confirm(Global.MSG.DELETE_CONFIRM, function (r) {
|
|
|
if (r) del();
|
|
|
|
|
|
});
|
|
|
} else {
|
|
|
del();
|
|
|
}
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 删除行后处理
|
|
|
* @param dr 删除行
|
|
|
* @return
|
|
|
*/
|
|
|
DataSource.prototype.onRowDeleted = function (dr) {
|
|
|
//删除后通知
|
|
|
this.fire('onRowDeleted', {
|
|
|
dataSrc: this,
|
|
|
row: dr
|
|
|
});
|
|
|
};
|
|
|
|
|
|
DataSource.prototype.onUpdateValue = function (dr, col) {
|
|
|
this.fire('onUpdateValue', {
|
|
|
row: dr,
|
|
|
col: col
|
|
|
})
|
|
|
};
|
|
|
|
|
|
DataSource.prototype.onDataColumnValidate = function (dr, dc, value) {
|
|
|
//自定义校验
|
|
|
var args = {
|
|
|
row: dr,
|
|
|
col: dc,
|
|
|
value: value,
|
|
|
isCancel: false
|
|
|
};
|
|
|
this.fire('onDataColumnValidate', args);
|
|
|
return !args.isCancel;
|
|
|
};
|
|
|
|
|
|
|
|
|
// 多选查询自定义校验
|
|
|
DataSource.prototype.onQueryDataColumnValidate = function (dc, value) {
|
|
|
//自定义校验
|
|
|
var args = {
|
|
|
col: dc,
|
|
|
value: value,
|
|
|
isCancel: false
|
|
|
};
|
|
|
this.fire('onQueryDataColumnValidate', args);
|
|
|
return !args.isCancel;
|
|
|
};
|
|
|
|
|
|
DataSource.prototype.onDataRowValidate = function (dr, error) {
|
|
|
//业务类校验
|
|
|
var args = {
|
|
|
row: dr,
|
|
|
isCancel: false,
|
|
|
msg: ''
|
|
|
};
|
|
|
this.fire('onDataRowValidate', args);
|
|
|
if (args.isCancel) {
|
|
|
error(args.msg);
|
|
|
}
|
|
|
return !args.isCancel;
|
|
|
};
|
|
|
|
|
|
DataSource.prototype.onGetUserRefData = function (row, column, data) {
|
|
|
var args = {
|
|
|
row: row,
|
|
|
col: column,
|
|
|
result: data
|
|
|
};
|
|
|
this.fire('onGetUserRefData', args);
|
|
|
return args.result;
|
|
|
};
|
|
|
|
|
|
DataSource.prototype.onRowAdded = function (dr) {
|
|
|
this.fire('onRowAdded', {
|
|
|
dataSrc: this,
|
|
|
row: dr
|
|
|
});
|
|
|
};
|
|
|
|
|
|
DataSource.prototype.onRowRemoved = function (dr) {
|
|
|
var args = {
|
|
|
dataSrc: this,
|
|
|
row: dr
|
|
|
};
|
|
|
this.fire('onRowRemoved', args);
|
|
|
};
|
|
|
|
|
|
DataSource.prototype.onCommitEdit = function() {
|
|
|
var args = {
|
|
|
isCancel: false
|
|
|
};
|
|
|
this.fire('commitEdit', args);
|
|
|
return !args.isCancel;
|
|
|
}
|
|
|
|
|
|
DataSource.prototype.onBeforeDataSrcSave = function () {
|
|
|
//保存前操作
|
|
|
var args = {
|
|
|
isCancel: false
|
|
|
};
|
|
|
this.fire('onBeforeDataSrcSave', args);
|
|
|
return !args.isCancel;
|
|
|
};
|
|
|
|
|
|
//提交所有的行并移除空行
|
|
|
DataSource.prototype.commitAndRemoveEmptyRow = function () {
|
|
|
var args = {
|
|
|
isCancel: false
|
|
|
};
|
|
|
this.fire('onBeforeDataSrcSave', args);
|
|
|
if (args.isCancel) {
|
|
|
return false;
|
|
|
}
|
|
|
var details = this.getDetails();
|
|
|
for (var i = 0; i < details.length; i++) {
|
|
|
args.isCancel = false;
|
|
|
details[i].fire('onBeforeDataSrcSave', args);
|
|
|
if (args.isCancel) {
|
|
|
return false;
|
|
|
}
|
|
|
}
|
|
|
return true;
|
|
|
};
|
|
|
|
|
|
DataSource.prototype.onAfterDataSrcSave = function (result) {
|
|
|
this.fire('onAfterDataSrcSave', {
|
|
|
result: result
|
|
|
});
|
|
|
};
|
|
|
|
|
|
DataSource.prototype.onCleared = function () {
|
|
|
this.fire('onCleared');
|
|
|
};
|
|
|
|
|
|
|
|
|
DataSource.prototype.onGetDefaultValue = function (dr, col, dfValue) {
|
|
|
var args = {
|
|
|
row: dr,
|
|
|
col: col,
|
|
|
value: dfValue
|
|
|
};
|
|
|
this.fire('onGetDefaultValue', args);
|
|
|
return args.value;
|
|
|
};
|
|
|
|
|
|
DataSource.prototype.onCurrentChanged = function (row, oldRow) {
|
|
|
var args = {
|
|
|
dataSrc: this,
|
|
|
oldRow: oldRow,
|
|
|
newRow: row
|
|
|
};
|
|
|
this.fire('onCurrentChanged', args);
|
|
|
};
|
|
|
|
|
|
DataSource.prototype.onValueChanged = function (dr, dc) {
|
|
|
var args = {
|
|
|
row: dr,
|
|
|
col: dc
|
|
|
};
|
|
|
this.fire('onValueChanged', args);
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/****事件-结束****/
|
|
|
|
|
|
win.DataSource = DataSource;
|
|
|
})(window);
|