package jnpf.onlinedev.service.impl; import cn.hutool.core.bean.BeanUtil; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import jnpf.base.entity.VisualdevReleaseEntity; import jnpf.base.model.VisualLogModel; import jnpf.base.service.SuperServiceImpl; import jnpf.base.service.VisualdevReleaseService; import jnpf.constant.JnpfConst; import jnpf.event.ProjectEventListener; import jnpf.model.visualJson.FieLdsModel; import jnpf.model.visualJson.FormDataModel; import jnpf.model.visualJson.TableFields; import jnpf.model.visualJson.TableModel; import jnpf.model.visualJson.config.ConfigModel; import jnpf.module.ProjectEventBuilder; import jnpf.module.ProjectEventInstance; import jnpf.onlinedev.entity.VisualLogEntity; import jnpf.onlinedev.mapper.VisualLogMapper; import jnpf.onlinedev.model.OnlineDevEnum.OnlineDataTypeEnum; import jnpf.onlinedev.model.log.VisualLogForm; import jnpf.onlinedev.model.log.VisualLogPage; import jnpf.onlinedev.service.VisualLogService; import jnpf.onlinedev.util.onlineDevUtil.OnlinePublicUtils; import jnpf.onlinedev.util.onlineDevUtil.OnlineSwapDataUtils; import jnpf.util.JsonUtil; import jnpf.util.PublishEventUtil; import jnpf.util.TableFeildsEnum; import jnpf.util.visiual.JnpfKeyConsts; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.collections4.MapUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.*; import java.util.stream.Collectors; /** * 数据日志实现 * * @author JNPF开发平台组 * @version v5.1.0 * @copyright 引迈信息技术有限公司 * @date 2024/8/27 18:24:42 */ @Service public class VisualLogServiceImpl extends SuperServiceImpl implements VisualLogService { @Autowired private VisualdevReleaseService visualdevReleaseService; @Autowired private OnlineSwapDataUtils onlineSwapDataUtils; /** * 创建日志事件 * * @param form 数据id */ @Override public void createEventLog(VisualLogForm form) { PublishEventUtil.publishLocalEvent(new ProjectEventBuilder(JnpfConst.VSLOG_EVENT_KEY, form)); } @Override public List getList(VisualLogPage pagination) { QueryWrapper queryWrapper = new QueryWrapper<>(); queryWrapper.lambda().eq(VisualLogEntity::getModelId, pagination.getModelId()); queryWrapper.lambda().eq(VisualLogEntity::getDataId, pagination.getDataId()); //排序 queryWrapper.lambda().orderByDesc(VisualLogEntity::getCreatorTime); Page page = new Page<>(pagination.getCurrentPage(), pagination.getPageSize()); IPage iPage = this.page(page, queryWrapper); return pagination.setData(iPage.getRecords(), iPage.getTotal()); } /** * 监听日志插入 * * @param redisEvent */ @ProjectEventListener(channelRegex = JnpfConst.VSLOG_EVENT_KEY + ".*") public void createLogByEvent(ProjectEventInstance redisEvent) { VisualLogForm form = (VisualLogForm) redisEvent.getSource(); VisualLogEntity visualLogEntity = new VisualLogEntity(); visualLogEntity.setType(form.getType()); visualLogEntity.setModelId(form.getModelId()); visualLogEntity.setDataId(form.getDataId()); //修改数据 if (Objects.equals(form.getType(), 1)) { List listLog = new ArrayList<>(); if (CollectionUtils.isNotEmpty(form.getListLog())) { listLog = form.getListLog(); } else { addLog(form, listLog); } visualLogEntity.setDataLog(JsonUtil.getObjectToString(listLog)); if (CollectionUtils.isNotEmpty(listLog)) { this.save(visualLogEntity); } } else { //新增数据 this.save(visualLogEntity); } } public void addLog(VisualLogForm formSource, List listLog) { VisualLogForm form = BeanUtil.copyProperties(formSource, VisualLogForm.class); VisualdevReleaseEntity visualdevEntity = visualdevReleaseService.getById(form.getModelId()); FormDataModel formData = JsonUtil.getJsonToBean(visualdevEntity.getFormData(), FormDataModel.class); List fieLdsModels = JsonUtil.getJsonToList(formData.getFields(), FieLdsModel.class); List tableModels = JsonUtil.getJsonToList(visualdevEntity.getVisualTables(), TableModel.class); List fields = new ArrayList<>(); OnlinePublicUtils.recursionFields(fields, fieLdsModels); List> swapInfoOld = onlineSwapDataUtils.getSwapInfo(new ArrayList>() {{ add(form.getOldData()); }}, fields, visualdevEntity.getId(), false, null); Map oldData = swapInfoOld.get(0); List> swapInfoNew = onlineSwapDataUtils.getSwapInfo(new ArrayList>() {{ add(form.getNewData()); }}, fields, visualdevEntity.getId(), false, null); Map newData = swapInfoNew.get(0); for (FieLdsModel item : fields) { ConfigModel config = item.getConfig(); String jnpfKey = config.getJnpfKey(); String label = config.getLabel(); String dataType = config.getDataType(); //移除系统字段 if (isSkipFields(item)) continue; if (JnpfKeyConsts.CHILD_TABLE.equals(jnpfKey)) { TableModel tableModel = tableModels.stream().filter(t -> t.getTable().equals(config.getTableName())).findFirst().orElse(null); TableFields mainField = tableModel.getFields().stream().filter(t -> Objects.equals(t.getPrimaryKey(), 1) && !t.getField().equalsIgnoreCase(TableFeildsEnum.TENANTID.getField())).findFirst().orElse(null); String mainKey = mainField.getField(); List children = item.getConfig().getChildren(); String vModel = item.getVModel(); //子表数据 List> childData = new ArrayList<>(); //子表表头 List> childField = new ArrayList<>(); for (FieLdsModel childItem : children) { String jnpfKeyChild = childItem.getConfig().getJnpfKey(); if (isSkipFields(childItem)) continue; Map childItemMap = new HashMap<>(); childItemMap.put("prop", childItem.getVModel()); childItemMap.put("label", childItem.getConfig().getLabel()); childItemMap.put("jnpfKey", jnpfKeyChild); boolean nameModified = false; if (JnpfKeyConsts.getNameModified().contains(jnpfKeyChild)) { if (JnpfKeyConsts.getNameModifiedNotDynamic().contains(jnpfKeyChild) || OnlineDataTypeEnum.DYNAMIC.getType().equals(childItem.getConfig().getDataType())) { nameModified = true; } } childItemMap.put("nameModified", nameModified); childField.add(childItemMap); } List> childOld = oldData.get(vModel) == null ? new ArrayList<>() : (List) oldData.get(vModel); List> childNew = newData.get(vModel) == null ? new ArrayList<>() : (List) newData.get(vModel); List newIds = childNew.stream().map(t -> t.get(mainKey)).collect(Collectors.toList()); List> deleteMap = childOld.stream().filter(t -> !newIds.contains(t.get(mainKey))).collect(Collectors.toList()); for (Map chilMap : deleteMap) { Map childDataMap = new HashMap<>(); for (FieLdsModel childItem : children) { String childJnpfKey = childItem.getConfig().getJnpfKey(); //移除系统字段 if (isSkipFields(childItem)) continue; String childVmodel = childItem.getVModel(); String childVmodel_old = "jnpf_old_" + childItem.getVModel(); String oldValue = getValueByType(chilMap, childVmodel, childJnpfKey); childDataMap.put(childVmodel, null); childDataMap.put(childVmodel_old, oldValue); childDataMap.put("jnpf_type", 2); } childData.add(childDataMap); } for (Map chilMap : childNew) { Object mainId = chilMap.get(mainKey); Map oldMap = childOld.stream().filter(t -> t.get(mainKey).equals(mainId)).findFirst().orElse(null); Integer jnpf_type = 1; if (oldMap == null) { jnpf_type = 0; } Map childDataMap = new HashMap<>(); boolean hasChanged = false; for (FieLdsModel childItem : children) { String childJnpfKey = childItem.getConfig().getJnpfKey(); //移除系统字段 if (isSkipFields(childItem)) continue; String childVmodel = childItem.getVModel(); String childVmodel_old = "jnpf_old_" + childItem.getVModel(); String newValue = getValueByType(chilMap, childVmodel, childJnpfKey); String oldValue = getValueByType(oldMap, childVmodel, childJnpfKey); if (!Objects.equals(newValue, oldValue)) { hasChanged = true; } childDataMap.put(childVmodel, newValue); childDataMap.put(childVmodel_old, oldValue); childDataMap.put("jnpf_type", jnpf_type); } if (hasChanged) { childData.add(childDataMap); } } if (CollectionUtils.isNotEmpty(childData)) { VisualLogModel vlogModel = new VisualLogModel(); vlogModel.setField(vModel); vlogModel.setFieldName(label); vlogModel.setJnpfKey(jnpfKey); vlogModel.setChidData(childData); vlogModel.setChidField(childField); vlogModel.setType(1); listLog.add(vlogModel); } } else { String vModel = item.getVModel(); if (!Objects.equals(oldData.get(vModel), newData.get(vModel))) { Integer actionType = 1;//0-新增,1-修改 if (oldData.get(vModel) == null || oldData.get(vModel).toString().trim().isEmpty()) { actionType = 0; } boolean nameModified = false; if (JnpfKeyConsts.getNameModified().contains(jnpfKey)) { if (JnpfKeyConsts.getNameModifiedNotDynamic().contains(jnpfKey) || OnlineDataTypeEnum.DYNAMIC.getType().equals(dataType)) { nameModified = true; } } String newValue = getValueByType(newData, vModel, jnpfKey); String oldValue = getValueByType(oldData, vModel, jnpfKey); VisualLogModel vlogModel = new VisualLogModel(); vlogModel.setField(vModel); vlogModel.setFieldName(label); vlogModel.setJnpfKey(jnpfKey); vlogModel.setNewData(newValue); vlogModel.setOldData(oldValue); vlogModel.setType(actionType); vlogModel.setNameModified(nameModified); listLog.add(vlogModel); } } } } /** * 跳过字段不处理 * * @param childItem * @return */ private boolean isSkipFields(FieLdsModel childItem) { //字段不处理直接跳过 :(JnpfKeyConsts.CALCULATE 计算公式仅展示也跳过) List skipFields = new ArrayList<>(); skipFields.addAll(JnpfKeyConsts.getSystemKey()); skipFields.add(JnpfKeyConsts.POPUPSELECT_ATTR); skipFields.add(JnpfKeyConsts.RELATIONFORM_ATTR); String jnpfKey = childItem.getConfig().getJnpfKey(); return skipFields.contains(jnpfKey) || (JnpfKeyConsts.CALCULATE.equals(jnpfKey) && Objects.equals(childItem.getIsStorage(), 0)); } private String getValueByType(Map map, String vModel, String jnpfKey) { if (map != null) { Object o = map.get(vModel); String value = o == null ? "" : o.toString(); switch (jnpfKey) { case JnpfKeyConsts.UPLOADFZ: List> listM = (List) o; if (listM != null) { StringJoiner sj = new StringJoiner(","); listM.stream().forEach(t -> sj.add(t.get("name").toString())); value = sj.toString(); } break; case JnpfKeyConsts.LOCATION: Map lcationMap = JsonUtil.stringToMap(value); if (MapUtils.isNotEmpty(lcationMap)) { value = lcationMap.get("fullAddress") != null ? lcationMap.get("fullAddress").toString() : ""; } break; default: break; } return value; } return null; } }