package foundation.version; import java.util.Date; import foundation.action.ActionProvider; import foundation.action.WorkflowDispatcher; import foundation.dao.Filter; import foundation.dao.OrderBy; import foundation.data.entity.Entity; import foundation.data.entity.EntitySet; import foundation.data.meta.field.FieldsRuntime; import foundation.data.object.DataObject; import foundation.data.object.EntitySaver; import foundation.persist.NamedSQL; import foundation.persist.SQLRunner; import foundation.util.DateTimeUtil; import foundation.util.ID; import foundation.util.MapList; import foundation.util.Util; public class VersionCenter extends ActionProvider{ private VersionBucket versionBucket; public VersionCenter() { versionBucket = VersionBucket.getInstance(); } @Override protected void publishMethod() { //1. 激活版本 addMethod("activateVersion"); //2. 封版 addMethod("lockedVersion"); //3. 历史转暂存 addMethod("historyToPreparatory"); } public void exec() throws Exception { String methodName = step.getActionName(); if("toActive".equalsIgnoreCase(methodName)) { toActive(); } else if("toHistory".equalsIgnoreCase(methodName)) { toHistory(); } else if("toPreparatory".equalsIgnoreCase(methodName)) { toPreparatory(); } } public boolean isVersionActive(String key) { int pos = key.indexOf("."); if (pos < 0 ) { return false; } String code = key.substring(0, pos); String dataName = key.substring(pos + 1); MapList metaList = versionBucket.get(code); VersionMeta meta = metaList.get(dataName); if (meta == null) { return false; } return meta.isVersionActive(); } public VersionIndex getIndex(String groupCode, String versionCode, String stateCode, boolean fromRequest) throws Exception { VersionState versionState = VersionState.parse(stateCode); VersionState nextVersion = versionState.getNextState(); MapList metas = versionBucket.get(groupCode); VersionMeta masterMeta = versionBucket.getMasterMeta(groupCode); int currntNo = masterMeta.getVersionSequence(); if (metas == null || metas.size() == 0 ) { return null; } DataObject dataObject = DataObject.getInstance("sys_version_log"); Filter filter = new Filter("group_code", groupCode); if (!Util.isEmpty(versionCode)) { filter.add("version_code", versionCode); } if (!Util.isEmpty(stateCode)) { filter.add("state_code", stateCode); } Entity entity = dataObject.getTableEntity(filter); String logId = ID.newValue(); if (entity == null) { //1. 获取临时版本号 VersionCode version = new VersionCode(masterMeta.getName(), currntNo); int versionNo = version.nextStandardValue(); versionCode = version.getCode(); //2. 保存版本日志到数据库 entity = dataObject.createTableEntity(false); entity.setId(logId); entity.set("version_no", versionNo); entity.set("version_code", versionCode); entity.set("group_code", groupCode); entity.set("state_code", versionState.name()); entity.set("state_name", versionState.getName()); entity.set("last_update_time", new Date()); if (nextVersion == VersionState.History) { entity.set("month_valid_to", new Date()); entity.set("valid_to", new Date()); } dataObject.insertEntity(entity); }else { logId = entity.getId(); if (VersionState.Active == versionState){ // 3.1 封版 if(fromRequest) { entity.set("month_valid_to", new Date()); entity.set("valid_to", new Date()); } else { String monthValidTo = DateTimeUtil.addDays(Util.newDateStr(), -1); entity.set("month_valid_to", monthValidTo); entity.set("valid_to", monthValidTo); } entity.set("is_using", "F"); entity.set("state_code", nextVersion.name()); entity.set("state_name", nextVersion.getName()); dataObject.updateEntity(entity); VersionIndex result = getIndex(groupCode, versionCode, VersionState.Preparing.name(), fromRequest); }else if (VersionState.Preparing == versionState){ // 3.2 生效 String nextVersionBegin = getNextVersionBegin(groupCode); String year = DateTimeUtil.getYear(nextVersionBegin); String month = DateTimeUtil.getMonth(nextVersionBegin, true); entity.set("year", year); entity.set("season", DateTimeUtil.getSeason(nextVersionBegin)); entity.set("month", month); entity.set("monthly", year + month); entity.set("month_valid_from", nextVersionBegin); entity.set("valid_from", nextVersionBegin); entity.set("is_using", "T"); entity.set("state_code", nextVersion.name()); entity.set("state_name", nextVersion.getName()); dataObject.updateEntity(entity); //4.更新版本序列号 int currentNo = entity.getInt("version_no"); masterMeta.setVersionSequence(currentNo); for(VersionMeta meta: metas) { meta.setVersionSequence(currentNo); } updateVersionSequence(groupCode, currentNo); VersionIndex result = getIndex(groupCode, versionCode, VersionState.Preparing.name(), fromRequest); } } VersionIndex result = new VersionIndex(logId, versionCode, metas, masterMeta); result.load(entity); return result; } private void updateVersionSequence(String groupCode, int currentNo) throws Exception { NamedSQL namedSQL = NamedSQL.getInstance("updateVersionSequence"); namedSQL.setParam("versionSequence", currentNo); namedSQL.setParam("code", groupCode); namedSQL.execute(); } public void activateVersion() throws Exception { String groupCode = null; if (dataReader != null) { groupCode = dataReader.getString("group_code"); } else if(context != null) { groupCode = context.getParam(); } VersionStep workStep = new VersionStep(groupCode, "toActive", this); WorkflowDispatcher dispatcher = WorkflowDispatcher.getInstance(); dispatcher.execWorkflow(dataReader, dataWriter, workStep, context); } public void toActive() throws Exception { String groupCode = null; if (dataReader != null) { groupCode = dataReader.getString("group_code"); } else if(context != null) { groupCode = context.getParam(); } DataObject logDataObject = DataObject.getInstance("sys_version_log"); Filter activeFilter = new Filter("state_code", VersionState.Active.name()); activeFilter = activeFilter.add("monthly", Util.DataTimeToString(new Date(), Util.MONTHLYFORMAT)); Entity entity = logDataObject.getTableEntity(activeFilter); String logId = entity.getId(); String versionCode = entity.getString("version_code"); logDataObject = DataObject.getInstance("sys_version_log_detail"); EntitySaver saver; //2. 得到 code 的 next value MapList metas = versionBucket.get(groupCode); NamedSQL namedSQL = NamedSQL.getInstance("versionDataCopy"); SQLRunner.beginTrans(); try { //3. 《预备表》搬运数据至《生效表》 for (VersionMeta meta : metas) { //3.1 清空生效表 String activeTable = meta.getDataName(); String preparatoryTable = meta.getPreparatoryDataName(); Filter filter = new Filter(); filter.add(meta.getFilter()); DataObject dataObject = DataObject.getInstance(activeTable); int operatorCount = dataObject.deleteEntity(filter); logger.info("1.清空 [{}]表暂存总计 {} 条", preparatoryTable, operatorCount); //3.1 获取表执行字段 DataObject preparatoryDataObject = DataObject.getInstance(preparatoryTable); FieldsRuntime fromFields = preparatoryDataObject.getTableFieldMetas(); FieldMappingCreator mappingCreator = FieldMappingCreator.createMapping(fromFields, "PreparatoryToActive", null); namedSQL.setTableName(activeTable); namedSQL.setParam("toFieldNames", mappingCreator.getToFields()); namedSQL.setParam("fromFieldNames", mappingCreator.getFromFields()); namedSQL.setParam("fromTableName", preparatoryTable); namedSQL.setFilter(meta.getFilter()); int recordCount = namedSQL.execute(); //3.2 保存生效明细日志 saver = logDataObject.createEntitySaver(); saver.set("id", ID.newValue()); saver.set("parent_id", logId); saver.set("dataName", activeTable); saver.set("dataName", meta.getDataNameType()); saver.set("record_count", recordCount); saver.insert(); } }catch (Exception e) { logger.info("{}:《预备表》搬运数据至《生效表》失败", groupCode); SQLRunner.rollback(); e.printStackTrace(); } SQLRunner.commit(); if (dataWriter != null) { dataWriter.reportOneMessage("activateVersion", "新版本" + versionCode + "已生效"); } } public void lockedVersion() throws Exception { String groupCode = null; if (dataReader != null) { groupCode = dataReader.getString("group_code"); } else if(context != null) { groupCode = context.getParam(); } VersionStep workStep = new VersionStep(groupCode, "toHistory", this); WorkflowDispatcher dispatcher = WorkflowDispatcher.getInstance(); dispatcher.execWorkflow(dataReader, dataWriter, workStep, context); } public void toHistory() throws Exception { boolean fromRequest = true; String groupCode= null; if (dataReader != null) { groupCode = dataReader.getString("group_code"); fromRequest = true; } else if(context != null) { groupCode = context.getParam(); fromRequest = false; } //1. 获取当前版本 Entity currentVersion = getCurrentVersion(groupCode); String logId = currentVersion.getId(); String versionCode = currentVersion.getString("version_code"); //2. 《正式表》搬运数据至《历史表》 MapList metas = versionBucket.get(groupCode); NamedSQL namedSQL = NamedSQL.getInstance("versionDataCopy"); DataObject logDataObject = DataObject.getInstance("sys_version_log_detail"); for (VersionMeta meta : metas) { String historyTable = meta.getHistoryDataName(); String activeTable = meta.getDataName(); //3.1 获取表执行字段 DataObject activeDataObject = DataObject.getInstance(activeTable); FieldsRuntime fromFields = activeDataObject.getTableFieldMetas(); FieldMappingCreator mappingCreator = FieldMappingCreator.createMapping(fromFields, "ActiveToHistory", versionCode); namedSQL.setTableName(historyTable); namedSQL.setParam("toFieldNames", mappingCreator.getToFields()); namedSQL.setParam("fromFieldNames", mappingCreator.getFromFields()); namedSQL.setParam("fromTableName", activeTable); namedSQL.setFilter(meta.getFilter()); int operatorCount = namedSQL.execute(); logger.info("[{}]--->[{}] {} 条", activeTable, historyTable, operatorCount); //3.2 保存历史版本明细日志 Filter filter = new Filter("parent_id", logId).add("dataname", activeTable); Entity entity = logDataObject.getTableEntity(filter); if (entity == null) { entity = logDataObject.createTableEmptyEntity(); entity.setId(ID.newValue()); entity.set("parent_id",logId); entity.set("dataname",meta.getDataName()); entity.set("dataname_type",meta.getDataNameType()); entity.set("active_record_count",operatorCount); entity.set("active_record_count",operatorCount); entity.set("history_record_count", operatorCount); logDataObject.insertEntity(entity); } else { entity.set("history_record_count", operatorCount); logDataObject.updateEntity(entity); } } //3. 更新版本,记录日志 VersionIndex index = getIndex(groupCode, null, VersionState.Active.name(), fromRequest); if(dataWriter != null) { dataWriter.reportOneMessage("lockedVersion", index.getGroupName() + "已生成版本" + versionCode); } else { logger.info(index.getGroupName() + "已生成版本" + versionCode); } } private Entity getCurrentVersion(String groupCode) throws Exception { DataObject dataObject = DataObject.getInstance("sys_version_log"); Filter filter = new Filter("group_code", groupCode); filter.add("state_code", VersionState.Active.name()); filter.add("is_using", "T"); return dataObject.getTableEntity(filter); } public void historyToPreparatory() throws Exception { String groupCode = null; if (dataReader != null) { groupCode = dataReader.getString("group_code"); } else if(context != null) { groupCode = context.getParam(); } VersionStep workStep = new VersionStep(groupCode, "toPreparatory", this); WorkflowDispatcher dispatcher = WorkflowDispatcher.getInstance(); dispatcher.execWorkflow(dataReader, dataWriter, workStep, context); } public void toPreparatory() throws Exception { String groupCode = dataReader.getString("group_code"); String version = dataReader.getString("version_code"); NamedSQL namedSQL = NamedSQL.getInstance("versionDataCopy"); DataObject dataObject; logger.info("{}, 《版本{}》搬运至《预设表》 开始......", groupCode, version); SQLRunner.beginTrans(); try { MapList metas = versionBucket.get(groupCode); for (VersionMeta meta : metas) { String historyTable = meta.getHistoryDataName(); String preparatoryTable = meta.getPreparatoryDataName(); Filter filter = new Filter(); filter.add(meta.getFilter()); dataObject = DataObject.getInstance(preparatoryTable); int operatorCount = dataObject.deleteEntity(filter); logger.info("1.清空 [{}]表暂存总计 {} 条", preparatoryTable, operatorCount); dataObject = DataObject.getInstance(historyTable); FieldsRuntime fromFields = dataObject.getTableFieldMetas(); FieldMappingCreator mappingCreator = FieldMappingCreator.createMapping(fromFields, "HistoryToPreparatory", null); namedSQL.setTableName(preparatoryTable); namedSQL.setParam("toFieldNames", mappingCreator.getToFields()); namedSQL.setParam("fromFieldNames", mappingCreator.getFromFields()); namedSQL.setParam("fromTableName", historyTable); filter.add("version_code", version); namedSQL.setFilter(filter); operatorCount = namedSQL.execute(); logger.info("2.[{}]--->[{}] {} 条", historyTable, preparatoryTable, operatorCount); } }catch (Exception e) { logger.info("{}, 《版本{}》搬运至《预设表》 失败", groupCode, version); SQLRunner.rollback(); e.printStackTrace(); } SQLRunner.commit(); logger.info("{}搬运至《预设表》完成", groupCode); } private String getNextVersionBegin(String groupCode) throws Exception { DataObject dataObject = DataObject.getInstance("sys_version_log"); Filter activeFilter = new Filter("group_code", groupCode).add("state_code", "!=", Util.quotedStr(VersionState.Preparing.name())); EntitySet activeVersionSet = dataObject.getTableEntitySet(activeFilter, new OrderBy("valid_from desc, valid_to desc")); if (activeVersionSet.size() == 0) { return DateTimeUtil.addDays(Util.getDateTimeStr(new Date(), Util.NORMALFORMAT), 1); } Entity activeVersion = activeVersionSet.getEntity(0); //1. 取当前生效版本的失效日期 Date date = activeVersion.getDate("valid_to"); if (date != null) { return DateTimeUtil.addDays(Util.getDateTimeStr(date, Util.NORMALFORMAT), 1); } //2. 取当前生效版本的本月失效时间(失效大于月底) date = activeVersion.getDate("month_valid_to"); if (date != null) { return DateTimeUtil.addDays(Util.getDateTimeStr(date, Util.NORMALFORMAT), 1); } //2. 取当前生效版本的本月失生效效时间(失效大于月底) date = activeVersion.getDate("month_valid_from"); return DateTimeUtil.addDays(Util.getDateTimeStr(date, Util.NORMALFORMAT), 1); } }