(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('
').replace(/\n/g, '
'); }; 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);