package com.moon.server.service.data; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.moon.server.entity.all.StaticData; import com.moon.server.entity.ctrl.DownloadReqEntity; import com.moon.server.entity.data.DownloadEntity; import com.moon.server.entity.data.MetaEntity; import com.moon.server.entity.sys.AttachEntity; import com.moon.server.entity.sys.MetaDownEntity; import com.moon.server.entity.sys.UserEntity; import com.moon.server.mapper.all.BasicMapper; import com.moon.server.mapper.all.GeomBaseMapper; import com.moon.server.mapper.data.MetaMapper; import com.moon.server.service.all.BaseQueryService; import com.moon.server.service.sys.MetaDownService; import com.moon.server.helper.*; import net.lingala.zip4j.ZipFile; import net.lingala.zip4j.model.FileHeader; import net.lingala.zip4j.model.ZipParameters; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import javax.servlet.http.HttpServletResponse; import java.io.File; import java.io.FileInputStream; import java.util.*; /** * 元数据 * @author WWW */ @Service public class MetaService implements MetaMapper { @Autowired PathHelper pathHelper; @Autowired MetaMapper metaMapper; @Autowired MetaDownService metaDownService; @Autowired DownloadService downloadService; private final static Log log = LogFactory.getLog(MetaService.class); @Override public Integer selectCount(String depcode, String dircode, Integer verid, String name) { depcode = StringHelper.getRightLike(depcode); dircode = StringHelper.getRightLike(dircode); name = StringHelper.getLikeUpperStr(name); return metaMapper.selectCount(depcode, dircode, verid, name); } @Override public List selectByPage(String depcode, String dircode, Integer verid, String name, Integer limit, Integer offset) { depcode = StringHelper.getRightLike(depcode); dircode = StringHelper.getRightLike(dircode); name = StringHelper.getLikeUpperStr(name); return metaMapper.selectByPage(depcode, dircode, verid, name, limit, offset); } @Override public List selectGdbByGuid(String guid) { return metaMapper.selectGdbByGuid(guid); } @Override public Integer selectMetasForCount(String depcode, String dirs, String name) { depcode = StringHelper.getRightLike(depcode); name = StringHelper.getLikeUpperStr(name); return metaMapper.selectMetasForCount(depcode, dirs, name); } @Override public List selectMetasForPage(String depcode, String dirs, String name, Integer limit, Integer offset) { depcode = StringHelper.getRightLike(depcode); name = StringHelper.getLikeUpperStr(name); return metaMapper.selectMetasForPage(depcode, dirs, name, limit, offset); } @Override public Integer selectCountForUpload(String name, Integer createUser, String types) { name = StringHelper.getLikeUpperStr(name); return metaMapper.selectCountForUpload(name, createUser, types); } @Override public List selectByPageForUpload(String name, Integer createUser, String types, Integer limit, Integer offset) { name = StringHelper.getLikeUpperStr(name); return metaMapper.selectByPageForUpload(name, createUser, types, limit, offset); } @Override public Integer selectCountByPid(Integer metaid, String name) { name = StringHelper.getLikeUpperStr(name); return metaMapper.selectCountByPid(metaid, name); } @Override public List selectPageByPid(Integer metaid, String name, Integer limit, Integer offset) { name = StringHelper.getLikeUpperStr(name); return metaMapper.selectPageByPid(metaid, name, limit, offset); } @Override public MetaEntity selectById(int id) { return metaMapper.selectById(id); } @Override public MetaEntity selectByGuid(String guid, String dircode, String tab) { return metaMapper.selectByGuid(guid, dircode, tab); } @Override public List selectByIdsForTab(String ids) { return metaMapper.selectByIdsForTab(ids); } @Override public List selectMetaFiles(List ids) { return metaMapper.selectMetaFiles(ids); } @Override public List selectXlsAnnex(Integer[] ids, String tabs) { return metaMapper.selectXlsAnnex(ids, tabs); } @Override public List selectMetasByDirCode(String dircode) { dircode = StringHelper.getRightLike(dircode); return metaMapper.selectMetasByDirCode(dircode); } @Override public List selectMetaOverflowDep(String ids, String depcode) { depcode = StringHelper.getRightLike(depcode); return metaMapper.selectMetaOverflowDep(ids, depcode); } @Override public Integer insert(MetaEntity entity) { return metaMapper.insert(entity); } @Override public Integer inserts(List list) { return metaMapper.inserts(list); } @Override public Integer deletes(String sql, String ids) { return metaMapper.deletes(sql, ids); } @Override public Integer update(MetaEntity entity) { return metaMapper.update(entity); } @Override public Integer updates(List list) { return metaMapper.updates(list); } /** * 删除元数据 */ public Integer deletes(List list) { String ids = StringHelper.join(list, ","); String sql = null; List metas = selectByIdsForTab(ids); if (null != metas && metas.size() > 0) { sql = getDelTabsSql(metas); } return deletes(sql, ids); } /** * 获取删除表记录SQL */ public String getDelTabsSql(List metas) { List list = getTabDeletes(metas, metas.get(0).getTab()); addCascadDeletes(list); addAttachDeletes(list); Collections.reverse(list); return StringHelper.join(list, ";"); } /** * 获取删除表记录SQL */ private List getTabDeletes(List metas, String tab) { List list = new ArrayList<>(); List pids = new ArrayList<>(); for (MetaEntity me : metas) { if (tab.equals(me.getTab())) { pids.add("'" + me.getEventid() + "'"); } else { list.add(String.format("delete from %s where parentid in (%s)", tab, StringHelper.join(pids, ","))); pids.clear(); tab = me.getTab(); pids.add("'" + me.getEventid() + "'"); } } if (pids.size() > 0) { list.add(String.format("delete from %s where parentid in (%s)", tab, StringHelper.join(pids, ","))); } return list; } /** * 添加级联删除 */ private void addCascadDeletes(List list) { int i = 0, c = list.size(); while (i < c) { String str = list.get(i); if (str.contains("bs.m_pipelinepoint ")) { list.add(str.replace("bs.m_pipelinepoint ", "bs.m_pipesegment ")); list.add(str.replace("bs.m_pipelinepoint ", "bs.m_pipeline ")); } if (str.contains("bs.s_explorationpoint ")) { list.add(str.replace("bs.s_explorationpoint ", "bs.s_surveyworksite ")); } if (str.contains("bs.m_surface_deformation_data ")) { list.add(str.replace("bs.m_surface_deformation_data ", "bs.m_surface_deformation_data_date ")); } i++; } } /** * 添加附件删除 */ private void addAttachDeletes(List list) { int i = 0, c = list.size(); while (i < c) { String str = list.get(i); String tab = str.substring("delete from ".length(), str.indexOf(" where ")); String select = str.replace("delete ", "select eventid "); list.add(String.format("delete from lf.sys_attach where tab='%s' and tab_guid in (%s)", tab, select)); i++; } } /** * 查看文件 */ public void downloadForView(String guid, boolean inline, HttpServletResponse res) { try { if (StringHelper.isEmpty(guid)) { WebHelper.writeStr2Page(res, StaticData.NO_FILE); return; } MetaEntity me = selectByGuid(guid, null, null); if (me == null) { WebHelper.writeStr2Page(res, StaticData.NO_FILE); return; } String filePath = pathHelper.getConfig().getUploadPath() + File.separator + me.getPath(); File file = new File(filePath); if (!file.exists() || file.isDirectory()) { WebHelper.writeJson2Page(res, "文件不存在"); } WebHelper.download(filePath, me.getName(), inline, res); } catch (Exception ex) { WebHelper.writeJson2Page(res, "文件下载出错"); log.error(ex.getMessage(), ex); } } /** * 查询元数据中溢出的单位ID */ public List selectMetaOverflowDep(UserEntity ue, DownloadReqEntity dr) { String ids = StringHelper.join(dr.getIds(), ","); return selectMetaOverflowDep(ids, ue.getDepcode()); } /** * 请求元数据下载 * * @param ue 用户实体 * @param dr 请求下载实体 * @return 下载文件GUID * @throws Exception 异常 */ public String downloadMeteReq(UserEntity ue, DownloadReqEntity dr) throws Exception { List list = selectMetaFiles(dr.getIds()); if (null == list || list.isEmpty()) { return null; } Map> tabs = getTabs(list); rmRepeatMetas(list); Map> dataMap = new HashMap<>(2); Map> annexMap = new HashMap<>(2); queryData(tabs, dataMap, annexMap); String tempName = StringHelper.YMDHMS2_FORMAT.format(new Date()); String tempPath = pathHelper.getTempPath(tempName); String gdbPath = tempPath + File.separator + "tabs.gdb"; File gdbFile = new File(gdbPath); if (gdbFile.exists() && gdbFile.isDirectory()) { FileHelper.deleteDir(gdbPath); } if (dataMap.size() > 0) { GdbHelper.createGdb(gdbPath, dataMap); } String zipFile = pathHelper.getDownloadFullPath() + File.separator + tempName + ".zip"; ZipFile zip = Zip4jHelper.createZipFile(zipFile, dr.getPwd()); ZipParameters params = Zip4jHelper.getZipParams(true); addMetaFiles(zip, params, list); if (dataMap.size() > 0) { zip.addFolder(new File(gdbPath), params); addAnnex(zip, params, annexMap); } String dbPwd = Md5Helper.reverse(Md5Helper.generate(dr.getPwd())); DownloadEntity de = getDownloadEntity(ue, zipFile, dbPwd); int rows = downloadService.insert(de); if (de.getId() > 0) { insertMetaDown(ue, list, de); } return rows > 0 ? de.getGuid() : null; } /** * 获取数据表 */ private Map> getTabs(List list) { Map> tabs = new HashMap<>(2); for (MetaEntity meta : list) { if (StringHelper.isEmpty(meta.getTab()) || meta.getRows() == 0 || StringHelper.isEmpty(meta.getEventid())) { continue; } if (!tabs.containsKey(meta.getTab())) { tabs.put(meta.getTab(), new ArrayList<>()); } List ids = tabs.get(meta.getTab()); if (!ids.contains(meta.getEventid())) { ids.add(meta.getEventid()); } } return tabs; } /** * 移除重复的元数据文件 */ private void rmRepeatMetas(List list) { List guidList = new ArrayList<>(); int i = 0; while (i < list.size()) { MetaEntity entity = list.get(i); if (guidList.contains(entity.getGuid())) { list.remove(i); continue; } guidList.add(entity.getGuid()); i++; } } /** * 查询数据 */ private void queryData(Map> tabs, Map> dataMap, Map> annexMap) { for (String tab : tabs.keySet()) { try { String entity = tab.toLowerCase().replace("_", "").split("\\.")[1]; BasicMapper baseMapper = ClassHelper.getBasicMapper(entity); if (null == baseMapper) { continue; } QueryWrapper wrapper = createQueryWrapper(baseMapper, tabs.get(tab)); addData(entity, baseMapper, wrapper, dataMap, annexMap); } catch (Exception ex) { log.error(ex.getMessage(), ex); } } } /** * 添加数据 */ public void addData(String entity, BasicMapper baseMapper, QueryWrapper wrapper, Map> dataMap, Map> annexMap) { List list = baseMapper.selectList(wrapper); if (null == list || list.size() == 0) { return; } if (!dataMap.containsKey(entity)) { dataMap.put(entity, list); } else { dataMap.get(entity).addAll(list); } if (wrapper.isEmptyOfWhere()) { wrapper.apply("1 = 1"); } if (StaticData.BBOREHOLE.equals(entity)) { wrapper.last("limit 100"); } String tab = BaseQueryService.getTabName(baseMapper); List annex = baseMapper.selectAnnex(tab, wrapper); if (null == annex || annex.isEmpty()) { return; } if (!annexMap.containsKey(entity)) { annexMap.put(tab.replace(StaticData.POINT, "_"), annex); } else { annexMap.get(tab.replace(StaticData.POINT, "_")).addAll(annex); } } /** * 创建查询包装器 */ private QueryWrapper createQueryWrapper(BasicMapper baseMapper, List ids) { for (int i = 0, c = ids.size(); i < c; i++) { ids.set(i, "'" + ids.get(i) + "'"); } String filter = String.format("parentid in (%s)", StringHelper.join(ids, ",")); QueryWrapper wrapper = new QueryWrapper(); if (baseMapper instanceof GeomBaseMapper) { wrapper.select("ST_AsText(geom) as geom, *"); } wrapper.apply(filter); return wrapper; } /** * 添加附件 */ public void addAnnex(ZipFile zip, ZipParameters params, Map> annexMap) { List files = new ArrayList<>(); String uploadPath = pathHelper.getConfig().getUploadPath(); for (String key : annexMap.keySet()) { for (AttachEntity ae : annexMap.get(key)) { try { File srcFile = new File(uploadPath + File.separator + ae.getPath()); if (!srcFile.exists() || srcFile.isDirectory()) { continue; } if (files.contains(srcFile.getPath())) { continue; } files.add(srcFile.getPath()); params.setFileNameInZip("annex" + File.separator + key + File.separator + ae.getName()); zip.addStream(new FileInputStream(srcFile), params); } catch (Exception ex) { log.error(ex.getMessage(), ex); } } } } /** * 添加元数据文件至Zip包 */ private void addMetaFiles(ZipFile zip, ZipParameters params, List list) { List names = new ArrayList<>(); String uploadPath = pathHelper.getConfig().getUploadPath(); for (MetaEntity mf : list) { if (names.contains(mf.getName())) { mf.setName(mf.getId() + "_" + mf.getName()); } else { names.add(mf.getName()); } try { switch ("." + mf.getType()) { case StaticData.MPT: addMultiFile(uploadPath, mf, zip, params, StaticData.MPT_EXT); break; case StaticData.JPG: addMultiFile(uploadPath, mf, zip, params, StaticData.JPG_EXT); case StaticData.IMG: addMultiFile(uploadPath, mf, zip, params, StaticData.IMG_EXT); break; case StaticData.TIF: addMultiFile(uploadPath, mf, zip, params, StaticData.TIF_EXT); break; case StaticData.TIFF: addMultiFile(uploadPath, mf, zip, params, StaticData.TIFF_EXT); break; case StaticData.SHP: addMultiFile(uploadPath, mf, zip, params, StaticData.SHP_EXT); break; case StaticData.GDB: continue; case StaticData.OSGB: addFolderFile(uploadPath, mf, zip, params); break; default: addSingleFile(uploadPath, mf, zip, params); break; } } catch (Exception ex) { log.error(ex.getMessage(), ex); } } } /** * 添加目录文件 */ private void addFolderFile(String uploadPath, MetaEntity mf, ZipFile zip, ZipParameters params) throws Exception { File file = new File(uploadPath + File.separator + mf.getPath()); if (!file.exists() || !file.isDirectory()) { return; } zip.addFolder(file, params); String fileName = FileHelper.getFileName(file.getPath()); FileHeader header = zip.getFileHeader(fileName); if (null != header) { zip.renameFile(header, mf.getName()); } } /** * 添加多文件 */ private void addMultiFile(String uploadPath, MetaEntity mf, ZipFile zip, ZipParameters params, List extList) throws Exception { addSingleFile(uploadPath, mf, zip, params); for (String ext : extList) { File file = new File(uploadPath + File.separator + mf.getPath().replace("." + mf.getType(), ext)); if (!file.exists() || file.isDirectory()) { continue; } zip.addFile(file, params); String fileName = FileHelper.getFileName(file.getPath()); FileHeader header = zip.getFileHeader(fileName); if (null != header) { zip.renameFile(header, mf.getName().replace("." + mf.getType(), ext)); } } } /** * 添加单文件 */ private void addSingleFile(String uploadPath, MetaEntity mf, ZipFile zip, ZipParameters params) throws Exception { File file = new File(uploadPath + File.separator + mf.getPath()); if (!file.exists() || file.isDirectory()) { return; } zip.addFile(file, params); String fileName = FileHelper.getFileName(file.getPath()); FileHeader header = zip.getFileHeader(fileName); if (null != header) { zip.renameFile(header, mf.getName()); } } /** * 获取下载实体类 */ private DownloadEntity getDownloadEntity(UserEntity ue, String file, String pwd) { DownloadEntity de = new DownloadEntity(); de.setName(FileHelper.getFileName(file)); // 1-Shp文件,2-专题图,3-元数据,4-业务数据,5-管道分析,6-统计报告,7-附件文件,8-瓦片文件 de.setType(3); de.setSizes(FileHelper.sizeToMb(new File(file).length())); de.setDepid(ue.getDepid()); de.setDcount(0); de.setPwd(pwd); de.setUrl(FileHelper.getRelativePath(file)); de.setDescr("元数据文件"); de.setGuid(FileHelper.getFileMd5(file)); de.setCreateUser(ue.getId()); // de.setGeom(null) return de; } /** * 插入元数据-下载表 */ private void insertMetaDown(UserEntity ue, List metas, DownloadEntity de) { List list = new ArrayList<>(); for (MetaEntity me : metas) { MetaDownEntity md = new MetaDownEntity(); md.setMetaid(me.getId()); md.setDownid(de.getId()); md.setCreateUser(ue.getId()); list.add(md); } metaDownService.inserts(list); } }