Merge branch 'main' of http://121.37.111.42:3000/zhengsl/WholeProcessPlatform into main_hzz
This commit is contained in:
commit
69e46e9914
@ -68,9 +68,10 @@ public class SecurityConfig {
|
|||||||
.requestMatchers("/dict/cache/**").permitAll()
|
.requestMatchers("/dict/cache/**").permitAll()
|
||||||
.requestMatchers("/sys/psbmodulelbb/**").permitAll()
|
.requestMatchers("/sys/psbmodulelbb/**").permitAll()
|
||||||
.requestMatchers("/base/operationLog/**").permitAll()
|
.requestMatchers("/base/operationLog/**").permitAll()
|
||||||
.requestMatchers("/system/**").permitAll()
|
// .requestMatchers("/system/**").permitAll()
|
||||||
|
.requestMatchers("/qgcExport/**").permitAll()
|
||||||
// .requestMatchers("/eng/**").permitAll()
|
// .requestMatchers("/eng/**").permitAll()
|
||||||
// .requestMatchers("/eq/**").permitAll()
|
.requestMatchers("/eq/**").permitAll()
|
||||||
// .requestMatchers("/env/**").permitAll()
|
// .requestMatchers("/env/**").permitAll()
|
||||||
// .requestMatchers("/warn/**").permitAll()
|
// .requestMatchers("/warn/**").permitAll()
|
||||||
// .requestMatchers("/threedroamb/**").permitAll()
|
// .requestMatchers("/threedroamb/**").permitAll()
|
||||||
|
|||||||
@ -299,4 +299,12 @@ public class SwaggerConfig {
|
|||||||
.packagesToScan("com.yfd.platform.qgc_lygk.along.controller")
|
.packagesToScan("com.yfd.platform.qgc_lygk.along.controller")
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public GroupedOpenApi groupExportApi() {
|
||||||
|
return GroupedOpenApi.builder()
|
||||||
|
.group("7. 综合导出")
|
||||||
|
.packagesToScan("com.yfd.platform.qgc_export.controller")
|
||||||
|
.build();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -13,7 +13,7 @@ import java.util.Map;
|
|||||||
public class EngStInfoResultVo {
|
public class EngStInfoResultVo {
|
||||||
|
|
||||||
@Schema(description = "主信息兼容对象")
|
@Schema(description = "主信息兼容对象")
|
||||||
private Map<String, Object> msStbprpT = new LinkedHashMap<>();
|
private EngVmsstbprptVo msStbprpT;
|
||||||
|
|
||||||
@Schema(description = "测值列表")
|
@Schema(description = "测值列表")
|
||||||
private List<Object> stcdValVoList = new ArrayList<>();
|
private List<Object> stcdValVoList = new ArrayList<>();
|
||||||
|
|||||||
@ -14,8 +14,14 @@ public class EngVmsstbprptVo implements Serializable {
|
|||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
private String id;
|
private String id;
|
||||||
|
private String sttp;
|
||||||
private String sttpCode;
|
private String sttpCode;
|
||||||
|
private String sttpMap;
|
||||||
|
private String logo;
|
||||||
private String sttpName;
|
private String sttpName;
|
||||||
|
private String sttpFullPath;
|
||||||
|
private String sttpTreeLevel;
|
||||||
|
private String rvcdFullPath;
|
||||||
private String stcd;
|
private String stcd;
|
||||||
private String stnm;
|
private String stnm;
|
||||||
private String ennm;
|
private String ennm;
|
||||||
|
|||||||
@ -80,7 +80,7 @@ public interface ISdEngInfoBHService extends IService<SdEngInfoBH> {
|
|||||||
|
|
||||||
List<SdEngInfoBH> selectRegDropdown(SdEngInfoBHRequest sdEngInfoBHRequest);
|
List<SdEngInfoBH> selectRegDropdown(SdEngInfoBHRequest sdEngInfoBHRequest);
|
||||||
|
|
||||||
EngBaseInfoVo getStInfoByStcd(String stcd);
|
EngVmsstbprptVo getStInfoByStcd(String stcd);
|
||||||
|
|
||||||
EngStInfoResultVo getStcdInfo(String stcd);
|
EngStInfoResultVo getStcdInfo(String stcd);
|
||||||
|
|
||||||
|
|||||||
@ -1001,68 +1001,269 @@ public class SdEngInfoBHServiceImpl extends ServiceImpl<SdEngInfoBHMapper, SdEng
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public EngBaseInfoVo getStInfoByStcd(String stcd) {
|
public EngVmsstbprptVo getStInfoByStcd(String stcd) {
|
||||||
SdEngInfoBH entity = this.getById(stcd);
|
|
||||||
if (entity == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
EngBaseInfoVo vo = new EngBaseInfoVo();
|
StringBuilder sql = new StringBuilder();
|
||||||
BeanUtil.copyProperties(entity, vo);
|
sql.append("SELECT *")
|
||||||
vo.setId(entity.getStcd());
|
|
||||||
vo.setStnm(entity.getEnnm());
|
|
||||||
|
|
||||||
String sql = "SELECT " +
|
.append(" FROM (")
|
||||||
"sttp.ID AS sttp, " +
|
.append(buildVmsstbprptViewSqlNew())
|
||||||
"sttp.STTP_CODE AS sttpCode, " +
|
.append(") t WHERE 1 = 1 AND t.STCD = #{map.stcd}");
|
||||||
"sttp.STTP_NAME AS sttpName, " +
|
EngVmsstbprptVo vo = microservicDynamicSQLMapper.getOneBySqlWithResultType(sql.toString(), Collections.singletonMap("stcd", stcd), EngVmsstbprptVo.class);
|
||||||
|
// SdEngInfoBH entity = this.getById(stcd);
|
||||||
|
// if (entity == null) {
|
||||||
|
// return null;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// EngBaseInfoVo vo = new EngBaseInfoVo();
|
||||||
|
// BeanUtil.copyProperties(entity, vo);
|
||||||
|
// vo.setId(entity.getStcd());
|
||||||
|
// vo.setStnm(entity.getEnnm());
|
||||||
|
//
|
||||||
|
// String sql = "SELECT " +
|
||||||
|
// "sttp.ID AS sttp, " +
|
||||||
|
// "sttp.STTP_CODE AS sttpCode, " +
|
||||||
|
// "sttp.STTP_NAME AS sttpName, " +
|
||||||
|
// "sttp.FULL_PATH AS sttpFullPath, " +
|
||||||
|
// "sttp.TREE_LEVEL AS sttpTreeLevel, " +
|
||||||
|
// "hb.BASENAME AS baseName, " +
|
||||||
|
// "hbrv.HBRVNM AS hbrvcdName, " +
|
||||||
|
// "rv.RVNM AS rvcdName, " +
|
||||||
|
// "rv.PATH AS rvcdFullPath, " +
|
||||||
|
// "addv.ADDVNM AS addvcdName, " +
|
||||||
|
// "addv.PATH AS addvcdFullPath, " +
|
||||||
|
// "country.COUNTRY_NAME AS countryName, " +
|
||||||
|
// "hy.HYNM AS hynm, " +
|
||||||
|
// "topHy.HYNM AS topHynm " +
|
||||||
|
// "FROM SD_ENGINFO_B_H eng " +
|
||||||
|
// "LEFT JOIN SD_STTP_B sttp ON sttp.STTP_CODE = 'ENG' " +
|
||||||
|
// " AND NVL(sttp.IS_DELETED, 0) = 0 " +
|
||||||
|
// " AND NVL(sttp.ENABLE, 1) = 1 " +
|
||||||
|
// "LEFT JOIN SD_HYDROBASE hb ON hb.BASEID = eng.BASE_ID " +
|
||||||
|
// "LEFT JOIN SD_HBRV_DIC hbrv ON hbrv.HBRVCD = eng.HBRVCD AND hbrv.BASEID = eng.BASE_ID " +
|
||||||
|
// " AND NVL(hbrv.ENABLED, 1) = 1 " +
|
||||||
|
// "LEFT JOIN SD_RVCD_DIC rv ON rv.RVCD = eng.RVCD " +
|
||||||
|
// "LEFT JOIN SD_ADDVCD_DIC addv ON addv.ADDVCD = eng.ADDVCD " +
|
||||||
|
// "LEFT JOIN SD_COUNTRY_B country ON country.COUNTRY_ID = eng.COUNTRY AND NVL(country.ENABLED, 1) = 1 " +
|
||||||
|
// "LEFT JOIN SD_HYCD_DIC hy ON hy.HYCD = eng.HYCD " +
|
||||||
|
// "LEFT JOIN SD_HYCD_DIC topHy ON topHy.HYCD = eng.TOP_HYCD " +
|
||||||
|
// "WHERE eng.STCD = #{map.stcd}";
|
||||||
|
//
|
||||||
|
// EngBaseInfoVo extra = microservicDynamicSQLMapper.getOneBySqlWithResultType(
|
||||||
|
// sql, java.util.Collections.singletonMap("stcd", stcd), EngBaseInfoVo.class);
|
||||||
|
// if (extra != null) {
|
||||||
|
// BeanUtil.copyProperties(extra, vo, CopyOptions.create().setIgnoreNullValue(true));
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// vo.setSttpCode("ENG");
|
||||||
|
// vo.setBlprdCode(entity.getBlprd() == null ? null : String.valueOf(entity.getBlprd()));
|
||||||
|
// vo.setBlprdCcode(entity.getBlprd() == null ? null : String.valueOf(entity.getBlprd()));
|
||||||
|
// vo.setBlprdName(resolveBlprdName(entity.getBlprd()));
|
||||||
|
// vo.setBlprdCname(vo.getBlprdName());
|
||||||
|
// vo.setDtinName(resolveDtinName(entity.getDtin()));
|
||||||
|
// vo.setBldsttName(resolveBldsttName(entity.getBldstt()));
|
||||||
|
// vo.setBldsttCcode(entity.getBldsttCode() == null ? null : String.valueOf(entity.getBldsttCode()));
|
||||||
|
// vo.setBldsttCcodeName(resolveBldsttCodeName(entity.getBldsttCode()));
|
||||||
|
// vo.setDvtpName(resolveDvtpName(entity.getDvtp()));
|
||||||
|
// vo.setRgcpName(resolveRgcpName(entity.getRgcp()));
|
||||||
|
// vo.setEngtpName(resolveEngtpName(entity.getEngtp()));
|
||||||
|
// vo.setPrscName(resolvePrscName(entity.getPrsc()));
|
||||||
|
// vo.setScrscName(resolveScrscName(entity.getScrsc()));
|
||||||
|
// vo.setPrgrName(resolvePrgrName(entity.getPrgr()));
|
||||||
|
return vo;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private String buildVmsstbprptViewSqlNew() {
|
||||||
|
return "SELECT " +
|
||||||
|
"eng.STCD AS id, " +
|
||||||
|
"'ENG' AS sttpCode, " +
|
||||||
|
"'ENG' AS sttpMap, " +
|
||||||
"sttp.FULL_PATH AS sttpFullPath, " +
|
"sttp.FULL_PATH AS sttpFullPath, " +
|
||||||
"sttp.TREE_LEVEL AS sttpTreeLevel, " +
|
"sttp.TREE_LEVEL AS sttpTreeLevel, " +
|
||||||
|
"sttp.ID AS sttp, " +
|
||||||
|
"'电站' AS sttpName, " +
|
||||||
|
"eng.STCD AS stcd, " +
|
||||||
|
"eng.ENNM AS stnm, " +
|
||||||
|
"eng.LGTD AS lgtd, " +
|
||||||
|
"eng.LTTD AS lttd, " +
|
||||||
|
"eng.REACHCD AS reachcd, " +
|
||||||
|
"eng.REACHCD_NAME AS reachcdName, " +
|
||||||
|
"eng.ENNM AS ennm, " +
|
||||||
|
"eng.BASE_ID AS baseId, " +
|
||||||
"hb.BASENAME AS baseName, " +
|
"hb.BASENAME AS baseName, " +
|
||||||
|
"eng.HBRVCD AS hbrvcd, " +
|
||||||
"hbrv.HBRVNM AS hbrvcdName, " +
|
"hbrv.HBRVNM AS hbrvcdName, " +
|
||||||
|
"eng.RVCD AS rvcd, " +
|
||||||
|
"eng.LOGO AS logo, " +
|
||||||
"rv.RVNM AS rvcdName, " +
|
"rv.RVNM AS rvcdName, " +
|
||||||
"rv.PATH AS rvcdFullPath, " +
|
"rv.PATH AS rvcdFullPath, " +
|
||||||
"addv.ADDVNM AS addvcdName, " +
|
"addv.ADDVNM AS addvcdName, " +
|
||||||
"addv.PATH AS addvcdFullPath, " +
|
|
||||||
"country.COUNTRY_NAME AS countryName, " +
|
|
||||||
"hy.HYNM AS hynm, " +
|
"hy.HYNM AS hynm, " +
|
||||||
"topHy.HYNM AS topHynm " +
|
"topHy.HYNM AS topHynm, " +
|
||||||
|
"hy.HYCD AS hycd, " +
|
||||||
|
"topHy.HYCD AS topHycd, " +
|
||||||
|
"eng.STLC AS stlc, " +
|
||||||
|
"eng.JCDT AS jcdt, " +
|
||||||
|
"eng.PIODT AS piodt, " +
|
||||||
|
"eng.AIODT AS aiodt, " +
|
||||||
|
"eng.BLDSTT AS bldstt, " +
|
||||||
|
"eng.BLDSTT_CODE AS bldsttCcode, " +
|
||||||
|
"CASE " +
|
||||||
|
" WHEN eng.BLDSTT_CODE = 0 OR eng.BLDSTT_CODE IS NULL THEN '未建/规划' " +
|
||||||
|
" WHEN eng.BLDSTT_CODE = 1 THEN '在建' " +
|
||||||
|
" WHEN eng.BLDSTT_CODE = 2 THEN '已建' " +
|
||||||
|
" ELSE NULL END AS bldsttCcodeName, " +
|
||||||
|
"eng.NRUPAR AS nrupar, " +
|
||||||
|
"eng.DSTCRVR AS dstcrvr, " +
|
||||||
|
"eng.AVYRP AS avyrp, " +
|
||||||
|
"eng.AVW AS avw, " +
|
||||||
|
"eng.AVQ AS avq, " +
|
||||||
|
"eng.AVQ01 AS avq01, " +
|
||||||
|
"eng.AVQ02 AS avq02, " +
|
||||||
|
"eng.AVQ03 AS avq03, " +
|
||||||
|
"eng.AVQ04 AS avq04, " +
|
||||||
|
"eng.AVQ05 AS avq05, " +
|
||||||
|
"eng.AVQ06 AS avq06, " +
|
||||||
|
"eng.AVQ07 AS avq07, " +
|
||||||
|
"eng.AVQ08 AS avq08, " +
|
||||||
|
"eng.AVQ09 AS avq09, " +
|
||||||
|
"eng.AVQ10 AS avq10, " +
|
||||||
|
"eng.AVQ11 AS avq11, " +
|
||||||
|
"eng.AVQ12 AS avq12, " +
|
||||||
|
"rbh.OBMXQ AS obmxq, " +
|
||||||
|
"rbh.OBMNQ AS obmnq, " +
|
||||||
|
"rbh.HMXQ AS hmxq, " +
|
||||||
|
"eng.DSNFQFRQ AS dsnfqfrq, " +
|
||||||
|
"eng.DSRCIN AS dsrcin, " +
|
||||||
|
"eng.CKFQFQR AS ckfqfqr, " +
|
||||||
|
"eng.CHRCIN AS chrcin, " +
|
||||||
|
"eng.OBMXW3 AS obmxw3, " +
|
||||||
|
"eng.DSW3 AS dsw3, " +
|
||||||
|
"eng.CKW3 AS ckw3, " +
|
||||||
|
"eng.AVSD AS avsd, " +
|
||||||
|
"eng.AVS AS avs, " +
|
||||||
|
"rbh.OBMXS AS obmxs, " +
|
||||||
|
"rbh.CKFLZ AS ckflz, " +
|
||||||
|
"rbh.DSFLZ AS dsflz, " +
|
||||||
|
"rbh.NORMZ AS normz, " +
|
||||||
|
"rbh.UZFC AS uzfc, " +
|
||||||
|
"eng.FSLTDZ AS fsltdz, " +
|
||||||
|
"eng.YDOWNZ AS ydownz, " +
|
||||||
|
"rbh.DDZ AS ddz, " +
|
||||||
|
"eng.NRZAR AS nrzar, " +
|
||||||
|
"eng.BCKLEN AS bcklen, " +
|
||||||
|
"rbh.TTCP AS ttcp, " +
|
||||||
|
"rbh.NMZCP AS nmzcp, " +
|
||||||
|
"b.VAL AS fldcpStr, " +
|
||||||
|
"rbh.ACTCP AS actcp, " +
|
||||||
|
"rbh.DDCP AS ddcp, " +
|
||||||
|
"eng.CPSC AS cpsc, " +
|
||||||
|
"eng.PRSC AS prsc, " +
|
||||||
|
"eng.RGCP AS rgcp, " +
|
||||||
|
"CASE eng.RGCP " +
|
||||||
|
" WHEN '1' THEN '多年调节' " +
|
||||||
|
" WHEN '2' THEN '年调节' " +
|
||||||
|
" WHEN '3' THEN '不完全年调节' " +
|
||||||
|
" WHEN '4' THEN '径流式(无调节)' " +
|
||||||
|
" WHEN '5' THEN '季调节' " +
|
||||||
|
" WHEN '6' THEN '月调节' " +
|
||||||
|
" WHEN '7' THEN '周调节' " +
|
||||||
|
" WHEN '8' THEN '日调节' " +
|
||||||
|
" WHEN '9' THEN '其他' " +
|
||||||
|
" ELSE NULL END AS rgcpName, " +
|
||||||
|
"eng.DSMXQ AS dsflzmxq, " +
|
||||||
|
"rbh.DSFLZXYZ AS dsflzxyz, " +
|
||||||
|
"eng.CHMXQ AS ckflzmxq, " +
|
||||||
|
"rbh.CKFLZXYZ AS ckflzxyz, " +
|
||||||
|
"rbh.KSQADJQ AS ksqadjq, " +
|
||||||
|
"rbh.KSQXYZ AS ksqxyz, " +
|
||||||
|
"eng.GEMAXRQ AS gemaxrq, " +
|
||||||
|
"rbh.MXGEQXYZ AS mxgeqxyz, " +
|
||||||
|
"pwr.TTPWR AS ttpwr, " +
|
||||||
|
"pwr.GNCNT AS gncnt, " +
|
||||||
|
"eng.GNTP AS gntp, " +
|
||||||
|
"pwr.GRNTPWR AS grntpwr, " +
|
||||||
|
"pwr.YRGE AS yrge, " +
|
||||||
|
"pwr.USHR AS ushr, " +
|
||||||
|
"pwr.K AS k, " +
|
||||||
|
"eng.DMTP AS dmtp, " +
|
||||||
|
"eng.DMCREL AS dmcrel, " +
|
||||||
|
"eng.MXDMHG AS mxdmhg, " +
|
||||||
|
"eng.DMLEN AS dmlen, " +
|
||||||
|
"pwr.SGYGE AS sgyge, " +
|
||||||
|
"UNYGE AS unyge, " +
|
||||||
|
"eng.GAP AS gap, " +
|
||||||
|
"eng.DVTP AS dvtp, " +
|
||||||
|
"CASE eng.DVTP " +
|
||||||
|
" WHEN '1' THEN '堤坝式' " +
|
||||||
|
" WHEN '2' THEN '引水式' " +
|
||||||
|
" WHEN '3' THEN '混合式' " +
|
||||||
|
" ELSE NULL END AS dvtpName, " +
|
||||||
|
"eng.DTIN AS dtin, " +
|
||||||
|
"eng.RUN_STATE AS runSTATE, " +
|
||||||
|
"eng.DTIN_ENV AS dtinEnv, " +
|
||||||
|
"CASE NVL(eng.DTIN, 0) " +
|
||||||
|
" WHEN 0 THEN '否' " +
|
||||||
|
" WHEN 1 THEN '是' " +
|
||||||
|
" ELSE NULL END AS dtinName, " +
|
||||||
|
"NVL(hb.ORDER_INDEX, 999999) AS baseStepSort, " +
|
||||||
|
"NVL(along.ORDER_INDEX, 999999) AS rvcdStepSort, " +
|
||||||
|
"NVL(rstSort.SORT, 999999) AS rstcdStepSort, " +
|
||||||
|
"NVL(siteSort.SORT, 999999) AS siteStepSort " +
|
||||||
"FROM SD_ENGINFO_B_H eng " +
|
"FROM SD_ENGINFO_B_H eng " +
|
||||||
"LEFT JOIN SD_STTP_B sttp ON sttp.STTP_CODE = 'ENG' " +
|
"LEFT JOIN SD_STTP_B sttp ON sttp.STTP_CODE = 'ENG' " +
|
||||||
" AND NVL(sttp.IS_DELETED, 0) = 0 " +
|
"LEFT JOIN SD_HYDROBASE hb ON hb.BASEID = eng.BASE_ID AND NVL(hb.IS_DELETED, 0) = 0 " +
|
||||||
" AND NVL(sttp.ENABLE, 1) = 1 " +
|
|
||||||
"LEFT JOIN SD_HYDROBASE hb ON hb.BASEID = eng.BASE_ID " +
|
|
||||||
"LEFT JOIN SD_HBRV_DIC hbrv ON hbrv.HBRVCD = eng.HBRVCD AND hbrv.BASEID = eng.BASE_ID " +
|
"LEFT JOIN SD_HBRV_DIC hbrv ON hbrv.HBRVCD = eng.HBRVCD AND hbrv.BASEID = eng.BASE_ID " +
|
||||||
" AND NVL(hbrv.ENABLED, 1) = 1 " +
|
" AND NVL(hbrv.IS_DELETED, 0) = 0 AND NVL(hbrv.ENABLED, 1) = 1 " +
|
||||||
"LEFT JOIN SD_RVCD_DIC rv ON rv.RVCD = eng.RVCD " +
|
"LEFT JOIN SD_RVCD_DIC rv ON rv.RVCD = eng.RVCD " +
|
||||||
"LEFT JOIN SD_ADDVCD_DIC addv ON addv.ADDVCD = eng.ADDVCD " +
|
"LEFT JOIN SD_ADDVCD_DIC addv ON addv.ADDVCD = eng.ADDVCD " +
|
||||||
"LEFT JOIN SD_COUNTRY_B country ON country.COUNTRY_ID = eng.COUNTRY AND NVL(country.ENABLED, 1) = 1 " +
|
"LEFT JOIN SD_HYCD_DIC hy ON hy.HYCD = eng.HYCD AND NVL(hy.IS_DELETED, 0) = 0 AND NVL(hy.ENABLED, 1) = 1 " +
|
||||||
"LEFT JOIN SD_HYCD_DIC hy ON hy.HYCD = eng.HYCD " +
|
"LEFT JOIN SD_HYCD_DIC topHy ON topHy.HYCD = eng.TOP_HYCD AND NVL(topHy.IS_DELETED, 0) = 0 AND NVL(topHy.ENABLED, 1) = 1 " +
|
||||||
"LEFT JOIN SD_HYCD_DIC topHy ON topHy.HYCD = eng.TOP_HYCD " +
|
"LEFT JOIN SD_PWR_B_H pwr ON pwr.STCD = eng.STCD AND NVL(pwr.IS_DELETED, 0) = 0 " +
|
||||||
"WHERE eng.STCD = #{map.stcd}";
|
"LEFT JOIN SD_RSVRFCCH_B_H rbh ON rbh.STCD = eng.STCD " +
|
||||||
|
"LEFT JOIN ( SELECT STCD\n" +
|
||||||
EngBaseInfoVo extra = microservicDynamicSQLMapper.getOneBySqlWithResultType(
|
" , MAX(CASE WHEN RN = 1 THEN TM END) AS TM\n" +
|
||||||
sql, java.util.Collections.singletonMap("stcd", stcd), EngBaseInfoVo.class);
|
" , MAX(CASE WHEN RN = 1 THEN VAL END) AS VAL\n" +
|
||||||
if (extra != null) {
|
" , MAX(VLSR) AS VLSR\n" +
|
||||||
BeanUtil.copyProperties(extra, vo, CopyOptions.create().setIgnoreNullValue(true));
|
" , MAX(VLSR_TM) AS VLSR_TM\n" +
|
||||||
}
|
" , LISTAGG('起始时间' || TO_CHAR(TM, 'YYYY-MM-DD') || '(' || VAL || ')' ||\n" +
|
||||||
|
" CASE WHEN VLSR IS NOT NULL THEN '来源' || VLSR ELSE '' END ||\n" +
|
||||||
vo.setSttpCode("ENG");
|
" CASE WHEN VLSR_TM IS NOT NULL THEN ',来源时间' || TO_CHAR(VLSR_TM, 'YYYY-MM-DD') ELSE '' END,\n" +
|
||||||
vo.setBlprdCode(entity.getBlprd() == null ? null : String.valueOf(entity.getBlprd()));
|
" CHR(10)) WITHIN GROUP (ORDER BY TM DESC) AS ALL_VAL\n" +
|
||||||
vo.setBlprdCcode(entity.getBlprd() == null ? null : String.valueOf(entity.getBlprd()));
|
" FROM ( SELECT STCD\n" +
|
||||||
vo.setBlprdName(resolveBlprdName(entity.getBlprd()));
|
" , TM\n" +
|
||||||
vo.setBlprdCname(vo.getBlprdName());
|
" , MAX(VLSR) AS VLSR\n" +
|
||||||
vo.setDtinName(resolveDtinName(entity.getDtin()));
|
" , MAX(VLSR_TM) AS VLSR_TM\n" +
|
||||||
vo.setBldsttName(resolveBldsttName(entity.getBldstt()));
|
" , LISTAGG(\n" +
|
||||||
vo.setBldsttCcode(entity.getBldsttCode() == null ? null : String.valueOf(entity.getBldsttCode()));
|
" SUBSTR(BGMD, 0, 2) || '月' || SUBSTR(BGMD, 3, 2) || '日' || '~' || SUBSTR(EDMD, 0, 2) || '月' ||\n" +
|
||||||
vo.setBldsttCcodeName(resolveBldsttCodeName(entity.getBldsttCode()));
|
" SUBSTR(EDMD, 3, 2) || '日' || '限值为' ||\n" +
|
||||||
vo.setDvtpName(resolveDvtpName(entity.getDvtp()));
|
" (CASE WHEN FLDCPMN IS NOT NULL THEN (DECODE(SUBSTR(FLDCPMN, 1, 1), '.', '0' || FLDCPMN, FLDCPMN) ||\n" +
|
||||||
vo.setRgcpName(resolveRgcpName(entity.getRgcp()));
|
" '~' || DECODE(SUBSTR(FLDCP, 1, 1), '.', '0' || FLDCP, FLDCP))\n" +
|
||||||
vo.setEngtpName(resolveEngtpName(entity.getEngtp()));
|
" ELSE TO_CHAR(FLDCP) END), ',') WITHIN GROUP (ORDER BY BGMD) AS VAL\n" +
|
||||||
vo.setPrscName(resolvePrscName(entity.getPrsc()));
|
" , ROW_NUMBER() OVER (PARTITION BY STCD ORDER BY TM DESC) RN\n" +
|
||||||
vo.setScrscName(resolveScrscName(entity.getScrsc()));
|
" FROM SD_RSVRFSR_B\n" +
|
||||||
vo.setPrgrName(resolvePrgrName(entity.getPrgr()));
|
" WHERE BGMD IS NOT NULL\n" +
|
||||||
return vo;
|
" AND EDMD IS NOT NULL\n" +
|
||||||
|
" AND FLDCPMN IS NOT NULL\n" +
|
||||||
|
" AND FLDCPMN > 0\n" +
|
||||||
|
" GROUP BY STCD, TM ) temp\n" +
|
||||||
|
" GROUP BY STCD) b ON b.STCD = eng.STCD " +
|
||||||
|
"LEFT JOIN MS_ALONG_B along ON along.BASEID = eng.BASE_ID AND along.CODE = 'common' AND NVL(along.IS_DELETED, 0) = 0 " +
|
||||||
|
"LEFT JOIN ( " +
|
||||||
|
" SELECT det.SORT,cfg.BASEID, cfg.RVCD, det.STCD " +
|
||||||
|
" FROM MS_ALONGDET_B det " +
|
||||||
|
" INNER JOIN MS_ALONG_B cfg ON det.ALONG_ID = cfg.ID " +
|
||||||
|
" WHERE NVL(det.IS_DELETED, 0) = 0 AND NVL(cfg.IS_DELETED, 0) = 0 AND cfg.CODE = 'common' " +
|
||||||
|
") rstSort ON rstSort.BASEID = eng.BASE_ID AND rstSort.STCD = eng.STCD " +
|
||||||
|
"LEFT JOIN ( " +
|
||||||
|
" SELECT det.SORT,cfg.BASEID, cfg.RVCD, det.STCD " +
|
||||||
|
" FROM MS_ALONGDET_B det " +
|
||||||
|
" INNER JOIN MS_ALONG_B cfg ON det.ALONG_ID = cfg.ID " +
|
||||||
|
" WHERE NVL(det.IS_DELETED, 0) = 0 AND NVL(cfg.IS_DELETED, 0) = 0 AND cfg.CODE = 'common' " +
|
||||||
|
") siteSort ON siteSort.BASEID = eng.BASE_ID AND siteSort.STCD = eng.STCD " +
|
||||||
|
"WHERE NVL(eng.IS_DELETED, 0) = 0 ";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -1070,27 +1271,27 @@ public class SdEngInfoBHServiceImpl extends ServiceImpl<SdEngInfoBHMapper, SdEng
|
|||||||
if (StrUtil.isBlank(stcd)) {
|
if (StrUtil.isBlank(stcd)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
EngVmsstbprptVo baseInfo = getStInfoByStcd(stcd);
|
||||||
|
if (baseInfo == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
Map<String, Object> stInfoMap = microservicDynamicSQLMapper.getOneBySql(buildStcdInfoViewSql(), Collections.singletonMap("stcd", stcd));
|
Map<String, Object> stInfoMap = microservicDynamicSQLMapper.getOneBySql(buildStcdInfoViewSql(), Collections.singletonMap("stcd", stcd));
|
||||||
if (stInfoMap != null && !stInfoMap.isEmpty()) {
|
if (stInfoMap != null && !stInfoMap.isEmpty()) {
|
||||||
EngStInfoResultVo result = new EngStInfoResultVo();
|
EngStInfoResultVo result = new EngStInfoResultVo();
|
||||||
result.setMsStbprpT(buildCamelCaseMsStbprpTMap(stInfoMap));
|
result.setMsStbprpT(baseInfo);
|
||||||
result.setStBaseInfo(buildStBaseInfo(stInfoMap));
|
result.setStBaseInfo(buildStBaseInfo(stInfoMap));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
EngBaseInfoVo baseInfo = getStInfoByStcd(stcd);
|
|
||||||
if (baseInfo == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
EngStBaseInfoVo stBaseInfo = new EngStBaseInfoVo();
|
EngStBaseInfoVo stBaseInfo = new EngStBaseInfoVo();
|
||||||
stBaseInfo.setStcd(baseInfo.getStcd());
|
stBaseInfo.setStcd(baseInfo.getStcd());
|
||||||
stBaseInfo.setStnm(baseInfo.getStnm());
|
stBaseInfo.setStnm(baseInfo.getStnm());
|
||||||
stBaseInfo.setSttpCode(baseInfo.getSttpCode());
|
stBaseInfo.setSttpCode(baseInfo.getSttpCode());
|
||||||
stBaseInfo.setSttpName(baseInfo.getSttpName());
|
stBaseInfo.setSttpName(baseInfo.getSttpName());
|
||||||
stBaseInfo.setSttpFullPath(baseInfo.getSttpFullPath());
|
// stBaseInfo.setSttpFullPath(baseInfo.getSttpFullPath());
|
||||||
stBaseInfo.setSttpTreeLevel(baseInfo.getSttpTreeLevel());
|
// stBaseInfo.setSttpTreeLevel(baseInfo.getSttpTreeLevel());
|
||||||
stBaseInfo.setStCode(null);
|
stBaseInfo.setStCode(null);
|
||||||
stBaseInfo.setStName(null);
|
stBaseInfo.setStName(null);
|
||||||
stBaseInfo.setBaseId(baseInfo.getBaseId());
|
stBaseInfo.setBaseId(baseInfo.getBaseId());
|
||||||
@ -1340,7 +1541,7 @@ public class SdEngInfoBHServiceImpl extends ServiceImpl<SdEngInfoBHMapper, SdEng
|
|||||||
"rbh.KSQXYZ AS ksqxyz, " +
|
"rbh.KSQXYZ AS ksqxyz, " +
|
||||||
"eng.GEMAXRQ AS gemaxrq, " +
|
"eng.GEMAXRQ AS gemaxrq, " +
|
||||||
"rbh.MXGEQXYZ AS mxgeqxyz, " +
|
"rbh.MXGEQXYZ AS mxgeqxyz, " +
|
||||||
"eng.YRGEB AS ttpwr, " +
|
"pwr.TTPWR AS ttpwr, " +
|
||||||
"pwr.GNCNT AS gncnt, " +
|
"pwr.GNCNT AS gncnt, " +
|
||||||
"eng.GNTP AS gntp, " +
|
"eng.GNTP AS gntp, " +
|
||||||
"pwr.GRNTPWR AS grntpwr, " +
|
"pwr.GRNTPWR AS grntpwr, " +
|
||||||
@ -3120,7 +3321,7 @@ public class SdEngInfoBHServiceImpl extends ServiceImpl<SdEngInfoBHMapper, SdEng
|
|||||||
"eng.LGTD AS lgtd, " +
|
"eng.LGTD AS lgtd, " +
|
||||||
"eng.LTTD AS lttd, " +
|
"eng.LTTD AS lttd, " +
|
||||||
"eng.ELEV AS dtmel, " +
|
"eng.ELEV AS dtmel, " +
|
||||||
"eng.YRGEB AS ttpwr, " +
|
"pwr.TTPWR AS ttpwr, " +
|
||||||
"'ENG' AS sttpMap, " +
|
"'ENG' AS sttpMap, " +
|
||||||
"CASE WHEN eng.PRSC IN (1, 2) THEN 1 WHEN eng.PRSC = 3 THEN 2 END AS endInstalledType, " +
|
"CASE WHEN eng.PRSC IN (1, 2) THEN 1 WHEN eng.PRSC = 3 THEN 2 END AS endInstalledType, " +
|
||||||
"CASE " +
|
"CASE " +
|
||||||
@ -3138,6 +3339,7 @@ public class SdEngInfoBHServiceImpl extends ServiceImpl<SdEngInfoBHMapper, SdEng
|
|||||||
"NVL(rstSort.SORT, 999999) AS rstcdStepSort, " +
|
"NVL(rstSort.SORT, 999999) AS rstcdStepSort, " +
|
||||||
"NVL(siteSort.SORT, 999999) AS siteStepSort " +
|
"NVL(siteSort.SORT, 999999) AS siteStepSort " +
|
||||||
"FROM SD_ENGINFO_B_H eng " +
|
"FROM SD_ENGINFO_B_H eng " +
|
||||||
|
"LEFT JOIN SD_PWR_B_H pwr ON pwr.STCD = eng.STCD AND NVL(pwr.IS_DELETED, 0) = 0 " +
|
||||||
"LEFT JOIN SD_HYDROBASE hb ON hb.BASEID = eng.BASE_ID AND NVL(hb.IS_DELETED, 0) = 0 " +
|
"LEFT JOIN SD_HYDROBASE hb ON hb.BASEID = eng.BASE_ID AND NVL(hb.IS_DELETED, 0) = 0 " +
|
||||||
"LEFT JOIN MS_ALONG_B along ON along.BASEID = eng.BASE_ID AND along.CODE = 'common' AND NVL(along.IS_DELETED, 0) = 0 " +
|
"LEFT JOIN MS_ALONG_B along ON along.BASEID = eng.BASE_ID AND along.CODE = 'common' AND NVL(along.IS_DELETED, 0) = 0 " +
|
||||||
"LEFT JOIN ( " +
|
"LEFT JOIN ( " +
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
package com.yfd.platform.qgc_base.service.impl;
|
package com.yfd.platform.qgc_base.service.impl;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
import com.yfd.platform.qgc_base.domain.SdEngInfoBH;
|
import com.yfd.platform.qgc_base.domain.SdEngInfoBH;
|
||||||
import com.yfd.platform.qgc_base.domain.SdHydrobase;
|
import com.yfd.platform.qgc_base.domain.SdHydrobase;
|
||||||
import com.yfd.platform.qgc_base.domain.SdHbrvDic;
|
import com.yfd.platform.qgc_base.domain.SdHbrvDic;
|
||||||
@ -363,25 +364,40 @@ public class TreeStructureServiceImpl implements ITreeStructureService {
|
|||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. 预加载所有流域下的电站(按流域分组)
|
if (rvcdList.isEmpty()) {
|
||||||
Map<String, List<SdEngInfoBH>> rvcdEngMap = new HashMap<>();
|
return result;
|
||||||
for (SdRvcdDic rvcdDic : rvcdList) {
|
}
|
||||||
List<SdEngInfoBH> engList = engInfoBHMapper.selectByRvcd(null,rvcdDic.getRvcd());
|
|
||||||
|
|
||||||
// 如果提供了电站名称参数,进行模糊匹配筛选
|
// 2. 收集所有流域编码,一次批量查询替代 N 次循环查询
|
||||||
if (StringUtils.hasText(engName) && engList != null) {
|
List<String> rvcdCodeList = rvcdList.stream()
|
||||||
engList = engList.stream()
|
.map(SdRvcdDic::getRvcd)
|
||||||
.filter(eng -> eng.getEnnm() != null && eng.getEnnm().contains(engName))
|
.collect(Collectors.toList());
|
||||||
.collect(Collectors.toList());
|
List<SdEngInfoBH> allEngList = engInfoBHMapper.selectList(new LambdaQueryWrapper<SdEngInfoBH>().in(SdEngInfoBH::getReachcd, rvcdCodeList));
|
||||||
}
|
// List<SdEngInfoBH> allEngList = engInfoBHMapper.selectByRvcdList(rvcdCodeList);
|
||||||
|
|
||||||
if (engList != null && !engList.isEmpty()) {
|
// 3. 按流域分组,同时在内存中过滤电站名称
|
||||||
rvcdEngMap.put(rvcdDic.getRvcd(), engList);
|
Map<String, List<SdEngInfoBH>> rvcdEngMap = new LinkedHashMap<>();
|
||||||
|
if (allEngList != null) {
|
||||||
|
for (SdEngInfoBH eng : allEngList) {
|
||||||
|
String engRvcd = eng.getReachcd();
|
||||||
|
if (!StringUtils.hasText(engRvcd) || !rvcdCodeList.contains(engRvcd)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (StringUtils.hasText(engName) && eng.getEnnm() != null
|
||||||
|
&& !eng.getEnnm().contains(engName)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
rvcdEngMap.computeIfAbsent(engRvcd, k -> new ArrayList<>()).add(eng);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. 构建二级树形结构(流域 -> 电站)
|
// 4. 构建二级树形结构(流域 -> 电站)
|
||||||
for (SdRvcdDic rvcdDic : rvcdList) {
|
for (SdRvcdDic rvcdDic : rvcdList) {
|
||||||
|
List<SdEngInfoBH> engList = rvcdEngMap.get(rvcdDic.getRvcd());
|
||||||
|
if (engList == null || engList.isEmpty()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
Map<String, Object> rvcdNode = new LinkedHashMap<>();
|
Map<String, Object> rvcdNode = new LinkedHashMap<>();
|
||||||
rvcdNode.put("type", "RVCD");
|
rvcdNode.put("type", "RVCD");
|
||||||
rvcdNode.put("code", rvcdDic.getRvcd());
|
rvcdNode.put("code", rvcdDic.getRvcd());
|
||||||
@ -389,37 +405,25 @@ public class TreeStructureServiceImpl implements ITreeStructureService {
|
|||||||
rvcdNode.put("path", rvcdDic.getPath());
|
rvcdNode.put("path", rvcdDic.getPath());
|
||||||
rvcdNode.put("orgLevel", 0);
|
rvcdNode.put("orgLevel", 0);
|
||||||
rvcdNode.put("grd", rvcdDic.getGrd());
|
rvcdNode.put("grd", rvcdDic.getGrd());
|
||||||
// rvcdNode.put("lgtd", rvcdDic.getLgtd());
|
|
||||||
// rvcdNode.put("lttd", rvcdDic.getLttd());
|
|
||||||
rvcdNode.put("parentId", "0");
|
rvcdNode.put("parentId", "0");
|
||||||
|
|
||||||
// 获取该流域下的所有电站
|
List<Map<String, Object>> engChildren = new ArrayList<>(engList.size());
|
||||||
List<SdEngInfoBH> engList = rvcdEngMap.get(rvcdDic.getRvcd());
|
for (SdEngInfoBH eng : engList) {
|
||||||
List<Map<String, Object>> engChildren = new ArrayList<>();
|
Map<String, Object> engNode = new LinkedHashMap<>();
|
||||||
|
engNode.put("type", "STATION");
|
||||||
if (engList != null && !engList.isEmpty()) {
|
engNode.put("code", eng.getStcd());
|
||||||
for (SdEngInfoBH eng : engList) {
|
engNode.put("name", eng.getEnnm());
|
||||||
Map<String, Object> engNode = new LinkedHashMap<>();
|
engNode.put("elev", eng.getElev());
|
||||||
engNode.put("type", "STATION");
|
engNode.put("usfl", eng.getUsfl());
|
||||||
engNode.put("code", eng.getStcd());
|
engNode.put("bldstt", eng.getBldstt());
|
||||||
engNode.put("name", eng.getEnnm());
|
engNode.put("engtp", eng.getEngtp());
|
||||||
// engNode.put("lgtd", eng.getLgtd());
|
engNode.put("parentId", rvcdDic.getRvcd());
|
||||||
// engNode.put("lttd", eng.getLttd());
|
engNode.put("orgLevel", 1);
|
||||||
engNode.put("elev", eng.getElev());
|
engChildren.add(engNode);
|
||||||
engNode.put("usfl", eng.getUsfl());
|
|
||||||
engNode.put("bldstt", eng.getBldstt());
|
|
||||||
engNode.put("engtp", eng.getEngtp());
|
|
||||||
engNode.put("parentId", rvcdDic.getRvcd());
|
|
||||||
engNode.put("orgLevel", 1);
|
|
||||||
engChildren.add(engNode);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 只有当该流域下有电站时才添加该流域节点
|
rvcdNode.put("children", engChildren);
|
||||||
if (!engChildren.isEmpty()) {
|
result.add(rvcdNode);
|
||||||
rvcdNode.put("children", engChildren);
|
|
||||||
result.add(rvcdNode);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|||||||
@ -24,6 +24,7 @@ import com.yfd.platform.qgc_eng.eq.entity.vo.StcdInfoVo;
|
|||||||
import com.yfd.platform.qgc_eng.eq.entity.vo.WbsbVo;
|
import com.yfd.platform.qgc_eng.eq.entity.vo.WbsbVo;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
public interface EngEqDataService {
|
public interface EngEqDataService {
|
||||||
|
|
||||||
@ -53,6 +54,26 @@ public interface EngEqDataService {
|
|||||||
|
|
||||||
EngEqRuleVo getEngLimit(DataSourceRequest dataSourceRequest);
|
EngEqRuleVo getEngLimit(DataSourceRequest dataSourceRequest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据测站编码和时间范围查询生态流量限值及来源
|
||||||
|
*
|
||||||
|
* @param stcd 测站编码
|
||||||
|
* @param startTime 开始时间 yyyy-MM-dd HH:mm:ss
|
||||||
|
* @param endTime 结束时间 yyyy-MM-dd HH:mm:ss
|
||||||
|
* @return 生态流量限值信息(含环保部/水利部限值及来源、多年平均流量及来源)
|
||||||
|
*/
|
||||||
|
EngEqRuleVo getEngLimitByTime(String stcd, String startTime, String endTime);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量查询生态流量限值及来源
|
||||||
|
*
|
||||||
|
* @param stcdList 测站编码列表
|
||||||
|
* @param startTime 开始时间 yyyy-MM-dd HH:mm:ss
|
||||||
|
* @param endTime 结束时间 yyyy-MM-dd HH:mm:ss
|
||||||
|
* @return STCD → 生态流量限值信息
|
||||||
|
*/
|
||||||
|
Map<String, EngEqRuleVo> getEngLimitByTimeBatch(List<String> stcdList, String startTime, String endTime);
|
||||||
|
|
||||||
QgcQecStaticVo getQgcStaticData(DataSourceRequest dataSourceRequest, String type);
|
QgcQecStaticVo getQgcStaticData(DataSourceRequest dataSourceRequest, String type);
|
||||||
|
|
||||||
DataSourceResult<WbsbVo> getWbsbList(DataSourceRequest dataSourceRequest);
|
DataSourceResult<WbsbVo> getWbsbList(DataSourceRequest dataSourceRequest);
|
||||||
|
|||||||
@ -47,9 +47,11 @@ import java.util.ArrayList;
|
|||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.LinkedHashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.math.RoundingMode;
|
import java.math.RoundingMode;
|
||||||
@ -57,6 +59,7 @@ import java.time.LocalDate;
|
|||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.time.ZoneId;
|
import java.time.ZoneId;
|
||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
public class EngEqDataServiceImpl implements EngEqDataService {
|
public class EngEqDataServiceImpl implements EngEqDataService {
|
||||||
@ -978,6 +981,143 @@ public class EngEqDataServiceImpl implements EngEqDataService {
|
|||||||
return vo;
|
return vo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EngEqRuleVo getEngLimitByTime(String stcd, String startTime, String endTime) {
|
||||||
|
EngEqRuleVo vo = new EngEqRuleVo().setStcd(stcd);
|
||||||
|
|
||||||
|
// 1. 查询电站信息(多年平均流量)
|
||||||
|
Map<String, Object> stationParamMap = new HashMap<>();
|
||||||
|
stationParamMap.put("stcd", stcd);
|
||||||
|
List<Map<String, Object>> stationList = microservicDynamicSQLMapper.pageAllList(
|
||||||
|
null,
|
||||||
|
"SELECT STCD, ENNM AS STNM, AVQ, AVQ_SRC FROM SD_ENGINFO_B_H " +
|
||||||
|
"WHERE STCD = #{map.stcd} AND NVL(IS_DELETED, 0) = 0",
|
||||||
|
stationParamMap
|
||||||
|
);
|
||||||
|
if (CollUtil.isNotEmpty(stationList)) {
|
||||||
|
Map<String, Object> station = stationList.get(0);
|
||||||
|
vo.setStnm(asString(station.get("STNM")));
|
||||||
|
BigDecimal avq = toBigDecimal(station.get("AVQ"));
|
||||||
|
if (avq != null) {
|
||||||
|
vo.setAvqStr(stripTrailingZeros(avq));
|
||||||
|
}
|
||||||
|
String avqSrc = asString(station.get("AVQ_SRC"));
|
||||||
|
if (StrUtil.isNotBlank(avqSrc)) {
|
||||||
|
vo.setAvqVlsr(avqSrc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 查询环保部限值规则
|
||||||
|
List<Map<String, Object>> eqmnList = queryEngLimitRuleDetails(stcd, startTime, endTime, "EQMN");
|
||||||
|
vo.setEqmnStr(buildEngLimitValue(eqmnList));
|
||||||
|
vo.setVlsr(buildEngLimitVlsr(eqmnList));
|
||||||
|
|
||||||
|
// 3. 查询水利部限值规则
|
||||||
|
List<Map<String, Object>> eqmnMwrList = queryEngLimitRuleDetails(stcd, startTime, endTime, "EQMNMWR");
|
||||||
|
vo.setEqmnmwrStr(buildEngLimitValue(eqmnMwrList));
|
||||||
|
vo.setMwrVlsr(buildEngLimitVlsr(eqmnMwrList));
|
||||||
|
|
||||||
|
return vo;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, EngEqRuleVo> getEngLimitByTimeBatch(List<String> stcdList, String startTime, String endTime) {
|
||||||
|
Map<String, EngEqRuleVo> result = new LinkedHashMap<>();
|
||||||
|
if (CollUtil.isEmpty(stcdList)) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 把列表转为 ('A','B','C') 格式的字符串
|
||||||
|
String stcdStr = stcdList.stream()
|
||||||
|
.map(s -> "'" + s + "'") // 手动加单引号
|
||||||
|
.collect(Collectors.joining(","));
|
||||||
|
|
||||||
|
String sql = "SELECT STCD, ENNM AS STNM, AVQ, AVQ_SRC FROM SD_ENGINFO_B_H " +
|
||||||
|
"WHERE STCD IN (" + stcdStr + ") " +
|
||||||
|
"AND NVL(IS_DELETED, 0) = 0";
|
||||||
|
|
||||||
|
// 此时 paramMap 甚至可以传空,因为值已经写死在 SQL 里了
|
||||||
|
List<Map<String, Object>> stationList = microservicDynamicSQLMapper.pageAllList(null, sql, new HashMap<>());
|
||||||
|
Map<String, Map<String, Object>> stationMap = new LinkedHashMap<>();
|
||||||
|
if (CollUtil.isNotEmpty(stationList)) {
|
||||||
|
for (Map<String, Object> row : stationList) {
|
||||||
|
stationMap.put(asString(row.get("STCD")), row);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 逐个查询限值规则并组装结果
|
||||||
|
for (String stcd : stcdList) {
|
||||||
|
EngEqRuleVo vo = new EngEqRuleVo().setStcd(stcd);
|
||||||
|
|
||||||
|
Map<String, Object> station = stationMap.get(stcd);
|
||||||
|
if (station != null) {
|
||||||
|
vo.setStnm(asString(station.get("STNM")));
|
||||||
|
BigDecimal avq = toBigDecimal(station.get("AVQ"));
|
||||||
|
if (avq != null) {
|
||||||
|
vo.setAvqStr(stripTrailingZeros(avq));
|
||||||
|
}
|
||||||
|
String avqSrc = asString(station.get("AVQ_SRC"));
|
||||||
|
if (StrUtil.isNotBlank(avqSrc)) {
|
||||||
|
vo.setAvqVlsr(avqSrc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Map<String, Object>> eqmnList = queryEngLimitRuleDetails(stcd, startTime, endTime, "EQMN");
|
||||||
|
vo.setEqmnStr(buildEngLimitValue(eqmnList));
|
||||||
|
vo.setVlsr(buildEngLimitVlsr(eqmnList));
|
||||||
|
|
||||||
|
List<Map<String, Object>> eqmnMwrList = queryEngLimitRuleDetails(stcd, startTime, endTime, "EQMNMWR");
|
||||||
|
vo.setEqmnmwrStr(buildEngLimitValue(eqmnMwrList));
|
||||||
|
vo.setMwrVlsr(buildEngLimitVlsr(eqmnMwrList));
|
||||||
|
|
||||||
|
result.put(stcd, vo);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 构建生态流量限值展示(不含前缀,仅时间段和限值)
|
||||||
|
*/
|
||||||
|
private String buildEngLimitValue(List<Map<String, Object>> detailList) {
|
||||||
|
if (CollUtil.isEmpty(detailList)) {
|
||||||
|
return "无限值要求";
|
||||||
|
}
|
||||||
|
List<String> parts = new ArrayList<>();
|
||||||
|
for (Map<String, Object> row : detailList) {
|
||||||
|
String beginTime = asString(row.get("BEGIN_TIME"));
|
||||||
|
String endTime = asString(row.get("END_TIME"));
|
||||||
|
BigDecimal minVal = toBigDecimal(row.get("MIN_VAL"));
|
||||||
|
if (StrUtil.length(beginTime) != 4 || StrUtil.length(endTime) != 4 || minVal == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
parts.add(String.format("%s月%s日~%s月%s日限值为:%s",
|
||||||
|
beginTime.substring(0, 2), beginTime.substring(2, 4),
|
||||||
|
endTime.substring(0, 2), endTime.substring(2, 4),
|
||||||
|
stripTrailingZeros(minVal)));
|
||||||
|
}
|
||||||
|
if (parts.isEmpty()) {
|
||||||
|
return "无限值要求";
|
||||||
|
}
|
||||||
|
return String.join(";", parts);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 提取限值来源(VLSR),去重后用逗号拼接
|
||||||
|
*/
|
||||||
|
private String buildEngLimitVlsr(List<Map<String, Object>> detailList) {
|
||||||
|
if (CollUtil.isEmpty(detailList)) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
Set<String> vlsrSet = new LinkedHashSet<>();
|
||||||
|
for (Map<String, Object> row : detailList) {
|
||||||
|
String vlsr = asString(row.get("VLSR"));
|
||||||
|
if (StrUtil.isNotBlank(vlsr)) {
|
||||||
|
vlsrSet.add(vlsr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return vlsrSet.isEmpty() ? "" : String.join(",", vlsrSet);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DataSourceResult<String> getFidKendoListCust(DataSourceRequest dataSourceRequest) {
|
public DataSourceResult<String> getFidKendoListCust(DataSourceRequest dataSourceRequest) {
|
||||||
DataSourceLoadOptionsBase loadOptions = dataSourceRequest == null ? null : dataSourceRequest.toDevRequest();
|
DataSourceLoadOptionsBase loadOptions = dataSourceRequest == null ? null : dataSourceRequest.toDevRequest();
|
||||||
|
|||||||
@ -531,14 +531,15 @@ public class VdMonitorServiceImpl implements VdMonitorService {
|
|||||||
if (StrUtil.isNotBlank(filterSql)) {
|
if (StrUtil.isNotBlank(filterSql)) {
|
||||||
sql.append(" AND ").append(filterSql).append(" ");
|
sql.append(" AND ").append(filterSql).append(" ");
|
||||||
}
|
}
|
||||||
sql.append(buildVdPointOrderBySql(dataSourceRequest == null ? null : dataSourceRequest.getSort()));
|
|
||||||
DataSourceResult<VdPointVo> result = new DataSourceResult<>();
|
DataSourceResult<VdPointVo> result = new DataSourceResult<>();
|
||||||
DataScopeApplyResult scopeApplyResult = dataScopeFilterService.appendCurrentUserStationScope(sql, paramMap, "t.RSTCD");
|
DataScopeApplyResult scopeApplyResult = dataScopeFilterService.appendCurrentUserStationScope(sql, paramMap, "t.rstcds");
|
||||||
if (scopeApplyResult.isEmptyResult()) {
|
if (scopeApplyResult.isEmptyResult()) {
|
||||||
result.setData(new ArrayList<>());
|
result.setData(new ArrayList<>());
|
||||||
result.setTotal(0L);
|
result.setTotal(0L);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
sql.append(buildVdPointOrderBySql(dataSourceRequest == null ? null : dataSourceRequest.getSort()));
|
||||||
List<VdPointVo> list = microservicDynamicSQLMapper.pageAllListWithResultType(
|
List<VdPointVo> list = microservicDynamicSQLMapper.pageAllListWithResultType(
|
||||||
page, sql.toString(), paramMap, VdPointVo.class);
|
page, sql.toString(), paramMap, VdPointVo.class);
|
||||||
result.setData(list);
|
result.setData(list);
|
||||||
|
|||||||
@ -1138,7 +1138,7 @@ public class WarnDataServiceImpl implements WarnDataService {
|
|||||||
"eng.LGTD AS lgtd, " +
|
"eng.LGTD AS lgtd, " +
|
||||||
"eng.LTTD AS lttd, " +
|
"eng.LTTD AS lttd, " +
|
||||||
"eng.ELEV AS dtmel, " +
|
"eng.ELEV AS dtmel, " +
|
||||||
"eng.YRGEB AS ttpwr, " +
|
"pwr.TTPWR AS ttpwr, " +
|
||||||
"'ENG' AS sttpMap, " +
|
"'ENG' AS sttpMap, " +
|
||||||
"CASE WHEN eng.PRSC IN (1, 2) THEN 1 WHEN eng.PRSC = 3 THEN 2 END AS endInstalledType, " +
|
"CASE WHEN eng.PRSC IN (1, 2) THEN 1 WHEN eng.PRSC = 3 THEN 2 END AS endInstalledType, " +
|
||||||
"CASE " +
|
"CASE " +
|
||||||
@ -1153,6 +1153,7 @@ public class WarnDataServiceImpl implements WarnDataService {
|
|||||||
"NVL(rstSort.SORT, 999999) AS rstcdStepSort, " +
|
"NVL(rstSort.SORT, 999999) AS rstcdStepSort, " +
|
||||||
"NVL(siteSort.SORT, 999999) AS siteStepSort " +
|
"NVL(siteSort.SORT, 999999) AS siteStepSort " +
|
||||||
"FROM SD_ENGINFO_B_H eng " +
|
"FROM SD_ENGINFO_B_H eng " +
|
||||||
|
"LEFT JOIN SD_PWR_B_H pwr ON pwr.STCD = eng.STCD AND NVL(pwr.IS_DELETED, 0) = 0 " +
|
||||||
"LEFT JOIN SD_HYDROBASE hb ON hb.BASEID = eng.BASE_ID AND NVL(hb.IS_DELETED, 0) = 0 " +
|
"LEFT JOIN SD_HYDROBASE hb ON hb.BASEID = eng.BASE_ID AND NVL(hb.IS_DELETED, 0) = 0 " +
|
||||||
"LEFT JOIN MS_ALONG_B along ON along.BASEID = eng.BASE_ID AND along.CODE = 'common' AND NVL(along.IS_DELETED, 0) = 0 " +
|
"LEFT JOIN MS_ALONG_B along ON along.BASEID = eng.BASE_ID AND along.CODE = 'common' AND NVL(along.IS_DELETED, 0) = 0 " +
|
||||||
"LEFT JOIN ( " +
|
"LEFT JOIN ( " +
|
||||||
|
|||||||
@ -7,6 +7,7 @@ import org.apache.ibatis.annotations.Param;
|
|||||||
import org.apache.ibatis.annotations.Select;
|
import org.apache.ibatis.annotations.Select;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 垂向水温年份数据Mapper
|
* 垂向水温年份数据Mapper
|
||||||
@ -28,4 +29,20 @@ public interface SdWtvtRMapper extends BaseMapper<SdWtvtYearVo> {
|
|||||||
"ORDER BY STCD, TO_CHAR(TM, 'yyyy') DESC" +
|
"ORDER BY STCD, TO_CHAR(TM, 'yyyy') DESC" +
|
||||||
"</script>")
|
"</script>")
|
||||||
List<SdWtvtYearVo> getWtrvDefaultYear(@Param("stcd") String stcd);
|
List<SdWtvtYearVo> getWtrvDefaultYear(@Param("stcd") String stcd);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询各测站水深对应的高程(HGT),按 STCD、WTHG 分组取最大值
|
||||||
|
*/
|
||||||
|
@Select("<script>" +
|
||||||
|
"SELECT STCD, WTHG, MAX(HGT) AS HGT " +
|
||||||
|
"FROM SD_WTVT_R " +
|
||||||
|
"WHERE IS_DELETED = 0 " +
|
||||||
|
"AND HGT IS NOT NULL " +
|
||||||
|
"AND STCD IN " +
|
||||||
|
"<foreach collection='stcdList' item='stcd' open='(' separator=',' close=')'>" +
|
||||||
|
"#{stcd}" +
|
||||||
|
"</foreach>" +
|
||||||
|
"GROUP BY STCD, WTHG" +
|
||||||
|
"</script>")
|
||||||
|
List<Map<String, Object>> selectDepthElevation(@Param("stcdList") List<String> stcdList);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3033,7 +3033,7 @@ public class SdWtMonitorServiceImpl implements SdWtMonitorService {
|
|||||||
// paramMap.put("dtinType", dtinType);
|
// paramMap.put("dtinType", dtinType);
|
||||||
// }
|
// }
|
||||||
|
|
||||||
DataScopeApplyResult scopeApplyResult = dataScopeFilterService.appendCurrentUserStationScope(sql, paramMap, "t.RSTCD");
|
DataScopeApplyResult scopeApplyResult = dataScopeFilterService.appendCurrentUserStationScope(sql, paramMap, "wt.RSTCD");
|
||||||
if (scopeApplyResult.isEmptyResult()) {
|
if (scopeApplyResult.isEmptyResult()) {
|
||||||
dataSourceResult.setData(new ArrayList<>());
|
dataSourceResult.setData(new ArrayList<>());
|
||||||
dataSourceResult.setTotal(0L);
|
dataSourceResult.setTotal(0L);
|
||||||
|
|||||||
@ -0,0 +1,198 @@
|
|||||||
|
package com.yfd.platform.qgc_export.controller;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
import com.yfd.platform.qgc_export.domain.ExportTask;
|
||||||
|
import com.yfd.platform.qgc_export.service.IQgcExportService;
|
||||||
|
import com.yfd.platform.qgc_export.service.ExportTaskService;
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import jakarta.annotation.Resource;
|
||||||
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.net.URLEncoder;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 综合导出控制器
|
||||||
|
*/
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/qgcExport")
|
||||||
|
@Tag(name = "综合导出")
|
||||||
|
public class QgcExportController {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private IQgcExportService qgcExportService;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private ExportTaskService exportTaskService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 原有同步导出接口(保留兼容)
|
||||||
|
*/
|
||||||
|
@PostMapping("/exportData")
|
||||||
|
@Operation(summary = "综合数据导出(ZIP 含多 Sheet Excel)— 同步返回文件流")
|
||||||
|
public void exportData(@RequestParam(required = false) String tmDimension,
|
||||||
|
@RequestParam(required = false) String dataField,
|
||||||
|
@RequestParam(required = false) String months,
|
||||||
|
@RequestParam(required = false) String stcd,
|
||||||
|
@RequestParam(required = false) String sysId,
|
||||||
|
@RequestParam(defaultValue = "true") boolean isDailyDimension,
|
||||||
|
@RequestParam(defaultValue = "false") boolean isCalcQec,
|
||||||
|
@RequestParam(required = false) String yearStatType,
|
||||||
|
@RequestParam(required = false) String year,
|
||||||
|
@RequestParam(required = false) String baseId,
|
||||||
|
HttpServletResponse response) {
|
||||||
|
|
||||||
|
List<String> dataFields = parseCsv(dataField);
|
||||||
|
List<String> monthList = parseCsv(months);
|
||||||
|
List<String> stationList = parseCsv(stcd);
|
||||||
|
List<String> baseIdList = parseCsv(baseId);
|
||||||
|
|
||||||
|
if (tmDimension == null || tmDimension.isEmpty()) {
|
||||||
|
tmDimension = "month";
|
||||||
|
}
|
||||||
|
|
||||||
|
if ("year".equals(tmDimension)) {
|
||||||
|
List<String> yearStatTypeList = parseCsv(yearStatType);
|
||||||
|
List<String> yearList = parseCsv(year);
|
||||||
|
qgcExportService.exportYearData(yearStatTypeList, yearList, stationList, baseIdList, response);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
qgcExportService.exportData(dataFields, monthList, stationList,
|
||||||
|
isDailyDimension, tmDimension, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ======================== 异步导出三接口 ========================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 接口一:创建导出任务,返回唯一任务 ID
|
||||||
|
*/
|
||||||
|
@PostMapping("/create")
|
||||||
|
@Operation(summary = "创建异步导出任务,返回 taskId")
|
||||||
|
public Map<String, Object> createTask(@RequestParam(required = false) String tmDimension,
|
||||||
|
@RequestParam(required = false) String dataField,
|
||||||
|
@RequestParam(required = false) String months,
|
||||||
|
@RequestParam(required = false) String stcd,
|
||||||
|
@RequestParam(defaultValue = "true") boolean isDailyDimension,
|
||||||
|
@RequestParam(required = false) String yearStatType,
|
||||||
|
@RequestParam(required = false) String year,
|
||||||
|
@RequestParam(required = false) String baseId) {
|
||||||
|
|
||||||
|
List<String> dataFields = parseCsv(dataField);
|
||||||
|
List<String> monthList = parseCsv(months);
|
||||||
|
List<String> stationList = parseCsv(stcd);
|
||||||
|
List<String> baseIdList = parseCsv(baseId);
|
||||||
|
|
||||||
|
if (tmDimension == null || tmDimension.isEmpty()) {
|
||||||
|
tmDimension = "month";
|
||||||
|
}
|
||||||
|
|
||||||
|
String taskId;
|
||||||
|
if ("year".equals(tmDimension)) {
|
||||||
|
List<String> yearStatTypeList = parseCsv(yearStatType);
|
||||||
|
List<String> yearList = parseCsv(year);
|
||||||
|
taskId = exportTaskService.submitYearExport(yearStatTypeList, yearList, stationList, baseIdList);
|
||||||
|
} else {
|
||||||
|
taskId = exportTaskService.submitMonthExport(dataFields, monthList, stationList,
|
||||||
|
isDailyDimension, tmDimension);
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, Object> result = new HashMap<>();
|
||||||
|
result.put("taskId", taskId);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 接口二:查询任务状态
|
||||||
|
*/
|
||||||
|
@GetMapping("/status")
|
||||||
|
@Operation(summary = "查询异步导出任务状态")
|
||||||
|
public Map<String, Object> getStatus(@RequestParam String taskId) {
|
||||||
|
ExportTask task = exportTaskService.getTask(taskId);
|
||||||
|
Map<String, Object> result = new HashMap<>();
|
||||||
|
if (task == null) {
|
||||||
|
result.put("exists", false);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
result.put("exists", true);
|
||||||
|
result.put("taskId", task.getTaskId());
|
||||||
|
result.put("status", task.getStatus().name());
|
||||||
|
result.put("statusDesc", task.getStatus().getDesc());
|
||||||
|
if (task.getErrorMessage() != null) {
|
||||||
|
result.put("errorMessage", task.getErrorMessage());
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 接口三:下载导出文件(参数与 /exportData 一致 + taskId,文件名根据 tmDimension 生成)
|
||||||
|
*/
|
||||||
|
@PostMapping("/download")
|
||||||
|
@Operation(summary = "下载异步导出的 ZIP 文件")
|
||||||
|
public void download(@RequestParam String taskId,
|
||||||
|
@RequestParam(required = false) String tmDimension,
|
||||||
|
@RequestParam(required = false) String dataField,
|
||||||
|
@RequestParam(required = false) String months,
|
||||||
|
@RequestParam(required = false) String stcd,
|
||||||
|
@RequestParam(defaultValue = "true") boolean isDailyDimension,
|
||||||
|
@RequestParam(required = false) String yearStatType,
|
||||||
|
@RequestParam(required = false) String year,
|
||||||
|
@RequestParam(required = false) String baseId,
|
||||||
|
HttpServletResponse response) {
|
||||||
|
ExportTask task = exportTaskService.getTask(taskId);
|
||||||
|
if (task == null || task.getStatus() != ExportTask.Status.DONE) {
|
||||||
|
response.setStatus(404);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tmDimension == null || tmDimension.isEmpty()) {
|
||||||
|
tmDimension = "month";
|
||||||
|
}
|
||||||
|
|
||||||
|
String zipFileName = getFileNamePrefix(tmDimension) + ".zip";
|
||||||
|
response.setContentType("application/zip");
|
||||||
|
response.setCharacterEncoding("UTF-8");
|
||||||
|
try {
|
||||||
|
response.setHeader("Content-Disposition",
|
||||||
|
"attachment; filename=" + URLEncoder.encode(zipFileName, "UTF-8"));
|
||||||
|
} catch (IOException e) {
|
||||||
|
response.setHeader("Content-Disposition", "attachment; filename=" + zipFileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
try (OutputStream os = response.getOutputStream()) {
|
||||||
|
exportTaskService.downloadTask(taskId, os);
|
||||||
|
} catch (IOException e) {
|
||||||
|
response.setStatus(500);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ======================== 工具方法 ========================
|
||||||
|
|
||||||
|
private static String getFileNamePrefix(String tmDimension) {
|
||||||
|
return switch (tmDimension) {
|
||||||
|
case "year" -> "年度报表";
|
||||||
|
case "month" -> "月度报表";
|
||||||
|
case "day" -> "日度报表";
|
||||||
|
case "hour" -> "小时报表";
|
||||||
|
default -> "未知报表";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<String> parseCsv(String value) {
|
||||||
|
if (StrUtil.isBlank(value)) {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
return Arrays.stream(value.split(","))
|
||||||
|
.map(String::trim)
|
||||||
|
.filter(StrUtil::isNotBlank)
|
||||||
|
.collect(java.util.stream.Collectors.toList());
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,58 @@
|
|||||||
|
package com.yfd.platform.qgc_export.domain;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导出任务 — 用于异步导出
|
||||||
|
*/
|
||||||
|
public class ExportTask {
|
||||||
|
|
||||||
|
public enum Status {
|
||||||
|
CREATED("已创建"),
|
||||||
|
PROCESSING("处理中"),
|
||||||
|
DONE("已完成"),
|
||||||
|
ERROR("失败");
|
||||||
|
|
||||||
|
private final String desc;
|
||||||
|
|
||||||
|
Status(String desc) { this.desc = desc; }
|
||||||
|
|
||||||
|
public String getDesc() { return desc; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 任务唯一 ID */
|
||||||
|
private String taskId;
|
||||||
|
/** 任务状态 */
|
||||||
|
private Status status;
|
||||||
|
/** 导出完成的临时文件 */
|
||||||
|
private File file;
|
||||||
|
/** ZIP 文件名 */
|
||||||
|
private String fileName;
|
||||||
|
/** 错误信息(status=ERROR 时) */
|
||||||
|
private String errorMessage;
|
||||||
|
/** 创建时间戳 */
|
||||||
|
private long createTime;
|
||||||
|
|
||||||
|
public ExportTask(String taskId) {
|
||||||
|
this.taskId = taskId;
|
||||||
|
this.status = Status.CREATED;
|
||||||
|
this.createTime = System.currentTimeMillis();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTaskId() { return taskId; }
|
||||||
|
public void setTaskId(String taskId) { this.taskId = taskId; }
|
||||||
|
|
||||||
|
public Status getStatus() { return status; }
|
||||||
|
public void setStatus(Status status) { this.status = status; }
|
||||||
|
|
||||||
|
public File getFile() { return file; }
|
||||||
|
public void setFile(File file) { this.file = file; }
|
||||||
|
|
||||||
|
public String getFileName() { return fileName; }
|
||||||
|
public void setFileName(String fileName) { this.fileName = fileName; }
|
||||||
|
|
||||||
|
public String getErrorMessage() { return errorMessage; }
|
||||||
|
public void setErrorMessage(String errorMessage) { this.errorMessage = errorMessage; }
|
||||||
|
|
||||||
|
public long getCreateTime() { return createTime; }
|
||||||
|
}
|
||||||
@ -0,0 +1,89 @@
|
|||||||
|
package com.yfd.platform.qgc_export.domain;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 电站运行数据表(小时级)
|
||||||
|
* 对应 Oracle 表: QGC_REFA.SD_HYDROPW_R
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@TableName("SD_HYDROPW_R")
|
||||||
|
public class SdHydropwR implements Serializable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
@TableId(type = IdType.INPUT)
|
||||||
|
private String id;
|
||||||
|
|
||||||
|
/** 水电工程编码 */
|
||||||
|
private String stcd;
|
||||||
|
|
||||||
|
/** 数据时间 */
|
||||||
|
private Date tm;
|
||||||
|
|
||||||
|
/** 坝上水位 (m) */
|
||||||
|
private BigDecimal rz;
|
||||||
|
|
||||||
|
/** 蓄水量 */
|
||||||
|
private BigDecimal w;
|
||||||
|
|
||||||
|
/** 坝下水位 (m) */
|
||||||
|
private BigDecimal dz;
|
||||||
|
|
||||||
|
/** 入库流量 */
|
||||||
|
private BigDecimal qi;
|
||||||
|
|
||||||
|
/** 出库流量 */
|
||||||
|
private BigDecimal qo;
|
||||||
|
|
||||||
|
/** 发电流量 */
|
||||||
|
private BigDecimal qn;
|
||||||
|
|
||||||
|
/** 泄洪流量 */
|
||||||
|
private BigDecimal qgt;
|
||||||
|
|
||||||
|
/** 生态流量 */
|
||||||
|
private BigDecimal qec;
|
||||||
|
|
||||||
|
/** 灌溉流量 */
|
||||||
|
private BigDecimal qc;
|
||||||
|
|
||||||
|
/** 发电量 */
|
||||||
|
private BigDecimal ge;
|
||||||
|
|
||||||
|
/** 平均出力 */
|
||||||
|
private BigDecimal na;
|
||||||
|
|
||||||
|
/** 生态流量是否达标 */
|
||||||
|
private Integer sfdb;
|
||||||
|
|
||||||
|
/** 泄洪水量 */
|
||||||
|
private BigDecimal gtw;
|
||||||
|
|
||||||
|
/** 发电水量 */
|
||||||
|
private BigDecimal wge;
|
||||||
|
|
||||||
|
/** 区间流量 */
|
||||||
|
private BigDecimal qr;
|
||||||
|
|
||||||
|
/** 耗水率 */
|
||||||
|
private BigDecimal wr;
|
||||||
|
|
||||||
|
/** 记录人等... */
|
||||||
|
private String recordUser;
|
||||||
|
private Date recordTime;
|
||||||
|
private String modifyUser;
|
||||||
|
private Date modifyTime;
|
||||||
|
private Integer isDeleted;
|
||||||
|
private String deleteUser;
|
||||||
|
private Date deleteTime;
|
||||||
|
private String fid;
|
||||||
|
private String remark;
|
||||||
|
}
|
||||||
@ -0,0 +1,72 @@
|
|||||||
|
package com.yfd.platform.qgc_export.domain;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 电站运行数据日统计表
|
||||||
|
* 对应 Oracle 表: QGC_REFA.SD_HYDROPWDAY_S
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@TableName("SD_HYDROPWDAY_S")
|
||||||
|
public class SdHydropwdayS implements Serializable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
@TableId(type = IdType.INPUT)
|
||||||
|
private String id;
|
||||||
|
|
||||||
|
/** 水电工程编码 */
|
||||||
|
private String stcd;
|
||||||
|
|
||||||
|
/** 时间 */
|
||||||
|
private Date dt;
|
||||||
|
|
||||||
|
/** 坝上水位 (m) */
|
||||||
|
private BigDecimal rz;
|
||||||
|
|
||||||
|
/** 蓄水量 */
|
||||||
|
private BigDecimal w;
|
||||||
|
|
||||||
|
/** 坝下水位 (m) */
|
||||||
|
private BigDecimal dz;
|
||||||
|
|
||||||
|
/** 入库流量 */
|
||||||
|
private BigDecimal qi;
|
||||||
|
|
||||||
|
/** 出库流量 */
|
||||||
|
private BigDecimal qo;
|
||||||
|
|
||||||
|
/** 发电流量 */
|
||||||
|
private BigDecimal qn;
|
||||||
|
|
||||||
|
/** 泄洪流量 */
|
||||||
|
private BigDecimal qgt;
|
||||||
|
|
||||||
|
/** 生态流量 */
|
||||||
|
private BigDecimal qec;
|
||||||
|
|
||||||
|
/** 灌溉流量 */
|
||||||
|
private BigDecimal qc;
|
||||||
|
|
||||||
|
/** 发电量 */
|
||||||
|
private BigDecimal ge;
|
||||||
|
|
||||||
|
/** 平均出力 */
|
||||||
|
private BigDecimal na;
|
||||||
|
|
||||||
|
/** 记录人等... */
|
||||||
|
private String recordUser;
|
||||||
|
private Date recordTime;
|
||||||
|
private String modifyUser;
|
||||||
|
private Date modifyTime;
|
||||||
|
private Integer isDeleted;
|
||||||
|
private String deleteUser;
|
||||||
|
private Date deleteTime;
|
||||||
|
}
|
||||||
@ -0,0 +1,50 @@
|
|||||||
|
package com.yfd.platform.qgc_export.domain;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生态流量监测数据表(小时级)
|
||||||
|
* 对应 Oracle 表: QGC_REFA.SD_QEC_R
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@TableName("SD_QEC_R")
|
||||||
|
public class SdQecR implements Serializable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
@TableId(type = IdType.INPUT)
|
||||||
|
private String id;
|
||||||
|
|
||||||
|
/** 水电工程编码 */
|
||||||
|
private String stcd;
|
||||||
|
|
||||||
|
/** 数据识别时间 */
|
||||||
|
private Date tm;
|
||||||
|
|
||||||
|
/** 生态流量 (m³/s) */
|
||||||
|
private BigDecimal qec;
|
||||||
|
|
||||||
|
/** AI识别生态流量值 */
|
||||||
|
private BigDecimal waterflow;
|
||||||
|
|
||||||
|
/** 生态流量泄放方式 */
|
||||||
|
private String tpqec;
|
||||||
|
|
||||||
|
/** 生态流量是否达标 */
|
||||||
|
private Integer sfdb;
|
||||||
|
|
||||||
|
private String recordUser;
|
||||||
|
private Date recordTime;
|
||||||
|
private String modifyUser;
|
||||||
|
private Date modifyTime;
|
||||||
|
private Integer isDeleted;
|
||||||
|
private String deleteUser;
|
||||||
|
private Date deleteTime;
|
||||||
|
}
|
||||||
@ -0,0 +1,50 @@
|
|||||||
|
package com.yfd.platform.qgc_export.domain;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生态流量监测数据日统计表
|
||||||
|
* 对应 Oracle 表: QGC_REFA.SD_QECDAY_S
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@TableName("SD_QECDAY_S")
|
||||||
|
public class SdQecdayS implements Serializable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
@TableId(type = IdType.INPUT)
|
||||||
|
private String id;
|
||||||
|
|
||||||
|
/** 水电工程编码 */
|
||||||
|
private String stcd;
|
||||||
|
|
||||||
|
/** 数据识别时间 */
|
||||||
|
private Date dt;
|
||||||
|
|
||||||
|
/** 生态流量 (m³/s) */
|
||||||
|
private BigDecimal qec;
|
||||||
|
|
||||||
|
/** AI识别生态流量值 */
|
||||||
|
private BigDecimal waterflow;
|
||||||
|
|
||||||
|
/** 生态流量泄放方式 */
|
||||||
|
private String tpqec;
|
||||||
|
|
||||||
|
/** 生态流量是否达标 */
|
||||||
|
private Integer sfdb;
|
||||||
|
|
||||||
|
private String recordUser;
|
||||||
|
private Date recordTime;
|
||||||
|
private String modifyUser;
|
||||||
|
private Date modifyTime;
|
||||||
|
private Integer isDeleted;
|
||||||
|
private String deleteUser;
|
||||||
|
private Date deleteTime;
|
||||||
|
}
|
||||||
@ -0,0 +1,69 @@
|
|||||||
|
package com.yfd.platform.qgc_export.domain;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 河道水情监测数据表(小时级)
|
||||||
|
* 对应 Oracle 表: QGC_REFA.SD_RIVER_R
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@TableName("SD_RIVER_R")
|
||||||
|
public class SdRiverR implements Serializable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
@TableId(type = IdType.INPUT)
|
||||||
|
private String id;
|
||||||
|
|
||||||
|
/** 站码 */
|
||||||
|
private String stcd;
|
||||||
|
|
||||||
|
/** 时间 */
|
||||||
|
private Date tm;
|
||||||
|
|
||||||
|
/** 水位 (m) */
|
||||||
|
private BigDecimal z;
|
||||||
|
|
||||||
|
/** 流量 (m³/s) */
|
||||||
|
private BigDecimal q;
|
||||||
|
|
||||||
|
/** 流速 (m/s) */
|
||||||
|
private BigDecimal v;
|
||||||
|
|
||||||
|
/** 测流方法 */
|
||||||
|
private String msqmt;
|
||||||
|
|
||||||
|
/** 创建人 */
|
||||||
|
private String recordUser;
|
||||||
|
|
||||||
|
/** 创建时间 */
|
||||||
|
private Date recordTime;
|
||||||
|
|
||||||
|
/** 更新人 */
|
||||||
|
private String modifyUser;
|
||||||
|
|
||||||
|
/** 更新时间 */
|
||||||
|
private Date modifyTime;
|
||||||
|
|
||||||
|
/** 是否已删除: 0=未删除 1=已删除 */
|
||||||
|
private Integer isDeleted;
|
||||||
|
|
||||||
|
/** 删除人 */
|
||||||
|
private String deleteUser;
|
||||||
|
|
||||||
|
/** 删除时间 */
|
||||||
|
private Date deleteTime;
|
||||||
|
|
||||||
|
/** 附件ID */
|
||||||
|
private String fid;
|
||||||
|
|
||||||
|
/** 备注 */
|
||||||
|
private String remark;
|
||||||
|
}
|
||||||
@ -0,0 +1,63 @@
|
|||||||
|
package com.yfd.platform.qgc_export.domain;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 河道水情监测数据天统计表(日级)
|
||||||
|
* 对应 Oracle 表: QGC_REFA.SD_RIVERDAY_S
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@TableName("SD_RIVERDAY_S")
|
||||||
|
public class SdRiverdayS implements Serializable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
@TableId(type = IdType.INPUT)
|
||||||
|
private String id;
|
||||||
|
|
||||||
|
/** 站码 */
|
||||||
|
private String stcd;
|
||||||
|
|
||||||
|
/** 时间 */
|
||||||
|
private Date dt;
|
||||||
|
|
||||||
|
/** 水位 (m) */
|
||||||
|
private BigDecimal z;
|
||||||
|
|
||||||
|
/** 流量 (m³/s) */
|
||||||
|
private BigDecimal q;
|
||||||
|
|
||||||
|
/** 流速 (m/s) */
|
||||||
|
private BigDecimal v;
|
||||||
|
|
||||||
|
/** 测流方法 */
|
||||||
|
private String msqmt;
|
||||||
|
|
||||||
|
/** 创建人 */
|
||||||
|
private String recordUser;
|
||||||
|
|
||||||
|
/** 创建时间 */
|
||||||
|
private Date recordTime;
|
||||||
|
|
||||||
|
/** 更新人 */
|
||||||
|
private String modifyUser;
|
||||||
|
|
||||||
|
/** 更新时间 */
|
||||||
|
private Date modifyTime;
|
||||||
|
|
||||||
|
/** 是否已删除: 0=未删除 1=已删除 */
|
||||||
|
private Integer isDeleted;
|
||||||
|
|
||||||
|
/** 删除人 */
|
||||||
|
private String deleteUser;
|
||||||
|
|
||||||
|
/** 删除时间 */
|
||||||
|
private Date deleteTime;
|
||||||
|
}
|
||||||
@ -0,0 +1,51 @@
|
|||||||
|
package com.yfd.platform.qgc_export.domain;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 水质监测数据表(小时级)
|
||||||
|
* 对应 Oracle 表: QGC_REFA.SD_WQ_R
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@TableName("SD_WQ_R")
|
||||||
|
public class SdWqR implements Serializable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
@TableId(type = IdType.INPUT)
|
||||||
|
private String id;
|
||||||
|
|
||||||
|
/** 站码 */
|
||||||
|
private String stcd;
|
||||||
|
|
||||||
|
/** 采样时间 */
|
||||||
|
private Date tm;
|
||||||
|
|
||||||
|
/** 水温 (℃) */
|
||||||
|
private BigDecimal wtmp;
|
||||||
|
|
||||||
|
/** PH */
|
||||||
|
private BigDecimal ph;
|
||||||
|
|
||||||
|
/** 溶解氧 (mg/L) */
|
||||||
|
private BigDecimal dox;
|
||||||
|
|
||||||
|
/** 电导率 (μS/cm) */
|
||||||
|
private BigDecimal cond;
|
||||||
|
|
||||||
|
/** 浊度 (NTU) */
|
||||||
|
private BigDecimal tu;
|
||||||
|
|
||||||
|
/** 是否达标: 0=不达标 1=达标 */
|
||||||
|
private Integer sfdb;
|
||||||
|
|
||||||
|
/** 是否已删除 */
|
||||||
|
private Integer isDeleted;
|
||||||
|
}
|
||||||
@ -0,0 +1,51 @@
|
|||||||
|
package com.yfd.platform.qgc_export.domain;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 水质监测日数据表
|
||||||
|
* 对应 Oracle 表: QGC_REFA.SD_WQDAY_S
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@TableName("SD_WQDAY_S")
|
||||||
|
public class SdWqdayS implements Serializable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
@TableId(type = IdType.INPUT)
|
||||||
|
private String id;
|
||||||
|
|
||||||
|
/** 站码 */
|
||||||
|
private String stcd;
|
||||||
|
|
||||||
|
/** 时间 */
|
||||||
|
private Date dt;
|
||||||
|
|
||||||
|
/** 水温 (℃) */
|
||||||
|
private BigDecimal wtmp;
|
||||||
|
|
||||||
|
/** PH */
|
||||||
|
private BigDecimal ph;
|
||||||
|
|
||||||
|
/** 溶解氧 (mg/L) */
|
||||||
|
private BigDecimal dox;
|
||||||
|
|
||||||
|
/** 电导率 (μS/cm) */
|
||||||
|
private BigDecimal cond;
|
||||||
|
|
||||||
|
/** 浊度 (NTU) */
|
||||||
|
private BigDecimal tu;
|
||||||
|
|
||||||
|
/** 是否达标 */
|
||||||
|
private Integer sfdb;
|
||||||
|
|
||||||
|
/** 是否已删除 */
|
||||||
|
private Integer isDeleted;
|
||||||
|
}
|
||||||
@ -0,0 +1,63 @@
|
|||||||
|
package com.yfd.platform.qgc_export.domain;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 河道水温监测数据表(小时级)
|
||||||
|
* 对应 Oracle 表: QGC_REFA.SD_WTRV_R
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@TableName("SD_WTRV_R")
|
||||||
|
public class SdWtrvR implements Serializable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
@TableId(type = IdType.INPUT)
|
||||||
|
private String id;
|
||||||
|
|
||||||
|
/** 水温站编码 */
|
||||||
|
private String stcd;
|
||||||
|
|
||||||
|
/** 数据时间 */
|
||||||
|
private Date tm;
|
||||||
|
|
||||||
|
/** 水温 (℃) */
|
||||||
|
private BigDecimal wt;
|
||||||
|
|
||||||
|
/** 备注 */
|
||||||
|
private String remark;
|
||||||
|
|
||||||
|
/** 附件ID */
|
||||||
|
private String fid;
|
||||||
|
|
||||||
|
/** 所属水生生态调查数据表ID */
|
||||||
|
private String werId;
|
||||||
|
|
||||||
|
/** 创建人 */
|
||||||
|
private String recordUser;
|
||||||
|
|
||||||
|
/** 创建时间 */
|
||||||
|
private Date recordTime;
|
||||||
|
|
||||||
|
/** 更新人 */
|
||||||
|
private String modifyUser;
|
||||||
|
|
||||||
|
/** 更新时间 */
|
||||||
|
private Date modifyTime;
|
||||||
|
|
||||||
|
/** 是否已删除 */
|
||||||
|
private Integer isDeleted;
|
||||||
|
|
||||||
|
/** 删除人 */
|
||||||
|
private String deleteUser;
|
||||||
|
|
||||||
|
/** 删除时间 */
|
||||||
|
private Date deleteTime;
|
||||||
|
}
|
||||||
@ -0,0 +1,54 @@
|
|||||||
|
package com.yfd.platform.qgc_export.domain;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 河道水温监测数据日统计表
|
||||||
|
* 对应 Oracle 表: QGC_REFA.SD_WTRVDAY_S
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@TableName("SD_WTRVDAY_S")
|
||||||
|
public class SdWtrvdayS implements Serializable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
@TableId(type = IdType.INPUT)
|
||||||
|
private String id;
|
||||||
|
|
||||||
|
/** 水温站编码 */
|
||||||
|
private String stcd;
|
||||||
|
|
||||||
|
/** 数据时间 */
|
||||||
|
private Date dt;
|
||||||
|
|
||||||
|
/** 水温 (℃) */
|
||||||
|
private BigDecimal wt;
|
||||||
|
|
||||||
|
/** 创建人 */
|
||||||
|
private String recordUser;
|
||||||
|
|
||||||
|
/** 创建时间 */
|
||||||
|
private Date recordTime;
|
||||||
|
|
||||||
|
/** 更新人 */
|
||||||
|
private String modifyUser;
|
||||||
|
|
||||||
|
/** 更新时间 */
|
||||||
|
private Date modifyTime;
|
||||||
|
|
||||||
|
/** 是否已删除 */
|
||||||
|
private Integer isDeleted;
|
||||||
|
|
||||||
|
/** 删除人 */
|
||||||
|
private String deleteUser;
|
||||||
|
|
||||||
|
/** 删除时间 */
|
||||||
|
private Date deleteTime;
|
||||||
|
}
|
||||||
@ -0,0 +1,27 @@
|
|||||||
|
package com.yfd.platform.qgc_export.domain;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SD_WTVTDAY_S 垂向水温日统计表
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@TableName("SD_WTVTDAY_S")
|
||||||
|
public class SdWtvtdayS implements Serializable {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
private String id;
|
||||||
|
private String stcd;
|
||||||
|
private Date dt;
|
||||||
|
private BigDecimal wthg; // 水深
|
||||||
|
private BigDecimal vwt; // 水温
|
||||||
|
private String recordUser;
|
||||||
|
private Date recordTime;
|
||||||
|
private Date modifyTime;
|
||||||
|
private Integer isDeleted;
|
||||||
|
}
|
||||||
@ -0,0 +1,56 @@
|
|||||||
|
package com.yfd.platform.qgc_export.domain;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableField;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* V_MS_STBPRP_T 视图扩展映射 — 用于年度导出时获取流域、基地等信息
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@TableName("V_MS_STBPRP_T")
|
||||||
|
public class StationInfo implements Serializable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
@TableField("STCD")
|
||||||
|
private String stcd;
|
||||||
|
|
||||||
|
@TableField("STNM")
|
||||||
|
private String stnm;
|
||||||
|
|
||||||
|
@TableField("ENNM")
|
||||||
|
private String ennm;
|
||||||
|
|
||||||
|
@TableField("STTP")
|
||||||
|
private String sttp;
|
||||||
|
|
||||||
|
@TableField("RSTCD")
|
||||||
|
private String rstcd;
|
||||||
|
|
||||||
|
@TableField("BASE_ID")
|
||||||
|
private String baseId;
|
||||||
|
|
||||||
|
@TableField("BASE_NAME")
|
||||||
|
private String baseName;
|
||||||
|
|
||||||
|
@TableField("HBRVCD_NAME")
|
||||||
|
private String hbrvcdName;
|
||||||
|
|
||||||
|
@TableField("RVCD_NAME")
|
||||||
|
private String rvcdName;
|
||||||
|
|
||||||
|
@TableField("REACHCD")
|
||||||
|
private String reachcd;
|
||||||
|
|
||||||
|
@TableField("REACHCD_NAME")
|
||||||
|
private String reachcdName;
|
||||||
|
|
||||||
|
@TableField("HYNM")
|
||||||
|
private String hynm;
|
||||||
|
|
||||||
|
@TableField("MWAY")
|
||||||
|
private Integer mway;
|
||||||
|
}
|
||||||
@ -0,0 +1,38 @@
|
|||||||
|
package com.yfd.platform.qgc_export.domain;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableField;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* V_MS_STBPRP_T 视图 — 仅用于电站→测站映射
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@TableName("V_MS_STBPRP_T")
|
||||||
|
public class StationMapping implements Serializable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
@TableField("STCD")
|
||||||
|
private String stcd;
|
||||||
|
|
||||||
|
@TableField("RSTCD")
|
||||||
|
private String rstcd;
|
||||||
|
|
||||||
|
@TableField("ENNM")
|
||||||
|
private String ennm;
|
||||||
|
|
||||||
|
/** 测站类型(如 ZQ=河道水情, XX=生态流量等),用于区分同一电站下不同类型的测站 */
|
||||||
|
@TableField("STTP")
|
||||||
|
private String sttp;
|
||||||
|
|
||||||
|
/** 测站名称 */
|
||||||
|
@TableField("STNM")
|
||||||
|
private String stnm;
|
||||||
|
|
||||||
|
/** 所属水电基地名称 */
|
||||||
|
@TableField("BASE_NAME")
|
||||||
|
private String baseName;
|
||||||
|
}
|
||||||
@ -0,0 +1,25 @@
|
|||||||
|
package com.yfd.platform.qgc_export.mapper;
|
||||||
|
|
||||||
|
import org.apache.ibatis.annotations.Param;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MS_ALONGDET_B 沿程配置详情表 Mapper
|
||||||
|
*/
|
||||||
|
public interface MsAlongdetBMapper {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询指定 STTP 类型的出库沿程配置(IO_DIRECTION=1),按 SORT 排序。
|
||||||
|
*/
|
||||||
|
List<Map<String, Object>> selectAlongStations(@Param("sttp") String sttp,
|
||||||
|
@Param("rstcdList") List<String> rstcdList);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询所有沿程配置的电站排序(MS_ALONG_B JOIN MS_ALONGDET_B),
|
||||||
|
* 按 MS_ALONG_B.ORDER_INDEX, MS_ALONGDET_B.SORT 排序。
|
||||||
|
* 返回 RSTCD, ORDER_INDEX。
|
||||||
|
*/
|
||||||
|
List<Map<String, Object>> selectAlongSortOrder(@Param("rstcdList") List<String> rstcdList);
|
||||||
|
}
|
||||||
@ -0,0 +1,28 @@
|
|||||||
|
package com.yfd.platform.qgc_export.mapper;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import com.yfd.platform.qgc_export.domain.SdHydropwR;
|
||||||
|
import org.apache.ibatis.annotations.Param;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SD_HYDROPW_R 电站运行小时数据 Mapper
|
||||||
|
*/
|
||||||
|
public interface SdHydropwRMapper extends BaseMapper<SdHydropwR> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量查询测站在指定时间范围内的原始小时数据(动态字段)
|
||||||
|
*
|
||||||
|
* @param stcdList 测站编码列表
|
||||||
|
* @param fieldName 查询字段名(RZ/DZ)
|
||||||
|
* @param startTime 起始时间
|
||||||
|
* @param endTime 结束时间
|
||||||
|
* @return [STCD, TM, VALUE]
|
||||||
|
*/
|
||||||
|
List<Map<String, Object>> selectRawData(@Param("stcdList") List<String> stcdList,
|
||||||
|
@Param("fieldName") String fieldName,
|
||||||
|
@Param("startTime") String startTime,
|
||||||
|
@Param("endTime") String endTime);
|
||||||
|
}
|
||||||
@ -0,0 +1,28 @@
|
|||||||
|
package com.yfd.platform.qgc_export.mapper;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import com.yfd.platform.qgc_export.domain.SdHydropwdayS;
|
||||||
|
import org.apache.ibatis.annotations.Param;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SD_HYDROPWDAY_S 电站运行日数据 Mapper
|
||||||
|
*/
|
||||||
|
public interface SdHydropwdaySMapper extends BaseMapper<SdHydropwdayS> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量查询测站在指定时间范围内的原始日数据(动态字段)
|
||||||
|
*
|
||||||
|
* @param stcdList 测站编码列表
|
||||||
|
* @param fieldName 查询字段名(RZ/DZ)
|
||||||
|
* @param startTime 起始时间
|
||||||
|
* @param endTime 结束时间
|
||||||
|
* @return [STCD, DT, VALUE]
|
||||||
|
*/
|
||||||
|
List<Map<String, Object>> selectRawData(@Param("stcdList") List<String> stcdList,
|
||||||
|
@Param("fieldName") String fieldName,
|
||||||
|
@Param("startTime") String startTime,
|
||||||
|
@Param("endTime") String endTime);
|
||||||
|
}
|
||||||
@ -0,0 +1,25 @@
|
|||||||
|
package com.yfd.platform.qgc_export.mapper;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import com.yfd.platform.qgc_export.domain.SdQecR;
|
||||||
|
import org.apache.ibatis.annotations.Param;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SD_QEC_R 生态流量小时数据 Mapper
|
||||||
|
*/
|
||||||
|
public interface SdQecRMapper extends BaseMapper<SdQecR> {
|
||||||
|
|
||||||
|
List<Map<String, Object>> selectRawData(@Param("stcdList") List<String> stcdList,
|
||||||
|
@Param("startTime") String startTime,
|
||||||
|
@Param("endTime") String endTime);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询生态流量达标数据(小时级),返回三种 SFDB 字段
|
||||||
|
*/
|
||||||
|
List<Map<String, Object>> selectComplianceData(@Param("stcdList") List<String> stcdList,
|
||||||
|
@Param("startTime") String startTime,
|
||||||
|
@Param("endTime") String endTime);
|
||||||
|
}
|
||||||
@ -0,0 +1,25 @@
|
|||||||
|
package com.yfd.platform.qgc_export.mapper;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import com.yfd.platform.qgc_export.domain.SdQecdayS;
|
||||||
|
import org.apache.ibatis.annotations.Param;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SD_QECDAY_S 生态流量日数据 Mapper
|
||||||
|
*/
|
||||||
|
public interface SdQecdaySMapper extends BaseMapper<SdQecdayS> {
|
||||||
|
|
||||||
|
List<Map<String, Object>> selectRawData(@Param("stcdList") List<String> stcdList,
|
||||||
|
@Param("startTime") String startTime,
|
||||||
|
@Param("endTime") String endTime);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询生态流量达标数据(日级),返回三种 SFDB 字段
|
||||||
|
*/
|
||||||
|
List<Map<String, Object>> selectComplianceData(@Param("stcdList") List<String> stcdList,
|
||||||
|
@Param("startTime") String startTime,
|
||||||
|
@Param("endTime") String endTime);
|
||||||
|
}
|
||||||
@ -0,0 +1,28 @@
|
|||||||
|
package com.yfd.platform.qgc_export.mapper;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import com.yfd.platform.qgc_export.domain.SdRiverR;
|
||||||
|
import org.apache.ibatis.annotations.Param;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SD_RIVER_R 河道水情小时数据 Mapper
|
||||||
|
*/
|
||||||
|
public interface SdRiverRMapper extends BaseMapper<SdRiverR> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量查询站点在指定时间范围内的原始小时数据
|
||||||
|
*
|
||||||
|
* @param stcdList 测站编码列表
|
||||||
|
* @param fieldName 查询字段名(V/Q/Z)
|
||||||
|
* @param startTime 起始时间
|
||||||
|
* @param endTime 结束时间
|
||||||
|
* @return [STCD, TM, VALUE]
|
||||||
|
*/
|
||||||
|
List<Map<String, Object>> selectRawData(@Param("stcdList") List<String> stcdList,
|
||||||
|
@Param("fieldName") String fieldName,
|
||||||
|
@Param("startTime") String startTime,
|
||||||
|
@Param("endTime") String endTime);
|
||||||
|
}
|
||||||
@ -0,0 +1,28 @@
|
|||||||
|
package com.yfd.platform.qgc_export.mapper;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import com.yfd.platform.qgc_export.domain.SdRiverdayS;
|
||||||
|
import org.apache.ibatis.annotations.Param;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SD_RIVERDAY_S 河道水情日数据 Mapper
|
||||||
|
*/
|
||||||
|
public interface SdRiverdaySMapper extends BaseMapper<SdRiverdayS> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量查询站点在指定时间范围内的原始日数据
|
||||||
|
*
|
||||||
|
* @param stcdList 测站编码列表
|
||||||
|
* @param fieldName 查询字段名(V/Q/Z)
|
||||||
|
* @param startTime 起始时间
|
||||||
|
* @param endTime 结束时间
|
||||||
|
* @return [STCD, DT, VALUE]
|
||||||
|
*/
|
||||||
|
List<Map<String, Object>> selectRawData(@Param("stcdList") List<String> stcdList,
|
||||||
|
@Param("fieldName") String fieldName,
|
||||||
|
@Param("startTime") String startTime,
|
||||||
|
@Param("endTime") String endTime);
|
||||||
|
}
|
||||||
@ -0,0 +1,47 @@
|
|||||||
|
package com.yfd.platform.qgc_export.mapper;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import com.yfd.platform.qgc_export.domain.SdWqR;
|
||||||
|
import org.apache.ibatis.annotations.Param;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SD_WQ_R 水质小时数据 Mapper
|
||||||
|
*/
|
||||||
|
public interface SdWqRMapper extends BaseMapper<SdWqR> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量查询测站在指定时间范围内的原始小时数据(含达标标志)
|
||||||
|
*
|
||||||
|
* @param stcdList 测站编码列表
|
||||||
|
* @param fieldName 查询字段名(WTMP/PH/DOX/COND/TU)
|
||||||
|
* @param startTime 起始时间
|
||||||
|
* @param endTime 结束时间
|
||||||
|
* @return [STCD, TM, VALUE, SFDB]
|
||||||
|
*/
|
||||||
|
List<Map<String, Object>> selectRawData(@Param("stcdList") List<String> stcdList,
|
||||||
|
@Param("fieldName") String fieldName,
|
||||||
|
@Param("startTime") String startTime,
|
||||||
|
@Param("endTime") String endTime);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询水质达标数据(小时级),按 STCD 聚合 SFDB=1 达标数、SFDB IN (0,1) 总数
|
||||||
|
*/
|
||||||
|
List<Map<String, Object>> selectComplianceData(@Param("stcdList") List<String> stcdList,
|
||||||
|
@Param("startTime") String startTime,
|
||||||
|
@Param("endTime") String endTime);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询各测站不达标要素(SFDB=0 时的 WQ_SFDBHN_YS)
|
||||||
|
*/
|
||||||
|
List<Map<String, Object>> selectPollutants(@Param("stcdList") List<String> stcdList,
|
||||||
|
@Param("startTime") String startTime,
|
||||||
|
@Param("endTime") String endTime);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询 SD_WQ_R 表的字段注释(字段名 → 中文描述)
|
||||||
|
*/
|
||||||
|
List<Map<String, Object>> selectColumnComments();
|
||||||
|
}
|
||||||
@ -0,0 +1,35 @@
|
|||||||
|
package com.yfd.platform.qgc_export.mapper;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import com.yfd.platform.qgc_export.domain.SdWqdayS;
|
||||||
|
import org.apache.ibatis.annotations.Param;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SD_WQDAY_S 水质日数据 Mapper
|
||||||
|
*/
|
||||||
|
public interface SdWqdaySMapper extends BaseMapper<SdWqdayS> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量查询测站在指定时间范围内的原始日数据
|
||||||
|
*
|
||||||
|
* @param stcdList 测站编码列表
|
||||||
|
* @param fieldName 查询字段名(WTMP/PH/DOX/COND/TU)
|
||||||
|
* @param startTime 起始时间
|
||||||
|
* @param endTime 结束时间
|
||||||
|
* @return [STCD, DT, VALUE]
|
||||||
|
*/
|
||||||
|
List<Map<String, Object>> selectRawData(@Param("stcdList") List<String> stcdList,
|
||||||
|
@Param("fieldName") String fieldName,
|
||||||
|
@Param("startTime") String startTime,
|
||||||
|
@Param("endTime") String endTime);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询水质达标数据(日级),按 STCD 聚合 SFDB=1 达标数、SFDB IN (0,1) 总数
|
||||||
|
*/
|
||||||
|
List<Map<String, Object>> selectComplianceData(@Param("stcdList") List<String> stcdList,
|
||||||
|
@Param("startTime") String startTime,
|
||||||
|
@Param("endTime") String endTime);
|
||||||
|
}
|
||||||
@ -0,0 +1,26 @@
|
|||||||
|
package com.yfd.platform.qgc_export.mapper;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import com.yfd.platform.qgc_export.domain.SdWtrvR;
|
||||||
|
import org.apache.ibatis.annotations.Param;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SD_WTRV_R 河道水温小时数据 Mapper
|
||||||
|
*/
|
||||||
|
public interface SdWtrvRMapper extends BaseMapper<SdWtrvR> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量查询测站在指定时间范围内的原始小时数据
|
||||||
|
*
|
||||||
|
* @param stcdList 测站编码列表
|
||||||
|
* @param startTime 起始时间
|
||||||
|
* @param endTime 结束时间
|
||||||
|
* @return [STCD, TM, VALUE]
|
||||||
|
*/
|
||||||
|
List<Map<String, Object>> selectRawData(@Param("stcdList") List<String> stcdList,
|
||||||
|
@Param("startTime") String startTime,
|
||||||
|
@Param("endTime") String endTime);
|
||||||
|
}
|
||||||
@ -0,0 +1,26 @@
|
|||||||
|
package com.yfd.platform.qgc_export.mapper;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import com.yfd.platform.qgc_export.domain.SdWtrvdayS;
|
||||||
|
import org.apache.ibatis.annotations.Param;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SD_WTRVDAY_S 河道水温日数据 Mapper
|
||||||
|
*/
|
||||||
|
public interface SdWtrvdaySMapper extends BaseMapper<SdWtrvdayS> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量查询测站在指定时间范围内的原始日数据
|
||||||
|
*
|
||||||
|
* @param stcdList 测站编码列表
|
||||||
|
* @param startTime 起始时间
|
||||||
|
* @param endTime 结束时间
|
||||||
|
* @return [STCD, DT, VALUE]
|
||||||
|
*/
|
||||||
|
List<Map<String, Object>> selectRawData(@Param("stcdList") List<String> stcdList,
|
||||||
|
@Param("startTime") String startTime,
|
||||||
|
@Param("endTime") String endTime);
|
||||||
|
}
|
||||||
@ -0,0 +1,28 @@
|
|||||||
|
package com.yfd.platform.qgc_export.mapper;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import com.yfd.platform.qgc_export.domain.SdWtvtdayS;
|
||||||
|
import org.apache.ibatis.annotations.Param;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SD_WTVTDAY_S 垂向水温日数据 Mapper
|
||||||
|
*/
|
||||||
|
public interface SdWtvtdaySMapper extends BaseMapper<SdWtvtdayS> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询月内每日垂向水温数据(含 EXTRACT(DAY FROM DT)),用于按指定日期筛选
|
||||||
|
*/
|
||||||
|
List<Map<String, Object>> selectDailyData(@Param("stcdList") List<String> stcdList,
|
||||||
|
@Param("startTime") String startTime,
|
||||||
|
@Param("endTime") String endTime);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询月均垂向水温,按 STCD、WTHG 分组
|
||||||
|
*/
|
||||||
|
List<Map<String, Object>> selectMonthlyAvg(@Param("stcdList") List<String> stcdList,
|
||||||
|
@Param("startTime") String startTime,
|
||||||
|
@Param("endTime") String endTime);
|
||||||
|
}
|
||||||
@ -0,0 +1,10 @@
|
|||||||
|
package com.yfd.platform.qgc_export.mapper;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import com.yfd.platform.qgc_export.domain.StationMapping;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* V_MS_STBPRP_T 视图 Mapper — 用于电站编码→测站编码转换
|
||||||
|
*/
|
||||||
|
public interface StationMappingMapper extends BaseMapper<StationMapping> {
|
||||||
|
}
|
||||||
@ -0,0 +1,27 @@
|
|||||||
|
package com.yfd.platform.qgc_export.mapper;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import com.yfd.platform.qgc_export.domain.StationInfo;
|
||||||
|
import org.apache.ibatis.annotations.Param;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 年度统计导出 Mapper
|
||||||
|
*/
|
||||||
|
public interface YearStatMapper extends BaseMapper<StationInfo> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询生态流量月度达标数据(SD_QECDRTP_S DRTP='MON')
|
||||||
|
* 返回 STCD、三部分达标数
|
||||||
|
*/
|
||||||
|
List<Map<String, Object>> selectQecMonthlyCompliance(@Param("stcdList") List<String> stcdList,
|
||||||
|
@Param("year") int year);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询生态流量月度达标数据(按 BASE_ID 分组)
|
||||||
|
*/
|
||||||
|
List<Map<String, Object>> selectQecMonthlyComplianceByBase(@Param("baseIdList") List<String> baseIdList,
|
||||||
|
@Param("year") int year);
|
||||||
|
}
|
||||||
@ -0,0 +1,30 @@
|
|||||||
|
package com.yfd.platform.qgc_export.processor;
|
||||||
|
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 电导率(COND) 指标处理器
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
public class CodcrProcessor extends WqIndicatorProcessor {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getFieldName() {
|
||||||
|
return "CODCR";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getSheetName() {
|
||||||
|
return "水质(化学需氧量)";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getDecimalPlaces() {
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getOrder() {
|
||||||
|
return 12;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,30 @@
|
|||||||
|
package com.yfd.platform.qgc_export.processor;
|
||||||
|
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 电导率(COND) 指标处理器
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
public class CondProcessor extends WqIndicatorProcessor {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getFieldName() {
|
||||||
|
return "COND";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getSheetName() {
|
||||||
|
return "水质(电导率)";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getDecimalPlaces() {
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getOrder() {
|
||||||
|
return 13;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,30 @@
|
|||||||
|
package com.yfd.platform.qgc_export.processor;
|
||||||
|
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 溶解氧(DOX) 指标处理器
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
public class DoxProcessor extends WqIndicatorProcessor {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getFieldName() {
|
||||||
|
return "DOX";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getSheetName() {
|
||||||
|
return "水质(溶解氧)";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getDecimalPlaces() {
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getOrder() {
|
||||||
|
return 11;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,27 @@
|
|||||||
|
package com.yfd.platform.qgc_export.processor;
|
||||||
|
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 出库水温(DWT) 标准格式处理器
|
||||||
|
* <p>
|
||||||
|
* Sheet 格式与水情指标一致:日数据(01-31) + 7个汇总指标。
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
public class DwtProcessor extends WtrvIndicatorProcessor {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getFieldName() {
|
||||||
|
return "DWT";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getSheetName() {
|
||||||
|
return "出库水温";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getOrder() {
|
||||||
|
return 8;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,32 @@
|
|||||||
|
package com.yfd.platform.qgc_export.processor;
|
||||||
|
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 出入库水温日变幅 处理器
|
||||||
|
* <p>
|
||||||
|
* 日变幅格式:日数据行展示每日变幅(当日最大-最小),汇总指标为"日变幅均值"和"日变幅最大值"。
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
public class DwtVariationProcessor extends WtrvIndicatorProcessor {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getFieldName() {
|
||||||
|
return "DWT";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getSheetName() {
|
||||||
|
return "出入库水温日变幅";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isVariation() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getOrder() {
|
||||||
|
return 9;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,25 @@
|
|||||||
|
package com.yfd.platform.qgc_export.processor;
|
||||||
|
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 坝下水位(DZ) 标准格式处理器
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
public class DzProcessor extends HydropwIndicatorProcessor {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getFieldName() {
|
||||||
|
return "DZ";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getSheetName() {
|
||||||
|
return "坝下水位";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getOrder() {
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,30 @@
|
|||||||
|
package com.yfd.platform.qgc_export.processor;
|
||||||
|
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 坝下水位(DZ) 日变幅格式处理器
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
public class DzVariationProcessor extends HydropwIndicatorProcessor {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getFieldName() {
|
||||||
|
return "DZ";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getSheetName() {
|
||||||
|
return "坝下水位日变幅";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isVariation() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getOrder() {
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,77 @@
|
|||||||
|
package com.yfd.platform.qgc_export.processor;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 指标处理器接口 — 每种指标(v/q/z/wq/dwt/qec 等)实现此接口
|
||||||
|
* <p>
|
||||||
|
* 新增指标时:实现本接口 + 在 QgcExportServiceImpl.resolveProcessors() 中注入即可。
|
||||||
|
*/
|
||||||
|
public interface ExportIndicatorProcessor {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 指标字段名,与前端 dataField 中的值对应(如 "v", "q", "z", "qec")
|
||||||
|
*/
|
||||||
|
String getFieldName();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Excel Sheet 页中文标题(如 "流速(m/s)")
|
||||||
|
*/
|
||||||
|
String getSheetName();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 测站类型(STTP),用于区分同一电站下不同用途的测站。
|
||||||
|
* <ul>
|
||||||
|
* <li>V/Q/Z 河道水情 → "ZQ"</li>
|
||||||
|
* <li>WQ 水质 → "WQ"</li>
|
||||||
|
* <li>DWT 出库水温 → "WTRV"</li>
|
||||||
|
* <li>RZ/DZ 坝上/坝下水位 → "ENG"</li>
|
||||||
|
* <li>QEC 生态流量 → 待定</li>
|
||||||
|
* </ul>
|
||||||
|
*/
|
||||||
|
default String getSttpType() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 数值保留的小数位数,默认 3 位
|
||||||
|
*/
|
||||||
|
default int getDecimalPlaces() {
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否有小时达标率指标(水质指标返回 true,在月均下方追加一行"小时达标率")
|
||||||
|
*/
|
||||||
|
default boolean hasComplianceRate() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否为日变幅格式(出库水温日变幅 Sheet)。
|
||||||
|
* 日变幅格式:日数据行展示每日变幅(=当日最大-最小),汇总指标为"日变幅均值"和"日变幅最大值"。
|
||||||
|
*/
|
||||||
|
default boolean isVariation() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sheet 排序号,升序排列。
|
||||||
|
* 数值越小越靠前,同组指标标准格式应排在日变幅格式之前。
|
||||||
|
*/
|
||||||
|
default int getOrder() {
|
||||||
|
return 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询原始数据
|
||||||
|
*
|
||||||
|
* @param stcds 测站编码列表(已从电站编码转换,且已按 STTP 过滤)
|
||||||
|
* @param startTime 起始时间
|
||||||
|
* @param endTime 结束时间
|
||||||
|
* @param isDaily 是否查询日表(true=日表, false=小时表)
|
||||||
|
* @return 原始数据行列表
|
||||||
|
*/
|
||||||
|
List<IndicatorDataRow> queryRawData(List<String> stcds, Date startTime, Date endTime, boolean isDaily);
|
||||||
|
}
|
||||||
@ -0,0 +1,69 @@
|
|||||||
|
package com.yfd.platform.qgc_export.processor;
|
||||||
|
|
||||||
|
import com.yfd.platform.qgc_export.mapper.SdHydropwRMapper;
|
||||||
|
import com.yfd.platform.qgc_export.mapper.SdHydropwdaySMapper;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 电站运行指标处理器基类 — RZ(坝上水位)/DZ(坝下水位) 使用 SD_HYDROPW_R / SD_HYDROPWDAY_S 表
|
||||||
|
* <p>
|
||||||
|
* 子类标注 @Component,getSttpType() 固定返回 "ENG"。
|
||||||
|
* 动态字段名由子类 getFieldName() 返回。
|
||||||
|
*/
|
||||||
|
public abstract class HydropwIndicatorProcessor implements ExportIndicatorProcessor {
|
||||||
|
|
||||||
|
protected SdHydropwRMapper sdHydropwRMapper;
|
||||||
|
protected SdHydropwdaySMapper sdHydropwdaySMapper;
|
||||||
|
|
||||||
|
private static final SimpleDateFormat SDF = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||||
|
|
||||||
|
public void setMappers(SdHydropwRMapper rMapper, SdHydropwdaySMapper sMapper) {
|
||||||
|
this.sdHydropwRMapper = rMapper;
|
||||||
|
this.sdHydropwdaySMapper = sMapper;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getSttpType() {
|
||||||
|
return "ENG";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getDecimalPlaces() {
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<IndicatorDataRow> queryRawData(List<String> stcds, Date startTime, Date endTime, boolean isDaily) {
|
||||||
|
String startStr = SDF.format(startTime);
|
||||||
|
String endStr = SDF.format(endTime);
|
||||||
|
|
||||||
|
List<Map<String, Object>> rawList;
|
||||||
|
if (isDaily) {
|
||||||
|
rawList = sdHydropwdaySMapper.selectRawData(stcds, getFieldName(), startStr, endStr);
|
||||||
|
} else {
|
||||||
|
rawList = sdHydropwRMapper.selectRawData(stcds, getFieldName(), startStr, endStr);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<IndicatorDataRow> rows = new ArrayList<>();
|
||||||
|
if (rawList != null) {
|
||||||
|
for (Map<String, Object> map : rawList) {
|
||||||
|
String stcd = (String) map.get("STCD");
|
||||||
|
Date tm = (Date) map.get(isDaily ? "DT" : "TM");
|
||||||
|
BigDecimal value = toBigDecimal(map.get("VALUE"));
|
||||||
|
if (stcd != null && tm != null && value != null) {
|
||||||
|
rows.add(new IndicatorDataRow(stcd, tm, value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return rows;
|
||||||
|
}
|
||||||
|
|
||||||
|
private BigDecimal toBigDecimal(Object val) {
|
||||||
|
if (val instanceof BigDecimal) return (BigDecimal) val;
|
||||||
|
if (val instanceof Number) return BigDecimal.valueOf(((Number) val).doubleValue());
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,35 @@
|
|||||||
|
package com.yfd.platform.qgc_export.processor;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 指标数据行 — 从数据库查询后的原始数据封装
|
||||||
|
*/
|
||||||
|
public class IndicatorDataRow {
|
||||||
|
/** 测站编码 */
|
||||||
|
private String stcd;
|
||||||
|
/** 数据时间 */
|
||||||
|
private Date tm;
|
||||||
|
/** 指标值 */
|
||||||
|
private BigDecimal value;
|
||||||
|
/** 是否达标(仅水质指标使用,0=不达标 1=达标) */
|
||||||
|
private Integer sfdb;
|
||||||
|
|
||||||
|
public IndicatorDataRow() {}
|
||||||
|
|
||||||
|
public IndicatorDataRow(String stcd, Date tm, BigDecimal value) {
|
||||||
|
this.stcd = stcd;
|
||||||
|
this.tm = tm;
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getStcd() { return stcd; }
|
||||||
|
public void setStcd(String stcd) { this.stcd = stcd; }
|
||||||
|
public Date getTm() { return tm; }
|
||||||
|
public void setTm(Date tm) { this.tm = tm; }
|
||||||
|
public BigDecimal getValue() { return value; }
|
||||||
|
public void setValue(BigDecimal value) { this.value = value; }
|
||||||
|
public Integer getSfdb() { return sfdb; }
|
||||||
|
public void setSfdb(Integer sfdb) { this.sfdb = sfdb; }
|
||||||
|
}
|
||||||
@ -0,0 +1,30 @@
|
|||||||
|
package com.yfd.platform.qgc_export.processor;
|
||||||
|
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PH 指标处理器
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
public class PhProcessor extends WqIndicatorProcessor {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getFieldName() {
|
||||||
|
return "PH";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getSheetName() {
|
||||||
|
return "水质(PH)";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getDecimalPlaces() {
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getOrder() {
|
||||||
|
return 15;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,22 @@
|
|||||||
|
package com.yfd.platform.qgc_export.processor;
|
||||||
|
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 流量(Q) 指标处理器
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
public class QProcessor extends RiverIndicatorProcessor {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getFieldName() { return "Q"; }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getSheetName() { return "流量(m³/s)"; }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getSttpType() { return "ZQ"; }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getOrder() { return 32; }
|
||||||
|
}
|
||||||
@ -0,0 +1,86 @@
|
|||||||
|
package com.yfd.platform.qgc_export.processor;
|
||||||
|
|
||||||
|
import com.yfd.platform.qgc_export.mapper.SdQecRMapper;
|
||||||
|
import com.yfd.platform.qgc_export.mapper.SdQecdaySMapper;
|
||||||
|
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生态流量(QEC) 处理器
|
||||||
|
* <p>
|
||||||
|
* 数据来源: SD_QEC_R / SD_QECDAY_S,STTP="ENG"。
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
public class QecProcessor implements ExportIndicatorProcessor {
|
||||||
|
|
||||||
|
private SdQecRMapper sdQecRMapper;
|
||||||
|
private SdQecdaySMapper sdQecdaySMapper;
|
||||||
|
|
||||||
|
private static final SimpleDateFormat SDF = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||||
|
|
||||||
|
public void setMappers(SdQecRMapper rMapper, SdQecdaySMapper sMapper) {
|
||||||
|
this.sdQecRMapper = rMapper;
|
||||||
|
this.sdQecdaySMapper = sMapper;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getFieldName() {
|
||||||
|
return "QEC";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getSheetName() {
|
||||||
|
return "生态流量";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getSttpType() {
|
||||||
|
return "ENG";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getDecimalPlaces() {
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getOrder() {
|
||||||
|
return 37;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<IndicatorDataRow> queryRawData(List<String> stcds, Date startTime, Date endTime, boolean isDaily) {
|
||||||
|
String startStr = SDF.format(startTime);
|
||||||
|
String endStr = SDF.format(endTime);
|
||||||
|
|
||||||
|
List<Map<String, Object>> rawList;
|
||||||
|
if (isDaily) {
|
||||||
|
rawList = sdQecdaySMapper.selectRawData(stcds, startStr, endStr);
|
||||||
|
} else {
|
||||||
|
rawList = sdQecRMapper.selectRawData(stcds, startStr, endStr);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<IndicatorDataRow> rows = new ArrayList<>();
|
||||||
|
if (rawList != null) {
|
||||||
|
for (Map<String, Object> map : rawList) {
|
||||||
|
String stcd = (String) map.get("STCD");
|
||||||
|
Date tm = (Date) map.get(isDaily ? "DT" : "TM");
|
||||||
|
BigDecimal value = toBigDecimal(map.get("VALUE"));
|
||||||
|
if (stcd != null && tm != null && value != null) {
|
||||||
|
rows.add(new IndicatorDataRow(stcd, tm, value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return rows;
|
||||||
|
}
|
||||||
|
|
||||||
|
private BigDecimal toBigDecimal(Object val) {
|
||||||
|
if (val instanceof BigDecimal) return (BigDecimal) val;
|
||||||
|
if (val instanceof Number) return BigDecimal.valueOf(((Number) val).doubleValue());
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,25 @@
|
|||||||
|
package com.yfd.platform.qgc_export.processor;
|
||||||
|
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 入库流量(QI) 处理器
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
public class QiProcessor extends HydropwIndicatorProcessor {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getFieldName() {
|
||||||
|
return "QI";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getSheetName() {
|
||||||
|
return "入库流量";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getOrder() {
|
||||||
|
return 5;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,25 @@
|
|||||||
|
package com.yfd.platform.qgc_export.processor;
|
||||||
|
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 出库流量(QO) 处理器
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
public class QoProcessor extends HydropwIndicatorProcessor {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getFieldName() {
|
||||||
|
return "QO";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getSheetName() {
|
||||||
|
return "出库流量";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getOrder() {
|
||||||
|
return 6;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,58 @@
|
|||||||
|
package com.yfd.platform.qgc_export.processor;
|
||||||
|
|
||||||
|
import com.yfd.platform.qgc_export.mapper.SdRiverRMapper;
|
||||||
|
import com.yfd.platform.qgc_export.mapper.SdRiverdaySMapper;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 河道水情指标处理器基类 — V/Q/Z 三个指标共用查询逻辑
|
||||||
|
* <p>
|
||||||
|
* 子类(VProcessor/QProcessor/ZProcessor)需标注 @Component 并提供 getFieldName/getSheetName
|
||||||
|
*/
|
||||||
|
public abstract class RiverIndicatorProcessor implements ExportIndicatorProcessor {
|
||||||
|
|
||||||
|
protected SdRiverRMapper sdRiverRMapper;
|
||||||
|
protected SdRiverdaySMapper sdRiverdaySMapper;
|
||||||
|
|
||||||
|
private static final SimpleDateFormat SDF_DATETIME = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||||
|
|
||||||
|
public void setMappers(SdRiverRMapper rMapper, SdRiverdaySMapper sMapper) {
|
||||||
|
this.sdRiverRMapper = rMapper;
|
||||||
|
this.sdRiverdaySMapper = sMapper;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<IndicatorDataRow> queryRawData(List<String> stcds, Date startTime, Date endTime, boolean isDaily) {
|
||||||
|
String startStr = SDF_DATETIME.format(startTime);
|
||||||
|
String endStr = SDF_DATETIME.format(endTime);
|
||||||
|
|
||||||
|
List<Map<String, Object>> rawList;
|
||||||
|
if (isDaily) {
|
||||||
|
rawList = sdRiverdaySMapper.selectRawData(stcds, getFieldName(), startStr, endStr);
|
||||||
|
} else {
|
||||||
|
rawList = sdRiverRMapper.selectRawData(stcds, getFieldName(), startStr, endStr);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<IndicatorDataRow> rows = new ArrayList<>();
|
||||||
|
if (rawList != null) {
|
||||||
|
for (Map<String, Object> map : rawList) {
|
||||||
|
String stcd = (String) map.get("STCD");
|
||||||
|
Date tm = (Date) map.get(isDaily ? "DT" : "TM");
|
||||||
|
BigDecimal value = null;
|
||||||
|
Object val = map.get("VALUE");
|
||||||
|
if (val instanceof BigDecimal) {
|
||||||
|
value = (BigDecimal) val;
|
||||||
|
} else if (val instanceof Number) {
|
||||||
|
value = BigDecimal.valueOf(((Number) val).doubleValue());
|
||||||
|
}
|
||||||
|
if (stcd != null && tm != null && value != null) {
|
||||||
|
rows.add(new IndicatorDataRow(stcd, tm, value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return rows;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,60 @@
|
|||||||
|
package com.yfd.platform.qgc_export.processor;
|
||||||
|
|
||||||
|
import com.yfd.platform.qgc_env.wt.mapper.SdWtvtRMapper;
|
||||||
|
import com.yfd.platform.qgc_export.mapper.SdWtvtdaySMapper;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 垂向水温(RWT) 处理器 — 双表头格式,按水深分层展示
|
||||||
|
* <p>
|
||||||
|
* STTP: WTVT, 使用 SD_WTVT_R / SD_WTVTDAY_S 表
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
public class RwtProcessor implements ExportIndicatorProcessor {
|
||||||
|
|
||||||
|
private SdWtvtRMapper sdWtvtRMapper;
|
||||||
|
private SdWtvtdaySMapper sdWtvtdaySMapper;
|
||||||
|
|
||||||
|
public void setMappers(SdWtvtRMapper rMapper, SdWtvtdaySMapper sMapper) {
|
||||||
|
this.sdWtvtRMapper = rMapper;
|
||||||
|
this.sdWtvtdaySMapper = sMapper;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SdWtvtRMapper getSdWtvtRMapper() { return sdWtvtRMapper; }
|
||||||
|
public SdWtvtdaySMapper getSdWtvtdaySMapper() { return sdWtvtdaySMapper; }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getFieldName() {
|
||||||
|
return "rwt";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getSheetName() {
|
||||||
|
return "垂向水温";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getSttpType() {
|
||||||
|
return "WTVT";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getDecimalPlaces() {
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getOrder() {
|
||||||
|
return 7;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<IndicatorDataRow> queryRawData(List<String> stcds, Date startTime, Date endTime, boolean isDaily) {
|
||||||
|
// RWT 使用自定义 Sheet 构建,不走标准数据查询流程
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,25 @@
|
|||||||
|
package com.yfd.platform.qgc_export.processor;
|
||||||
|
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 坝上水位(RZ) 标准格式处理器
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
public class RzProcessor extends HydropwIndicatorProcessor {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getFieldName() {
|
||||||
|
return "RZ";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getSheetName() {
|
||||||
|
return "坝上水位";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getOrder() {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,30 @@
|
|||||||
|
package com.yfd.platform.qgc_export.processor;
|
||||||
|
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 坝上水位(RZ) 日变幅格式处理器
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
public class RzVariationProcessor extends HydropwIndicatorProcessor {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getFieldName() {
|
||||||
|
return "RZ";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getSheetName() {
|
||||||
|
return "坝上水位日变幅";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isVariation() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getOrder() {
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,30 @@
|
|||||||
|
package com.yfd.platform.qgc_export.processor;
|
||||||
|
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 浊度(TU) 指标处理器
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
public class TuProcessor extends WqIndicatorProcessor {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getFieldName() {
|
||||||
|
return "TU";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getSheetName() {
|
||||||
|
return "水质(浊度)";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getDecimalPlaces() {
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getOrder() {
|
||||||
|
return 14;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,22 @@
|
|||||||
|
package com.yfd.platform.qgc_export.processor;
|
||||||
|
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 流速(V) 指标处理器
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
public class VProcessor extends RiverIndicatorProcessor {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getFieldName() { return "V"; }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getSheetName() { return "流速(m/s)"; }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getSttpType() { return "ZQ"; }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getOrder() { return 33; }
|
||||||
|
}
|
||||||
@ -0,0 +1,77 @@
|
|||||||
|
package com.yfd.platform.qgc_export.processor;
|
||||||
|
|
||||||
|
import com.yfd.platform.qgc_export.mapper.SdWqRMapper;
|
||||||
|
import com.yfd.platform.qgc_export.mapper.SdWqdaySMapper;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 水质指标处理器基类 — 5个水质指标(WTMP/PH/DOX/COND/TU)共用查询逻辑
|
||||||
|
* <p>
|
||||||
|
* 小时表查询额外提取 SFDB(是否达标)字段,用于计算小时达标率。
|
||||||
|
* 子类需标注 @Component 并提供 getFieldName/getSheetName/getDecimalPlaces。
|
||||||
|
*/
|
||||||
|
public abstract class WqIndicatorProcessor implements ExportIndicatorProcessor {
|
||||||
|
|
||||||
|
protected SdWqRMapper sdWqRMapper;
|
||||||
|
protected SdWqdaySMapper sdWqdaySMapper;
|
||||||
|
|
||||||
|
private static final SimpleDateFormat SDF = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||||
|
|
||||||
|
public void setMappers(SdWqRMapper rMapper, SdWqdaySMapper sMapper) {
|
||||||
|
this.sdWqRMapper = rMapper;
|
||||||
|
this.sdWqdaySMapper = sMapper;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getSttpType() {
|
||||||
|
return "WQ";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasComplianceRate() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<IndicatorDataRow> queryRawData(List<String> stcds, Date startTime, Date endTime, boolean isDaily) {
|
||||||
|
String startStr = SDF.format(startTime);
|
||||||
|
String endStr = SDF.format(endTime);
|
||||||
|
|
||||||
|
List<Map<String, Object>> rawList;
|
||||||
|
if (isDaily) {
|
||||||
|
rawList = sdWqdaySMapper.selectRawData(stcds, getFieldName(), startStr, endStr);
|
||||||
|
} else {
|
||||||
|
rawList = sdWqRMapper.selectRawData(stcds, getFieldName(), startStr, endStr);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<IndicatorDataRow> rows = new ArrayList<>();
|
||||||
|
if (rawList != null) {
|
||||||
|
for (Map<String, Object> map : rawList) {
|
||||||
|
String stcd = (String) map.get("STCD");
|
||||||
|
Date tm = (Date) map.get(isDaily ? "DT" : "TM");
|
||||||
|
BigDecimal value = toBigDecimal(map.get("VALUE"));
|
||||||
|
if (stcd != null && tm != null && value != null) {
|
||||||
|
IndicatorDataRow row = new IndicatorDataRow(stcd, tm, value);
|
||||||
|
// 小时表额外携带 SFDB(达标标志)
|
||||||
|
if (!isDaily) {
|
||||||
|
Object sfdbObj = map.get("SFDB");
|
||||||
|
if (sfdbObj instanceof Number) {
|
||||||
|
row.setSfdb(((Number) sfdbObj).intValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rows.add(row);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return rows;
|
||||||
|
}
|
||||||
|
|
||||||
|
private BigDecimal toBigDecimal(Object val) {
|
||||||
|
if (val instanceof BigDecimal) return (BigDecimal) val;
|
||||||
|
if (val instanceof Number) return BigDecimal.valueOf(((Number) val).doubleValue());
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,30 @@
|
|||||||
|
package com.yfd.platform.qgc_export.processor;
|
||||||
|
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 水温(WTMP) 指标处理器
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
public class WtmpProcessor extends WqIndicatorProcessor {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getFieldName() {
|
||||||
|
return "WTMP";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getSheetName() {
|
||||||
|
return "水质(水温)";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getDecimalPlaces() {
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getOrder() {
|
||||||
|
return 10;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,68 @@
|
|||||||
|
package com.yfd.platform.qgc_export.processor;
|
||||||
|
|
||||||
|
import com.yfd.platform.qgc_export.mapper.SdWtrvRMapper;
|
||||||
|
import com.yfd.platform.qgc_export.mapper.SdWtrvdaySMapper;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 河道水温指标处理器基类 — DWT(出库水温)使用 SD_WTRV_R / SD_WTRVDAY_S 表
|
||||||
|
* <p>
|
||||||
|
* 子类标注 @Component,getSttpType() 固定返回 "WTRV"。
|
||||||
|
*/
|
||||||
|
public abstract class WtrvIndicatorProcessor implements ExportIndicatorProcessor {
|
||||||
|
|
||||||
|
protected SdWtrvRMapper sdWtrvRMapper;
|
||||||
|
protected SdWtrvdaySMapper sdWtrvdaySMapper;
|
||||||
|
|
||||||
|
private static final SimpleDateFormat SDF = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||||
|
|
||||||
|
public void setMappers(SdWtrvRMapper rMapper, SdWtrvdaySMapper sMapper) {
|
||||||
|
this.sdWtrvRMapper = rMapper;
|
||||||
|
this.sdWtrvdaySMapper = sMapper;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getSttpType() {
|
||||||
|
return "WTRV";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getDecimalPlaces() {
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<IndicatorDataRow> queryRawData(List<String> stcds, Date startTime, Date endTime, boolean isDaily) {
|
||||||
|
String startStr = SDF.format(startTime);
|
||||||
|
String endStr = SDF.format(endTime);
|
||||||
|
|
||||||
|
List<Map<String, Object>> rawList;
|
||||||
|
if (isDaily) {
|
||||||
|
rawList = sdWtrvdaySMapper.selectRawData(stcds, startStr, endStr);
|
||||||
|
} else {
|
||||||
|
rawList = sdWtrvRMapper.selectRawData(stcds, startStr, endStr);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<IndicatorDataRow> rows = new ArrayList<>();
|
||||||
|
if (rawList != null) {
|
||||||
|
for (Map<String, Object> map : rawList) {
|
||||||
|
String stcd = (String) map.get("STCD");
|
||||||
|
Date tm = (Date) map.get(isDaily ? "DT" : "TM");
|
||||||
|
BigDecimal value = toBigDecimal(map.get("VALUE"));
|
||||||
|
if (stcd != null && tm != null && value != null) {
|
||||||
|
rows.add(new IndicatorDataRow(stcd, tm, value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return rows;
|
||||||
|
}
|
||||||
|
|
||||||
|
private BigDecimal toBigDecimal(Object val) {
|
||||||
|
if (val instanceof BigDecimal) return (BigDecimal) val;
|
||||||
|
if (val instanceof Number) return BigDecimal.valueOf(((Number) val).doubleValue());
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,22 @@
|
|||||||
|
package com.yfd.platform.qgc_export.processor;
|
||||||
|
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 水位(Z) 指标处理器
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
public class ZProcessor extends RiverIndicatorProcessor {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getFieldName() { return "Z"; }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getSheetName() { return "水位(m)"; }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getSttpType() { return "ZQ"; }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getOrder() { return 31; }
|
||||||
|
}
|
||||||
@ -0,0 +1,227 @@
|
|||||||
|
package com.yfd.platform.qgc_export.service;
|
||||||
|
|
||||||
|
import com.yfd.platform.qgc_export.domain.ExportTask;
|
||||||
|
import jakarta.annotation.Resource;
|
||||||
|
import jakarta.servlet.ServletOutputStream;
|
||||||
|
import jakarta.servlet.WriteListener;
|
||||||
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
|
import jakarta.servlet.http.HttpServletResponseWrapper;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导出任务管理服务 — 异步导出 + 状态查询 + 文件下载
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
public class ExportTaskService {
|
||||||
|
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(ExportTaskService.class);
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private IQgcExportService qgcExportService;
|
||||||
|
|
||||||
|
/** 任务缓存(taskId → task) */
|
||||||
|
private final Map<String, ExportTask> taskMap = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建月度/小时/日导出任务,返回任务 ID
|
||||||
|
*/
|
||||||
|
public String submitMonthExport(List<String> dataFields, List<String> months,
|
||||||
|
List<String> stationCodes, boolean isDailyDimension,
|
||||||
|
String tmDimension) {
|
||||||
|
String taskId = UUID.randomUUID().toString().replace("-", "");
|
||||||
|
ExportTask task = new ExportTask(taskId);
|
||||||
|
task.setStatus(ExportTask.Status.PROCESSING);
|
||||||
|
taskMap.put(taskId, task);
|
||||||
|
|
||||||
|
CompletableFuture.runAsync(() -> {
|
||||||
|
File tempFile = null;
|
||||||
|
try {
|
||||||
|
tempFile = File.createTempFile("qgc_export_", ".zip");
|
||||||
|
FileOutputStream fos = new FileOutputStream(tempFile);
|
||||||
|
CapturingResponse capturing = new CapturingResponse(fos);
|
||||||
|
qgcExportService.exportData(dataFields, months, stationCodes,
|
||||||
|
isDailyDimension, tmDimension, capturing);
|
||||||
|
capturing.flushAndClose();
|
||||||
|
fos.close();
|
||||||
|
task.setFile(tempFile);
|
||||||
|
task.setStatus(ExportTask.Status.DONE);
|
||||||
|
log.info("导出任务 {} 完成,文件: {}", taskId, tempFile.getAbsolutePath());
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("导出任务 {} 失败", taskId, e);
|
||||||
|
task.setErrorMessage(e.getMessage());
|
||||||
|
task.setStatus(ExportTask.Status.ERROR);
|
||||||
|
if (tempFile != null) {
|
||||||
|
try { Files.deleteIfExists(tempFile.toPath()); } catch (IOException ignored) {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return taskId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建年度导出任务,返回任务 ID
|
||||||
|
*/
|
||||||
|
public String submitYearExport(List<String> yearStatType, List<String> years,
|
||||||
|
List<String> stationCodes, List<String> baseIds) {
|
||||||
|
String taskId = UUID.randomUUID().toString().replace("-", "");
|
||||||
|
ExportTask task = new ExportTask(taskId);
|
||||||
|
task.setStatus(ExportTask.Status.PROCESSING);
|
||||||
|
taskMap.put(taskId, task);
|
||||||
|
|
||||||
|
CompletableFuture.runAsync(() -> {
|
||||||
|
File tempFile = null;
|
||||||
|
try {
|
||||||
|
tempFile = File.createTempFile("qgc_export_", ".zip");
|
||||||
|
FileOutputStream fos = new FileOutputStream(tempFile);
|
||||||
|
CapturingResponse capturing = new CapturingResponse(fos);
|
||||||
|
qgcExportService.exportYearData(yearStatType, years, stationCodes,
|
||||||
|
baseIds, capturing);
|
||||||
|
capturing.flushAndClose();
|
||||||
|
fos.close();
|
||||||
|
task.setFile(tempFile);
|
||||||
|
task.setStatus(ExportTask.Status.DONE);
|
||||||
|
log.info("年度导出任务 {} 完成,文件: {}", taskId, tempFile.getAbsolutePath());
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("年度导出任务 {} 失败", taskId, e);
|
||||||
|
task.setErrorMessage(e.getMessage());
|
||||||
|
task.setStatus(ExportTask.Status.ERROR);
|
||||||
|
if (tempFile != null) {
|
||||||
|
try { Files.deleteIfExists(tempFile.toPath()); } catch (IOException ignored) {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return taskId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询任务状态
|
||||||
|
*/
|
||||||
|
public ExportTask getTask(String taskId) {
|
||||||
|
return taskMap.get(taskId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将任务文件写入 OutputStream(下载),写完后删除临时文件和任务缓存
|
||||||
|
*/
|
||||||
|
public void downloadTask(String taskId, OutputStream os) throws IOException {
|
||||||
|
ExportTask task = taskMap.get(taskId);
|
||||||
|
if (task == null || task.getStatus() != ExportTask.Status.DONE || task.getFile() == null) {
|
||||||
|
throw new IllegalStateException("任务未完成或文件不存在");
|
||||||
|
}
|
||||||
|
try (FileInputStream fis = new FileInputStream(task.getFile())) {
|
||||||
|
byte[] buf = new byte[8192];
|
||||||
|
int len;
|
||||||
|
while ((len = fis.read(buf)) != -1) {
|
||||||
|
os.write(buf, 0, len);
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
try { Files.deleteIfExists(task.getFile().toPath()); } catch (IOException e) {
|
||||||
|
log.warn("删除临时文件失败: {}", task.getFile(), e);
|
||||||
|
}
|
||||||
|
taskMap.remove(taskId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 清理超时任务(可由定时任务调用)
|
||||||
|
*/
|
||||||
|
public void cleanExpiredTasks(long timeoutMs) {
|
||||||
|
long now = System.currentTimeMillis();
|
||||||
|
taskMap.entrySet().removeIf(entry -> {
|
||||||
|
ExportTask task = entry.getValue();
|
||||||
|
if (now - task.getCreateTime() > timeoutMs) {
|
||||||
|
if (task.getFile() != null) {
|
||||||
|
try { Files.deleteIfExists(task.getFile().toPath()); } catch (IOException ignored) {}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// ==================== 内部类 ====================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 最小化 HttpServletResponse — 基于 HttpServletResponseWrapper,仅重写导出用到的 5 个方法
|
||||||
|
*/
|
||||||
|
private static class CapturingResponse extends HttpServletResponseWrapper {
|
||||||
|
private final FileOutputStream fos;
|
||||||
|
private final ServletOutputStream sos;
|
||||||
|
|
||||||
|
/** 兜底 response,仅用于满足 super() 非 null 约束,实际所有调用都被本类重写 */
|
||||||
|
private static final HttpServletResponse NOOP = new HttpServletResponse() {
|
||||||
|
@Override public ServletOutputStream getOutputStream() { throw new UnsupportedOperationException(); }
|
||||||
|
@Override public java.io.PrintWriter getWriter() { throw new UnsupportedOperationException(); }
|
||||||
|
@Override public String getCharacterEncoding() { return null; }
|
||||||
|
@Override public String getContentType() { return null; }
|
||||||
|
@Override public void setCharacterEncoding(String charset) {}
|
||||||
|
@Override public void setContentLength(int len) {}
|
||||||
|
@Override public void setContentLengthLong(long len) {}
|
||||||
|
@Override public void setContentType(String type) {}
|
||||||
|
@Override public void setBufferSize(int size) {}
|
||||||
|
@Override public int getBufferSize() { return 0; }
|
||||||
|
@Override public void flushBuffer() {}
|
||||||
|
@Override public void resetBuffer() {}
|
||||||
|
@Override public boolean isCommitted() { return false; }
|
||||||
|
@Override public void reset() {}
|
||||||
|
@Override public void setLocale(java.util.Locale loc) {}
|
||||||
|
@Override public java.util.Locale getLocale() { return java.util.Locale.getDefault(); }
|
||||||
|
@Override public void addCookie(jakarta.servlet.http.Cookie cookie) {}
|
||||||
|
@Override public boolean containsHeader(String name) { return false; }
|
||||||
|
@Override public String encodeURL(String url) { return url; }
|
||||||
|
@Override public String encodeRedirectURL(String url) { return url; }
|
||||||
|
@Override public void sendError(int sc, String msg) {}
|
||||||
|
@Override public void sendError(int sc) {}
|
||||||
|
@Override public void sendRedirect(String location) {}
|
||||||
|
@Override public void sendRedirect(String location, int sc, boolean clearBuffer) {}
|
||||||
|
@Override public void setDateHeader(String name, long date) {}
|
||||||
|
@Override public void addDateHeader(String name, long date) {}
|
||||||
|
@Override public void setHeader(String name, String value) {}
|
||||||
|
@Override public void addHeader(String name, String value) {}
|
||||||
|
@Override public void setIntHeader(String name, int value) {}
|
||||||
|
@Override public void addIntHeader(String name, int value) {}
|
||||||
|
@Override public void setStatus(int sc) {}
|
||||||
|
@Override public int getStatus() { return 200; }
|
||||||
|
@Override public String getHeader(String name) { return null; }
|
||||||
|
@Override public java.util.Collection<String> getHeaders(String name) { return java.util.Collections.emptyList(); }
|
||||||
|
@Override public java.util.Collection<String> getHeaderNames() { return java.util.Collections.emptyList(); }
|
||||||
|
};
|
||||||
|
|
||||||
|
CapturingResponse(FileOutputStream fos) {
|
||||||
|
super(NOOP);
|
||||||
|
this.fos = fos;
|
||||||
|
this.sos = new ServletOutputStream() {
|
||||||
|
@Override public void write(int b) throws IOException { fos.write(b); }
|
||||||
|
@Override public boolean isReady() { return true; }
|
||||||
|
@Override public void setWriteListener(WriteListener listener) {}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
void flushAndClose() throws IOException {
|
||||||
|
sos.flush();
|
||||||
|
fos.flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public ServletOutputStream getOutputStream() { return sos; }
|
||||||
|
@Override public void setContentType(String type) {}
|
||||||
|
@Override public void setCharacterEncoding(String charset) {}
|
||||||
|
@Override public void setHeader(String name, String value) {}
|
||||||
|
@Override public String getCharacterEncoding() { return "UTF-8"; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,42 @@
|
|||||||
|
package com.yfd.platform.qgc_export.service;
|
||||||
|
|
||||||
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 综合导出服务接口
|
||||||
|
*/
|
||||||
|
public interface IQgcExportService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 执行综合导出,生成 ZIP 并写入 HttpServletResponse
|
||||||
|
*
|
||||||
|
* @param dataFields 指标字段列表(如 ["v","q","z"])
|
||||||
|
* @param months 月份列表(如 ["2026-08","2026-07"])
|
||||||
|
* @param stationCodes 电站编码列表(RSTCD,前端传入)
|
||||||
|
* @param isDailyDimension 是否查日表
|
||||||
|
* @param tmDimension 时间维度 (hour/day/month/year)
|
||||||
|
* @param response HttpServletResponse
|
||||||
|
*/
|
||||||
|
void exportData(List<String> dataFields,
|
||||||
|
List<String> months,
|
||||||
|
List<String> stationCodes,
|
||||||
|
boolean isDailyDimension,
|
||||||
|
String tmDimension,
|
||||||
|
HttpServletResponse response);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 年度统计导出(水质达标率 + 生态流量达标率)
|
||||||
|
*
|
||||||
|
* @param yearStatType 统计指标类型(wq, qec)
|
||||||
|
* @param years 年份列表(如 ["2026","2025"])
|
||||||
|
* @param stationCodes 电站编码列表(RSTCD)
|
||||||
|
* @param baseIds 水电基地编码列表(BASE_ID)
|
||||||
|
* @param response HttpServletResponse
|
||||||
|
*/
|
||||||
|
void exportYearData(List<String> yearStatType,
|
||||||
|
List<String> years,
|
||||||
|
List<String> stationCodes,
|
||||||
|
List<String> baseIds,
|
||||||
|
HttpServletResponse response);
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
@ -12,10 +12,7 @@ import com.yfd.platform.qgc_base.domain.SdEngInfoBH;
|
|||||||
import com.yfd.platform.qgc_base.service.ISdEngInfoBHService;
|
import com.yfd.platform.qgc_base.service.ISdEngInfoBHService;
|
||||||
import com.yfd.platform.qgc_base.service.ISdHbrvDicService;
|
import com.yfd.platform.qgc_base.service.ISdHbrvDicService;
|
||||||
import com.yfd.platform.system.domain.*;
|
import com.yfd.platform.system.domain.*;
|
||||||
import com.yfd.platform.system.mapper.SysMenuMapper;
|
import com.yfd.platform.system.mapper.*;
|
||||||
import com.yfd.platform.system.mapper.SysOrganizationMapper;
|
|
||||||
import com.yfd.platform.system.mapper.SysRoleMapper;
|
|
||||||
import com.yfd.platform.system.mapper.SysUserTenantMapper;
|
|
||||||
import com.yfd.platform.system.service.ISmsVerifyCodeService;
|
import com.yfd.platform.system.service.ISmsVerifyCodeService;
|
||||||
import com.yfd.platform.system.service.ISysLogService;
|
import com.yfd.platform.system.service.ISysLogService;
|
||||||
import com.yfd.platform.system.service.IUserService;
|
import com.yfd.platform.system.service.IUserService;
|
||||||
@ -85,6 +82,10 @@ public class SmsVerifyCodeController {
|
|||||||
@Resource
|
@Resource
|
||||||
private ISdHbrvDicService hbrvDicService;
|
private ISdHbrvDicService hbrvDicService;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private SysUserMapper sysUserMapper;
|
||||||
|
|
||||||
|
|
||||||
@Value("${rsa.private_key}")
|
@Value("${rsa.private_key}")
|
||||||
private String privateKey;
|
private String privateKey;
|
||||||
private static final String URGE_CONTENT = "根据生态环境部要求,请贵电站尽快完成过鱼数据的报送工作,感谢支持。";
|
private static final String URGE_CONTENT = "根据生态环境部要求,请贵电站尽快完成过鱼数据的报送工作,感谢支持。";
|
||||||
@ -478,7 +479,7 @@ public class SmsVerifyCodeController {
|
|||||||
return ResponseResult.error("验证码错误或已过期");
|
return ResponseResult.error("验证码错误或已过期");
|
||||||
}
|
}
|
||||||
|
|
||||||
SysUser user = userService.getUserByPhone(phone, tenantId);
|
SysUser user = userService.getUserByPhone(phone, null);
|
||||||
if (user == null) {
|
if (user == null) {
|
||||||
return ResponseResult.error("该手机号未注册");
|
return ResponseResult.error("该手机号未注册");
|
||||||
}
|
}
|
||||||
@ -500,19 +501,43 @@ public class SmsVerifyCodeController {
|
|||||||
Authentication authenticate = new UsernamePasswordAuthenticationToken(user, null, authenticationToken.getAuthorities());
|
Authentication authenticate = new UsernamePasswordAuthenticationToken(user, null, authenticationToken.getAuthorities());
|
||||||
SecurityContextHolder.getContext().setAuthentication(authenticate);
|
SecurityContextHolder.getContext().setAuthentication(authenticate);
|
||||||
|
|
||||||
LoginUser loginUser = new LoginUser();
|
// 判断是否为超级管理员(LEVEL=1)
|
||||||
loginUser.setUser(user);
|
boolean isSuperAdmin = (isSuperAdmin(user.getId())||user.getUsertype()==0);
|
||||||
loginUser.setUsername(user.getUsername());
|
|
||||||
//Todo 根据用户查询权限信息 添加到LoginUser中
|
// 查询用户可访问的门户列表
|
||||||
|
List<String> accessibleTenantIds = sysUserTenantMapper.getTenantIdsByUserId(user.getId());
|
||||||
|
|
||||||
|
// 非超级管理员必须指定门户,且必须在可访问列表中
|
||||||
|
if (!isSuperAdmin) {
|
||||||
|
if (StrUtil.isBlank(tenantId)) {
|
||||||
|
throw new RuntimeException("用户无权限访问该平台");
|
||||||
|
}
|
||||||
|
if (accessibleTenantIds == null || !accessibleTenantIds.contains(tenantId)) {
|
||||||
|
throw new RuntimeException("用户无权限访问该平台");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 加载权限:超级管理员加载全部权限,普通用户按门户过滤
|
// 加载权限:超级管理员加载全部权限,普通用户按门户过滤
|
||||||
boolean isSuperAdmin = userService.isSuperAdmin(user.getId());
|
|
||||||
List<String> permissions;
|
List<String> permissions;
|
||||||
if (isSuperAdmin) {
|
if (isSuperAdmin) {
|
||||||
permissions = sysMenuMapper.selectPermsByUserId(user.getId(), null);
|
permissions = sysMenuMapper.selectPermsByUserId(user.getId(), null);
|
||||||
} else {
|
} else {
|
||||||
permissions = sysMenuMapper.selectPermsByUserId(user.getId(), tenantId);
|
permissions = sysMenuMapper.selectPermsByUserId(user.getId(), tenantId);
|
||||||
}
|
}
|
||||||
loginUser.setPermissions(permissions);
|
|
||||||
|
LoginUser loginUser = new LoginUser(user, permissions, tenantId, accessibleTenantIds, isSuperAdmin);
|
||||||
|
|
||||||
|
// LoginUser loginUser = new LoginUser();
|
||||||
|
// loginUser.setUser(user);
|
||||||
|
// loginUser.setUsername(user.getUsername());
|
||||||
|
// boolean isSuperAdmin = userService.isSuperAdmin(user.getId());
|
||||||
|
// List<String> permissions;
|
||||||
|
// if (isSuperAdmin) {
|
||||||
|
// permissions = sysMenuMapper.selectPermsByUserId(user.getId(), null);
|
||||||
|
// } else {
|
||||||
|
// permissions = sysMenuMapper.selectPermsByUserId(user.getId(), tenantId);
|
||||||
|
// }
|
||||||
|
// loginUser.setPermissions(permissions);
|
||||||
HttpServletRequest request = RequestHolder.getHttpServletRequest();
|
HttpServletRequest request = RequestHolder.getHttpServletRequest();
|
||||||
SysLog sysLog = new SysLog();
|
SysLog sysLog = new SysLog();
|
||||||
sysLog.setUsercode(user.getUsername());
|
sysLog.setUsercode(user.getUsername());
|
||||||
@ -549,4 +574,12 @@ public class SmsVerifyCodeController {
|
|||||||
|
|
||||||
return ResponseResult.successData(map);
|
return ResponseResult.successData(map);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断用户是否为超级管理员(拥有LEVEL=1的角色)
|
||||||
|
*/
|
||||||
|
private boolean isSuperAdmin(String userId) {
|
||||||
|
String maxLevel = sysUserMapper.getMaxLevel(userId);
|
||||||
|
return "1".equals(maxLevel);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -76,30 +76,65 @@ public class SysMenuServiceImpl extends ServiceImpl<SysMenuMapper, SysMenu> impl
|
|||||||
String name,
|
String name,
|
||||||
String isdisplay,
|
String isdisplay,
|
||||||
String tenantId) {
|
String tenantId) {
|
||||||
List<Map<String, Object>> mapList=null;
|
if (StrUtil.isEmpty(name)) {
|
||||||
List<Map<String, Object>> listMap =new ArrayList<>();
|
// 一次查询该系统下所有菜单,内存中构建树(替代递归逐层查 DB)
|
||||||
if(StrUtil.isEmpty(name)){//不带名称查询,返回树结构
|
|
||||||
QueryWrapper<SysMenu> queryWrapper = new QueryWrapper<>();
|
QueryWrapper<SysMenu> queryWrapper = new QueryWrapper<>();
|
||||||
queryWrapper.eq("parentid", "0").eq("systemcode", systemcode)
|
queryWrapper.eq("systemcode", systemcode)
|
||||||
.eq(StrUtil.isNotBlank(tenantId), "tenant_id", tenantId)
|
.eq(StrUtil.isNotBlank(tenantId), "tenant_id", tenantId)
|
||||||
.orderByAsc("orderno");
|
.orderByAsc("orderno");
|
||||||
mapList = this.listMaps(queryWrapper);
|
List<Map<String, Object>> allMenus = this.listMaps(queryWrapper);
|
||||||
listMap.addAll(ObjectConverterUtil.convertMapFieldsToEntityFormat(SysMenu.class, mapList));
|
List<Map<String, Object>> allConverted = ObjectConverterUtil.convertMapFieldsToEntityFormat(SysMenu.class, allMenus);
|
||||||
for (int i = 0; i < listMap.size(); i++) {
|
|
||||||
//查询下一子集
|
// 构建 id -> node 索引,并预初始化 children 空列表
|
||||||
List<Map<String, Object>> childList = child(listMap.get(i).get(
|
Map<String, Map<String, Object>> nodeMap = new LinkedHashMap<>();
|
||||||
"id").toString(), systemcode, name, null, null, tenantId);
|
for (Map<String, Object> menu : allConverted) {
|
||||||
listMap.get(i).put("children", childList); //添加新列 子集
|
menu.put("children", new ArrayList<>());
|
||||||
|
nodeMap.put(String.valueOf(menu.get("id")), menu);
|
||||||
}
|
}
|
||||||
}else{ //根据菜单名称查询,直接返回类别
|
|
||||||
|
// 单次遍历挂载子节点到父节点
|
||||||
|
List<Map<String, Object>> roots = new ArrayList<>();
|
||||||
|
for (Map<String, Object> menu : allConverted) {
|
||||||
|
String parentId = String.valueOf(menu.get("parentid"));
|
||||||
|
Map<String, Object> parent = nodeMap.get(parentId);
|
||||||
|
if (parent != null) {
|
||||||
|
// @SuppressWarnings("unchecked")
|
||||||
|
List<Map<String, Object>> children = (List<Map<String, Object>>) parent.get("children");
|
||||||
|
children.add(menu);
|
||||||
|
} else {
|
||||||
|
roots.add(menu);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 递归按 orderno 排序
|
||||||
|
sortTreeByOrderno(roots);
|
||||||
|
return roots;
|
||||||
|
} else {
|
||||||
|
// 根据菜单名称查询,直接返回列表
|
||||||
QueryWrapper<SysMenu> queryWrapper = new QueryWrapper<>();
|
QueryWrapper<SysMenu> queryWrapper = new QueryWrapper<>();
|
||||||
queryWrapper.like("name", name).eq("systemcode", systemcode)
|
queryWrapper.like("name", name).eq("systemcode", systemcode)
|
||||||
.eq(StrUtil.isNotBlank(tenantId), "tenant_id", tenantId)
|
.eq(StrUtil.isNotBlank(tenantId), "tenant_id", tenantId)
|
||||||
.orderByAsc("name");
|
.orderByAsc("name");
|
||||||
mapList = this.listMaps(queryWrapper);
|
List<Map<String, Object>> mapList = this.listMaps(queryWrapper);
|
||||||
listMap.addAll(ObjectConverterUtil.convertMapFieldsToEntityFormat(SysMenu.class, mapList));
|
return ObjectConverterUtil.convertMapFieldsToEntityFormat(SysMenu.class, mapList);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 递归按 orderno 排序树节点(保持与原 child() 相同的排序语义)
|
||||||
|
*/
|
||||||
|
private void sortTreeByOrderno(List<Map<String, Object>> nodes) {
|
||||||
|
nodes.sort(Comparator.comparingInt(m -> {
|
||||||
|
Object orderno = m.get("orderno");
|
||||||
|
return orderno instanceof Number ? ((Number) orderno).intValue() : 0;
|
||||||
|
}));
|
||||||
|
for (Map<String, Object> node : nodes) {
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
List<Map<String, Object>> children = (List<Map<String, Object>>) node.get("children");
|
||||||
|
if (children != null && !children.isEmpty()) {
|
||||||
|
sortTreeByOrderno(children);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return listMap;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************
|
/***********************************
|
||||||
|
|||||||
@ -641,11 +641,38 @@ public class UserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impleme
|
|||||||
Page<SysUser> page) {
|
Page<SysUser> page) {
|
||||||
Page<SysUser> mapPage = sysUserMapper.queryUsers(orgid,
|
Page<SysUser> mapPage = sysUserMapper.queryUsers(orgid,
|
||||||
username, tenantId, page);
|
username, tenantId, page);
|
||||||
mapPage.getRecords().forEach(record -> {
|
List<SysUser> records = mapPage.getRecords();
|
||||||
String id = record.getId();
|
if (records.isEmpty()) {
|
||||||
List<SysRole> sysRoles = sysRoleMapper.getRoleByUserId(id);
|
return mapPage;
|
||||||
record.setRoles(sysRoles);
|
}
|
||||||
});
|
|
||||||
|
// 收集所有用户ID,一次批量查询角色(替代 N+1 查询)
|
||||||
|
List<String> userIds = records.stream()
|
||||||
|
.map(SysUser::getId)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
List<Map<String, Object>> allRoleMaps = sysRoleMapper.getUserRolesByUserIds(userIds);
|
||||||
|
|
||||||
|
// 按 userId 分组,将 Map 转为 SysRole 对象
|
||||||
|
Map<String, List<SysRole>> userRoleMap = new HashMap<>();
|
||||||
|
if (allRoleMaps != null) {
|
||||||
|
for (Map<String, Object> roleMap : allRoleMaps) {
|
||||||
|
String userId = (String) roleMap.get("userId");
|
||||||
|
if (userId == null) continue;
|
||||||
|
SysRole role = new SysRole();
|
||||||
|
role.setId((String) roleMap.get("id"));
|
||||||
|
role.setRolecode((String) roleMap.get("rolecode"));
|
||||||
|
role.setRolename((String) roleMap.get("rolename"));
|
||||||
|
role.setLevel((String) roleMap.get("level"));
|
||||||
|
role.setDescription((String) roleMap.get("description"));
|
||||||
|
role.setIsvaild((String) roleMap.get("isvaild"));
|
||||||
|
role.setOrgscope((String) roleMap.get("orgscope"));
|
||||||
|
role.setOptscope((String) roleMap.get("optscope"));
|
||||||
|
role.setBusscope((String) roleMap.get("busscope"));
|
||||||
|
userRoleMap.computeIfAbsent(userId, k -> new ArrayList<>()).add(role);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
records.forEach(r -> r.setRoles(userRoleMap.getOrDefault(r.getId(), Collections.emptyList())));
|
||||||
return mapPage;
|
return mapPage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
765
backend/src/main/java/com/yfd/platform/utils/ExportZipUtil.java
Normal file
765
backend/src/main/java/com/yfd/platform/utils/ExportZipUtil.java
Normal file
@ -0,0 +1,765 @@
|
|||||||
|
package com.yfd.platform.utils;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import org.apache.poi.ss.usermodel.*;
|
||||||
|
import org.apache.poi.ss.util.CellRangeAddress;
|
||||||
|
import org.apache.poi.xssf.streaming.SXSSFSheet;
|
||||||
|
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import jakarta.servlet.ServletOutputStream;
|
||||||
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
|
import java.io.*;
|
||||||
|
import java.net.URLEncoder;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.function.Function;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 综合导出工具类 — 将多维度数据导出为 ZIP 压缩包,内含若干 Excel (.xlsx) 文件,每个 Excel 支持多 Sheet 页。
|
||||||
|
*
|
||||||
|
* <h3>使用示例</h3>
|
||||||
|
* <pre>{@code
|
||||||
|
* // 1. 构建 Sheet 数据
|
||||||
|
* SheetData stationSheet = new SheetData("电站基础信息",
|
||||||
|
* Arrays.asList("测站编码", "测站名称", "经度", "纬度"),
|
||||||
|
* stationRows); // List<List<Object>>
|
||||||
|
*
|
||||||
|
* SheetData monitorSheet = new SheetData("监测数据",
|
||||||
|
* Arrays.asList("时间", "水位", "流量"),
|
||||||
|
* monitorRows);
|
||||||
|
*
|
||||||
|
* // 2. 构建 Excel 数据(一个 Excel = 多个 Sheet)
|
||||||
|
* ExcelData excel1 = new ExcelData("电站数据", Arrays.asList(stationSheet, monitorSheet));
|
||||||
|
* ExcelData excel2 = new ExcelData("流域数据", Arrays.asList(basinSheet));
|
||||||
|
*
|
||||||
|
* // 3. 导出到 HttpServletResponse
|
||||||
|
* ExportZipUtil.exportToResponse(response, "数据导出_20260731.zip", Arrays.asList(excel1, excel2));
|
||||||
|
*
|
||||||
|
* // 或导出到文件
|
||||||
|
* ExportZipUtil.exportToFile(new File("D:/export.zip"), Arrays.asList(excel1, excel2));
|
||||||
|
*
|
||||||
|
* // 类型安全的构建方式
|
||||||
|
* SheetData sheet = ExportZipUtil.fromTypedData("电站信息",
|
||||||
|
* Arrays.asList("编码", "名称", "经度"),
|
||||||
|
* Arrays.asList(Station::getStcd, Station::getStnm, Station::getLgtd),
|
||||||
|
* stationList);
|
||||||
|
* }</pre>
|
||||||
|
*
|
||||||
|
* @author system
|
||||||
|
* @since 2026-07-31
|
||||||
|
*/
|
||||||
|
public class ExportZipUtil {
|
||||||
|
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(ExportZipUtil.class);
|
||||||
|
|
||||||
|
private ExportZipUtil() {
|
||||||
|
// 工具类,禁止实例化
|
||||||
|
}
|
||||||
|
|
||||||
|
// ======================== 数据模型 ========================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 单个 Sheet 页数据定义
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
public static class SheetData {
|
||||||
|
/** Sheet 页名称 */
|
||||||
|
private String sheetName;
|
||||||
|
/** 表头列名集合 */
|
||||||
|
private List<String> headers;
|
||||||
|
/** 数据行集合(每行是一个 Object 列表,与 headers 一一对应) */
|
||||||
|
private List<List<Object>> rows;
|
||||||
|
/**
|
||||||
|
* 需要合并的区域列表,每项 int[4] = {firstRow, lastRow, firstCol, lastCol}(0-based)。
|
||||||
|
* 在数据写入后由 fillSheet 统一合并。
|
||||||
|
*/
|
||||||
|
private List<int[]> mergedRegions;
|
||||||
|
/**
|
||||||
|
* rows 中前 headerRowCount 行使用双层标题样式:
|
||||||
|
* 第 0 行用 headerStyle,第 1 行用 subHeaderStyle,以此类推。
|
||||||
|
* 默认 0 表示全部行使用 dataStyle。
|
||||||
|
*/
|
||||||
|
private int headerRowCount;
|
||||||
|
|
||||||
|
public SheetData(String sheetName, List<String> headers, List<List<Object>> rows) {
|
||||||
|
this.sheetName = sheetName;
|
||||||
|
this.headers = headers;
|
||||||
|
this.rows = rows;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 单个 Excel 文件数据定义(一个 Excel = 多个 Sheet)
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
public static class ExcelData {
|
||||||
|
/** Excel 文件名(不含 .xlsx 扩展名,在 ZIP 中自动添加) */
|
||||||
|
private String fileName;
|
||||||
|
/** 该 Excel 包含的所有 Sheet 页 */
|
||||||
|
private List<SheetData> sheets;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ======================== 分组表头数据模型 ========================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 带分组表头的 Sheet 页数据定义(支持合并单元格)
|
||||||
|
*
|
||||||
|
* <p>生成的 Excel 结构:
|
||||||
|
* <pre>
|
||||||
|
* Row 0: [rowHeaderLabel(合并)] [group0Name(合并 subCols 列)] [group1Name(合并 subCols 列)] ...
|
||||||
|
* Row 1: [ ] [sub0] [sub1] ... [subN] [sub0] [sub1] ... [subN] ...
|
||||||
|
* Row 2+: rowLabel0 data...
|
||||||
|
* Row 3 : rowLabel1 data...
|
||||||
|
* </pre></p>
|
||||||
|
*
|
||||||
|
* <h3>使用示例</h3>
|
||||||
|
* <pre>{@code
|
||||||
|
* GroupedSheetData sheet = new GroupedSheetData("流速(m/s)", "日期",
|
||||||
|
* Arrays.asList("XX水电站", "YY水电站"),
|
||||||
|
* Arrays.asList("日均最低", "日均最高", "月内最低", "月内最低时间", "月内最高", "月内最高时间"));
|
||||||
|
* // 每行:[rowLabel, g0_sub0, g0_sub1, ..., g0_sub5, g1_sub0, ...]
|
||||||
|
* sheet.getRows().add(Arrays.asList("2026-08", 0.5, 1.2, 0.3, "2026-08-15 03:00:00", 2.1, "...", ...));
|
||||||
|
* }</pre>
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@NoArgsConstructor
|
||||||
|
public static class GroupedSheetData {
|
||||||
|
/** Sheet 页名称 */
|
||||||
|
private String sheetName;
|
||||||
|
/** 行标题列名(如"日期",该列在 Row0+Row1 纵向合并) */
|
||||||
|
private String rowHeaderLabel;
|
||||||
|
/** 分组名称列表(如["XX水电站","YY水电站"]) */
|
||||||
|
private List<String> groupNames;
|
||||||
|
/** 子表头列表(每个分组下都有相同的子表头) */
|
||||||
|
private List<String> subHeaders;
|
||||||
|
/** 数据行:每行为 [rowLabel, group0.sub0, group0.sub1, ..., group0.subN, group1.sub0, ...] */
|
||||||
|
private List<List<Object>> rows = new ArrayList<>();
|
||||||
|
|
||||||
|
public GroupedSheetData(String sheetName, String rowHeaderLabel,
|
||||||
|
List<String> groupNames, List<String> subHeaders) {
|
||||||
|
this.sheetName = sheetName;
|
||||||
|
this.rowHeaderLabel = rowHeaderLabel;
|
||||||
|
this.groupNames = groupNames;
|
||||||
|
this.subHeaders = subHeaders;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ======================== 核心导出方法 ========================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导出 ZIP 压缩包到 HttpServletResponse(浏览器下载)
|
||||||
|
*
|
||||||
|
* @param response HttpServletResponse
|
||||||
|
* @param zipFileName 下载文件名(含 .zip 扩展名)
|
||||||
|
* @param excelList 要导出的 Excel 数据集合
|
||||||
|
*/
|
||||||
|
public static void exportToResponse(HttpServletResponse response, String zipFileName, List<ExcelData> excelList) {
|
||||||
|
response.setContentType("application/zip");
|
||||||
|
response.setCharacterEncoding("UTF-8");
|
||||||
|
try {
|
||||||
|
response.setHeader("Content-Disposition",
|
||||||
|
"attachment; filename=" + URLEncoder.encode(zipFileName, "UTF-8"));
|
||||||
|
} catch (UnsupportedEncodingException e) {
|
||||||
|
response.setHeader("Content-Disposition", "attachment; filename=export.zip");
|
||||||
|
}
|
||||||
|
|
||||||
|
try (ServletOutputStream os = response.getOutputStream()) {
|
||||||
|
exportToStream(os, excelList);
|
||||||
|
os.flush();
|
||||||
|
} catch (IOException e) {
|
||||||
|
log.error("导出 ZIP 到 Response 失败", e);
|
||||||
|
throw new RuntimeException("导出失败: " + e.getMessage(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导出 ZIP 压缩包到本地文件
|
||||||
|
*
|
||||||
|
* @param targetFile 目标文件
|
||||||
|
* @param excelList 要导出的 Excel 数据集合
|
||||||
|
*/
|
||||||
|
public static void exportToFile(File targetFile, List<ExcelData> excelList) {
|
||||||
|
try (FileOutputStream fos = new FileOutputStream(targetFile)) {
|
||||||
|
exportToStream(fos, excelList);
|
||||||
|
} catch (IOException e) {
|
||||||
|
log.error("导出 ZIP 到文件失败: {}", targetFile.getAbsolutePath(), e);
|
||||||
|
throw new RuntimeException("导出失败: " + e.getMessage(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导出 ZIP 压缩包到任意 OutputStream
|
||||||
|
* <p>
|
||||||
|
* 实现原理:先将每个 Excel 写入临时字节数组,再用内存 ZIP 打包,避免磁盘 IO。
|
||||||
|
*
|
||||||
|
* @param os 目标输出流
|
||||||
|
* @param excelList 要导出的 Excel 数据集合
|
||||||
|
*/
|
||||||
|
public static void exportToStream(OutputStream os, List<ExcelData> excelList) throws IOException {
|
||||||
|
if (excelList == null || excelList.isEmpty()) {
|
||||||
|
log.warn("导出数据为空,跳过 ZIP 生成");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 延迟创建 ZIP,累计所有 Excel 字节数组
|
||||||
|
ByteArrayOutputStream zipBaos = new ByteArrayOutputStream();
|
||||||
|
try (java.util.zip.ZipOutputStream zos = new java.util.zip.ZipOutputStream(zipBaos)) {
|
||||||
|
for (ExcelData excelData : excelList) {
|
||||||
|
if (excelData.getSheets() == null || excelData.getSheets().isEmpty()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
byte[] excelBytes = workbookToBytes(createWorkbook(excelData));
|
||||||
|
String entryName = sanitizeFileName(excelData.getFileName()) + ".xlsx";
|
||||||
|
|
||||||
|
java.util.zip.ZipEntry entry = new java.util.zip.ZipEntry(entryName);
|
||||||
|
zos.putNextEntry(entry);
|
||||||
|
zos.write(excelBytes);
|
||||||
|
zos.closeEntry();
|
||||||
|
}
|
||||||
|
zos.finish();
|
||||||
|
}
|
||||||
|
|
||||||
|
os.write(zipBaos.toByteArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
// ======================== 分组表头导出方法 ========================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导出分组表头数据为 ZIP(每个 GroupedSheetData 生成一个独立的 Excel 文件在 ZIP 中)
|
||||||
|
*
|
||||||
|
* @param response HttpServletResponse
|
||||||
|
* @param zipFileName 下载文件名
|
||||||
|
* @param sheets 分组表头数据列表(每个元素 = ZIP 中一个 .xlsx 文件)
|
||||||
|
*/
|
||||||
|
public static void exportGroupedToResponse(HttpServletResponse response, String zipFileName,
|
||||||
|
List<GroupedSheetData> sheets) {
|
||||||
|
response.setContentType("application/zip");
|
||||||
|
response.setCharacterEncoding("UTF-8");
|
||||||
|
try {
|
||||||
|
response.setHeader("Content-Disposition",
|
||||||
|
"attachment; filename=" + URLEncoder.encode(zipFileName, "UTF-8"));
|
||||||
|
} catch (UnsupportedEncodingException e) {
|
||||||
|
response.setHeader("Content-Disposition", "attachment; filename=export.zip");
|
||||||
|
}
|
||||||
|
try (ServletOutputStream os = response.getOutputStream()) {
|
||||||
|
exportGroupedToStream(os, sheets);
|
||||||
|
os.flush();
|
||||||
|
} catch (IOException e) {
|
||||||
|
log.error("导出分组 ZIP 到 Response 失败", e);
|
||||||
|
throw new RuntimeException("导出失败: " + e.getMessage(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导出分组表头数据 ZIP 到任意 OutputStream
|
||||||
|
* <p>
|
||||||
|
* 每个 GroupedSheetData 作为一个 .xlsx 文件打入 ZIP。
|
||||||
|
*/
|
||||||
|
public static void exportGroupedToStream(OutputStream os, List<GroupedSheetData> sheets) throws IOException {
|
||||||
|
if (sheets == null || sheets.isEmpty()) {
|
||||||
|
log.warn("导出数据为空,跳过 ZIP 生成");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ByteArrayOutputStream zipBaos = new ByteArrayOutputStream();
|
||||||
|
try (java.util.zip.ZipOutputStream zos = new java.util.zip.ZipOutputStream(zipBaos)) {
|
||||||
|
for (GroupedSheetData sheet : sheets) {
|
||||||
|
SXSSFWorkbook workbook = new SXSSFWorkbook(100);
|
||||||
|
try {
|
||||||
|
fillGroupedSheet(workbook, sheet);
|
||||||
|
byte[] bytes = workbookToBytes(workbook);
|
||||||
|
String entryName = sanitizeFileName(sheet.getSheetName()) + ".xlsx";
|
||||||
|
java.util.zip.ZipEntry entry = new java.util.zip.ZipEntry(entryName);
|
||||||
|
zos.putNextEntry(entry);
|
||||||
|
zos.write(bytes);
|
||||||
|
zos.closeEntry();
|
||||||
|
} finally {
|
||||||
|
workbook.close();
|
||||||
|
workbook.dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
zos.finish();
|
||||||
|
}
|
||||||
|
os.write(zipBaos.toByteArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 向 Workbook 中填充一个带分组表头的 Sheet
|
||||||
|
*
|
||||||
|
* @param workbook 目标 Workbook
|
||||||
|
* @param data 分组表头数据
|
||||||
|
*/
|
||||||
|
public static void fillGroupedSheet(Workbook workbook, GroupedSheetData data) {
|
||||||
|
String name = safeName(data.getSheetName());
|
||||||
|
Sheet sheet = workbook.createSheet(name);
|
||||||
|
if (sheet instanceof SXSSFSheet) {
|
||||||
|
((SXSSFSheet) sheet).trackAllColumnsForAutoSizing();
|
||||||
|
}
|
||||||
|
|
||||||
|
CellStyle groupHeaderStyle = createHeaderStyle(workbook);
|
||||||
|
CellStyle subHeaderStyle = createSubHeaderStyle(workbook);
|
||||||
|
CellStyle dataStyle = createDataStyle(workbook);
|
||||||
|
|
||||||
|
int groupCount = data.getGroupNames() != null ? data.getGroupNames().size() : 0;
|
||||||
|
int subCols = data.getSubHeaders() != null ? data.getSubHeaders().size() : 0;
|
||||||
|
int totalCols = 1 + groupCount * subCols; // 1 = rowHeaderLabel
|
||||||
|
|
||||||
|
// Row 0: 分组表头
|
||||||
|
Row groupRow = sheet.createRow(0);
|
||||||
|
groupRow.setHeightInPoints(24);
|
||||||
|
|
||||||
|
Cell labelCell = groupRow.createCell(0);
|
||||||
|
labelCell.setCellValue(data.getRowHeaderLabel());
|
||||||
|
labelCell.setCellStyle(groupHeaderStyle);
|
||||||
|
// 行标题列 Row0+Row1 合并
|
||||||
|
if (data.getRowHeaderLabel() != null) {
|
||||||
|
sheet.addMergedRegion(new CellRangeAddress(0, 1, 0, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
int colIdx = 1;
|
||||||
|
for (int g = 0; g < groupCount; g++) {
|
||||||
|
String groupName = data.getGroupNames().get(g);
|
||||||
|
Cell gc = groupRow.createCell(colIdx);
|
||||||
|
gc.setCellValue(groupName);
|
||||||
|
gc.setCellStyle(groupHeaderStyle);
|
||||||
|
if (subCols > 1) {
|
||||||
|
sheet.addMergedRegion(new CellRangeAddress(0, 0, colIdx, colIdx + subCols - 1));
|
||||||
|
}
|
||||||
|
colIdx += subCols;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Row 1: 子表头
|
||||||
|
Row subRow = sheet.createRow(1);
|
||||||
|
subRow.setHeightInPoints(22);
|
||||||
|
colIdx = 1;
|
||||||
|
for (int g = 0; g < groupCount; g++) {
|
||||||
|
for (int s = 0; s < subCols; s++) {
|
||||||
|
Cell sc = subRow.createCell(colIdx++);
|
||||||
|
sc.setCellValue(data.getSubHeaders().get(s));
|
||||||
|
sc.setCellStyle(subHeaderStyle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Row 2+: 数据行
|
||||||
|
if (data.getRows() != null) {
|
||||||
|
int rowIdx = 2;
|
||||||
|
for (List<Object> rowData : data.getRows()) {
|
||||||
|
Row dataRow = sheet.createRow(rowIdx++);
|
||||||
|
for (int c = 0; c < Math.min(rowData.size(), totalCols); c++) {
|
||||||
|
Cell cell = dataRow.createCell(c);
|
||||||
|
Object val = rowData.get(c);
|
||||||
|
if (c == 0) {
|
||||||
|
// 行标题列用居中对齐
|
||||||
|
cell.setCellStyle(groupHeaderStyle);
|
||||||
|
} else {
|
||||||
|
cell.setCellStyle(dataStyle);
|
||||||
|
}
|
||||||
|
setCellValue(cell, val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 自动列宽
|
||||||
|
autoSizeColumns(sheet, totalCols);
|
||||||
|
|
||||||
|
// 冻结前两行
|
||||||
|
sheet.createFreezePane(0, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建子表头样式(浅蓝背景、加粗、居中、带边框)
|
||||||
|
*/
|
||||||
|
public static CellStyle createSubHeaderStyle(Workbook workbook) {
|
||||||
|
CellStyle style = workbook.createCellStyle();
|
||||||
|
style.setFillForegroundColor(IndexedColors.LIGHT_CORNFLOWER_BLUE.getIndex());
|
||||||
|
style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
|
||||||
|
|
||||||
|
Font font = workbook.createFont();
|
||||||
|
font.setBold(true);
|
||||||
|
font.setFontHeightInPoints((short) 10);
|
||||||
|
style.setFont(font);
|
||||||
|
|
||||||
|
style.setAlignment(HorizontalAlignment.CENTER);
|
||||||
|
style.setVerticalAlignment(VerticalAlignment.CENTER);
|
||||||
|
setThinBorder(style);
|
||||||
|
return style;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ======================== Excel 生成方法 ========================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据 ExcelData 创建一个完整的 Excel Workbook(含所有 Sheet)
|
||||||
|
* <p>
|
||||||
|
* 使用 SXSSFWorkbook(流式写入),支持大数据量导出,内存占用可控。
|
||||||
|
*
|
||||||
|
* @param excelData 单个 Excel 的数据定义
|
||||||
|
* @return 填充完毕的 Workbook(调用方负责关闭以释放临时文件)
|
||||||
|
*/
|
||||||
|
public static Workbook createWorkbook(ExcelData excelData) {
|
||||||
|
SXSSFWorkbook workbook = new SXSSFWorkbook(100); // 内存中保留 100 行,其余写临时文件
|
||||||
|
CellStyle headerStyle = createHeaderStyle(workbook);
|
||||||
|
CellStyle dataStyle = createDataStyle(workbook);
|
||||||
|
|
||||||
|
for (SheetData sheetData : excelData.getSheets()) {
|
||||||
|
if (sheetData == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
fillSheet(workbook, sheetData, headerStyle, dataStyle);
|
||||||
|
}
|
||||||
|
|
||||||
|
return workbook;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 填充单个 Sheet 页的数据
|
||||||
|
*
|
||||||
|
* @param workbook 目标 Workbook
|
||||||
|
* @param sheetData Sheet 数据定义
|
||||||
|
* @param headerStyle 表头样式
|
||||||
|
* @param dataStyle 数据行样式
|
||||||
|
*/
|
||||||
|
public static void fillSheet(Workbook workbook, SheetData sheetData, CellStyle headerStyle, CellStyle dataStyle) {
|
||||||
|
String name = safeName(sheetData.getSheetName());
|
||||||
|
Sheet sheet = workbook.createSheet(name);
|
||||||
|
|
||||||
|
// SXSSFSheet 必须在写入数据前开启列追踪,否则 autoSizeColumn 会报错
|
||||||
|
if (sheet instanceof SXSSFSheet) {
|
||||||
|
((SXSSFSheet) sheet).trackAllColumnsForAutoSizing();
|
||||||
|
}
|
||||||
|
|
||||||
|
List<String> headers = sheetData.getHeaders();
|
||||||
|
List<List<Object>> rows = sheetData.getRows();
|
||||||
|
int colCount = headers != null ? headers.size() : 0;
|
||||||
|
|
||||||
|
// 设置列宽默认值(后续在数据写入后统一自动调整)
|
||||||
|
int currentRow = 0;
|
||||||
|
|
||||||
|
// ---- 写表头 ----
|
||||||
|
if (headers != null && !headers.isEmpty()) {
|
||||||
|
Row headerRow = sheet.createRow(currentRow++);
|
||||||
|
headerRow.setHeightInPoints(22);
|
||||||
|
for (int i = 0; i < colCount; i++) {
|
||||||
|
Cell cell = headerRow.createCell(i);
|
||||||
|
cell.setCellValue(headers.get(i));
|
||||||
|
cell.setCellStyle(headerStyle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---- 写数据行 ----
|
||||||
|
if (rows != null) {
|
||||||
|
CellStyle subHeaderStyle = createSubHeaderStyle(workbook);
|
||||||
|
for (int r = 0; r < rows.size(); r++) {
|
||||||
|
List<Object> rowData = rows.get(r);
|
||||||
|
Row dataRow = sheet.createRow(currentRow++);
|
||||||
|
int hc = sheetData.getHeaderRowCount();
|
||||||
|
CellStyle rowStyle;
|
||||||
|
if (r < hc) {
|
||||||
|
// 多层标题:第0行=headerStyle, 第1行=subHeaderStyle, 后续=subHeaderStyle
|
||||||
|
rowStyle = r == 0 ? headerStyle : subHeaderStyle;
|
||||||
|
} else {
|
||||||
|
rowStyle = dataStyle;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < Math.min(rowData.size(), colCount); i++) {
|
||||||
|
Cell cell = dataRow.createCell(i);
|
||||||
|
Object value = rowData.get(i);
|
||||||
|
setCellValue(cell, value);
|
||||||
|
cell.setCellStyle(rowStyle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---- 合并单元格 ----
|
||||||
|
if (sheetData.getMergedRegions() != null) {
|
||||||
|
for (int[] region : sheetData.getMergedRegions()) {
|
||||||
|
sheet.addMergedRegion(new CellRangeAddress(region[0], region[1], region[2], region[3]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---- 自动调整列宽 ----
|
||||||
|
autoSizeColumns(sheet, colCount);
|
||||||
|
|
||||||
|
// 冻结表头行
|
||||||
|
if (currentRow > 1) {
|
||||||
|
int freezeRows = 1 + sheetData.getHeaderRowCount();
|
||||||
|
sheet.createFreezePane(0, Math.min(freezeRows, currentRow - 1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ======================== 样式定义 ========================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建表头样式(蓝色背景、白色加粗字体、居中对齐、带边框)
|
||||||
|
*/
|
||||||
|
public static CellStyle createHeaderStyle(Workbook workbook) {
|
||||||
|
CellStyle style = workbook.createCellStyle();
|
||||||
|
|
||||||
|
// 背景色:浅淡的苍白蓝
|
||||||
|
style.setFillForegroundColor(IndexedColors.PALE_BLUE.getIndex());
|
||||||
|
style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
|
||||||
|
|
||||||
|
// 字体:黑色加粗
|
||||||
|
Font font = workbook.createFont();
|
||||||
|
font.setBold(true);
|
||||||
|
font.setColor(IndexedColors.BLACK.getIndex());
|
||||||
|
font.setFontHeightInPoints((short) 11);
|
||||||
|
style.setFont(font);
|
||||||
|
|
||||||
|
// 对齐:居中
|
||||||
|
style.setAlignment(HorizontalAlignment.CENTER);
|
||||||
|
style.setVerticalAlignment(VerticalAlignment.CENTER);
|
||||||
|
|
||||||
|
// 边框
|
||||||
|
setThinBorder(style);
|
||||||
|
|
||||||
|
return style;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建数据行样式(无背景、正常字体、左对齐、带边框)
|
||||||
|
*/
|
||||||
|
public static CellStyle createDataStyle(Workbook workbook) {
|
||||||
|
CellStyle style = workbook.createCellStyle();
|
||||||
|
|
||||||
|
style.setAlignment(HorizontalAlignment.LEFT);
|
||||||
|
style.setVerticalAlignment(VerticalAlignment.CENTER);
|
||||||
|
|
||||||
|
// 自动换行
|
||||||
|
style.setWrapText(true);
|
||||||
|
|
||||||
|
setThinBorder(style);
|
||||||
|
|
||||||
|
return style;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置细线边框
|
||||||
|
*/
|
||||||
|
private static void setThinBorder(CellStyle style) {
|
||||||
|
style.setBorderTop(BorderStyle.THIN);
|
||||||
|
style.setBorderRight(BorderStyle.THIN);
|
||||||
|
style.setBorderBottom(BorderStyle.THIN);
|
||||||
|
style.setBorderLeft(BorderStyle.THIN);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ======================== 列宽自动调整 ========================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 自动调整列宽(根据内容宽度)
|
||||||
|
* <p>
|
||||||
|
* 遍历每一列,取表头和所有数据行中最宽的内容作为列宽基准。
|
||||||
|
*
|
||||||
|
* @param sheet Sheet 对象
|
||||||
|
* @param colCount 列数
|
||||||
|
*/
|
||||||
|
public static void autoSizeColumns(Sheet sheet, int colCount) {
|
||||||
|
for (int i = 0; i < colCount; i++) {
|
||||||
|
sheet.autoSizeColumn(i);
|
||||||
|
// 自动列宽后留一点余量,避免内容紧贴边框
|
||||||
|
int currentWidth = sheet.getColumnWidth(i);
|
||||||
|
if (currentWidth > 0) {
|
||||||
|
sheet.setColumnWidth(i, Math.min(currentWidth + 512, 255 * 256)); // 最大 255 字符宽
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ======================== 辅助方法 ========================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 类型安全方式构建 SheetData
|
||||||
|
* <p>
|
||||||
|
* 适用于已有实体类 List 的场景,通过方法引用指定字段取值,避免手动逐字段提取。
|
||||||
|
*
|
||||||
|
* <pre>{@code
|
||||||
|
* SheetData data = ExportZipUtil.fromTypedData("电站信息",
|
||||||
|
* Arrays.asList("编码", "名称", "经度", "纬度"),
|
||||||
|
* Arrays.asList(Station::getStcd, Station::getStnm, Station::getLgtd, Station::getLttd),
|
||||||
|
* stationList);
|
||||||
|
* }</pre>
|
||||||
|
*
|
||||||
|
* @param sheetName Sheet 名称
|
||||||
|
* @param headers 表头列表
|
||||||
|
* @param extractors 字段取值函数(与 headers 一一对应)
|
||||||
|
* @param data 实体数据集合
|
||||||
|
* @param <T> 实体类型
|
||||||
|
* @return 构建好的 SheetData
|
||||||
|
*/
|
||||||
|
public static <T> SheetData fromTypedData(String sheetName,
|
||||||
|
List<String> headers,
|
||||||
|
List<Function<T, Object>> extractors,
|
||||||
|
List<T> data) {
|
||||||
|
List<List<Object>> rows = data.stream()
|
||||||
|
.map(entity -> extractors.stream()
|
||||||
|
.map(ext -> ext.apply(entity))
|
||||||
|
.collect(Collectors.toList()))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
return new SheetData(sheetName, headers, rows);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将 Workbook 写入字节数组并关闭 Workbook
|
||||||
|
*/
|
||||||
|
private static byte[] workbookToBytes(Workbook workbook) throws IOException {
|
||||||
|
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||||
|
try {
|
||||||
|
workbook.write(baos);
|
||||||
|
} finally {
|
||||||
|
workbook.close();
|
||||||
|
// SXSSFWorkbook 会清理临时文件
|
||||||
|
if (workbook instanceof SXSSFWorkbook) {
|
||||||
|
((SXSSFWorkbook) workbook).dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return baos.toByteArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文件名非法字符过滤(Windows + 通用)
|
||||||
|
*/
|
||||||
|
private static String sanitizeFileName(String fileName) {
|
||||||
|
if (fileName == null || fileName.isEmpty()) {
|
||||||
|
return "sheet";
|
||||||
|
}
|
||||||
|
return fileName.replaceAll("[\\\\/:*?\"<>|]", "_");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sheet 名称安全处理(Excel Sheet 名最长 31 字符)
|
||||||
|
*/
|
||||||
|
private static String safeName(String name) {
|
||||||
|
if (name == null || name.isEmpty()) {
|
||||||
|
return "Sheet1";
|
||||||
|
}
|
||||||
|
// Excel Sheet 名禁止包含 [ ] : * ? / \
|
||||||
|
String safe = name.replaceAll("[\\[\\]:*?/\\\\]", "_");
|
||||||
|
return safe.length() > 31 ? safe.substring(0, 31) : safe;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置单元格值(自动适配类型)
|
||||||
|
*/
|
||||||
|
private static void setCellValue(Cell cell, Object value) {
|
||||||
|
if (value == null) {
|
||||||
|
cell.setCellValue("");
|
||||||
|
} else if (value instanceof Number) {
|
||||||
|
cell.setCellValue(((Number) value).doubleValue());
|
||||||
|
} else if (value instanceof Boolean) {
|
||||||
|
cell.setCellValue((Boolean) value);
|
||||||
|
} else if (value instanceof java.util.Date) {
|
||||||
|
cell.setCellValue((java.util.Date) value);
|
||||||
|
} else {
|
||||||
|
cell.setCellValue(String.valueOf(value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ======================== 测试方法 ========================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 本地运行测试,生成模拟数据 ZIP 文件到 D:/export_sample.zip
|
||||||
|
*/
|
||||||
|
public static void main(String[] args) {
|
||||||
|
// ---------- Excel 1:电站基础数据(1个Sheet:基础信息) ----------
|
||||||
|
List<List<Object>> stationRows = new ArrayList<>();
|
||||||
|
for (int i = 1; i <= 50; i++) {
|
||||||
|
stationRows.add(Arrays.asList(
|
||||||
|
"STCD" + String.format("%05d", i), // 测站编码
|
||||||
|
"XX水电站" + i + "号", // 测站名称
|
||||||
|
"长江流域", // 所在流域
|
||||||
|
110.123456 + Math.random() * 10, // 经度
|
||||||
|
30.654321 + Math.random() * 10, // 纬度
|
||||||
|
"坝式水电站", // 工程类型
|
||||||
|
Math.random() > 0.5 ? "运行中" : "在建", // 建设状态
|
||||||
|
"省级", // 级别
|
||||||
|
2000 + (i % 24) // 建成时间
|
||||||
|
));
|
||||||
|
}
|
||||||
|
SheetData stationSheet = new SheetData("电站基础信息",
|
||||||
|
Arrays.asList("测站编码", "测站名称", "所在流域", "经度", "纬度",
|
||||||
|
"工程类型", "建设状态", "级别", "建成时间"),
|
||||||
|
stationRows);
|
||||||
|
|
||||||
|
// ---------- Sheet 2:水位监测数据 ----------
|
||||||
|
List<List<Object>> monitorRows = new ArrayList<>();
|
||||||
|
String[] months = {"2026-01", "2026-02", "2026-03", "2026-04", "2026-05", "2026-06"};
|
||||||
|
for (int i = 1; i <= 30; i++) {
|
||||||
|
for (String month : months) {
|
||||||
|
monitorRows.add(Arrays.asList(
|
||||||
|
"STCD" + String.format("%05d", i),
|
||||||
|
"XX水电站" + i + "号",
|
||||||
|
month,
|
||||||
|
String.format("%.2f", 100 + Math.random() * 50), // 水位(m)
|
||||||
|
String.format("%.2f", 500 + Math.random() * 2000), // 流量(m³/s)
|
||||||
|
String.format("%.1f", 15 + Math.random() * 20), // 水温(℃)
|
||||||
|
Math.random() > 0.8 ? "超标" : "正常" // 水质状态
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SheetData monitorSheet = new SheetData("水位监测数据",
|
||||||
|
Arrays.asList("测站编码", "测站名称", "监测月份", "水位(m)", "流量(m³/s)",
|
||||||
|
"水温(℃)", "水质状态"),
|
||||||
|
monitorRows);
|
||||||
|
|
||||||
|
// ---------- Excel 2:流域概况数据 ----------
|
||||||
|
List<List<Object>> basinRows = new ArrayList<>();
|
||||||
|
String[] basinNames = {"长江流域", "黄河流域", "珠江流域", "淮河流域", "松花江流域", "海河流域"};
|
||||||
|
String[] provinces = {"湖北/湖南/四川", "河南/山东/陕西", "广东/广西", "安徽/江苏", "黑龙江/吉林", "河北/天津"};
|
||||||
|
for (int i = 0; i < basinNames.length; i++) {
|
||||||
|
basinRows.add(Arrays.asList(
|
||||||
|
"RV" + String.format("%03d", i + 1), // 流域编码
|
||||||
|
basinNames[i], // 流域名称
|
||||||
|
i == 0 ? "一级" : "二级", // 级别
|
||||||
|
provinces[i], // 覆盖省份
|
||||||
|
100 + Math.random() * 900, // 流域面积(万km²)
|
||||||
|
500 + Math.random() * 5000, // 年径流量(亿m³)
|
||||||
|
(int) (1000 + Math.random() * 2000), // 电站数量
|
||||||
|
"良好" // 生态状态
|
||||||
|
));
|
||||||
|
}
|
||||||
|
SheetData basinSheet = new SheetData("流域概况",
|
||||||
|
Arrays.asList("流域编码", "流域名称", "级别", "覆盖省份", "流域面积(万km²)",
|
||||||
|
"年径流量(亿m³)", "电站数量(个)", "生态状态"),
|
||||||
|
basinRows);
|
||||||
|
|
||||||
|
// ---------- Sheet 4:鱼道设施数据 ----------
|
||||||
|
List<List<Object>> fishwayRows = new ArrayList<>();
|
||||||
|
String[] types = {"竖缝式鱼道", "池堰式鱼道", "升鱼机", "集运鱼船"};
|
||||||
|
for (int i = 1; i <= 20; i++) {
|
||||||
|
fishwayRows.add(Arrays.asList(
|
||||||
|
"STCD" + String.format("%05d", i),
|
||||||
|
"XX水电站" + i + "号",
|
||||||
|
types[i % types.length], // 鱼道类型
|
||||||
|
String.format("%.1f", 5 + Math.random() * 95), // 过鱼效率(%)
|
||||||
|
String.format("%.2f", 50 + Math.random() * 200), // 鱼道长度(m)
|
||||||
|
String.format("%.1f", 2 + Math.random() * 8), // 鱼道宽度(m)
|
||||||
|
Math.random() > 0.3 ? "运行中" : "检修中", // 运行状态
|
||||||
|
"2025-0" + (1 + i % 9) + "-01" // 投运日期
|
||||||
|
));
|
||||||
|
}
|
||||||
|
SheetData fishwaySheet = new SheetData("鱼道设施",
|
||||||
|
Arrays.asList("电站编码", "电站名称", "鱼道类型", "过鱼效率(%)",
|
||||||
|
"鱼道长度(m)", "鱼道宽度(m)", "运行状态", "投运日期"),
|
||||||
|
fishwayRows);
|
||||||
|
|
||||||
|
// ---------- 组装导出 ----------
|
||||||
|
ExcelData excel1 = new ExcelData("电站综合数据", Arrays.asList(stationSheet, monitorSheet));
|
||||||
|
ExcelData excel2 = new ExcelData("流域与鱼道数据", Arrays.asList(basinSheet, fishwaySheet));
|
||||||
|
|
||||||
|
String outputPath = "D:/export_sample.zip";
|
||||||
|
try {
|
||||||
|
log.info("开始生成测试数据...");
|
||||||
|
exportToFile(new File(outputPath), Arrays.asList(excel1, excel2));
|
||||||
|
log.info("导出成功!文件路径: {}", outputPath);
|
||||||
|
System.out.println("导出成功!文件路径: " + outputPath);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("导出失败", e);
|
||||||
|
System.err.println("导出失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -13,8 +13,8 @@ spring:
|
|||||||
# ==================== 达梦(DM) 数据源 ====================
|
# ==================== 达梦(DM) 数据源 ====================
|
||||||
dm-master:
|
dm-master:
|
||||||
driverClassName: dm.jdbc.driver.DmDriver
|
driverClassName: dm.jdbc.driver.DmDriver
|
||||||
url: "${DB_DM_MASTER_URL:jdbc:dm://172.16.21.143:5236/QGC_REFA}"
|
url: "${DB_DM_MASTER_URL:jdbc:dm://172.16.21.143:5236/QGC_REFA_TEST}"
|
||||||
username: "${DB_DM_MASTER_USERNAME:QGC_REFA}"
|
username: "${DB_DM_MASTER_USERNAME:QGC_REFA_TEST}"
|
||||||
password: "${DB_DM_MASTER_PASSWORD:Y4M4K1oCkL8U}"
|
password: "${DB_DM_MASTER_PASSWORD:Y4M4K1oCkL8U}"
|
||||||
initial-size: 5
|
initial-size: 5
|
||||||
min-idle: 5
|
min-idle: 5
|
||||||
@ -42,8 +42,8 @@ spring:
|
|||||||
max-pool-prepared-statement-per-connection-size: 100
|
max-pool-prepared-statement-per-connection-size: 100
|
||||||
dm-slave:
|
dm-slave:
|
||||||
driverClassName: dm.jdbc.driver.DmDriver
|
driverClassName: dm.jdbc.driver.DmDriver
|
||||||
url: "${DB_DM_SLAVE_URL:jdbc:dm://172.16.21.143:5236/QGC_REFA}"
|
url: "${DB_DM_SLAVE_URL:jdbc:dm://172.16.21.143:5236/QGC_REFA_TEST}"
|
||||||
username: "${DB_DM_SLAVE_USERNAME:QGC_REFA}"
|
username: "${DB_DM_SLAVE_USERNAME:QGC_REFA_TEST}"
|
||||||
password: "${DB_DM_SLAVE_PASSWORD:Y4M4K1oCkL8U}"
|
password: "${DB_DM_SLAVE_PASSWORD:Y4M4K1oCkL8U}"
|
||||||
initial-size: 5
|
initial-size: 5
|
||||||
min-idle: 5
|
min-idle: 5
|
||||||
|
|||||||
@ -53,83 +53,97 @@
|
|||||||
ORDER BY ORDER_INDEX ASC
|
ORDER BY ORDER_INDEX ASC
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
|
|
||||||
<select id="selectRegDropdown" resultMap="BaseResultMap">
|
<select id="selectRegDropdown" resultMap="BaseResultMap">
|
||||||
SELECT
|
SELECT *
|
||||||
t.RVCD,
|
FROM V_SD_RVCD_DIC_TREE
|
||||||
t.DISPLAY_RVNM AS RVNM,
|
WHERE 1=1
|
||||||
t.PRVCD,
|
|
||||||
t.GRD,
|
|
||||||
t.PATH,
|
|
||||||
t.ORDER_INDEX,
|
|
||||||
-- t.LGTD,
|
|
||||||
-- t.LTTD,
|
|
||||||
-- t.AREA,
|
|
||||||
-- t.PERIMETER,
|
|
||||||
-- t.COUNTRY,
|
|
||||||
-- t.LOGO,
|
|
||||||
-- t.INTRODUCE,
|
|
||||||
-- t.INFFILE,
|
|
||||||
t.SHORTNAME,
|
|
||||||
t.SHEPRANGE,
|
|
||||||
t.BASEID
|
|
||||||
-- ,
|
|
||||||
-- t.ENABLED,
|
|
||||||
-- t.RECORD_USER,
|
|
||||||
-- t.RECORD_TIME,
|
|
||||||
-- t.MODIFY_USER,
|
|
||||||
-- t.MODIFY_TIME,
|
|
||||||
-- t.IS_DELETED,
|
|
||||||
-- t.DELETE_USER,
|
|
||||||
-- t.DELETE_TIME
|
|
||||||
FROM (
|
|
||||||
SELECT
|
|
||||||
d.RVCD,
|
|
||||||
LTRIM(SYS_CONNECT_BY_PATH(d.RVNM, '-'), '-') AS DISPLAY_RVNM,
|
|
||||||
d.PRVCD,
|
|
||||||
d.GRD,
|
|
||||||
d.PATH,
|
|
||||||
d.ORDER_INDEX,
|
|
||||||
-- d.LGTD,
|
|
||||||
-- d.LTTD,
|
|
||||||
-- d.AREA,
|
|
||||||
-- d.PERIMETER,
|
|
||||||
-- d.COUNTRY,
|
|
||||||
-- d.LOGO,
|
|
||||||
-- d.INTRODUCE,
|
|
||||||
-- d.INFFILE,
|
|
||||||
d.SHORTNAME,
|
|
||||||
d.SHEPRANGE,
|
|
||||||
d.BASEID,
|
|
||||||
-- d.ENABLED,
|
|
||||||
-- d.RECORD_USER,
|
|
||||||
-- d.RECORD_TIME,
|
|
||||||
-- d.MODIFY_USER,
|
|
||||||
-- d.MODIFY_TIME,
|
|
||||||
-- d.IS_DELETED,
|
|
||||||
-- d.DELETE_USER,
|
|
||||||
-- d.DELETE_TIME,
|
|
||||||
SYS_CONNECT_BY_PATH(LPAD(NVL(d.ORDER_INDEX, 999999999), 10, '0'), '/') AS ORDER_PATH,
|
|
||||||
LEVEL AS TREE_LEVEL
|
|
||||||
FROM (
|
|
||||||
SELECT *
|
|
||||||
FROM SD_RVCD_DIC
|
|
||||||
WHERE NVL(ENABLED, 1) = 1
|
|
||||||
AND NVL(IS_DELETED, 0) = 0
|
|
||||||
) d
|
|
||||||
START WITH d.PRVCD IS NULL OR d.PRVCD = '' OR d.PRVCD = '0'
|
|
||||||
CONNECT BY PRIOR d.RVCD = d.PRVCD
|
|
||||||
ORDER SIBLINGS BY d.ORDER_INDEX ASC, d.RVCD ASC
|
|
||||||
) t
|
|
||||||
WHERE t.TREE_LEVEL > 1
|
|
||||||
<if test="rvcd != null and rvcd != ''">
|
<if test="rvcd != null and rvcd != ''">
|
||||||
AND t.RVCD = #{rvcd}
|
AND RVCD = #{rvcd}
|
||||||
</if>
|
</if>
|
||||||
<if test="rvnm != null and rvnm != ''">
|
<if test="rvnm != null and rvnm != ''">
|
||||||
AND t.DISPLAY_RVNM LIKE '%' || #{rvnm} || '%'
|
AND RVNM LIKE '%' || #{rvnm} || '%'
|
||||||
</if>
|
</if>
|
||||||
ORDER BY t.ORDER_PATH ASC, t.RVCD ASC
|
ORDER BY ORDER_PATH ASC, RVCD ASC
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
|
<!-- <select id="selectRegDropdown" resultMap="BaseResultMap">-->
|
||||||
|
<!-- SELECT-->
|
||||||
|
<!-- t.RVCD,-->
|
||||||
|
<!-- t.DISPLAY_RVNM AS RVNM,-->
|
||||||
|
<!-- t.PRVCD,-->
|
||||||
|
<!-- t.GRD,-->
|
||||||
|
<!-- t.PATH,-->
|
||||||
|
<!-- t.ORDER_INDEX,-->
|
||||||
|
<!---- t.LGTD,-->
|
||||||
|
<!---- t.LTTD,-->
|
||||||
|
<!---- t.AREA,-->
|
||||||
|
<!---- t.PERIMETER,-->
|
||||||
|
<!---- t.COUNTRY,-->
|
||||||
|
<!---- t.LOGO,-->
|
||||||
|
<!---- t.INTRODUCE,-->
|
||||||
|
<!---- t.INFFILE,-->
|
||||||
|
<!-- t.SHORTNAME,-->
|
||||||
|
<!-- t.SHEPRANGE,-->
|
||||||
|
<!-- t.BASEID-->
|
||||||
|
<!---- ,-->
|
||||||
|
<!---- t.ENABLED,-->
|
||||||
|
<!---- t.RECORD_USER,-->
|
||||||
|
<!---- t.RECORD_TIME,-->
|
||||||
|
<!---- t.MODIFY_USER,-->
|
||||||
|
<!---- t.MODIFY_TIME,-->
|
||||||
|
<!---- t.IS_DELETED,-->
|
||||||
|
<!---- t.DELETE_USER,-->
|
||||||
|
<!---- t.DELETE_TIME-->
|
||||||
|
<!-- FROM (-->
|
||||||
|
<!-- SELECT-->
|
||||||
|
<!-- d.RVCD,-->
|
||||||
|
<!-- LTRIM(SYS_CONNECT_BY_PATH(d.RVNM, '-'), '-') AS DISPLAY_RVNM,-->
|
||||||
|
<!-- d.PRVCD,-->
|
||||||
|
<!-- d.GRD,-->
|
||||||
|
<!-- d.PATH,-->
|
||||||
|
<!-- d.ORDER_INDEX,-->
|
||||||
|
<!---- d.LGTD,-->
|
||||||
|
<!---- d.LTTD,-->
|
||||||
|
<!---- d.AREA,-->
|
||||||
|
<!---- d.PERIMETER,-->
|
||||||
|
<!---- d.COUNTRY,-->
|
||||||
|
<!---- d.LOGO,-->
|
||||||
|
<!---- d.INTRODUCE,-->
|
||||||
|
<!---- d.INFFILE,-->
|
||||||
|
<!-- d.SHORTNAME,-->
|
||||||
|
<!-- d.SHEPRANGE,-->
|
||||||
|
<!-- d.BASEID,-->
|
||||||
|
<!---- d.ENABLED,-->
|
||||||
|
<!---- d.RECORD_USER,-->
|
||||||
|
<!---- d.RECORD_TIME,-->
|
||||||
|
<!---- d.MODIFY_USER,-->
|
||||||
|
<!---- d.MODIFY_TIME,-->
|
||||||
|
<!---- d.IS_DELETED,-->
|
||||||
|
<!---- d.DELETE_USER,-->
|
||||||
|
<!---- d.DELETE_TIME,-->
|
||||||
|
<!-- SYS_CONNECT_BY_PATH(LPAD(NVL(d.ORDER_INDEX, 999999999), 10, '0'), '/') AS ORDER_PATH,-->
|
||||||
|
<!-- LEVEL AS TREE_LEVEL-->
|
||||||
|
<!-- FROM (-->
|
||||||
|
<!-- SELECT *-->
|
||||||
|
<!-- FROM SD_RVCD_DIC-->
|
||||||
|
<!-- WHERE NVL(ENABLED, 1) = 1-->
|
||||||
|
<!-- AND NVL(IS_DELETED, 0) = 0-->
|
||||||
|
<!-- ) d-->
|
||||||
|
<!-- START WITH d.PRVCD IS NULL OR d.PRVCD = '' OR d.PRVCD = '0'-->
|
||||||
|
<!-- CONNECT BY PRIOR d.RVCD = d.PRVCD-->
|
||||||
|
<!-- ORDER SIBLINGS BY d.ORDER_INDEX ASC, d.RVCD ASC-->
|
||||||
|
<!-- ) t-->
|
||||||
|
<!-- WHERE t.TREE_LEVEL > 1-->
|
||||||
|
<!-- <if test="rvcd != null and rvcd != ''">-->
|
||||||
|
<!-- AND t.RVCD = #{rvcd}-->
|
||||||
|
<!-- </if>-->
|
||||||
|
<!-- <if test="rvnm != null and rvnm != ''">-->
|
||||||
|
<!-- AND t.DISPLAY_RVNM LIKE '%' || #{rvnm} || '%'-->
|
||||||
|
<!-- </if>-->
|
||||||
|
<!-- ORDER BY t.ORDER_PATH ASC, t.RVCD ASC-->
|
||||||
|
<!-- </select>-->
|
||||||
|
|
||||||
<select id="selectRegDropdownWithEng" resultMap="BaseResultMap">
|
<select id="selectRegDropdownWithEng" resultMap="BaseResultMap">
|
||||||
SELECT
|
SELECT
|
||||||
t.RVCD,
|
t.RVCD,
|
||||||
|
|||||||
@ -0,0 +1,42 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||||
|
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||||
|
<mapper namespace="com.yfd.platform.qgc_export.mapper.MsAlongdetBMapper">
|
||||||
|
|
||||||
|
<!-- 查询指定 STTP 的出库沿程配置,关联 V_MS_STBPRP_T 获取测站名称 -->
|
||||||
|
<select id="selectAlongStations" resultType="java.util.HashMap">
|
||||||
|
SELECT
|
||||||
|
A.RSTCD,
|
||||||
|
A.STCD,
|
||||||
|
A.SORT,
|
||||||
|
A.STTP,
|
||||||
|
S.STNM,
|
||||||
|
S.BASE_NAME
|
||||||
|
FROM MS_ALONGDET_B A
|
||||||
|
LEFT JOIN V_MS_STBPRP_T S ON S.STCD = A.STCD AND S.STTP = A.STTP
|
||||||
|
WHERE NVL(A.IS_DELETED, 0) = 0
|
||||||
|
AND A.IO_DIRECTION = '1'
|
||||||
|
AND A.STTP = #{sttp}
|
||||||
|
AND A.RSTCD IN
|
||||||
|
<foreach collection="rstcdList" item="rstcd" open="(" separator="," close=")">
|
||||||
|
#{rstcd}
|
||||||
|
</foreach>
|
||||||
|
ORDER BY A.SORT
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<!-- 查询所有沿程配置的电站排序(MS_ALONG_B + MS_ALONGDET_B),
|
||||||
|
按 MS_ALONG_B.ORDER_INDEX, MS_ALONGDET_B.SORT 排序 -->
|
||||||
|
<select id="selectAlongSortOrder" resultType="java.util.HashMap">
|
||||||
|
SELECT D.STCD, B.ORDER_INDEX
|
||||||
|
FROM MS_ALONGDET_B D
|
||||||
|
INNER JOIN MS_ALONG_B B ON B.ID = D.ALONG_ID AND NVL(B.IS_DELETED, 0) = 0
|
||||||
|
WHERE NVL(D.IS_DELETED, 0) = 0
|
||||||
|
-- AND D.IO_DIRECTION = '1'
|
||||||
|
AND D.STCD IN
|
||||||
|
<foreach collection="rstcdList" item="rstcd" open="(" separator="," close=")">
|
||||||
|
#{rstcd}
|
||||||
|
</foreach>
|
||||||
|
ORDER BY B.ORDER_INDEX, D.SORT
|
||||||
|
</select>
|
||||||
|
|
||||||
|
</mapper>
|
||||||
@ -0,0 +1,23 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||||
|
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||||
|
<mapper namespace="com.yfd.platform.qgc_export.mapper.SdHydropwRMapper">
|
||||||
|
|
||||||
|
<!-- 电站运行小时数据动态字段查询 -->
|
||||||
|
<select id="selectRawData" resultType="java.util.HashMap">
|
||||||
|
SELECT
|
||||||
|
STCD,
|
||||||
|
TM,
|
||||||
|
${fieldName} AS VALUE
|
||||||
|
FROM SD_HYDROPW_R
|
||||||
|
WHERE IS_DELETED = 0
|
||||||
|
AND STCD IN
|
||||||
|
<foreach collection="stcdList" item="stcd" open="(" separator="," close=")">
|
||||||
|
#{stcd}
|
||||||
|
</foreach>
|
||||||
|
AND TM >= TO_DATE(#{startTime}, 'YYYY-MM-DD HH24:MI:SS')
|
||||||
|
AND TM < TO_DATE(#{endTime}, 'YYYY-MM-DD HH24:MI:SS')
|
||||||
|
AND ${fieldName} IS NOT NULL
|
||||||
|
</select>
|
||||||
|
|
||||||
|
</mapper>
|
||||||
@ -0,0 +1,23 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||||
|
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||||
|
<mapper namespace="com.yfd.platform.qgc_export.mapper.SdHydropwdaySMapper">
|
||||||
|
|
||||||
|
<!-- 电站运行日数据动态字段查询 -->
|
||||||
|
<select id="selectRawData" resultType="java.util.HashMap">
|
||||||
|
SELECT
|
||||||
|
STCD,
|
||||||
|
DT,
|
||||||
|
${fieldName} AS VALUE
|
||||||
|
FROM SD_HYDROPWDAY_S
|
||||||
|
WHERE IS_DELETED = 0
|
||||||
|
AND STCD IN
|
||||||
|
<foreach collection="stcdList" item="stcd" open="(" separator="," close=")">
|
||||||
|
#{stcd}
|
||||||
|
</foreach>
|
||||||
|
AND DT >= TO_DATE(#{startTime}, 'YYYY-MM-DD HH24:MI:SS')
|
||||||
|
AND DT < TO_DATE(#{endTime}, 'YYYY-MM-DD HH24:MI:SS')
|
||||||
|
AND ${fieldName} IS NOT NULL
|
||||||
|
</select>
|
||||||
|
|
||||||
|
</mapper>
|
||||||
@ -0,0 +1,39 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||||
|
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||||
|
<mapper namespace="com.yfd.platform.qgc_export.mapper.SdQecRMapper">
|
||||||
|
|
||||||
|
<select id="selectRawData" resultType="java.util.HashMap">
|
||||||
|
SELECT
|
||||||
|
STCD,
|
||||||
|
TM,
|
||||||
|
QEC AS VALUE
|
||||||
|
FROM SD_QEC_R
|
||||||
|
WHERE IS_DELETED = 0
|
||||||
|
AND STCD IN
|
||||||
|
<foreach collection="stcdList" item="stcd" open="(" separator="," close=")">
|
||||||
|
#{stcd}
|
||||||
|
</foreach>
|
||||||
|
AND TM >= TO_DATE(#{startTime}, 'YYYY-MM-DD HH24:MI:SS')
|
||||||
|
AND TM < TO_DATE(#{endTime}, 'YYYY-MM-DD HH24:MI:SS')
|
||||||
|
AND QEC IS NOT NULL
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<!-- 生态流量达标数据:返回三种 SFDB 用于计算各部达标率 -->
|
||||||
|
<select id="selectComplianceData" resultType="java.util.HashMap">
|
||||||
|
SELECT
|
||||||
|
STCD,
|
||||||
|
SFDB,
|
||||||
|
MWR_SFDB,
|
||||||
|
AVQ_SFDB
|
||||||
|
FROM SD_QEC_R
|
||||||
|
WHERE IS_DELETED = 0
|
||||||
|
AND STCD IN
|
||||||
|
<foreach collection="stcdList" item="stcd" open="(" separator="," close=")">
|
||||||
|
#{stcd}
|
||||||
|
</foreach>
|
||||||
|
AND TM >= TO_DATE(#{startTime}, 'YYYY-MM-DD HH24:MI:SS')
|
||||||
|
AND TM < TO_DATE(#{endTime}, 'YYYY-MM-DD HH24:MI:SS')
|
||||||
|
</select>
|
||||||
|
|
||||||
|
</mapper>
|
||||||
@ -0,0 +1,39 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||||
|
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||||
|
<mapper namespace="com.yfd.platform.qgc_export.mapper.SdQecdaySMapper">
|
||||||
|
|
||||||
|
<select id="selectRawData" resultType="java.util.HashMap">
|
||||||
|
SELECT
|
||||||
|
STCD,
|
||||||
|
DT,
|
||||||
|
QEC AS VALUE
|
||||||
|
FROM SD_QECDAY_S
|
||||||
|
WHERE IS_DELETED = 0
|
||||||
|
AND STCD IN
|
||||||
|
<foreach collection="stcdList" item="stcd" open="(" separator="," close=")">
|
||||||
|
#{stcd}
|
||||||
|
</foreach>
|
||||||
|
AND DT >= TO_DATE(#{startTime}, 'YYYY-MM-DD HH24:MI:SS')
|
||||||
|
AND DT < TO_DATE(#{endTime}, 'YYYY-MM-DD HH24:MI:SS')
|
||||||
|
AND QEC IS NOT NULL
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<!-- 生态流量达标数据:返回三种 SFDB 用于计算各部达标率 -->
|
||||||
|
<select id="selectComplianceData" resultType="java.util.HashMap">
|
||||||
|
SELECT
|
||||||
|
STCD,
|
||||||
|
SFDB,
|
||||||
|
MWR_SFDB,
|
||||||
|
AVQ_SFDB
|
||||||
|
FROM SD_QECDAY_S
|
||||||
|
WHERE IS_DELETED = 0
|
||||||
|
AND STCD IN
|
||||||
|
<foreach collection="stcdList" item="stcd" open="(" separator="," close=")">
|
||||||
|
#{stcd}
|
||||||
|
</foreach>
|
||||||
|
AND DT >= TO_DATE(#{startTime}, 'YYYY-MM-DD HH24:MI:SS')
|
||||||
|
AND DT < TO_DATE(#{endTime}, 'YYYY-MM-DD HH24:MI:SS')
|
||||||
|
</select>
|
||||||
|
|
||||||
|
</mapper>
|
||||||
@ -0,0 +1,26 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||||
|
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||||
|
<mapper namespace="com.yfd.platform.qgc_export.mapper.SdRiverRMapper">
|
||||||
|
|
||||||
|
<!--
|
||||||
|
动态字段查询:根据 fieldName 参数选择 V/Q/Z 列
|
||||||
|
利用 STCD + TM + IS_DELETED 复合索引
|
||||||
|
-->
|
||||||
|
<select id="selectRawData" resultType="java.util.HashMap">
|
||||||
|
SELECT
|
||||||
|
STCD,
|
||||||
|
TM,
|
||||||
|
${fieldName} AS VALUE
|
||||||
|
FROM SD_RIVER_R
|
||||||
|
WHERE IS_DELETED = 0
|
||||||
|
AND STCD IN
|
||||||
|
<foreach collection="stcdList" item="stcd" open="(" separator="," close=")">
|
||||||
|
#{stcd}
|
||||||
|
</foreach>
|
||||||
|
AND TM >= TO_DATE(#{startTime}, 'YYYY-MM-DD HH24:MI:SS')
|
||||||
|
AND TM < TO_DATE(#{endTime}, 'YYYY-MM-DD HH24:MI:SS')
|
||||||
|
AND ${fieldName} IS NOT NULL
|
||||||
|
</select>
|
||||||
|
|
||||||
|
</mapper>
|
||||||
@ -0,0 +1,26 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||||
|
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||||
|
<mapper namespace="com.yfd.platform.qgc_export.mapper.SdRiverdaySMapper">
|
||||||
|
|
||||||
|
<!--
|
||||||
|
动态字段查询:根据 fieldName 参数选择 V/Q/Z 列
|
||||||
|
利用 STCD + DT + IS_DELETED 复合索引
|
||||||
|
-->
|
||||||
|
<select id="selectRawData" resultType="java.util.HashMap">
|
||||||
|
SELECT
|
||||||
|
STCD,
|
||||||
|
DT,
|
||||||
|
${fieldName} AS VALUE
|
||||||
|
FROM SD_RIVERDAY_S
|
||||||
|
WHERE IS_DELETED = 0
|
||||||
|
AND STCD IN
|
||||||
|
<foreach collection="stcdList" item="stcd" open="(" separator="," close=")">
|
||||||
|
#{stcd}
|
||||||
|
</foreach>
|
||||||
|
AND DT >= TO_DATE(#{startTime}, 'YYYY-MM-DD HH24:MI:SS')
|
||||||
|
AND DT < TO_DATE(#{endTime}, 'YYYY-MM-DD HH24:MI:SS')
|
||||||
|
AND ${fieldName} IS NOT NULL
|
||||||
|
</select>
|
||||||
|
|
||||||
|
</mapper>
|
||||||
71
backend/src/main/resources/mapper/qgc_export/SdWqRMapper.xml
Normal file
71
backend/src/main/resources/mapper/qgc_export/SdWqRMapper.xml
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||||
|
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||||
|
<mapper namespace="com.yfd.platform.qgc_export.mapper.SdWqRMapper">
|
||||||
|
|
||||||
|
<!--
|
||||||
|
水质小时数据动态字段查询
|
||||||
|
利用 STCD + TM + IS_DELETED 复合索引
|
||||||
|
-->
|
||||||
|
<select id="selectRawData" resultType="java.util.HashMap">
|
||||||
|
SELECT
|
||||||
|
STCD,
|
||||||
|
TM,
|
||||||
|
${fieldName} AS VALUE,
|
||||||
|
SFDB
|
||||||
|
FROM SD_WQ_R
|
||||||
|
WHERE IS_DELETED = 0
|
||||||
|
AND STCD IN
|
||||||
|
<foreach collection="stcdList" item="stcd" open="(" separator="," close=")">
|
||||||
|
#{stcd}
|
||||||
|
</foreach>
|
||||||
|
AND TM >= TO_DATE(#{startTime}, 'YYYY-MM-DD HH24:MI:SS')
|
||||||
|
AND TM < TO_DATE(#{endTime}, 'YYYY-MM-DD HH24:MI:SS')
|
||||||
|
AND ${fieldName} IS NOT NULL
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<!-- 水质小时达标率统计:按 STCD 聚合 SFDB=1 达标数、总数 -->
|
||||||
|
<select id="selectComplianceData" resultType="java.util.HashMap">
|
||||||
|
SELECT
|
||||||
|
STCD,
|
||||||
|
SUM(CASE WHEN SFDB = 1 THEN 1 ELSE 0 END) AS COMPLIANT_CNT,
|
||||||
|
SUM(CASE WHEN SFDB IN (0, 1) THEN 1 ELSE 0 END) AS TOTAL_CNT
|
||||||
|
FROM SD_WQ_R
|
||||||
|
WHERE IS_DELETED = 0
|
||||||
|
AND STCD IN
|
||||||
|
<foreach collection="stcdList" item="stcd" open="(" separator="," close=")">
|
||||||
|
#{stcd}
|
||||||
|
</foreach>
|
||||||
|
AND TM >= TO_DATE(#{startTime}, 'YYYY-MM-DD HH24:MI:SS')
|
||||||
|
AND TM < TO_DATE(#{endTime}, 'YYYY-MM-DD HH24:MI:SS')
|
||||||
|
AND SFDB IS NOT NULL
|
||||||
|
GROUP BY STCD
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<!-- 查询各测站主要污染物(SFDB=0 时的 WQ_SFDBHN_YS) -->
|
||||||
|
<select id="selectPollutants" resultType="java.util.HashMap">
|
||||||
|
SELECT
|
||||||
|
STCD,
|
||||||
|
WQ_SFDBHN_YS AS POLLUTANT
|
||||||
|
FROM SD_WQ_R
|
||||||
|
WHERE IS_DELETED = 0
|
||||||
|
AND SFDB = 0
|
||||||
|
AND WQ_SFDBHN_YS IS NOT NULL
|
||||||
|
AND STCD IN
|
||||||
|
<foreach collection="stcdList" item="stcd" open="(" separator="," close=")">
|
||||||
|
#{stcd}
|
||||||
|
</foreach>
|
||||||
|
AND TM >= TO_DATE(#{startTime}, 'YYYY-MM-DD HH24:MI:SS')
|
||||||
|
AND TM < TO_DATE(#{endTime}, 'YYYY-MM-DD HH24:MI:SS')
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<!-- 查询 SD_WQ_R 表的要素中文名(通过 ST_TB_B + ST_TB_YS_B 关联) -->
|
||||||
|
<select id="selectColumnComments" resultType="java.util.HashMap">
|
||||||
|
SELECT YS.YS AS COLUMN_NAME, YS.YS_SHOW_NAME AS COMMENTS
|
||||||
|
FROM ST_TB_B TB
|
||||||
|
INNER JOIN ST_TB_YS_B YS ON YS.TB_ID = TB.ID AND NVL(YS.IS_DELETED, 0) = 0
|
||||||
|
WHERE NVL(TB.IS_DELETED, 0) = 0
|
||||||
|
AND TB.TB = 'SD_WQ_R'
|
||||||
|
</select>
|
||||||
|
|
||||||
|
</mapper>
|
||||||
@ -0,0 +1,44 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||||
|
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||||
|
<mapper namespace="com.yfd.platform.qgc_export.mapper.SdWqdaySMapper">
|
||||||
|
|
||||||
|
<!--
|
||||||
|
水质日数据动态字段查询
|
||||||
|
利用 STCD + DT + IS_DELETED 复合索引
|
||||||
|
-->
|
||||||
|
<select id="selectRawData" resultType="java.util.HashMap">
|
||||||
|
SELECT
|
||||||
|
STCD,
|
||||||
|
DT,
|
||||||
|
${fieldName} AS VALUE
|
||||||
|
FROM SD_WQDAY_S
|
||||||
|
WHERE IS_DELETED = 0
|
||||||
|
AND STCD IN
|
||||||
|
<foreach collection="stcdList" item="stcd" open="(" separator="," close=")">
|
||||||
|
#{stcd}
|
||||||
|
</foreach>
|
||||||
|
AND DT >= TO_DATE(#{startTime}, 'YYYY-MM-DD HH24:MI:SS')
|
||||||
|
AND DT < TO_DATE(#{endTime}, 'YYYY-MM-DD HH24:MI:SS')
|
||||||
|
AND ${fieldName} IS NOT NULL
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<!-- 水质日均达标率统计:按 STCD 聚合 SFDB=1 达标数、总数 -->
|
||||||
|
<select id="selectComplianceData" resultType="java.util.HashMap">
|
||||||
|
SELECT
|
||||||
|
STCD,
|
||||||
|
SUM(CASE WHEN SFDB = 1 THEN 1 ELSE 0 END) AS COMPLIANT_CNT,
|
||||||
|
SUM(CASE WHEN SFDB IN (0, 1) THEN 1 ELSE 0 END) AS TOTAL_CNT
|
||||||
|
FROM SD_WQDAY_S
|
||||||
|
WHERE IS_DELETED = 0
|
||||||
|
AND STCD IN
|
||||||
|
<foreach collection="stcdList" item="stcd" open="(" separator="," close=")">
|
||||||
|
#{stcd}
|
||||||
|
</foreach>
|
||||||
|
AND DT >= TO_DATE(#{startTime}, 'YYYY-MM-DD HH24:MI:SS')
|
||||||
|
AND DT < TO_DATE(#{endTime}, 'YYYY-MM-DD HH24:MI:SS')
|
||||||
|
AND SFDB IS NOT NULL
|
||||||
|
GROUP BY STCD
|
||||||
|
</select>
|
||||||
|
|
||||||
|
</mapper>
|
||||||
@ -0,0 +1,23 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||||
|
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||||
|
<mapper namespace="com.yfd.platform.qgc_export.mapper.SdWtrvRMapper">
|
||||||
|
|
||||||
|
<!-- 河道水温小时数据查询 -->
|
||||||
|
<select id="selectRawData" resultType="java.util.HashMap">
|
||||||
|
SELECT
|
||||||
|
STCD,
|
||||||
|
TM,
|
||||||
|
WT AS VALUE
|
||||||
|
FROM SD_WTRV_R
|
||||||
|
WHERE IS_DELETED = 0
|
||||||
|
AND STCD IN
|
||||||
|
<foreach collection="stcdList" item="stcd" open="(" separator="," close=")">
|
||||||
|
#{stcd}
|
||||||
|
</foreach>
|
||||||
|
AND TM >= TO_DATE(#{startTime}, 'YYYY-MM-DD HH24:MI:SS')
|
||||||
|
AND TM < TO_DATE(#{endTime}, 'YYYY-MM-DD HH24:MI:SS')
|
||||||
|
AND WT IS NOT NULL
|
||||||
|
</select>
|
||||||
|
|
||||||
|
</mapper>
|
||||||
@ -0,0 +1,23 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||||
|
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||||
|
<mapper namespace="com.yfd.platform.qgc_export.mapper.SdWtrvdaySMapper">
|
||||||
|
|
||||||
|
<!-- 河道水温日数据查询 -->
|
||||||
|
<select id="selectRawData" resultType="java.util.HashMap">
|
||||||
|
SELECT
|
||||||
|
STCD,
|
||||||
|
DT,
|
||||||
|
WT AS VALUE
|
||||||
|
FROM SD_WTRVDAY_S
|
||||||
|
WHERE IS_DELETED = 0
|
||||||
|
AND STCD IN
|
||||||
|
<foreach collection="stcdList" item="stcd" open="(" separator="," close=")">
|
||||||
|
#{stcd}
|
||||||
|
</foreach>
|
||||||
|
AND DT >= TO_DATE(#{startTime}, 'YYYY-MM-DD HH24:MI:SS')
|
||||||
|
AND DT < TO_DATE(#{endTime}, 'YYYY-MM-DD HH24:MI:SS')
|
||||||
|
AND WT IS NOT NULL
|
||||||
|
</select>
|
||||||
|
|
||||||
|
</mapper>
|
||||||
@ -0,0 +1,42 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||||
|
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||||
|
<mapper namespace="com.yfd.platform.qgc_export.mapper.SdWtvtdaySMapper">
|
||||||
|
|
||||||
|
<!-- 查询月内每日垂向水温数据 -->
|
||||||
|
<select id="selectDailyData" resultType="java.util.HashMap">
|
||||||
|
SELECT
|
||||||
|
STCD,
|
||||||
|
WTHG,
|
||||||
|
VWT,
|
||||||
|
EXTRACT(DAY FROM DT) AS DAY_NUM
|
||||||
|
FROM SD_WTVTDAY_S
|
||||||
|
WHERE IS_DELETED = 0
|
||||||
|
AND STCD IN
|
||||||
|
<foreach collection="stcdList" item="stcd" open="(" separator="," close=")">
|
||||||
|
#{stcd}
|
||||||
|
</foreach>
|
||||||
|
AND DT >= TO_DATE(#{startTime}, 'YYYY-MM-DD HH24:MI:SS')
|
||||||
|
AND DT < TO_DATE(#{endTime}, 'YYYY-MM-DD HH24:MI:SS')
|
||||||
|
AND VWT IS NOT NULL
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<!-- 查询月均垂向水温 -->
|
||||||
|
<select id="selectMonthlyAvg" resultType="java.util.HashMap">
|
||||||
|
SELECT
|
||||||
|
STCD,
|
||||||
|
WTHG,
|
||||||
|
AVG(VWT) AS VWT
|
||||||
|
FROM SD_WTVTDAY_S
|
||||||
|
WHERE IS_DELETED = 0
|
||||||
|
AND STCD IN
|
||||||
|
<foreach collection="stcdList" item="stcd" open="(" separator="," close=")">
|
||||||
|
#{stcd}
|
||||||
|
</foreach>
|
||||||
|
AND DT >= TO_DATE(#{startTime}, 'YYYY-MM-DD HH24:MI:SS')
|
||||||
|
AND DT < TO_DATE(#{endTime}, 'YYYY-MM-DD HH24:MI:SS')
|
||||||
|
AND VWT IS NOT NULL
|
||||||
|
GROUP BY STCD, WTHG
|
||||||
|
</select>
|
||||||
|
|
||||||
|
</mapper>
|
||||||
@ -0,0 +1,49 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||||
|
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||||
|
<mapper namespace="com.yfd.platform.qgc_export.mapper.YearStatMapper">
|
||||||
|
|
||||||
|
<!-- 生态流量月度达标统计:按 STCD 聚合三种 SFDB -->
|
||||||
|
<select id="selectQecMonthlyCompliance" resultType="java.util.HashMap">
|
||||||
|
SELECT
|
||||||
|
STCD,
|
||||||
|
SUM(CASE WHEN SFDB = 1 THEN 1 ELSE 0 END) AS QEC_COMPLIANT,
|
||||||
|
SUM(CASE WHEN SFDB IN (0, 1) THEN 1 ELSE 0 END) AS QEC_TOTAL,
|
||||||
|
SUM(CASE WHEN MWR_SFDB = 1 THEN 1 ELSE 0 END) AS MWR_COMPLIANT,
|
||||||
|
SUM(CASE WHEN MWR_SFDB IN (0, 1) THEN 1 ELSE 0 END) AS MWR_TOTAL,
|
||||||
|
SUM(CASE WHEN AVQ_SFDB = 1 THEN 1 ELSE 0 END) AS AVQ_COMPLIANT,
|
||||||
|
SUM(CASE WHEN AVQ_SFDB IN (0, 1) THEN 1 ELSE 0 END) AS AVQ_TOTAL
|
||||||
|
FROM SD_QECDRTP_S
|
||||||
|
WHERE IS_DELETED = 0
|
||||||
|
AND DRTP = 'MON'
|
||||||
|
AND STCD IN
|
||||||
|
<foreach collection="stcdList" item="stcd" open="(" separator="," close=")">
|
||||||
|
#{stcd}
|
||||||
|
</foreach>
|
||||||
|
AND YEAR = #{year}
|
||||||
|
GROUP BY STCD
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<!-- 生态流量月度达标统计:按 BASE_ID 聚合 -->
|
||||||
|
<select id="selectQecMonthlyComplianceByBase" resultType="java.util.HashMap">
|
||||||
|
SELECT
|
||||||
|
v.BASE_ID,
|
||||||
|
SUM(CASE WHEN d.SFDB = 1 THEN 1 ELSE 0 END) AS QEC_COMPLIANT,
|
||||||
|
SUM(CASE WHEN d.SFDB IN (0, 1) THEN 1 ELSE 0 END) AS QEC_TOTAL,
|
||||||
|
SUM(CASE WHEN d.MWR_SFDB = 1 THEN 1 ELSE 0 END) AS MWR_COMPLIANT,
|
||||||
|
SUM(CASE WHEN d.MWR_SFDB IN (0, 1) THEN 1 ELSE 0 END) AS MWR_TOTAL,
|
||||||
|
SUM(CASE WHEN d.AVQ_SFDB = 1 THEN 1 ELSE 0 END) AS AVQ_COMPLIANT,
|
||||||
|
SUM(CASE WHEN d.AVQ_SFDB IN (0, 1) THEN 1 ELSE 0 END) AS AVQ_TOTAL
|
||||||
|
FROM SD_QECDRTP_S d
|
||||||
|
INNER JOIN V_MS_STBPRP_T v ON v.STCD = d.STCD AND v.STTP = 'ENG'
|
||||||
|
WHERE d.IS_DELETED = 0
|
||||||
|
AND d.DRTP = 'MON'
|
||||||
|
AND v.BASE_ID IN
|
||||||
|
<foreach collection="baseIdList" item="bid" open="(" separator="," close=")">
|
||||||
|
#{bid}
|
||||||
|
</foreach>
|
||||||
|
AND d.YEAR = #{year}
|
||||||
|
GROUP BY v.BASE_ID
|
||||||
|
</select>
|
||||||
|
|
||||||
|
</mapper>
|
||||||
Loading…
Reference in New Issue
Block a user