数据同步故障记录单处置工单主表

main
王宇航 2026-11-03 13:25:10 +08:00
parent 3dad453694
commit f0d9135a06
25 changed files with 1253 additions and 335 deletions

View File

@ -21,6 +21,7 @@ import org.springframework.http.ResponseEntity;
import jakarta.servlet.http.HttpServletRequest;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Arrays;
import java.util.Collections;
@ -212,11 +213,16 @@ public class YsdpApiController extends BaseApiController {
// ===================== 日期处理(自动今天 / 前一天,不写死)=====================
LocalDate now = LocalDate.now();
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
String today = now.format(formatter); // 今天
//today = "2026-03-30";
String compareDay = now.minusDays(1).format(formatter); // 对比日:前一天
LocalDateTime percentNow = LocalDateTime.now();
DateTimeFormatter percentFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
String comparePercentDay = percentNow.minusDays(1).format(percentFormatter);
// 配置覆盖对比日期
YsOperateManager manager = ysOperateManagerService.getOne(
new QueryWrapper<YsOperateManager>()
@ -225,6 +231,7 @@ public class YsdpApiController extends BaseApiController {
);
if (manager != null) {
compareDay = manager.getCompareDate().substring(0,10);
comparePercentDay = compareDay+ comparePercentDay.substring(10);
}
//compareDay = "2026-03-01";
// ===================== 查询数据 =====================
@ -232,10 +239,14 @@ public class YsdpApiController extends BaseApiController {
List<YsYunyingMaxDTO> compareList = ysYunyingService.getYunyingList(compareDay);
List<YsYunyingMax> maxList = ysYunyingMaxService.getYunyinglist();
// 用于百分比计算时刻 开始时间、结束时间
List<YsYunyingMaxDTO> comparePercentList = ysYunyingService.getYunyingPercentList(compareDay,comparePercentDay);
// 空值保护
todayList = Optional.ofNullable(todayList).orElse(Collections.emptyList());
compareList = Optional.ofNullable(compareList).orElse(Collections.emptyList());
maxList = Optional.ofNullable(maxList).orElse(Collections.emptyList());
comparePercentList = Optional.ofNullable(comparePercentList).orElse(Collections.emptyList());
// ===================== 按线路聚合(03、04、07、15)=====================
// 目标线路
@ -257,6 +268,12 @@ public class YsdpApiController extends BaseApiController {
.filter(dto -> lineId.equals(dto.getLineId()))
.findFirst()
.orElse(new YsYunyingMax()); // 不存在则给空对象,
YsYunyingMaxDTO comparePercent = comparePercentList.stream()
.filter(dto -> lineId.equals(dto.getLineId()))
.findFirst()
.orElse(new YsYunyingMaxDTO()); // 不存在则给空对象,
// 2. 转为 JSONObject,保留所有字段
JSONObject result = new JSONObject();
// 5. 统一放入结果
@ -266,6 +283,7 @@ public class YsdpApiController extends BaseApiController {
result.put("today", today1);
result.put("compareDay", compare1);
result.put("maxDay", max1);
result.put("comparePercent", comparePercent);
resultArray.add(result);
}
} catch (Exception ex) {

View File

@ -112,4 +112,7 @@ public interface YsYunyingMapper extends BaseMapper<YsYunying> {
public String getStationCompareValue(String compareDay, String stationId);
public YsInterfaceDTO getInterface(String type);
// 获取时间段客流信息
public List<YsYunyingMaxDTO> getYunyingPercentList(String startTime,String endTime);
}

View File

@ -131,6 +131,50 @@
ORDER BY line_id;
</select>
<select id="getYunyingPercentList" resultType="net.juntech.modules.ysdp.service.dto.YsYunyingMaxDTO">
SELECT
line_id,
-- 累计时段:从早到晚依次累加
SUM(CASE WHEN time_period &lt;= '05:00-06:00' THEN total_pull ELSE 0 END) AS time1, -- 05-06
SUM(CASE WHEN time_period &lt;= '06:00-08:00' THEN total_pull ELSE 0 END) AS time2, -- 05-08
SUM(CASE WHEN time_period &lt;= '08:00-10:00' THEN total_pull ELSE 0 END) AS time3, -- 05-10
SUM(CASE WHEN time_period &lt;= '10:00-12:00' THEN total_pull ELSE 0 END) AS time4, -- 05-12
SUM(CASE WHEN time_period &lt;= '12:00-14:00' THEN total_pull ELSE 0 END) AS time5, -- 05-14
SUM(CASE WHEN time_period &lt;= '14:00-16:00' THEN total_pull ELSE 0 END) AS time6, -- 05-16
SUM(CASE WHEN time_period &lt;= '16:00-18:00' THEN total_pull ELSE 0 END) AS time7, -- 05-18
SUM(CASE WHEN time_period &lt;= '18:00-20:00' THEN total_pull ELSE 0 END) AS time8, -- 05-20
SUM(CASE WHEN time_period &lt;= '20:00-22:00' THEN total_pull ELSE 0 END) AS time9, -- 05-22
SUM(CASE WHEN time_period &lt;= '22:00-24:00' THEN total_pull ELSE 0 END) AS time10, -- 05-24
SUM(total_pull) AS totalSum -- 全天总和
FROM (
SELECT
line_id,
-- 时段定义
CASE
WHEN HOUR(end_time) = 5 THEN '05:00-06:00'
WHEN HOUR(end_time) BETWEEN 6 AND 7 THEN '06:00-08:00'
WHEN HOUR(end_time) BETWEEN 8 AND 9 THEN '08:00-10:00'
WHEN HOUR(end_time) BETWEEN 10 AND 11 THEN '10:00-12:00'
WHEN HOUR(end_time) BETWEEN 12 AND 13 THEN '12:00-14:00'
WHEN HOUR(end_time) BETWEEN 14 AND 15 THEN '14:00-16:00'
WHEN HOUR(end_time) BETWEEN 16 AND 17 THEN '16:00-18:00'
WHEN HOUR(end_time) BETWEEN 18 AND 19 THEN '18:00-20:00'
WHEN HOUR(end_time) BETWEEN 20 AND 21 THEN '20:00-22:00'
WHEN HOUR(end_time) BETWEEN 22 AND 23 THEN '22:00-24:00'
END AS time_period,
ROUND((SUM(pull_num) + SUM(departure_num)) / 100) AS total_pull
FROM ys_yunying
WHERE
end_time&gt;= #{startTime}
AND end_time &lt; #{endTime}
AND HOUR(end_time) &gt;= 5
AND line_id IN ('03','04','07','15')
GROUP BY line_id, time_period
) t
GROUP BY line_id
ORDER BY line_id;
</select>
<!-- <select id="getStationMaxList" resultType="net.juntech.modules.ysdp.service.dto.YsYunyingDTO">-->
<!-- SELECT-->
<!--&#45;&#45; ROW_NUMBER() OVER(ORDER BY ROUND((SUM(a.pull_num) + SUM(a.departure_num)) / 100) DESC) AS sortNo,-->

View File

@ -143,4 +143,8 @@ public class YsYunyingService extends ServiceImpl<YsYunyingMapper, YsYunying> {
return ysYunyingMapper.getInterface(type);
}
// 获取时间段客流信息
public List<YsYunyingMaxDTO> getYunyingPercentList(String startTime,String endTime) {
return ysYunyingMapper.getYunyingPercentList(startTime,endTime);
}
}

View File

@ -9,6 +9,8 @@ import lombok.extern.slf4j.Slf4j;
import net.juntech.modules.ysdp.sync.service.Erp5minsTrnKmSyncService;
import net.juntech.modules.ysdp.sync.service.ErpClerEvtSyncService;
import net.juntech.modules.ysdp.sync.service.ErpOperIndxSyncService;
import net.juntech.modules.ysdp.sync.service.ErpRecordSheetSyncService;
import net.juntech.modules.ysdp.sync.service.ErpWorkOrderSyncService;
import net.juntech.modules.ysdp.sync.task.DataCenterSyncTaskRegistrar;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
@ -41,6 +43,12 @@ public class DataSyncController {
@Autowired
private ErpClerEvtSyncService clerEvtSyncService;
@Autowired
private ErpRecordSheetSyncService recordSheetSyncService;
@Autowired
private ErpWorkOrderSyncService workOrderSyncService;
/**
* 同步所有表(指定日期)
*/
@ -54,6 +62,8 @@ public class DataSyncController {
operIndxSyncService.syncByDate(date);
trnKmSyncService.syncByDate(date);
clerEvtSyncService.syncByDate(date);
recordSheetSyncService.syncByDate(date);
workOrderSyncService.syncByDate(date);
response.put("success", true);
response.put("message", "同步完成");
} catch (Exception e) {
@ -114,6 +124,46 @@ public class DataSyncController {
return ResponseEntity.ok(response);
}
/**
* 同步故障记录单主表
*/
@Operation(summary = "同步故障记录单主表")
@PreAuthorize("hasAnyAuthority('ysdp:dataSync:manual')")
@PostMapping("/syncRecordSheet")
public ResponseEntity<Map<String, Object>> syncRecordSheet(@RequestParam String date) {
Map<String, Object> response = new HashMap<>();
try {
int count = recordSheetSyncService.syncByDate(date);
response.put("success", true);
response.put("count", count);
} catch (Exception e) {
log.error("同步失败", e);
response.put("success", false);
response.put("message", e.getMessage());
}
return ResponseEntity.ok(response);
}
/**
* 同步故障记录单-处置工单主表
*/
@Operation(summary = "同步故障记录单-处置工单主表")
@PreAuthorize("hasAnyAuthority('ysdp:dataSync:manual')")
@PostMapping("/syncWorkOrder")
public ResponseEntity<Map<String, Object>> syncWorkOrder(@RequestParam String date) {
Map<String, Object> response = new HashMap<>();
try {
int count = workOrderSyncService.syncByDate(date);
response.put("success", true);
response.put("count", count);
} catch (Exception e) {
log.error("同步失败", e);
response.put("success", false);
response.put("message", e.getMessage());
}
return ResponseEntity.ok(response);
}
/**
* 获取同步任务当前配置(读取 sys_schedule)
*/
@ -126,7 +176,7 @@ public class DataSyncController {
response.put("jobName", DataCenterSyncTaskRegistrar.JOB_NAME);
response.put("jobGroup", DataCenterSyncTaskRegistrar.JOB_GROUP);
response.put("defaultCron", DataCenterSyncTaskRegistrar.DEFAULT_CRON);
response.put("tables", new String[]{"erp_oper_indx", "erp_5mins_trn_km", "erp_cler_evt"});
response.put("tables", new String[]{"erp_oper_indx", "erp_5mins_trn_km", "erp_cler_evt", "erp_record_sheet", "erp_work_order"});
response.put("message", "调度由 jeeplus-quartz 管理,请在 /quartz/scheduleJob 页面查看/修改");
return ResponseEntity.ok(response);
}

View File

@ -0,0 +1,211 @@
package net.juntech.modules.ysdp.sync.domain;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
/**
* 故障记录单主表
* apiName: erp_record_sheet
*/
@Data
@TableName("erp_record_sheet")
public class ErpRecordSheet implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(type = IdType.AUTO)
private Long id; // id
@TableField("source_id")
private String sourceId; // API原始ID
@TableField("cocc_person")
private String coccPerson; // COCC处置人
@TableField("is_self_repair")
private String isSelfRepair; // 是否自检自修(0否/1是)
@TableField("merge_time")
private Date mergeTime; // 合并时间
@TableField("main_fault_id")
private String mainFaultId; // 主故障单ID
@TableField("location_export")
private String locationExport; // 位置导出(线路车站)
@TableField("sys_org_code")
private String sysOrgCode; // 系统组织编码
@TableField("repair_situation")
private String repairSituation; // 修复情况
@TableField("train_station_name")
private String trainStationName; // 车站名称
@TableField("fault_target_name")
private String faultTargetName; // 故障对象名称
@TableField("fault_status")
private String faultStatus; // 故障状态
@TableField("merge_reason")
private String mergeReason; // 合并原因
@TableField("second_confirm_person_name")
private String secondConfirmPersonName; // 二次确认人姓名
@TableField("fault_location_desc")
private String faultLocationDesc; // 故障位置描述
@TableField("create_by_name")
private String createByName; // 创建人姓名
@TableField("building")
private String building; // 楼宇
@TableField("real_report_person")
private String realReportPerson; // 实际报修人
@TableField("path_cn")
private String pathCn; // 设备路径(中文)
@TableField("fault_location")
private String faultLocation; // 故障位置
@TableField("cocc_signing_status")
private String coccSigningStatus; // COCC签收状态
@TableField("delay_status")
private String delayStatus; // 延迟状态
@TableField("sys_org_name")
private String sysOrgName; // 系统组织名称
@TableField("occ_person_name")
private String occPersonName; // OCC处理人姓名
@TableField("fault_facility")
private String faultFacility; // 故障设备
@TableField("fault_target")
private String faultTarget; // 故障对象
@TableField("area_end")
private String areaEnd; // 结束区域
@TableField("merge_person_name")
private String mergePersonName; // 合并人姓名
@TableField("merge_org")
private String mergeOrg; // 合并组织
@TableField("unrepair_annex")
private String unrepairAnnex; // 未修复附件
@TableField("create_time")
private Date createTime; // 创建时间
@TableField("location_detail")
private String locationDetail; // 位置明细
@TableField("train_number")
private String trainNumber; // 列车号
@TableField("other_no_fixed_key")
private String otherNoFixedKey; // 其它未固定键
@TableField("fault_type")
private String faultType; // 故障类型
@TableField("fault_phenomenon_name")
private String faultPhenomenonName; // 故障现象名称
@TableField("second_confirm_person")
private String secondConfirmPerson; // 二次确认人
@TableField("occ_person")
private String occPerson; // OCC处理人
@TableField("phone")
private String phone; // 联系电话
@TableField("report_time")
private Date reportTime; // 报修时间
@TableField("large_category")
private String largeCategory; // 大类
@TableField("fault_number")
private String faultNumber; // 故障编号
@TableField("facility_number")
private String facilityNumber; // 设备编号
@TableField("area_start")
private String areaStart; // 开始区域
@TableField("middle_category")
private String middleCategory; // 中类
@TableField("parking_lot")
private String parkingLot; // 停车场/段
@TableField("examine_person")
private String examinePerson; // 审核人
@TableField("second_confirm_time")
private Date secondConfirmTime; // 二次确认时间
@TableField("fault_phenomenon_detail")
private String faultPhenomenonDetail; // 故障现象明细
@TableField("area_start_name")
private String areaStartName; // 开始区域名称
@TableField("fault_annex")
private String faultAnnex; // 故障附件
@TableField("out_substation")
private String outSubstation; // 外变电站
@TableField("cocc_person_name")
private String coccPersonName; // COCC处置人姓名
@TableField("fault_phenomenon")
private String faultPhenomenon; // 故障现象
@TableField("examine_person_name")
private String examinePersonName; // 审核人姓名
@TableField("define_check")
private String defineCheck; // 确认核查
@TableField("repair_order_number")
private String repairOrderNumber; // 维修工单号
@TableField("fault_detail")
private String faultDetail; // 故障详情
@TableField("create_by")
private String createBy; // 创建人
@TableField("is_new_line_fault")
private Integer isNewLineFault; // 是否新线故障
@TableField("fault_facility_name")
private String faultFacilityName; // 故障设备名称
@TableField("update_time")
private Date updateTime; // 更新时间
@TableField("connect_train")
private String connectTrain; // 相关列车
@TableField("is_deleted")
private Integer isDeleted; // 是否删除
@TableField("fault_time")
private Date faultTime; // 故障时间
@TableField("real_report_org")
private String realReportOrg; // 实际报修组织
@TableField("line_type")
private String lineType; // 线路类型
@TableField("train_station")
private String trainStation; // 列车/车站
@TableField("update_by")
private String updateBy; // 更新人
@TableField("track")
private String track; // 线路(轨)
@TableField("report_org_name")
private String reportOrgName; // 报修组织名称
@TableField("first_confirm_person")
private String firstConfirmPerson; // 首次确认人
@TableField("occ_signing_status")
private String occSigningStatus; // OCC签收状态
@TableField("delay_time")
private String delayTime; // 延迟时间
@TableField("special_station_line")
private String specialStationLine; // 特殊车站线路
@TableField("track_name")
private String trackName; // 线路名称
@TableField("unrepair_desc")
private String unrepairDesc; // 未修复说明
@TableField("update_by_name")
private String updateByName; // 更新人姓名
@TableField("cocc_time")
private Date coccTime; // COCC时间
@TableField("first_confirm_person_name")
private String firstConfirmPersonName; // 首次确认人姓名
@TableField("vehicle_type")
private String vehicleType; // 车辆类型
@TableField("first_confirm_time")
private Date firstConfirmTime; // 首次确认时间
@TableField("area_end_name")
private String areaEndName; // 结束区域名称
@TableField("location_type")
private String locationType; // 位置类型
@TableField("occ_time")
private Date occTime; // OCC时间
@TableField("dept_path")
private String deptPath; // 部门路径
@TableField("is_connect")
private String isConnect; // 是否接续
@TableField("merge_status")
private String mergeStatus; // 合并状态
@TableField("process_instance_id")
private String processInstanceId; // 流程实例ID
@TableField("car_number")
private String carNumber; // 车号
@TableField("disposal_result")
private String disposalResult; // 处置结果
@TableField("merge_person")
private String mergePerson; // 合并人
@TableField("new_line_danger_level")
private String newLineDangerLevel; // 新线危险等级
@TableField("report_org")
private String reportOrg; // 报修组织
@TableField("control_center")
private String controlCenter; // 控制中心
}

View File

@ -0,0 +1,173 @@
package net.juntech.modules.ysdp.sync.domain;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
/**
* 故障记录单-处置工单主表
* apiName: erp_work_order
*/
@Data
@TableName("erp_work_order")
public class ErpWorkOrder implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(type = IdType.AUTO)
private Long id; // id
@TableField("source_id")
private String sourceId; // API原始ID
@TableField("is_responsible")
private Integer isResponsible; // 是否责任
@TableField("is_second_distribute")
private String isSecondDistribute; // 是否二次分派
@TableField("second_distribute_dept_name")
private String secondDistributeDeptName; // 二次分派部门名称
@TableField("sys_org_code")
private String sysOrgCode; // 系统组织编码
@TableField("repair_situation")
private String repairSituation; // 修复情况
@TableField("distribute_person_name")
private String distributePersonName; // 分派人姓名
@TableField("fault_deal_desc")
private String faultDealDesc; // 故障处置描述
@TableField("fault_target_name")
private String faultTargetName; // 故障对象名称
@TableField("create_by_name")
private String createByName; // 创建人姓名
@TableField("work_order_number")
private String workOrderNumber; // 工单编号
@TableField("solution")
private String solution; // 解决方案
@TableField("is_own_repair")
private String isOwnRepair; // 是否自修
@TableField("path_cn")
private String pathCn; // 设备路径(中文)
@TableField("delay_status")
private String delayStatus; // 延迟状态
@TableField("sys_org_name")
private String sysOrgName; // 系统组织名称
@TableField("fault_facility")
private String faultFacility; // 故障设备
@TableField("reason_cause")
private String reasonCause; // 原因说明
@TableField("fault_target")
private String faultTarget; // 故障对象
@TableField("repair_file")
private String repairFile; // 维修文件
@TableField("repair_leader_name")
private String repairLeaderName; // 维修队长姓名
@TableField("is_out_repair")
private Integer isOutRepair; // 是否外委维修
@TableField("unrepair_annex")
private String unrepairAnnex; // 未修复附件
@TableField("create_time")
private Date createTime; // 创建时间
@TableField("second_distribute_dept")
private String secondDistributeDept; // 二次分派部门
@TableField("repair_org")
private String repairOrg; // 维修组织
@TableField("fault_type")
private String faultType; // 故障类型
@TableField("close_time")
private Date closeTime; // 关闭时间
@TableField("fault_phenomenon_name")
private String faultPhenomenonName; // 故障现象名称
@TableField("incident_response_level")
private String incidentResponseLevel; // 事件响应等级
@TableField("arrive_time")
private Date arriveTime; // 到达时间
@TableField("part_count")
private String partCount; // 配件数量
@TableField("repair_team")
private String repairTeam; // 维修班组
@TableField("large_category")
private String largeCategory; // 大类
@TableField("repair_complete_time")
private Date repairCompleteTime; // 维修完成时间
@TableField("fault_number")
private String faultNumber; // 故障编号
@TableField("reason_cause_code")
private String reasonCauseCode; // 原因编码
@TableField("team_repair_time")
private Date teamRepairTime; // 班组维修时间
@TableField("table_feedback_timeout")
private String tableFeedbackTimeout; // 反馈超时(表)
@TableField("repair_person")
private String repairPerson; // 维修人
@TableField("middle_category")
private String middleCategory; // 中类
@TableField("work_order_status")
private String workOrderStatus; // 工单状态
@TableField("repair_team_id")
private String repairTeamId; // 维修班组ID
@TableField("main_child_order")
private String mainChildOrder; // 主/子工单
@TableField("repair_person_name")
private String repairPersonName; // 维修人姓名
@TableField("other_fault_attribution")
private String otherFaultAttribution; // 其它故障归因
@TableField("fault_phenomenon")
private String faultPhenomenon; // 故障现象
@TableField("distribute_person")
private String distributePerson; // 分派人
@TableField("create_by")
private String createBy; // 创建人
@TableField("fault_facility_name")
private String faultFacilityName; // 故障设备名称
@TableField("update_time")
private Date updateTime; // 更新时间
@TableField("is_deleted")
private Integer isDeleted; // 是否删除
@TableField("is_diseased")
private Integer isDiseased; // 是否病害
@TableField("repair_leader")
private String repairLeader; // 维修队长
@TableField("update_by")
private String updateBy; // 更新人
@TableField("operational_impact")
private String operationalImpact; // 运营影响
@TableField("delay_time")
private Date delayTime; // 延迟时间
@TableField("feedback_timeout")
private Integer feedbackTimeout; // 反馈超时
@TableField("repair_org_name")
private String repairOrgName; // 维修组织名称
@TableField("degraded_state")
private String degradedState; // 降级状态
@TableField("child_deal_minute")
private Integer childDealMinute; // 子单处置时长(分钟)
@TableField("confirm_person")
private String confirmPerson; // 确认人
@TableField("unrepair_desc")
private String unrepairDesc; // 未修复说明
@TableField("org_repair_time")
private Date orgRepairTime; // 组织维修时间
@TableField("update_by_name")
private String updateByName; // 更新人姓名
@TableField("fault_record_sheet_id")
private String faultRecordSheetId; // 故障记录单ID
@TableField("outsourced_units")
private String outsourcedUnits; // 外委单位
@TableField("confirm_person_name")
private String confirmPersonName; // 确认人姓名
@TableField("confirm_time")
private Date confirmTime; // 确认时间
@TableField("deal_minute")
private Integer dealMinute; // 处置时长(分钟)
@TableField("operator_name")
private String operatorName; // 操作人员姓名
@TableField("dept_path")
private String deptPath; // 部门路径
@TableField("build_number")
private String buildNumber; // 楼宇编号
@TableField("fault_attribution")
private String faultAttribution; // 故障归因
@TableField("part_name")
private String partName; // 配件名称
}

View File

@ -0,0 +1,12 @@
package net.juntech.modules.ysdp.sync.mapper;
import com.baomidou.mybatisplus.annotation.InterceptorIgnore;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import net.juntech.modules.ysdp.sync.domain.ErpRecordSheet;
/**
* 故障记录单主表 Mapper
*/
@InterceptorIgnore(tenantLine = "true")
public interface ErpRecordSheetMapper extends BaseMapper<ErpRecordSheet> {
}

View File

@ -0,0 +1,12 @@
package net.juntech.modules.ysdp.sync.mapper;
import com.baomidou.mybatisplus.annotation.InterceptorIgnore;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import net.juntech.modules.ysdp.sync.domain.ErpWorkOrder;
/**
* 故障记录单-处置工单主表 Mapper
*/
@InterceptorIgnore(tenantLine = "true")
public interface ErpWorkOrderMapper extends BaseMapper<ErpWorkOrder> {
}

View File

@ -155,6 +155,126 @@ public class DataCenterSyncBase {
return resultArray;
}
/** 服务端过滤后 totalSize 的上限;超过则判定过滤未生效,回退本地过滤(两张故障表全表为 40 万+) */
private static final int API_FILTER_MAX_TOTAL = 20000;
/** 已通过交叉校验、确认服务端日期过滤生效的接口 */
private static final java.util.Set<String> API_FILTER_TRUSTED =
java.util.Collections.newSetFromMap(new java.util.concurrent.ConcurrentHashMap<>());
/**
* 分页获取指定日期的数据(优先走 API 端过滤)
*
* 数据中心支持通过 apiParam 传日期条件,例如:
* {"create_time":{"fieldLabel":"create_time","fieldType":"character varying","isOr":"0","type":"4","value":"20261029"}}
* 对 40 万行的表,服务端过滤可避免每天全表翻页;若服务端未生效或调用异常,自动回退到本地过滤。
*
* @param apiName 接口名
* @param dateField 日期字段
* @param dateValue 日期值 yyyy-MM-dd
*/
protected JSONArray fetchAllDataByApiParam(String apiName, String dateField, String dateValue) {
if (dateField == null || dateField.isEmpty() || dateValue == null || dateValue.isEmpty()) {
return fetchAllData(apiName, dateField, dateValue);
}
try {
JSONObject condition = new JSONObject();
condition.put("fieldLabel", dateField);
condition.put("fieldType", "character varying");
condition.put("isOr", "0");
condition.put("type", "4");
// 服务端日期条件使用 yyyyMMdd
condition.put("value", dateValue.replace("-", ""));
JSONObject apiParam = new JSONObject();
apiParam.put(dateField, condition);
JSONObject firstPage = callApi(apiName, apiParam, 1, config.getPageSize());
int totalSize = firstPage.optInt("totalSize", 0);
if (totalSize > API_FILTER_MAX_TOTAL) {
log.warn("接口 {} 服务端日期过滤未生效(totalSize={},接近全表),回退为本地过滤", apiName, totalSize);
return fetchAllData(apiName, dateField, dateValue);
}
if (totalSize <= 0 && !API_FILTER_TRUSTED.contains(apiName)) {
// 首次遇到 0 条时无法区分"当天确实没有数据"和"接口忽略过滤条件",
// 抽样校验前 API_FILTER_PROBE_PAGES 页未过滤数据;抽样未命中即认为服务端过滤可信
if (probeHasDate(apiName, dateField, dateValue)) {
log.warn("接口 {} 服务端日期过滤返回 0 条但未过滤抽样中命中该日期,判定过滤不可用,改为本地过滤", apiName);
return fetchAllData(apiName, dateField, dateValue);
}
API_FILTER_TRUSTED.add(apiName);
log.warn("接口 {} 服务端日期过滤校验通过(抽样未命中该日期),后续按服务端过滤结果采信", apiName);
return new JSONArray();
}
JSONArray resultArray = new JSONArray();
appendDateMatched(resultArray, firstPage.optJSONArray("data"), dateField, dateValue);
int totalPages = totalSize > 0
? (int) Math.ceil((double) totalSize / config.getPageSize())
: 1;
for (int page = 2; page <= totalPages; page++) {
JSONObject response = callApi(apiName, apiParam, page, config.getPageSize());
appendDateMatched(resultArray, response.optJSONArray("data"), dateField, dateValue);
}
log.warn("接口 {} 服务端过滤 [{}={}] 命中 {} 条(totalSize={})",
apiName, dateField, dateValue, resultArray.size(), totalSize);
return resultArray;
} catch (Exception e) {
log.warn("接口 {} 服务端日期过滤调用失败,回退为本地过滤:{}", apiName, e.getMessage());
return fetchAllData(apiName, dateField, dateValue);
}
}
/** 服务端返回 0 条时,抽样校验的页数(避免为确认过滤是否生效而翻完整个 40 万行) */
private static final int API_FILTER_PROBE_PAGES = 5;
/**
* 抽样检查未过滤数据的前几页是否含指定日期,用于判断服务端过滤条件是否真正生效
*/
private boolean probeHasDate(String apiName, String dateField, String dateValue) {
try {
for (int page = 1; page <= API_FILTER_PROBE_PAGES; page++) {
JSONObject response = callApi(apiName, new JSONObject(), page, config.getPageSize());
JSONArray data = response.optJSONArray("data");
if (data == null || data.isEmpty()) {
return false;
}
for (int i = 0; i < data.size(); i++) {
String itemDate = data.getJSONObject(i).optString(dateField);
if (itemDate != null && itemDate.startsWith(dateValue)) {
return true;
}
}
if (data.size() < config.getPageSize()) {
return false;
}
}
} catch (Exception e) {
// 抽样失败不影响主流程,按可信处理,避免退化为全表扫描
log.warn("接口 {} 过滤抽样校验失败:{}", apiName, e.getMessage());
}
return false;
}
/**
* 服务端已按日期过滤,这里再做一次本地校验,防止接口忽略参数导致脏数据入库
*/
private void appendDateMatched(JSONArray target, JSONArray data, String dateField, String dateValue) {
if (data == null || data.isEmpty()) {
return;
}
for (int i = 0; i < data.size(); i++) {
JSONObject json = data.getJSONObject(i);
String itemDate = json.optString(dateField);
if (!json.has(dateField) || (itemDate != null && itemDate.startsWith(dateValue))) {
target.add(json);
}
}
}
// 辅助方法
protected Integer parseInteger(Object value) {
if (value == null || "".equals(value)) return null;
@ -188,10 +308,20 @@ public class DataCenterSyncBase {
protected Date parseDate(String dateStr, String format) {
if (dateStr == null || dateStr.isEmpty()) return null;
// 数据中心部分时间字段会用 0001-01-01 00:00:00 表示"无值",MySQL datetime 最小为 1000-01-01,直接置空
if (dateStr.startsWith("0001-01-01") || dateStr.startsWith("0000-00-00")) return null;
try {
SimpleDateFormat sdf = new SimpleDateFormat(format);
return sdf.parse(dateStr);
} catch (Exception e) {
// 兼容只有日期的情况,如 delay_time = "2026-10-13"
if (dateStr.length() == 10) {
try {
return new SimpleDateFormat("yyyy-MM-dd").parse(dateStr);
} catch (Exception ignored) {
return null;
}
}
return null;
}
}

View File

@ -0,0 +1,136 @@
package net.juntech.modules.ysdp.sync.service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import net.juntech.modules.ysdp.sync.domain.ErpRecordSheet;
import net.juntech.modules.ysdp.sync.mapper.ErpRecordSheetMapper;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
/**
* 故障记录单主表数据同步服务
*/
@Slf4j
@Service
@Transactional
public class ErpRecordSheetSyncService extends ServiceImpl<ErpRecordSheetMapper, ErpRecordSheet> {
@Autowired
private DataCenterSyncBase syncBase;
public int syncByDate(String date) {
log.info("同步 erp_record_sheet,日期:{}", date);
JSONArray dataArray = syncBase.fetchAllDataByApiParam("erp_record_sheet", "create_time", date);
int count = 0;
for (int i = 0; i < dataArray.size(); i++) {
JSONObject json = dataArray.getJSONObject(i);
if (syncBase.isEmptyData(json)) continue;
ErpRecordSheet entity = new ErpRecordSheet();
entity.setSourceId(json.optString("id"));
entity.setCoccPerson(json.optString("cocc_person"));
entity.setIsSelfRepair(json.optString("is_self_repair"));
entity.setMergeTime(syncBase.parseDate(json.optString("merge_time"), "yyyy-MM-dd HH:mm:ss"));
entity.setMainFaultId(json.optString("main_fault_id"));
entity.setLocationExport(json.optString("location_export"));
entity.setSysOrgCode(json.optString("sys_org_code"));
entity.setRepairSituation(json.optString("repair_situation"));
entity.setTrainStationName(json.optString("train_station_name"));
entity.setFaultTargetName(json.optString("fault_target_name"));
entity.setFaultStatus(json.optString("fault_status"));
entity.setMergeReason(json.optString("merge_reason"));
entity.setSecondConfirmPersonName(json.optString("second_confirm_person_name"));
entity.setFaultLocationDesc(json.optString("fault_location_desc"));
entity.setCreateByName(json.optString("create_by_name"));
entity.setBuilding(json.optString("building"));
entity.setRealReportPerson(json.optString("real_report_person"));
entity.setPathCn(json.optString("path_cn"));
entity.setFaultLocation(json.optString("fault_location"));
entity.setCoccSigningStatus(json.optString("cocc_signing_status"));
entity.setDelayStatus(json.optString("delay_status"));
entity.setSysOrgName(json.optString("sys_org_name"));
entity.setOccPersonName(json.optString("occ_person_name"));
entity.setFaultFacility(json.optString("fault_facility"));
entity.setFaultTarget(json.optString("fault_target"));
entity.setAreaEnd(json.optString("area_end"));
entity.setMergePersonName(json.optString("merge_person_name"));
entity.setMergeOrg(json.optString("merge_org"));
entity.setUnrepairAnnex(json.optString("unrepair_annex"));
entity.setCreateTime(syncBase.parseDate(json.optString("create_time"), "yyyy-MM-dd HH:mm:ss"));
entity.setLocationDetail(json.optString("location_detail"));
entity.setTrainNumber(json.optString("train_number"));
entity.setOtherNoFixedKey(json.optString("other_no_fixed_key"));
entity.setFaultType(json.optString("fault_type"));
entity.setFaultPhenomenonName(json.optString("fault_phenomenon_name"));
entity.setSecondConfirmPerson(json.optString("second_confirm_person"));
entity.setOccPerson(json.optString("occ_person"));
entity.setPhone(json.optString("phone"));
entity.setReportTime(syncBase.parseDate(json.optString("report_time"), "yyyy-MM-dd HH:mm:ss"));
entity.setLargeCategory(json.optString("large_category"));
entity.setFaultNumber(json.optString("fault_number"));
entity.setFacilityNumber(json.optString("facility_number"));
entity.setAreaStart(json.optString("area_start"));
entity.setMiddleCategory(json.optString("middle_category"));
entity.setParkingLot(json.optString("parking_lot"));
entity.setExaminePerson(json.optString("examine_person"));
entity.setSecondConfirmTime(syncBase.parseDate(json.optString("second_confirm_time"), "yyyy-MM-dd HH:mm:ss"));
entity.setFaultPhenomenonDetail(json.optString("fault_phenomenon_detail"));
entity.setAreaStartName(json.optString("area_start_name"));
entity.setFaultAnnex(json.optString("fault_annex"));
entity.setOutSubstation(json.optString("out_substation"));
entity.setCoccPersonName(json.optString("cocc_person_name"));
entity.setFaultPhenomenon(json.optString("fault_phenomenon"));
entity.setExaminePersonName(json.optString("examine_person_name"));
entity.setDefineCheck(json.optString("define_check"));
entity.setRepairOrderNumber(json.optString("repair_order_number"));
entity.setFaultDetail(json.optString("fault_detail"));
entity.setCreateBy(json.optString("create_by"));
entity.setIsNewLineFault(syncBase.parseInteger(json.opt("is_new_line_fault")));
entity.setFaultFacilityName(json.optString("fault_facility_name"));
entity.setUpdateTime(syncBase.parseDate(json.optString("update_time"), "yyyy-MM-dd HH:mm:ss"));
entity.setConnectTrain(json.optString("connect_train"));
entity.setIsDeleted(syncBase.parseInteger(json.opt("is_deleted")));
entity.setFaultTime(syncBase.parseDate(json.optString("fault_time"), "yyyy-MM-dd HH:mm:ss"));
entity.setRealReportOrg(json.optString("real_report_org"));
entity.setLineType(json.optString("line_type"));
entity.setTrainStation(json.optString("train_station"));
entity.setUpdateBy(json.optString("update_by"));
entity.setTrack(json.optString("track"));
entity.setReportOrgName(json.optString("report_org_name"));
entity.setFirstConfirmPerson(json.optString("first_confirm_person"));
entity.setOccSigningStatus(json.optString("occ_signing_status"));
entity.setDelayTime(json.optString("delay_time"));
entity.setSpecialStationLine(json.optString("special_station_line"));
entity.setTrackName(json.optString("track_name"));
entity.setUnrepairDesc(json.optString("unrepair_desc"));
entity.setUpdateByName(json.optString("update_by_name"));
entity.setCoccTime(syncBase.parseDate(json.optString("cocc_time"), "yyyy-MM-dd HH:mm:ss"));
entity.setFirstConfirmPersonName(json.optString("first_confirm_person_name"));
entity.setVehicleType(json.optString("vehicle_type"));
entity.setFirstConfirmTime(syncBase.parseDate(json.optString("first_confirm_time"), "yyyy-MM-dd HH:mm:ss"));
entity.setAreaEndName(json.optString("area_end_name"));
entity.setLocationType(json.optString("location_type"));
entity.setOccTime(syncBase.parseDate(json.optString("occ_time"), "yyyy-MM-dd HH:mm:ss"));
entity.setDeptPath(json.optString("dept_path"));
entity.setIsConnect(json.optString("is_connect"));
entity.setMergeStatus(json.optString("merge_status"));
entity.setProcessInstanceId(json.optString("process_instance_id"));
entity.setCarNumber(json.optString("car_number"));
entity.setDisposalResult(json.optString("disposal_result"));
entity.setMergePerson(json.optString("merge_person"));
entity.setNewLineDangerLevel(json.optString("new_line_danger_level"));
entity.setReportOrg(json.optString("report_org"));
entity.setControlCenter(json.optString("control_center"));
save(entity);
count++;
}
log.info("同步完成:{} 条", count);
return count;
}
}

View File

@ -0,0 +1,117 @@
package net.juntech.modules.ysdp.sync.service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import net.juntech.modules.ysdp.sync.domain.ErpWorkOrder;
import net.juntech.modules.ysdp.sync.mapper.ErpWorkOrderMapper;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
/**
* 故障记录单-处置工单主表数据同步服务
*/
@Slf4j
@Service
@Transactional
public class ErpWorkOrderSyncService extends ServiceImpl<ErpWorkOrderMapper, ErpWorkOrder> {
@Autowired
private DataCenterSyncBase syncBase;
public int syncByDate(String date) {
log.info("同步 erp_work_order,日期:{}", date);
JSONArray dataArray = syncBase.fetchAllDataByApiParam("erp_work_order", "create_time", date);
int count = 0;
for (int i = 0; i < dataArray.size(); i++) {
JSONObject json = dataArray.getJSONObject(i);
if (syncBase.isEmptyData(json)) continue;
ErpWorkOrder entity = new ErpWorkOrder();
entity.setSourceId(json.optString("id"));
entity.setIsResponsible(syncBase.parseInteger(json.opt("is_responsible")));
entity.setIsSecondDistribute(json.optString("is_second_distribute"));
entity.setSecondDistributeDeptName(json.optString("second_distribute_dept_name"));
entity.setSysOrgCode(json.optString("sys_org_code"));
entity.setRepairSituation(json.optString("repair_situation"));
entity.setDistributePersonName(json.optString("distribute_person_name"));
entity.setFaultDealDesc(json.optString("fault_deal_desc"));
entity.setFaultTargetName(json.optString("fault_target_name"));
entity.setCreateByName(json.optString("create_by_name"));
entity.setWorkOrderNumber(json.optString("work_order_number"));
entity.setSolution(json.optString("solution"));
entity.setIsOwnRepair(json.optString("is_own_repair"));
entity.setPathCn(json.optString("path_cn"));
entity.setDelayStatus(json.optString("delay_status"));
entity.setSysOrgName(json.optString("sys_org_name"));
entity.setFaultFacility(json.optString("fault_facility"));
entity.setReasonCause(json.optString("reason_cause"));
entity.setFaultTarget(json.optString("fault_target"));
entity.setRepairFile(json.optString("repair_file"));
entity.setRepairLeaderName(json.optString("repair_leader_name"));
entity.setIsOutRepair(syncBase.parseInteger(json.opt("is_out_repair")));
entity.setUnrepairAnnex(json.optString("unrepair_annex"));
entity.setCreateTime(syncBase.parseDate(json.optString("create_time"), "yyyy-MM-dd HH:mm:ss"));
entity.setSecondDistributeDept(json.optString("second_distribute_dept"));
entity.setRepairOrg(json.optString("repair_org"));
entity.setFaultType(json.optString("fault_type"));
entity.setCloseTime(syncBase.parseDate(json.optString("close_time"), "yyyy-MM-dd HH:mm:ss"));
entity.setFaultPhenomenonName(json.optString("fault_phenomenon_name"));
entity.setIncidentResponseLevel(json.optString("incident_response_level"));
entity.setArriveTime(syncBase.parseDate(json.optString("arrive_time"), "yyyy-MM-dd HH:mm:ss"));
entity.setPartCount(json.optString("part_count"));
entity.setRepairTeam(json.optString("repair_team"));
entity.setLargeCategory(json.optString("large_category"));
entity.setRepairCompleteTime(syncBase.parseDate(json.optString("repair_complete_time"), "yyyy-MM-dd HH:mm:ss"));
entity.setFaultNumber(json.optString("fault_number"));
entity.setReasonCauseCode(json.optString("reason_cause_code"));
entity.setTeamRepairTime(syncBase.parseDate(json.optString("team_repair_time"), "yyyy-MM-dd HH:mm:ss"));
entity.setTableFeedbackTimeout(json.optString("table_feedback_timeout"));
entity.setRepairPerson(json.optString("repair_person"));
entity.setMiddleCategory(json.optString("middle_category"));
entity.setWorkOrderStatus(json.optString("work_order_status"));
entity.setRepairTeamId(json.optString("repair_team_id"));
entity.setMainChildOrder(json.optString("main_child_order"));
entity.setRepairPersonName(json.optString("repair_person_name"));
entity.setOtherFaultAttribution(json.optString("other_fault_attribution"));
entity.setFaultPhenomenon(json.optString("fault_phenomenon"));
entity.setDistributePerson(json.optString("distribute_person"));
entity.setCreateBy(json.optString("create_by"));
entity.setFaultFacilityName(json.optString("fault_facility_name"));
entity.setUpdateTime(syncBase.parseDate(json.optString("update_time"), "yyyy-MM-dd HH:mm:ss"));
entity.setIsDeleted(syncBase.parseInteger(json.opt("is_deleted")));
entity.setIsDiseased(syncBase.parseInteger(json.opt("is_diseased")));
entity.setRepairLeader(json.optString("repair_leader"));
entity.setUpdateBy(json.optString("update_by"));
entity.setOperationalImpact(json.optString("operational_impact"));
entity.setDelayTime(syncBase.parseDate(json.optString("delay_time"), "yyyy-MM-dd HH:mm:ss"));
entity.setFeedbackTimeout(syncBase.parseInteger(json.opt("feedback_timeout")));
entity.setRepairOrgName(json.optString("repair_org_name"));
entity.setDegradedState(json.optString("degraded_state"));
entity.setChildDealMinute(syncBase.parseInteger(json.opt("child_deal_minute")));
entity.setConfirmPerson(json.optString("confirm_person"));
entity.setUnrepairDesc(json.optString("unrepair_desc"));
entity.setOrgRepairTime(syncBase.parseDate(json.optString("org_repair_time"), "yyyy-MM-dd HH:mm:ss"));
entity.setUpdateByName(json.optString("update_by_name"));
entity.setFaultRecordSheetId(json.optString("fault_record_sheet_id"));
entity.setOutsourcedUnits(json.optString("outsourced_units"));
entity.setConfirmPersonName(json.optString("confirm_person_name"));
entity.setConfirmTime(syncBase.parseDate(json.optString("confirm_time"), "yyyy-MM-dd HH:mm:ss"));
entity.setDealMinute(syncBase.parseInteger(json.opt("deal_minute")));
entity.setOperatorName(json.optString("operator_name"));
entity.setDeptPath(json.optString("dept_path"));
entity.setBuildNumber(json.optString("build_number"));
entity.setFaultAttribution(json.optString("fault_attribution"));
entity.setPartName(json.optString("part_name"));
save(entity);
count++;
}
log.info("同步完成:{} 条", count);
return count;
}
}

View File

@ -51,7 +51,7 @@ public class DataCenterSyncTaskRegistrar implements CommandLineRunner {
job.setStatus(CommonConstants.YES);
job.setIsInfo(CommonConstants.NO);
job.setClassName(DataCenterSyncTask.class.getName());
job.setRemarks("数据中心三张表同步(erp_oper_indx / erp_5mins_trn_km / erp_cler_evt)");
job.setRemarks("数据中心同步任务(29 张表,含 erp_record_sheet / erp_work_order)");
job.setTenantId(TENANT_ID);
scheduleJobService.saveOrUpdate(job);
log.warn("数据中心同步任务已自动注册:name={}, cron={}", JOB_NAME, DEFAULT_CRON);

View File

@ -101,6 +101,12 @@ public class DataCenterSyncTask extends Task {
@Autowired
private ErpZoneDepotSyncService erpZoneDepotSyncService;
@Autowired
private ErpRecordSheetSyncService erpRecordSheetSyncService;
@Autowired
private ErpWorkOrderSyncService erpWorkOrderSyncService;
@Override
public void run() {
log.warn("==================== 【Quartz 任务】数据中心同步开始 ====================");
@ -137,6 +143,8 @@ public class DataCenterSyncTask extends Task {
syncTable("天气预警", () -> erpWeatherWarningSyncService.syncByDate(dateStr));
syncTable("施工区域", () -> erpZoneSyncService.syncByDate(dateStr));
syncTable("施工区域车场", () -> erpZoneDepotSyncService.syncByDate(dateStr));
syncTable("故障记录单主表", () -> erpRecordSheetSyncService.syncByDate(dateStr));
syncTable("处置工单主表", () -> erpWorkOrderSyncService.syncByDate(dateStr));
log.warn("==================== 【Quartz 任务】数据中心同步结束 ====================");
}

View File

@ -1,106 +1,106 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<!--<?xml version="1.0" encoding="UTF-8"?>-->
<!--<project xmlns="http://maven.apache.org/POM/4.0.0"-->
<!-- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"-->
<!-- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">-->
<!-- <modelVersion>4.0.0</modelVersion>-->
<parent>
<groupId>org.jeeplus</groupId>
<artifactId>jeeplus-plugins</artifactId>
<version>9.0</version>
</parent>
<!-- <parent>-->
<!-- <groupId>org.jeeplus</groupId>-->
<!-- <artifactId>jeeplus-plugins</artifactId>-->
<!-- <version>9.0</version>-->
<!-- </parent>-->
<artifactId>jeeplus-ureport</artifactId>
<packaging>jar</packaging>
<!-- <artifactId>jeeplus-ureport</artifactId>-->
<!-- <packaging>jar</packaging>-->
<name>jeeplus-ureport</name>
<description>ureport project for jeeplus</description>
<!-- <name>jeeplus-ureport</name>-->
<!-- <description>ureport project for jeeplus</description>-->
<dependencies>
<dependency>
<groupId>org.jeeplus</groupId>
<artifactId>jeeplus-admin</artifactId>
<version>${project.parent.version}</version>
</dependency>
<dependency>
<groupId>org.antlr</groupId>
<artifactId>antlr4-runtime</artifactId>
<version>4.5</version>
</dependency>
<!-- <dependencies>-->
<!-- <dependency>-->
<!-- <groupId>org.jeeplus</groupId>-->
<!-- <artifactId>jeeplus-admin</artifactId>-->
<!-- <version>${project.parent.version}</version>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>org.antlr</groupId>-->
<!-- <artifactId>antlr4-runtime</artifactId>-->
<!-- <version>4.5</version>-->
<!-- </dependency>-->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-fileupload2-core</artifactId>
<version>2.0.0-M2</version>
</dependency>
<!-- <dependency>-->
<!-- <groupId>org.apache.commons</groupId>-->
<!-- <artifactId>commons-fileupload2-core</artifactId>-->
<!-- <version>2.0.0-M2</version>-->
<!-- </dependency>-->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.6</version>
<scope>system</scope>
<systemPath>${project.basedir}/lib/commons-fileupload-1.6.jar</systemPath>
</dependency>
<dependency>
<groupId>com.bstek.ureport</groupId>
<artifactId>ureport2-console</artifactId>
<version>2.2.10</version>
<scope>system</scope>
<systemPath>${project.basedir}/lib/ureport2-console-2.2.10.jar</systemPath>
</dependency>
<dependency>
<groupId>com.bstek.ureport</groupId>
<artifactId>ureport2-core</artifactId>
<version>2.2.10</version>
<scope>system</scope>
<systemPath>${project.basedir}/lib/ureport2-core-2.2.10.jar</systemPath>
</dependency>
<dependency>
<groupId>com.bstek.ureport</groupId>
<artifactId>ureport2-font</artifactId>
<version>2.0.2</version>
<scope>system</scope>
<systemPath>${project.basedir}/lib/ureport2-font-2.0.2.jar</systemPath>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.5.13</version>
</dependency>
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>core</artifactId>
<version>3.5.3</version>
</dependency>
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity</artifactId>
<version>1.7</version>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.9.11</version>
</dependency>
<dependency>
<groupId>commons-net</groupId>
<artifactId>commons-net</artifactId>
<version>3.3</version>
</dependency>
<!-- <dependency>-->
<!-- <groupId>commons-fileupload</groupId>-->
<!-- <artifactId>commons-fileupload</artifactId>-->
<!-- <version>1.6</version>-->
<!-- <scope>system</scope>-->
<!-- <systemPath>${project.basedir}/lib/commons-fileupload-1.6.jar</systemPath>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>com.bstek.ureport</groupId>-->
<!-- <artifactId>ureport2-console</artifactId>-->
<!-- <version>2.2.10</version>-->
<!-- <scope>system</scope>-->
<!-- <systemPath>${project.basedir}/lib/ureport2-console-2.2.10.jar</systemPath>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>com.bstek.ureport</groupId>-->
<!-- <artifactId>ureport2-core</artifactId>-->
<!-- <version>2.2.10</version>-->
<!-- <scope>system</scope>-->
<!-- <systemPath>${project.basedir}/lib/ureport2-core-2.2.10.jar</systemPath>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>com.bstek.ureport</groupId>-->
<!-- <artifactId>ureport2-font</artifactId>-->
<!-- <version>2.0.2</version>-->
<!-- <scope>system</scope>-->
<!-- <systemPath>${project.basedir}/lib/ureport2-font-2.0.2.jar</systemPath>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>com.itextpdf</groupId>-->
<!-- <artifactId>itextpdf</artifactId>-->
<!-- <version>5.5.13</version>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>com.google.zxing</groupId>-->
<!-- <artifactId>core</artifactId>-->
<!-- <version>3.5.3</version>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>org.apache.velocity</groupId>-->
<!-- <artifactId>velocity</artifactId>-->
<!-- <version>1.7</version>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>org.codehaus.jackson</groupId>-->
<!-- <artifactId>jackson-mapper-asl</artifactId>-->
<!-- <version>1.9.11</version>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>commons-net</groupId>-->
<!-- <artifactId>commons-net</artifactId>-->
<!-- <version>3.3</version>-->
<!-- </dependency>-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.jeeplus</groupId>
<artifactId>jeeplus-datasource</artifactId>
<version>${project.parent.version}</version>
</dependency>
<!-- <dependency>-->
<!-- <groupId>org.springframework.boot</groupId>-->
<!-- <artifactId>spring-boot-starter-data-jpa</artifactId>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>org.jeeplus</groupId>-->
<!-- <artifactId>jeeplus-datasource</artifactId>-->
<!-- <version>${project.parent.version}</version>-->
<!-- </dependency>-->
</dependencies>
<!-- </dependencies>-->
</project>
<!--</project>-->

View File

@ -1,25 +1,25 @@
package com.jeeplus.ureport.cache;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
@Controller
public class CacheController {
private final ErasableMemoryCache erasableMemoryCache;
public CacheController(ErasableMemoryCache erasableMemoryCache) {
this.erasableMemoryCache = erasableMemoryCache;
}
/**
* 清除缓存的入口
*
* @return 返回首页
*/
@PostMapping("/clearCache")
public String clearCache() {
erasableMemoryCache.clearCache ( );
return "redirect:/reports/index";
}
}
//package com.jeeplus.ureport.cache;
//
//import org.springframework.stereotype.Controller;
//import org.springframework.web.bind.annotation.PostMapping;
//
//@Controller
//public class CacheController {
//
// private final ErasableMemoryCache erasableMemoryCache;
//
// public CacheController(ErasableMemoryCache erasableMemoryCache) {
// this.erasableMemoryCache = erasableMemoryCache;
// }
//
// /**
// * 清除缓存的入口
// *
// * @return 返回首页
// */
// @PostMapping("/clearCache")
// public String clearCache() {
// erasableMemoryCache.clearCache ( );
// return "redirect:/reports/index";
// }
//}

View File

@ -1,32 +1,32 @@
package com.jeeplus.ureport.cache;
import com.bstek.ureport.cache.ReportDefinitionCache;
import com.bstek.ureport.definition.ReportDefinition;
import org.springframework.stereotype.Component;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@Component
public class ErasableMemoryCache implements ReportDefinitionCache {
private final Map <String, ReportDefinition> reportMap = new ConcurrentHashMap <String, ReportDefinition> ( );
/**
* 清除缓存
*/
public void clearCache() {
this.reportMap.clear ( );
}
@Override
public ReportDefinition getReportDefinition(String file) {
return reportMap.get ( file );
}
@Override
public void cacheReportDefinition(String file, ReportDefinition reportDefinition) {
reportMap.remove ( file );
reportMap.put ( file, reportDefinition );
}
}
//package com.jeeplus.ureport.cache;
//
//import com.bstek.ureport.cache.ReportDefinitionCache;
//import com.bstek.ureport.definition.ReportDefinition;
//import org.springframework.stereotype.Component;
//
//import java.util.Map;
//import java.util.concurrent.ConcurrentHashMap;
//
//@Component
//public class ErasableMemoryCache implements ReportDefinitionCache {
//
// private final Map <String, ReportDefinition> reportMap = new ConcurrentHashMap <String, ReportDefinition> ( );
//
// /**
// * 清除缓存
// */
// public void clearCache() {
// this.reportMap.clear ( );
// }
//
// @Override
// public ReportDefinition getReportDefinition(String file) {
// return reportMap.get ( file );
// }
//
// @Override
// public void cacheReportDefinition(String file, ReportDefinition reportDefinition) {
// reportMap.remove ( file );
// reportMap.put ( file, reportDefinition );
// }
//}

View File

@ -1,20 +1,20 @@
package com.jeeplus.ureport.cache;
import com.bstek.ureport.cache.ReportDefinitionCache;
import com.bstek.ureport.definition.ReportDefinition;
import org.springframework.stereotype.Component;
@Component
public class NullCache implements ReportDefinitionCache {
@Override
public ReportDefinition getReportDefinition(String file) {
System.out.println ( "NullCache.getReportDefinition" );
System.out.println ( "file = " + file );
return null;
}
@Override
public void cacheReportDefinition(String file, ReportDefinition reportDefinition) {
System.out.println ( "NullCache.cacheReportDefinition" );
}
}
//package com.jeeplus.ureport.cache;
//
//import com.bstek.ureport.cache.ReportDefinitionCache;
//import com.bstek.ureport.definition.ReportDefinition;
//import org.springframework.stereotype.Component;
//
//@Component
//public class NullCache implements ReportDefinitionCache {
// @Override
// public ReportDefinition getReportDefinition(String file) {
// System.out.println ( "NullCache.getReportDefinition" );
// System.out.println ( "file = " + file );
// return null;
// }
//
// @Override
// public void cacheReportDefinition(String file, ReportDefinition reportDefinition) {
// System.out.println ( "NullCache.cacheReportDefinition" );
// }
//}

View File

@ -1,19 +1,19 @@
package com.jeeplus.ureport.config;
import com.bstek.ureport.console.UReportServlet;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportResource;
@ImportResource("classpath:context.xml")
@Configuration
public class ReportConfiguration {
@Bean
public ServletRegistrationBean <UReportServlet> servletRegistrationBean() {
return new ServletRegistrationBean <> ( new UReportServlet ( ), "/ureport/*" );
}
}
//package com.jeeplus.ureport.config;
//
//import com.bstek.ureport.console.UReportServlet;
//import org.springframework.boot.web.servlet.ServletRegistrationBean;
//import org.springframework.context.annotation.Bean;
//import org.springframework.context.annotation.Configuration;
//import org.springframework.context.annotation.ImportResource;
//
//@ImportResource("classpath:context.xml")
//@Configuration
//public class ReportConfiguration {
//
//
// @Bean
// public ServletRegistrationBean <UReportServlet> servletRegistrationBean() {
// return new ServletRegistrationBean <> ( new UReportServlet ( ), "/ureport/*" );
// }
//
//}

View File

@ -1,34 +1,34 @@
package com.jeeplus.ureport.controller;
import com.jeeplus.common.utils.ResponseUtil;
import com.jeeplus.ureport.service.ReportService;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
@Slf4j
@Tag(name = "报表")
@RestController
@RequestMapping("/reports")
public class ReportController {
private final ReportService reportService;
ReportController(ReportService reportService) {
this.reportService = reportService;
}
@GetMapping("/list")
public ResponseEntity getReports() {
log.debug ( "ReportController.getReports" );
return ResponseUtil.newInstance ( ).add ( "reports", reportService.getReportFiles ( ) ).add ( "prefix", "file:" ).ok ( );
}
@DeleteMapping("/delete")
public ResponseEntity delete(@RequestParam("id") String id) {
log.debug ( "ReportController.deleteById {}", id );
reportService.deleteReport ( id );
return ResponseEntity.ok ( "删除报表成功!" );
}
}
//package com.jeeplus.ureport.controller;
//
//import com.jeeplus.common.utils.ResponseUtil;
//import com.jeeplus.ureport.service.ReportService;
//import io.swagger.v3.oas.annotations.tags.Tag;
//import lombok.extern.slf4j.Slf4j;
//import org.springframework.http.ResponseEntity;
//import org.springframework.web.bind.annotation.*;
//
//@Slf4j
//@Tag(name = "报表")
//@RestController
//@RequestMapping("/reports")
//public class ReportController {
//
// private final ReportService reportService;
//
// ReportController(ReportService reportService) {
// this.reportService = reportService;
// }
//
// @GetMapping("/list")
// public ResponseEntity getReports() {
// log.debug ( "ReportController.getReports" );
// return ResponseUtil.newInstance ( ).add ( "reports", reportService.getReportFiles ( ) ).add ( "prefix", "file:" ).ok ( );
// }
//
// @DeleteMapping("/delete")
// public ResponseEntity delete(@RequestParam("id") String id) {
// log.debug ( "ReportController.deleteById {}", id );
// reportService.deleteReport ( id );
// return ResponseEntity.ok ( "删除报表成功!" );
// }
//}

View File

@ -1,43 +1,43 @@
package com.jeeplus.ureport.model;
import com.bstek.ureport.definition.datasource.BuildinDatasource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;
@Component
public class ReportDatasource implements BuildinDatasource {
@Autowired
private DataSource dataSource;
/**
* @return 返回数据源名称
*/
@Override
public String name() {
return "本地数据库";
}
/**
* @return 返回当前采用数据源的一个连接
*/
@Override
public Connection getConnection() {
try {
return dataSource.getConnection ( );
} catch (SQLException e) {
throw new RuntimeException ( e );
}
}
}
//package com.jeeplus.ureport.model;
//
//
//import com.bstek.ureport.definition.datasource.BuildinDatasource;
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.stereotype.Component;
//
//import javax.sql.DataSource;
//import java.sql.Connection;
//import java.sql.SQLException;
//
//@Component
//public class ReportDatasource implements BuildinDatasource {
//
// @Autowired
// private DataSource dataSource;
//
// /**
// * @return 返回数据源名称
// */
//
// @Override
// public String name() {
// return "本地数据库";
// }
//
//
// /**
// * @return 返回当前采用数据源的一个连接
// */
//
// @Override
// public Connection getConnection() {
//
// try {
// return dataSource.getConnection ( );
//
// } catch (SQLException e) {
// throw new RuntimeException ( e );
// }
// }
//
//}

View File

@ -1,42 +1,42 @@
package com.jeeplus.ureport.service;
import com.bstek.ureport.provider.report.ReportFile;
import com.bstek.ureport.provider.report.file.FileReportProvider;
import com.jeeplus.ureport.cache.ErasableMemoryCache;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import java.util.List;
@Slf4j
@Service
public class ReportService {
private final ErasableMemoryCache erasableMemoryCache;
private final FileReportProvider fileReportProvider;
public ReportService(ErasableMemoryCache erasableMemoryCache, FileReportProvider fileReportProvider) {
this.erasableMemoryCache = erasableMemoryCache;
this.fileReportProvider = fileReportProvider;
}
public List <ReportFile> getReportFiles() {
log.debug ( "ReportService.getReportFiles" );
return fileReportProvider.getReportFiles ( );
}
public void deleteReport(String file) {
log.debug ( "ReportService.deleteReport, file: {}", file );
if ( file.startsWith ( fileReportProvider.getPrefix ( ) ) ) {
fileReportProvider.deleteReport ( file );
} else {
log.error ( "ReportService.deleteReport, error when deleteById: {}", file );
}
// fix: deleteById report and cache.
if ( erasableMemoryCache != null ) {
erasableMemoryCache.clearCache ( );
}
}
}
//package com.jeeplus.ureport.service;
//
//import com.bstek.ureport.provider.report.ReportFile;
//import com.bstek.ureport.provider.report.file.FileReportProvider;
//import com.jeeplus.ureport.cache.ErasableMemoryCache;
//import lombok.extern.slf4j.Slf4j;
//import org.springframework.stereotype.Service;
//
//import java.util.List;
//
//@Slf4j
//@Service
//public class ReportService {
//
// private final ErasableMemoryCache erasableMemoryCache;
//
// private final FileReportProvider fileReportProvider;
//
// public ReportService(ErasableMemoryCache erasableMemoryCache, FileReportProvider fileReportProvider) {
// this.erasableMemoryCache = erasableMemoryCache;
// this.fileReportProvider = fileReportProvider;
// }
//
//
// public List <ReportFile> getReportFiles() {
// log.debug ( "ReportService.getReportFiles" );
// return fileReportProvider.getReportFiles ( );
// }
//
// public void deleteReport(String file) {
// log.debug ( "ReportService.deleteReport, file: {}", file );
// if ( file.startsWith ( fileReportProvider.getPrefix ( ) ) ) {
// fileReportProvider.deleteReport ( file );
// } else {
// log.error ( "ReportService.deleteReport, error when deleteById: {}", file );
// }
// // fix: deleteById report and cache.
// if ( erasableMemoryCache != null ) {
// erasableMemoryCache.clearCache ( );
// }
// }
//}

View File

@ -2,5 +2,5 @@
# On windows:
# ureport.fileStoreDir=D:/ureport/ureportFiles
# On Linux:
ureport.fileStoreDir=/Users/liugf/Documents/ureport
ureport.disableHttpSessionReportCache=true
#ureport.fileStoreDir=/Users/liugf/Documents/ureport
#ureport.disableHttpSessionReportCache=true

View File

@ -1,19 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<!--<?xml version="1.0" encoding="UTF-8"?>-->
<!--<beans xmlns="http://www.springframework.org/schema/beans"-->
<!-- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"-->
<!-- xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">-->
<!-- 引入ureport2报表xml配置文件 -->
<import resource="classpath:ureport-console-context.xml"/>
<!-- &lt;!&ndash; 引入ureport2报表xml配置文件 &ndash;&gt;-->
<!-- <import resource="classpath:ureport-console-context.xml"/>-->
<!-- 修改目录文件位置。这里多说几句,官方文档默认是在/WEB-INF/config.properties下面,
WEB-INF每次运行的时候都会动态生成一个临时目录,我们是找不到的,所以我们将位置修改成绝对路径,自己可以找到。
由于config.properties是在resouces配置下,所以使用classpath: -->
<bean id="propertyConfigurer" parent="ureport.props">
<property name="location">
<value>classpath:config.properties</value>
</property>
</bean>
<!-- &lt;!&ndash; 修改目录文件位置。这里多说几句,官方文档默认是在/WEB-INF/config.properties下面,-->
<!-- WEB-INF每次运行的时候都会动态生成一个临时目录,我们是找不到的,所以我们将位置修改成绝对路径,自己可以找到。-->
<!-- 由于config.properties是在resouces配置下,所以使用classpath: &ndash;&gt;-->
<!-- <bean id="propertyConfigurer" parent="ureport.props">-->
<!-- <property name="location">-->
<!-- <value>classpath:config.properties</value>-->
<!-- </property>-->
<!-- </bean>-->
</beans>
<!--</beans>-->

View File

@ -24,7 +24,7 @@
<module>jeeplus-file</module>
<module>jeeplus-quartz</module>
<module>jeeplus-tools</module>
<module>jeeplus-ureport</module>
<!-- <module>jeeplus-ureport</module>-->
<module>jeeplus-wps</module>
</modules>