Commit 9e0e468b8a9ec6822e82d4761cd6186f24f36b05

Authored by 徐烜
1 parent 5375a34e

浦东公交调度系统-车辆信息同步功能

1、初始化,不使用之前基于springbath的功能,使用内部调用ktr方式完成同步
2、基础后台服务,前台的页面已经完成
Showing 32 changed files with 2520 additions and 12 deletions
doc/jar/jsonpath-1.0.jar 0 → 100644
No preview for this file type
doc/pom错误解决.txt 0 → 100644
  1 +1、jsonpath手动导入
  2 +pom定义如下:
  3 +<!-- https://mvnrepository.com/artifact/jsonpath/jsonpath -->
  4 +<dependency>
  5 + <groupId>jsonpath</groupId>
  6 + <artifactId>jsonpath</artifactId>
  7 + <version>1.0</version>
  8 +</dependency>
  9 +pom中repositoy添加如下:
  10 +<repository>
  11 + <id>pentaho-public</id>
  12 + <url>https://repo.orl.eng.hitachivantara.com/artifactory/pnt-mvn/</url>
  13 +</repository>
  14 +如果无法获取,可能由于被墙了,则手动导入,控制台输入命令如下:
  15 +mvn install:install-file -DgroupId=jsonpath -DartifactId=jsonpath -Dversion=1.0 -Dpackaging=jar -Dfile=./jar/jsonpath-1.0.jar
@@ -34,7 +34,7 @@ @@ -34,7 +34,7 @@
34 <groupId>org.springframework.boot</groupId> 34 <groupId>org.springframework.boot</groupId>
35 <artifactId>spring-boot-starter-security</artifactId> 35 <artifactId>spring-boot-starter-security</artifactId>
36 </dependency> 36 </dependency>
37 - <!-- <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-config</artifactId> 37 + <!-- <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-config</artifactId>
38 </dependency> --> 38 </dependency> -->
39 <dependency> 39 <dependency>
40 <groupId>org.springframework.boot</groupId> 40 <groupId>org.springframework.boot</groupId>
@@ -396,7 +396,27 @@ @@ -396,7 +396,27 @@
396 <artifactId>wsdl4j</artifactId> 396 <artifactId>wsdl4j</artifactId>
397 </dependency> 397 </dependency>
398 398
399 - </dependencies> 399 + <dependency>
  400 + <groupId>org.projectlombok</groupId>
  401 + <artifactId>lombok</artifactId>
  402 + </dependency>
  403 +
  404 + <!-- https://mvnrepository.com/artifact/jsonpath/jsonpath -->
  405 + <dependency>
  406 + <groupId>jsonpath</groupId>
  407 + <artifactId>jsonpath</artifactId>
  408 + <version>1.0</version>
  409 + </dependency>
  410 +
  411 + <!-- https://mvnrepository.com/artifact/com.googlecode.json-simple/json-simple -->
  412 + <dependency>
  413 + <groupId>com.googlecode.json-simple</groupId>
  414 + <artifactId>json-simple</artifactId>
  415 + <version>1.1</version>
  416 + </dependency>
  417 +
  418 +
  419 + </dependencies>
400 420
401 <dependencyManagement> 421 <dependencyManagement>
402 <dependencies> 422 <dependencies>
@@ -472,6 +492,10 @@ @@ -472,6 +492,10 @@
472 <id>spring-milestones</id> 492 <id>spring-milestones</id>
473 <url>http://repo.spring.io/milestone</url> 493 <url>http://repo.spring.io/milestone</url>
474 </repository> 494 </repository>
  495 + <repository>
  496 + <id>pentaho-public</id>
  497 + <url>https://repo.orl.eng.hitachivantara.com/artifactory/pnt-mvn/</url>
  498 + </repository>
475 </repositories> 499 </repositories>
476 <pluginRepositories> 500 <pluginRepositories>
477 <pluginRepository> 501 <pluginRepository>
src/main/java/com/bsth/controller/schedule/datasync/VehicleDataSyncController.java 0 → 100644
  1 +package com.bsth.controller.schedule.datasync;
  2 +
  3 +import com.bsth.controller.schedule.BController;
  4 +import com.bsth.controller.schedule.datasync.common.ApiResult;
  5 +import com.bsth.entity.schedule.datasync.VehicleDataSyncLog;
  6 +import com.bsth.service.schedule.datasync.VehicleDataSyncService;
  7 +import com.bsth.service.schedule.datasync.task.VehicleDataSyncTaskFlag;
  8 +import org.springframework.beans.factory.annotation.Autowired;
  9 +import org.springframework.web.bind.annotation.GetMapping;
  10 +import org.springframework.web.bind.annotation.PathVariable;
  11 +import org.springframework.web.bind.annotation.RequestMapping;
  12 +import org.springframework.web.bind.annotation.RestController;
  13 +
  14 +import javax.servlet.http.HttpServletResponse;
  15 +import java.io.*;
  16 +
  17 +@RestController
  18 +@RequestMapping("dataSync/vehicle")
  19 +public class VehicleDataSyncController extends BController<VehicleDataSyncLog, Long> {
  20 + @Autowired
  21 + private VehicleDataSyncService vehicleDataSyncService;
  22 +
  23 + /**
  24 + * 同步标识。
  25 + * @return
  26 + */
  27 + @GetMapping(value = "/flag")
  28 + public ApiResult dataSyncFlag() {
  29 + try {
  30 + VehicleDataSyncTaskFlag taskFlag = VehicleDataSyncTaskFlag
  31 + .builder() // TODO:以后加别的参数
  32 + .build();
  33 + this.vehicleDataSyncService.addToDataSyncTaskQueue(taskFlag);
  34 + return ApiResult.success(
  35 + "200",
  36 + "添加同步任务成功",
  37 + "添加同步任务成功");
  38 + } catch (Exception exp) {
  39 + return ApiResult.failure(
  40 + "500",
  41 + "添加同步任务失败,内部错误:" + exp.getMessage());
  42 + }
  43 + }
  44 +
  45 + /**
  46 + * 获取同步日志。
  47 + * @param response
  48 + * @param id 日志Id
  49 + */
  50 + @GetMapping(value = "/logfile/{id}")
  51 + public void exportTaskLogFile(
  52 + HttpServletResponse response,
  53 + @PathVariable("id") long id) {
  54 + File file = this.vehicleDataSyncService.getTaskLogFile(id);
  55 + if (file == null || !file.exists()) {
  56 + throw new RuntimeException("日志文件不存在!");
  57 + }
  58 +
  59 + try {
  60 + responseStreamFile(response, file);
  61 + } catch (Exception exp) {
  62 + exp.printStackTrace();
  63 + throw new RuntimeException("获取同步日志文件错误:" + exp.getMessage());
  64 + }
  65 + }
  66 +
  67 + // 流输出文件
  68 + private void responseStreamFile(HttpServletResponse response, File file) throws IOException {
  69 + // 流输出导出文件
  70 + response.setHeader("content-type", "application/octet-stream");
  71 + response.setHeader("Content-Disposition", "attachment; filename=" + file.getName());
  72 + response.setContentType("application/octet-stream");
  73 +
  74 + try (
  75 + OutputStream os = response.getOutputStream();
  76 + BufferedOutputStream bos = new BufferedOutputStream(os);
  77 + InputStream is = new FileInputStream(file);
  78 + BufferedInputStream bis = new BufferedInputStream(is)
  79 + ) {
  80 + int length;
  81 + byte[] temp = new byte[1024 * 10];
  82 + while ((length = bis.read(temp)) != -1) {
  83 + bos.write(temp, 0, length);
  84 + }
  85 + bos.flush();
  86 + }
  87 + }
  88 +}
src/main/java/com/bsth/controller/schedule/datasync/common/ApiResult.java 0 → 100644
  1 +package com.bsth.controller.schedule.datasync.common;
  2 +
  3 +import java.io.Serializable;
  4 +
  5 +/**
  6 + * 对外api接口返回类。
  7 + */
  8 +public class ApiResult implements Serializable {
  9 + private static final long serialVersionUID = 2100700232168722289L;
  10 +
  11 + /** 返回数据 */
  12 + private Object result;
  13 + /** 是否成功 */
  14 + private Boolean success;
  15 + /** 返回描述 */
  16 + private String msg;
  17 + /** 返回码 */
  18 + private String code;
  19 +
  20 + // TODO:可能还有其他字段
  21 +
  22 +
  23 + public Object getResult() {
  24 + return result;
  25 + }
  26 +
  27 + public void setResult(Object result) {
  28 + this.result = result;
  29 + }
  30 +
  31 + public Boolean getSuccess() {
  32 + return success;
  33 + }
  34 +
  35 + public void setSuccess(Boolean success) {
  36 + this.success = success;
  37 + }
  38 +
  39 + public String getMsg() {
  40 + return msg;
  41 + }
  42 +
  43 + public void setMsg(String msg) {
  44 + this.msg = msg;
  45 + }
  46 +
  47 + public String getCode() {
  48 + return code;
  49 + }
  50 +
  51 + public void setCode(String code) {
  52 + this.code = code;
  53 + }
  54 +
  55 + public ApiResult() {}
  56 + public ApiResult(Builder builder) {
  57 + this.result = builder.result;
  58 + this.success = builder.success;
  59 + this.msg = builder.msg;
  60 + this.code = builder.code;
  61 + }
  62 +
  63 + public static ApiResult success(String code, String msg, Object result) {
  64 + return ApiResult.getBuilder()
  65 + .setResult(result)
  66 + .setMsg(msg)
  67 + .setCode(code)
  68 + .setSuccess(true)
  69 + .build();
  70 + }
  71 + public static ApiResult failure(String code, String msg) {
  72 + return ApiResult.getBuilder()
  73 + .setCode(code)
  74 + .setMsg(msg)
  75 + .setSuccess(false)
  76 + .build();
  77 + }
  78 +
  79 + static Builder getBuilder() {
  80 + return new Builder();
  81 + }
  82 + static class Builder {
  83 + /** 返回数据 */
  84 + private Object result;
  85 + /** 是否成功 */
  86 + private Boolean success;
  87 + /** 返回描述 */
  88 + private String msg;
  89 + /** 返回码 */
  90 + private String code;
  91 +
  92 + public Builder setResult(Object result) {
  93 + this.result = result;
  94 + return this;
  95 + }
  96 +
  97 + public Builder setSuccess(Boolean success) {
  98 + this.success = success;
  99 + return this;
  100 + }
  101 +
  102 + public Builder setMsg(String msg) {
  103 + this.msg = msg;
  104 + return this;
  105 + }
  106 +
  107 + public Builder setCode(String code) {
  108 + this.code = code;
  109 + return this;
  110 + }
  111 +
  112 + public ApiResult build() {
  113 + return new ApiResult(this);
  114 + }
  115 + }
  116 +
  117 +}
src/main/java/com/bsth/entity/schedule/datasync/VehicleDataSyncLog.java 0 → 100644
  1 +package com.bsth.entity.schedule.datasync;
  2 +
  3 +import javax.persistence.*;
  4 +import java.io.Serializable;
  5 +import java.util.Date;
  6 +
  7 +/**
  8 + * 车辆数据同步日志。
  9 + */
  10 +@Entity
  11 +@Table(name = "bsth_c_data_sync_cars")
  12 +public class VehicleDataSyncLog implements Serializable {
  13 + private static final long serialVersionUID = -3042098095111282402L;
  14 + /** 主键Id */
  15 + @Id
  16 + @GeneratedValue(strategy = GenerationType.IDENTITY)
  17 + private Long id;
  18 +
  19 + /** 待同步的记录数 */
  20 + private Integer syncRowCounts;
  21 + /** 同步-插入记录数 */
  22 + private Integer syncInsertCounts;
  23 + /** 同步-更新记录数 */
  24 + private Integer syncUpdateCounts;
  25 + /** 同步-错误记录数 */
  26 + private Integer syncErrorCounts;
  27 +
  28 + /** 开始时间 */
  29 + @Column(nullable = false)
  30 + @Temporal(TemporalType.TIMESTAMP)
  31 + private Date startDate;
  32 + /** 结束时间 */
  33 + @Temporal(TemporalType.TIMESTAMP)
  34 + private Date endDate;
  35 +
  36 + /** 同步状态 */
  37 + @Column(nullable = false)
  38 + @Convert(converter = VehicleDataSyncStatusEnumConverter.class)
  39 + private VehicleDataSyncStatusEnum status;
  40 +
  41 + /** 执行结果信息 */
  42 + @Column(length = 2000)
  43 + private String processMsg;
  44 +
  45 + /** 执行耗时(秒) */
  46 + private Integer processSeconds;
  47 +
  48 + public Long getId() {
  49 + return id;
  50 + }
  51 +
  52 + public void setId(Long id) {
  53 + this.id = id;
  54 + }
  55 +
  56 + public Integer getSyncRowCounts() {
  57 + return syncRowCounts;
  58 + }
  59 +
  60 + public void setSyncRowCounts(Integer syncRowCounts) {
  61 + this.syncRowCounts = syncRowCounts;
  62 + }
  63 +
  64 + public Integer getSyncInsertCounts() {
  65 + return syncInsertCounts;
  66 + }
  67 +
  68 + public void setSyncInsertCounts(Integer syncInsertCounts) {
  69 + this.syncInsertCounts = syncInsertCounts;
  70 + }
  71 +
  72 + public Integer getSyncUpdateCounts() {
  73 + return syncUpdateCounts;
  74 + }
  75 +
  76 + public void setSyncUpdateCounts(Integer syncUpdateCounts) {
  77 + this.syncUpdateCounts = syncUpdateCounts;
  78 + }
  79 +
  80 + public Integer getSyncErrorCounts() {
  81 + return syncErrorCounts;
  82 + }
  83 +
  84 + public void setSyncErrorCounts(Integer syncErrorCounts) {
  85 + this.syncErrorCounts = syncErrorCounts;
  86 + }
  87 +
  88 + public Date getStartDate() {
  89 + return startDate;
  90 + }
  91 +
  92 + public void setStartDate(Date startDate) {
  93 + this.startDate = startDate;
  94 + }
  95 +
  96 + public Date getEndDate() {
  97 + return endDate;
  98 + }
  99 +
  100 + public void setEndDate(Date endDate) {
  101 + this.endDate = endDate;
  102 + }
  103 +
  104 + public VehicleDataSyncStatusEnum getStatus() {
  105 + return status;
  106 + }
  107 +
  108 + public void setStatus(VehicleDataSyncStatusEnum status) {
  109 + this.status = status;
  110 + }
  111 +
  112 + public String getProcessMsg() {
  113 + return processMsg;
  114 + }
  115 +
  116 + public void setProcessMsg(String processMsg) {
  117 + this.processMsg = processMsg;
  118 + }
  119 +
  120 + public Integer getProcessSeconds() {
  121 + return processSeconds;
  122 + }
  123 +
  124 + public void setProcessSeconds(Integer processSeconds) {
  125 + this.processSeconds = processSeconds;
  126 + }
  127 +}
src/main/java/com/bsth/entity/schedule/datasync/VehicleDataSyncStatusEnum.java 0 → 100644
  1 +package com.bsth.entity.schedule.datasync;
  2 +
  3 +import com.fasterxml.jackson.annotation.JsonCreator;
  4 +import com.fasterxml.jackson.annotation.JsonValue;
  5 +import org.springframework.util.StringUtils;
  6 +
  7 +import java.util.HashMap;
  8 +import java.util.Map;
  9 +
  10 +/**
  11 + * 车辆数据同步状态enum。
  12 + */
  13 +public enum VehicleDataSyncStatusEnum {
  14 +
  15 + PREPARE("同步准备"),
  16 + PREPARE_FAIL("同步准备失败"),
  17 + SYNCING("同步中"),
  18 + END("同步结束");
  19 +
  20 + /** 字典描述(对应数据库的字典) */
  21 + private String dicDesc;
  22 +
  23 + @JsonCreator
  24 + VehicleDataSyncStatusEnum(String dicDesc) {
  25 + this.dicDesc = dicDesc;
  26 + }
  27 +
  28 + @JsonValue
  29 + public String getDicDesc() {
  30 + return dicDesc;
  31 + }
  32 +
  33 + public void setDicDesc(String dicDesc) {
  34 + this.dicDesc = dicDesc;
  35 + }
  36 +
  37 + @Override
  38 + public String toString() {
  39 + return dicDesc;
  40 + }
  41 +
  42 + public static Map<String, VehicleDataSyncStatusEnum> enumMap =
  43 + new HashMap<String, VehicleDataSyncStatusEnum>() {{
  44 + put("同步准备", PREPARE);
  45 + put("同步准备失败", PREPARE_FAIL);
  46 + put("同步中", SYNCING);
  47 + put("同步结束", END);
  48 + }};
  49 +
  50 + public static VehicleDataSyncStatusEnum fromDicDesc(String dicDesc) {
  51 + if (StringUtils.isEmpty(dicDesc)) {
  52 + throw new RuntimeException("车辆数据同步状态描述不能为空!");
  53 + } else if (enumMap.get(dicDesc) == null) {
  54 + throw new RuntimeException("车辆数据同步状态未定义:" + dicDesc);
  55 + }
  56 + return enumMap.get(dicDesc);
  57 + }
  58 +}
src/main/java/com/bsth/entity/schedule/datasync/VehicleDataSyncStatusEnumConverter.java 0 → 100644
  1 +package com.bsth.entity.schedule.datasync;
  2 +
  3 +import javax.persistence.AttributeConverter;
  4 +import javax.persistence.Convert;
  5 +
  6 +/**
  7 + * 车辆数据同步状态jpa转换器。
  8 + */
  9 +@Convert
  10 +public class VehicleDataSyncStatusEnumConverter implements AttributeConverter<VehicleDataSyncStatusEnum, String> {
  11 + @Override
  12 + public String convertToDatabaseColumn(VehicleDataSyncStatusEnum vehicleDataSyncStatusEnum) {
  13 + return vehicleDataSyncStatusEnum.getDicDesc();
  14 + }
  15 +
  16 + @Override
  17 + public VehicleDataSyncStatusEnum convertToEntityAttribute(String dbData) {
  18 + return VehicleDataSyncStatusEnum.fromDicDesc(dbData);
  19 + }
  20 +}
src/main/java/com/bsth/repository/schedule/batch/VehicleDataSyncLogRepository.java 0 → 100644
  1 +package com.bsth.repository.schedule.batch;
  2 +
  3 +import com.bsth.entity.schedule.datasync.VehicleDataSyncLog;
  4 +import com.bsth.repository.BaseRepository;
  5 +import org.springframework.stereotype.Repository;
  6 +
  7 +@Repository
  8 +public interface VehicleDataSyncLogRepository extends BaseRepository<VehicleDataSyncLog, Long> {
  9 +}
src/main/java/com/bsth/service/schedule/datasync/VehicleDataSyncService.java 0 → 100644
  1 +package com.bsth.service.schedule.datasync;
  2 +
  3 +import com.bsth.service.schedule.datasync.task.VehicleDataSyncTaskFlag;
  4 +
  5 +import java.io.File;
  6 +
  7 +/**
  8 + * 车辆信息同步接口。
  9 + */
  10 +public interface VehicleDataSyncService {
  11 + /**
  12 + * 添加数据同步任务到队列-等待同步。
  13 + * @param taskFlag 同步标识对象
  14 + */
  15 + void addToDataSyncTaskQueue(VehicleDataSyncTaskFlag taskFlag);
  16 +
  17 + /**
  18 + * 获取车辆数据同步task Id。
  19 + * @param vehicleDataSyncLogId VehicleDataSyncLog主键Id
  20 + * @return 日志文件
  21 + */
  22 + File getTaskLogFile(Long vehicleDataSyncLogId);
  23 +}
src/main/java/com/bsth/service/schedule/datasync/VehicleDataSyncServiceImpl.java 0 → 100644
  1 +package com.bsth.service.schedule.datasync;
  2 +
  3 +import ch.qos.logback.classic.LoggerContext;
  4 +import ch.qos.logback.core.FileAppender;
  5 +import com.bsth.entity.schedule.datasync.VehicleDataSyncLog;
  6 +import com.bsth.entity.schedule.datasync.VehicleDataSyncStatusEnum;
  7 +import com.bsth.service.schedule.datasync.log.VehicleDataSyncLogService;
  8 +import com.bsth.service.schedule.datasync.task.VehicleDataSyncTaskFlag;
  9 +import com.bsth.service.schedule.datasync.task.VehicleDataSyncTaskThread;
  10 +import com.bsth.service.schedule.utils.DataToolsProperties;
  11 +import com.bsth.service.schedule.utils.DataToolsService;
  12 +import com.bsth.service.schedule.utils.DataToolsServiceImpl;
  13 +import org.apache.commons.lang3.StringUtils;
  14 +import org.apache.commons.lang3.time.DateFormatUtils;
  15 +import org.slf4j.Logger;
  16 +import org.slf4j.LoggerFactory;
  17 +import org.slf4j.MDC;
  18 +import org.springframework.beans.factory.DisposableBean;
  19 +import org.springframework.beans.factory.annotation.Autowired;
  20 +import org.springframework.beans.factory.annotation.Qualifier;
  21 +import org.springframework.stereotype.Service;
  22 +
  23 +import javax.annotation.PostConstruct;
  24 +import java.io.File;
  25 +import java.io.PrintWriter;
  26 +import java.io.StringWriter;
  27 +import java.nio.file.Path;
  28 +import java.nio.file.Paths;
  29 +import java.text.MessageFormat;
  30 +import java.util.Date;
  31 +import java.util.concurrent.ArrayBlockingQueue;
  32 +import java.util.concurrent.CountDownLatch;
  33 +
  34 +/**
  35 + * 车辆信息同步实现。
  36 + */
  37 +@Service("VehicleDataSyncServiceImpl2")
  38 +public class VehicleDataSyncServiceImpl implements VehicleDataSyncService, Runnable, DisposableBean {
  39 + /** 日志记录器 */
  40 + private final static Logger LOG = LoggerFactory.getLogger(VehicleDataSyncServiceImpl.class);
  41 +
  42 + /** 同步阻塞队列 */
  43 + private ArrayBlockingQueue<VehicleDataSyncTaskFlag> dataSyncQueue;
  44 + /** 队列容量 */
  45 + private final static int QUEUE_CAPACITY = 100;
  46 +
  47 + /** bean是否销毁(用于优雅退出) */
  48 + private volatile boolean beanDestroy = false;
  49 +
  50 + @PostConstruct
  51 + public void init() {
  52 + LOG.info("车辆数据同步服务启动!");
  53 + // 创建队列,指定长度100
  54 + dataSyncQueue = new ArrayBlockingQueue<>(100);
  55 + LOG.info("队列容量={},待处理量={}", QUEUE_CAPACITY, dataSyncQueue.size());
  56 + // 启动线程实例
  57 + new Thread(this).start();
  58 + }
  59 +
  60 + @Override
  61 + public void addToDataSyncTaskQueue(VehicleDataSyncTaskFlag vehicleDataSyncFlag) {
  62 + if (!this.beanDestroy) {
  63 + // 1、初始创建同步日志对象
  64 + VehicleDataSyncLog vehicleDataSyncLog = new VehicleDataSyncLog();
  65 + vehicleDataSyncLog.setStartDate(new Date());
  66 + vehicleDataSyncLog.setStatus(VehicleDataSyncStatusEnum.PREPARE);
  67 + vehicleDataSyncLog = this.vehicleDataSyncLogService.save(vehicleDataSyncLog);
  68 + vehicleDataSyncFlag.setVehicleDataSyncLogId(vehicleDataSyncLog.getId()); // 设定日志Id
  69 + if (!this.dataSyncQueue.offer(vehicleDataSyncFlag)) {
  70 + vehicleDataSyncLog.setEndDate(new Date());
  71 + vehicleDataSyncLog.setStatus(VehicleDataSyncStatusEnum.PREPARE_FAIL);
  72 + vehicleDataSyncLog.setProcessMsg(MessageFormat.format(
  73 + "同步队列已满,队列容量={0},待处理量={1}, 无法添加同步任务!",
  74 + QUEUE_CAPACITY, dataSyncQueue.size()));
  75 + this.vehicleDataSyncLogService.save(vehicleDataSyncLog);
  76 + }
  77 + }
  78 + LOG.info("队列容量={},待处理量={}", QUEUE_CAPACITY, dataSyncQueue.size());
  79 + }
  80 +
  81 + @Override
  82 + public void destroy() throws Exception {
  83 + beanDestroy = true;
  84 + int queueSize = this.dataSyncQueue.size();
  85 + while (queueSize != 0) {
  86 + // 队列中的同步操作全部完成
  87 + try {
  88 + // 等待1秒后继续判定
  89 + Thread.sleep(1000);
  90 + } catch (Exception exp) {
  91 + exp.printStackTrace();
  92 + }
  93 + }
  94 + LOG.info("车辆数据同步服务销毁!");
  95 + }
  96 +
  97 + @Autowired
  98 + private VehicleDataSyncLogService vehicleDataSyncLogService;
  99 + @Autowired
  100 + @Qualifier(value = "dataToolsServiceImpl")
  101 + private DataToolsService dataToolsService;
  102 + @Autowired
  103 + private DataToolsProperties dataToolsProperties;
  104 + @Override
  105 + public void run() {
  106 + int queueSize = this.dataSyncQueue.size();
  107 + // 如果没有销毁bean,则一直检索队列,如果销毁bean,则需要等待所有队列元素执行完毕
  108 + while (!this.beanDestroy || queueSize > 0) {
  109 + // flag出队列
  110 + VehicleDataSyncTaskFlag flag = this.dataSyncQueue.poll();
  111 + if (flag != null) {
  112 + // 同步日志对象
  113 + VehicleDataSyncLog vehicleDataSyncLog = null;
  114 + try {
  115 + // 1、获取同步日志
  116 + vehicleDataSyncLog = this.vehicleDataSyncLogService.findById(
  117 + flag.getVehicleDataSyncLogId());
  118 + // 2、设定logback MDC key,用于子线程单独输出日志
  119 + String taskLogKey = String.format(
  120 + "%s.%s",
  121 + DateFormatUtils.format(vehicleDataSyncLog.getStartDate(), "yyyy-MM-dd"),
  122 + String.valueOf(vehicleDataSyncLog.getId()));
  123 + MDC.put("taskLogKey", taskLogKey);
  124 + // 3、开始同步
  125 + vehicleDataSyncLog.setStatus(VehicleDataSyncStatusEnum.SYNCING);
  126 + vehicleDataSyncLog = this.vehicleDataSyncLogService.save(vehicleDataSyncLog);
  127 + // 3-1、启动同步线程
  128 + CountDownLatch countDownLatch = new CountDownLatch(1);
  129 + new Thread(VehicleDataSyncTaskThread.builder()
  130 + .countDownLatch(countDownLatch)
  131 + .dataToolsService((DataToolsServiceImpl) dataToolsService)
  132 + .dataToolsProperties(dataToolsProperties)
  133 + .vehicleDataSyncLogService(vehicleDataSyncLogService)
  134 + .vehicleDataSyncLog(vehicleDataSyncLog)
  135 + .mdcCopyOfContextMap(MDC.getCopyOfContextMap())
  136 + .build()).start();
  137 + // 4、等待同步结束
  138 + countDownLatch.await();
  139 + // 4-1、更新日志
  140 + vehicleDataSyncLog.setEndDate(new Date());
  141 + long runMills = vehicleDataSyncLog.getEndDate().getTime() - vehicleDataSyncLog.getStartDate().getTime();
  142 + vehicleDataSyncLog.setProcessSeconds((int) runMills / 1000);
  143 + vehicleDataSyncLog.setStatus(VehicleDataSyncStatusEnum.END);
  144 + vehicleDataSyncLog.setProcessMsg("成功!");
  145 + this.vehicleDataSyncLogService.save(vehicleDataSyncLog);
  146 + } catch (Exception exp) {
  147 + // 获取异常stack信息
  148 + StringWriter sw = new StringWriter();
  149 + PrintWriter pw = new PrintWriter(sw);
  150 + exp.printStackTrace(pw);
  151 +
  152 + // 更新日志
  153 + vehicleDataSyncLog.setEndDate(new Date());
  154 + long runMills = vehicleDataSyncLog.getEndDate().getTime() - vehicleDataSyncLog.getStartDate().getTime();
  155 + vehicleDataSyncLog.setProcessSeconds((int) runMills / 1000);
  156 + vehicleDataSyncLog.setStatus(VehicleDataSyncStatusEnum.END);
  157 + vehicleDataSyncLog.setProcessMsg("有问题:" + StringUtils.substring(sw.toString(), 0, 1800)); // 日志限定长度
  158 + this.vehicleDataSyncLogService.save(vehicleDataSyncLog);
  159 + } finally {
  160 + MDC.clear();
  161 + }
  162 + }
  163 +
  164 + // 等待100毫秒后继续判定
  165 + try {
  166 + Thread.sleep(100);
  167 + } catch (Exception exp) {
  168 + exp.printStackTrace();
  169 + }
  170 +
  171 + }
  172 +
  173 + }
  174 +
  175 + /** 日志格式 */
  176 + private final static String TASK_LOG_PATTERN = "vehicle-data-sync.%s.%s.log";
  177 + @Override
  178 + public File getTaskLogFile(Long vehicleDataSyncLogId) {
  179 + VehicleDataSyncLog vehicleDataSyncLog = this.vehicleDataSyncLogService.findById(vehicleDataSyncLogId);
  180 + if (vehicleDataSyncLog == null) {
  181 + throw new RuntimeException("日志Id=" + vehicleDataSyncLogId + ",不存在!");
  182 + }
  183 + // 组合日志文件名称
  184 + String logFileName = String.format(
  185 + TASK_LOG_PATTERN,
  186 + DateFormatUtils.format(vehicleDataSyncLog.getStartDate(), "yyyy-MM-dd"),
  187 + String.valueOf(vehicleDataSyncLogId));
  188 +
  189 + File file = null;
  190 + try {
  191 + Path rootPath = this.getLogbackFilePath();
  192 + Path logFilePath = Paths.get(rootPath.toString(), "datasync", "vehicle", logFileName);
  193 + return logFilePath.toFile();
  194 + } catch (Exception exp) {
  195 + exp.printStackTrace();
  196 + }
  197 + return file;
  198 + }
  199 +
  200 + // 获取Logback中命名为File的Appender的日志文件输出路径,然后反向获取 ${LOG_BASE} 目录
  201 + private Path getLogbackFilePath() throws Exception {
  202 + LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory();
  203 + ch.qos.logback.classic.Logger logger = loggerContext.getLogger("ROOT");
  204 + FileAppender fileAppender = (FileAppender) logger.getAppender("FILE");//"FILE"是logback配置中,输出日志文件的appender的name属性
  205 + File file = new File(fileAppender.getFile());
  206 + Path filePath = Paths.get(file.getCanonicalPath()); // 这个等于 ${LOG_BASE}/main/main.log
  207 + return filePath.getParent().getParent();
  208 + }
  209 +
  210 + public static void main(String[] args) throws Exception {
  211 + String filepath = "/Users/xu/resource/project_code/bsth_project/bsth_control_parent/E:/bsth_control_logs";
  212 + Path p = Paths.get(filepath);
  213 + System.out.println(p.getParent().getParent());
  214 +
  215 + }
  216 +}
src/main/java/com/bsth/service/schedule/datasync/log/VehicleDataSyncLogService.java 0 → 100644
  1 +package com.bsth.service.schedule.datasync.log;
  2 +
  3 +import com.bsth.entity.schedule.datasync.VehicleDataSyncLog;
  4 +import com.bsth.service.schedule.BService;
  5 +
  6 +public interface VehicleDataSyncLogService extends BService<VehicleDataSyncLog, Long> {
  7 +}
src/main/java/com/bsth/service/schedule/datasync/log/VehicleDataSyncLogServiceImpl.java 0 → 100644
  1 +package com.bsth.service.schedule.datasync.log;
  2 +
  3 +import com.bsth.control_v2.plan_module.common.exception.PlanModuleException;
  4 +import com.bsth.entity.schedule.datasync.VehicleDataSyncLog;
  5 +import com.bsth.service.schedule.exception.ScheduleException;
  6 +import com.bsth.service.schedule.impl.BServiceImpl;
  7 +import org.springframework.stereotype.Service;
  8 +import org.springframework.transaction.annotation.Isolation;
  9 +import org.springframework.transaction.annotation.Propagation;
  10 +import org.springframework.transaction.annotation.Transactional;
  11 +
  12 +@Service
  13 +@Transactional(isolation = Isolation.READ_COMMITTED, propagation = Propagation.REQUIRED)
  14 +public class VehicleDataSyncLogServiceImpl extends BServiceImpl<VehicleDataSyncLog, Long> implements VehicleDataSyncLogService {
  15 +
  16 + @Override
  17 + public void delete(Long aLong) throws ScheduleException {
  18 + throw new PlanModuleException("不支持delete方法!");
  19 + }
  20 +
  21 +}
src/main/java/com/bsth/service/schedule/datasync/task/VehicleDataSyncTaskFlag.java 0 → 100644
  1 +package com.bsth.service.schedule.datasync.task;
  2 +
  3 +import lombok.AllArgsConstructor;
  4 +import lombok.Builder;
  5 +import lombok.Data;
  6 +
  7 +/**
  8 + * 车辆信息同步标示对象。
  9 + */
  10 +@Data
  11 +@Builder
  12 +@AllArgsConstructor
  13 +public class VehicleDataSyncTaskFlag {
  14 + // TODO:对象放在队列中,自定义属性暂时不需要,以后需要再加
  15 +
  16 + /** 日志Id(同步进入准备中状态设定) */
  17 + private Long vehicleDataSyncLogId;
  18 +
  19 + public VehicleDataSyncTaskFlag() {}
  20 +}
src/main/java/com/bsth/service/schedule/datasync/task/VehicleDataSyncTaskThread.java 0 → 100644
  1 +package com.bsth.service.schedule.datasync.task;
  2 +
  3 +import com.bsth.entity.schedule.datasync.VehicleDataSyncLog;
  4 +import com.bsth.service.schedule.datasync.log.VehicleDataSyncLogService;
  5 +import com.bsth.service.schedule.utils.DataToolsProperties;
  6 +import com.bsth.service.schedule.utils.DataToolsServiceImpl;
  7 +import lombok.AllArgsConstructor;
  8 +import lombok.Builder;
  9 +import lombok.Data;
  10 +import lombok.ToString;
  11 +import org.pentaho.di.core.exception.KettleException;
  12 +import org.pentaho.di.core.logging.KettleLogStore;
  13 +import org.pentaho.di.core.logging.LoggingBuffer;
  14 +import org.pentaho.di.core.logging.LoggingRegistry;
  15 +import org.pentaho.di.trans.Trans;
  16 +import org.pentaho.di.trans.TransMeta;
  17 +import org.pentaho.di.trans.step.StepInterface;
  18 +import org.pentaho.di.trans.step.StepStatus;
  19 +import org.slf4j.Logger;
  20 +import org.slf4j.LoggerFactory;
  21 +import org.slf4j.MDC;
  22 +
  23 +import java.io.File;
  24 +import java.util.HashMap;
  25 +import java.util.Map;
  26 +import java.util.concurrent.CountDownLatch;
  27 +
  28 +/**
  29 + * 车辆信息同步任务线程。
  30 + */
  31 +@Data
  32 +@Builder
  33 +@AllArgsConstructor
  34 +public class VehicleDataSyncTaskThread implements Runnable {
  35 + /** 日志记录器 */
  36 + private final static Logger LOG = LoggerFactory.getLogger(VehicleDataSyncTaskThread.class);
  37 +
  38 + private CountDownLatch countDownLatch;
  39 + private DataToolsServiceImpl dataToolsService;
  40 + private DataToolsProperties dataToolsProperties;
  41 + private VehicleDataSyncLogService vehicleDataSyncLogService;
  42 + private VehicleDataSyncLog vehicleDataSyncLog;
  43 + private Map<String, String> mdcCopyOfContextMap;
  44 +
  45 + public VehicleDataSyncTaskThread() {}
  46 +
  47 + @Override
  48 + public void run() {
  49 + try {
  50 + // 设置父线程MDC上下文
  51 + MDC.setContextMap(mdcCopyOfContextMap);
  52 +
  53 + LOG.info("------执行同步线程[taskLogKey={}]------", MDC.get("taskLogKey"));
  54 +
  55 + // 1、获取ktr
  56 + File ktrFile = new File(this.getClass().getResource(
  57 + dataToolsProperties.getVehicleDatasyncktr()).toURI());
  58 + // 2、创建命名参数
  59 + Map<String, String> ktrNamedParams = new HashMap<>();
  60 +
  61 + // 3、执行ktr
  62 + Map<String, ProcessKtrStepMeature> processKtrStepMeatureMap =
  63 + this.processKtr(ktrFile, ktrNamedParams);
  64 +
  65 + // TODO:
  66 +
  67 + LOG.info("ktr执行度量值:{}", processKtrStepMeatureMap);
  68 +
  69 + } catch (Exception exp) {
  70 + // 获取异常stack信息
  71 + LOG.error(exp.getMessage(), exp);
  72 + } finally {
  73 + LOG.info("------同步线程[taskLogKey={}]执行完毕------", MDC.get("taskLogKey"));
  74 + MDC.clear();
  75 + countDownLatch.countDown();
  76 + }
  77 + }
  78 +
  79 + /**
  80 + * 通用执行ktr。
  81 + * @param ktrFile ktr文件名字
  82 + * @param namedParams ktr命名参数
  83 + * @return 返回Map, key为step名字,value为step度量对象
  84 + */
  85 + private Map<String, ProcessKtrStepMeature> processKtr(File ktrFile, Map<String, String> namedParams) {
  86 + TransMeta transMeta = null;
  87 + Trans trans = null;
  88 +
  89 + String transMetaLogId;
  90 + String transLogId;
  91 +
  92 + Map<String, ProcessKtrStepMeature> processKtrStepMeatureMap = new HashMap<>();
  93 +
  94 + try {
  95 + // 1、初始化kettle
  96 + this.dataToolsService.initKettle();
  97 + // 1-1、检查参数
  98 + if (!ktrFile.exists()) {
  99 + throw new RuntimeException("ktr转换文件不存在,path=" + ktrFile.getAbsolutePath());
  100 + }
  101 + // 2、使用kettle运行封装数据导入逻辑的ktr转换文件
  102 + // 2.1、初始化kettle(组件初始化已经做了)
  103 + // 2.2、创建转换元数据,转换
  104 + // 2.3、设定ktr命名参数
  105 + transMeta = new TransMeta(ktrFile.getAbsolutePath());
  106 + trans = new Trans(transMeta);
  107 + for (String key : namedParams.keySet()) {
  108 + trans.setParameterValue(key, namedParams.get(key));
  109 + }
  110 + // 2.4、执行转换
  111 + trans.execute(null);
  112 + // 2.5、等待转换结束
  113 + trans.waitUntilFinished();
  114 + } catch (KettleException exp) {
  115 + LOG.error(exp.getMessage(), exp);
  116 + } catch (Exception exp) {
  117 + throw new RuntimeException(exp);
  118 + } finally {
  119 + // 获取步骤度量值
  120 + for (int i = 0; i < trans.nrSteps(); i++) {
  121 + StepInterface baseStep = trans.getRunThread(i);
  122 + StepStatus stepStatus = new StepStatus(baseStep);
  123 + processKtrStepMeatureMap.put(stepStatus.getStepname(),
  124 + ProcessKtrStepMeature.builder()
  125 + .inputs(stepStatus.getLinesInput())
  126 + .outputs(stepStatus.getLinesOutput())
  127 + .reads(stepStatus.getLinesRead())
  128 + .writes(stepStatus.getLinesWritten())
  129 + .updates(stepStatus.getLinesUpdated())
  130 + .errors(stepStatus.getErrors())
  131 + .build());
  132 + }
  133 +
  134 + // 获取日志
  135 + transLogId = trans.getLogChannelId();
  136 + transMetaLogId = transMeta.getLogChannelId();
  137 +
  138 + LoggingBuffer loggingBuffer = KettleLogStore.getAppender();
  139 + StringBuffer stringBuffer = loggingBuffer.getBuffer(
  140 + trans.getLogChannelId(), false
  141 + );
  142 +
  143 + LOG.info(stringBuffer.toString());
  144 +
  145 + // 清除日志操作
  146 + KettleLogStore.discardLines(transLogId, true);
  147 + KettleLogStore.discardLines(transMetaLogId, true);
  148 + LoggingRegistry.getInstance().removeIncludingChildren(transLogId);
  149 + }
  150 +
  151 + return processKtrStepMeatureMap;
  152 + }
  153 +
  154 + /**
  155 + * ktr执行度量。
  156 + */
  157 + @Data
  158 + @Builder
  159 + @AllArgsConstructor
  160 + @ToString
  161 + public static class ProcessKtrStepMeature {
  162 + /** 输入(一般是input类型的step有) */
  163 + private long inputs;
  164 + /** 输出(一般是output类型的step有) */
  165 + private long outputs;
  166 + /** 读取 */
  167 + private long reads;
  168 + /** 写 */
  169 + private long writes;
  170 + /** 更新 */
  171 + private long updates;
  172 + /** 错误 */
  173 + private long errors;
  174 +
  175 + public ProcessKtrStepMeature() {}
  176 + }
  177 +}
src/main/java/com/bsth/service/schedule/utils/DataToolsProperties.java
@@ -50,7 +50,7 @@ public class DataToolsProperties { @@ -50,7 +50,7 @@ public class DataToolsProperties {
50 /** ktr通用变量-数据库库名 */ 50 /** ktr通用变量-数据库库名 */
51 private String kvarsDbdname; 51 private String kvarsDbdname;
52 52
53 - /**------------------------- 导入数据ktr --------------------------*/ 53 + //------------------------- 导入数据ktr --------------------------//
54 /** 车辆信息导入ktr转换 */ 54 /** 车辆信息导入ktr转换 */
55 @NotNull 55 @NotNull
56 private String carsDatainputktr; 56 private String carsDatainputktr;
@@ -92,7 +92,7 @@ public class DataToolsProperties { @@ -92,7 +92,7 @@ public class DataToolsProperties {
92 private String scheduleruleDatainputktr; 92 private String scheduleruleDatainputktr;
93 93
94 94
95 - /**------------------------- 导出数据ktr --------------------------*/ 95 + //------------------------- 导出数据ktr --------------------------//
96 /** 车辆信息导出ktr转换 */ 96 /** 车辆信息导出ktr转换 */
97 @NotNull 97 @NotNull
98 private String carsDataoutputktr; 98 private String carsDataoutputktr;
@@ -118,6 +118,11 @@ public class DataToolsProperties { @@ -118,6 +118,11 @@ public class DataToolsProperties {
118 /** 路牌信息导出 */ 118 /** 路牌信息导出 */
119 private String guideboardsDataoutputktr; 119 private String guideboardsDataoutputktr;
120 120
  121 + //------------------------ 数据同步ktr -----------------------//
  122 + @NotNull
  123 + /** 车辆信息同步 */
  124 + private String vehicleDatasyncktr;
  125 +
121 // TODO: 126 // TODO:
122 127
123 public String getFileuploadDir() { 128 public String getFileuploadDir() {
@@ -367,4 +372,12 @@ public class DataToolsProperties { @@ -367,4 +372,12 @@ public class DataToolsProperties {
367 public void setTtinfodetailDatainputktr2version2(String ttinfodetailDatainputktr2version2) { 372 public void setTtinfodetailDatainputktr2version2(String ttinfodetailDatainputktr2version2) {
368 this.ttinfodetailDatainputktr2version2 = ttinfodetailDatainputktr2version2; 373 this.ttinfodetailDatainputktr2version2 = ttinfodetailDatainputktr2version2;
369 } 374 }
  375 +
  376 + public String getVehicleDatasyncktr() {
  377 + return vehicleDatasyncktr;
  378 + }
  379 +
  380 + public void setVehicleDatasyncktr(String vehicleDatasyncktr) {
  381 + this.vehicleDatasyncktr = vehicleDatasyncktr;
  382 + }
370 } 383 }
src/main/java/com/bsth/service/schedule/utils/DataToolsServiceImpl.java
@@ -13,7 +13,6 @@ import org.pentaho.di.trans.TransMeta; @@ -13,7 +13,6 @@ import org.pentaho.di.trans.TransMeta;
13 import org.slf4j.Logger; 13 import org.slf4j.Logger;
14 import org.slf4j.LoggerFactory; 14 import org.slf4j.LoggerFactory;
15 import org.springframework.beans.factory.annotation.Autowired; 15 import org.springframework.beans.factory.annotation.Autowired;
16 -import org.springframework.boot.context.properties.EnableConfigurationProperties;  
17 import org.springframework.stereotype.Component; 16 import org.springframework.stereotype.Component;
18 17
19 import java.io.File; 18 import java.io.File;
@@ -38,7 +37,7 @@ public class DataToolsServiceImpl implements DataToolsService { @@ -38,7 +37,7 @@ public class DataToolsServiceImpl implements DataToolsService {
38 /** 原子操作类 */ 37 /** 原子操作类 */
39 private AtomicBoolean flag = new AtomicBoolean(false); 38 private AtomicBoolean flag = new AtomicBoolean(false);
40 39
41 - private void initKettle() throws Exception { 40 + public void initKettle() throws Exception {
42 if (flag.compareAndSet(false, true)) { 41 if (flag.compareAndSet(false, true)) {
43 LOGGER.info("kettle初始化......"); 42 LOGGER.info("kettle初始化......");
44 43
@@ -283,4 +282,5 @@ public class DataToolsServiceImpl implements DataToolsService { @@ -283,4 +282,5 @@ public class DataToolsServiceImpl implements DataToolsService {
283 LoggingRegistry.getInstance().removeIncludingChildren(transLogId); 282 LoggingRegistry.getInstance().removeIncludingChildren(transLogId);
284 } 283 }
285 } 284 }
  285 +
286 } 286 }
src/main/resources/application-dev.properties
@@ -13,7 +13,7 @@ spring.jpa.show-sql= true @@ -13,7 +13,7 @@ spring.jpa.show-sql= true
13 13
14 #DATABASE 14 #DATABASE
15 spring.datasource.driver-class-name= com.mysql.jdbc.Driver 15 spring.datasource.driver-class-name= com.mysql.jdbc.Driver
16 -spring.datasource.url= jdbc:mysql://127.0.0.1/test_control?useUnicode=true&characterEncoding=utf-8&useSSL=false 16 +spring.datasource.url= jdbc:mysql://127.0.0.1/control?useUnicode=true&characterEncoding=utf-8&useSSL=false
17 #spring.datasource.url= jdbc:mysql://192.168.168.222/control?useUnicode=true&characterEncoding=utf-8&useSSL=false 17 #spring.datasource.url= jdbc:mysql://192.168.168.222/control?useUnicode=true&characterEncoding=utf-8&useSSL=false
18 spring.datasource.username= root 18 spring.datasource.username= root
19 spring.datasource.password= 19 spring.datasource.password=
@@ -40,4 +40,4 @@ http.gps.real.url= http://114.80.178.12:18080/transport_server/rtgps/ @@ -40,4 +40,4 @@ http.gps.real.url= http://114.80.178.12:18080/transport_server/rtgps/
40 ## gateway send directive 40 ## gateway send directive
41 http.send.directive = http://192.168.168.201:9090/transport_server/message/ 41 http.send.directive = http://192.168.168.201:9090/transport_server/message/
42 ## rfid data 42 ## rfid data
43 -http.rfid.url= http://114.80.178.12:29000/rfid  
44 \ No newline at end of file 43 \ No newline at end of file
  44 +http.rfid.url= http://114.80.178.12:29000/rfid
src/main/resources/application.properties
1 -spring.profiles.active = test 1 +spring.profiles.active = dev
2 2
3 spring.view.suffix=.html 3 spring.view.suffix=.html
4 server.session-timeout=-1 4 server.session-timeout=-1
src/main/resources/datatools/config-dev.properties
@@ -10,7 +10,7 @@ datatools.kvars_dbuname=root @@ -10,7 +10,7 @@ datatools.kvars_dbuname=root
10 #数据库密码 10 #数据库密码
11 datatools.kvars_dbpwd= 11 datatools.kvars_dbpwd=
12 #数据库库名 12 #数据库库名
13 -datatools.kvars_dbdname=test_control 13 +datatools.kvars_dbdname=control
14 14
15 # 3、上传数据配置信息 15 # 3、上传数据配置信息
16 # 上传文件目录配置(根据不同的环境需要修正) 16 # 上传文件目录配置(根据不同的环境需要修正)
@@ -77,6 +77,9 @@ datatools.employeesconfig_dataoutputktr=/datatools/ktrs/employeesConfigDataOutpu @@ -77,6 +77,9 @@ datatools.employeesconfig_dataoutputktr=/datatools/ktrs/employeesConfigDataOutpu
77 datatools.guideboards_dataoutputktr=/datatools/ktrs/guideboardDataOutput.ktr 77 datatools.guideboards_dataoutputktr=/datatools/ktrs/guideboardDataOutput.ktr
78 78
79 79
  80 +##--------------------------- 数据同步ktr ------------------------##
  81 +datatools.vehicle_datasyncktr=/datatools/ktrs/vehicleDataSync.ktr
  82 +
80 # TODO: 83 # TODO:
81 84
82 85
src/main/resources/datatools/config-prod.properties
@@ -77,5 +77,7 @@ datatools.employeesconfig_dataoutputktr=/datatools/ktrs/employeesConfigDataOutpu @@ -77,5 +77,7 @@ datatools.employeesconfig_dataoutputktr=/datatools/ktrs/employeesConfigDataOutpu
77 # 路牌信息导出 77 # 路牌信息导出
78 datatools.guideboards_dataoutputktr=/datatools/ktrs/guideboardDataOutput.ktr 78 datatools.guideboards_dataoutputktr=/datatools/ktrs/guideboardDataOutput.ktr
79 79
  80 +##--------------------------- 数据同步ktr ------------------------##
  81 +datatools.vehicle_datasyncktr=/datatools/ktrs/vehicleDataSync.ktr
80 82
81 # TODO: 83 # TODO:
src/main/resources/datatools/config-test.properties
@@ -77,5 +77,7 @@ datatools.employeesconfig_dataoutputktr=/datatools/ktrs/employeesConfigDataOutpu @@ -77,5 +77,7 @@ datatools.employeesconfig_dataoutputktr=/datatools/ktrs/employeesConfigDataOutpu
77 # 路牌信息导出 77 # 路牌信息导出
78 datatools.guideboards_dataoutputktr=/datatools/ktrs/guideboardDataOutput.ktr 78 datatools.guideboards_dataoutputktr=/datatools/ktrs/guideboardDataOutput.ktr
79 79
  80 +##--------------------------- 数据同步ktr ------------------------##
  81 +datatools.vehicle_datasyncktr=/datatools/ktrs/vehicleDataSync.ktr
80 82
81 # TODO: 83 # TODO:
src/main/resources/datatools/ktrs/vehicleDataSync.ktr 0 → 100644
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<transformation>
  3 + <info>
  4 + <name>&#x8f66;&#x8f86;&#x4fe1;&#x606f;&#x540c;&#x6b65;</name>
  5 + <description/>
  6 + <extended_description/>
  7 + <trans_version/>
  8 + <trans_type>Normal</trans_type>
  9 + <trans_status>0</trans_status>
  10 + <directory>&#x2f;</directory>
  11 + <parameters>
  12 + <parameter>
  13 + <name>password</name>
  14 + <default_value>856s543af26166g8</default_value>
  15 + <description>&#x5bc6;&#x94a5;</description>
  16 + </parameter>
  17 + <parameter>
  18 + <name>url</name>
  19 + <default_value>http&#x3a;&#x2f;&#x2f;180.166.5.82&#x3a;8076&#x2f;cars&#x2f;getCarsInterface</default_value>
  20 + <description>&#x8f66;&#x8f86;&#x5e93;&#x7cfb;&#x7edf;&#x7684;&#x76f8;&#x5173;url&#x5730;&#x5740;</description>
  21 + </parameter>
  22 + </parameters>
  23 + <log>
  24 +<trans-log-table><connection/>
  25 +<schema/>
  26 +<table/>
  27 +<size_limit_lines/>
  28 +<interval/>
  29 +<timeout_days/>
  30 +<field><id>ID_BATCH</id><enabled>Y</enabled><name>ID_BATCH</name></field><field><id>CHANNEL_ID</id><enabled>Y</enabled><name>CHANNEL_ID</name></field><field><id>TRANSNAME</id><enabled>Y</enabled><name>TRANSNAME</name></field><field><id>STATUS</id><enabled>Y</enabled><name>STATUS</name></field><field><id>LINES_READ</id><enabled>Y</enabled><name>LINES_READ</name><subject/></field><field><id>LINES_WRITTEN</id><enabled>Y</enabled><name>LINES_WRITTEN</name><subject/></field><field><id>LINES_UPDATED</id><enabled>Y</enabled><name>LINES_UPDATED</name><subject/></field><field><id>LINES_INPUT</id><enabled>Y</enabled><name>LINES_INPUT</name><subject/></field><field><id>LINES_OUTPUT</id><enabled>Y</enabled><name>LINES_OUTPUT</name><subject/></field><field><id>LINES_REJECTED</id><enabled>Y</enabled><name>LINES_REJECTED</name><subject/></field><field><id>ERRORS</id><enabled>Y</enabled><name>ERRORS</name></field><field><id>STARTDATE</id><enabled>Y</enabled><name>STARTDATE</name></field><field><id>ENDDATE</id><enabled>Y</enabled><name>ENDDATE</name></field><field><id>LOGDATE</id><enabled>Y</enabled><name>LOGDATE</name></field><field><id>DEPDATE</id><enabled>Y</enabled><name>DEPDATE</name></field><field><id>REPLAYDATE</id><enabled>Y</enabled><name>REPLAYDATE</name></field><field><id>LOG_FIELD</id><enabled>Y</enabled><name>LOG_FIELD</name></field><field><id>EXECUTING_SERVER</id><enabled>N</enabled><name>EXECUTING_SERVER</name></field><field><id>EXECUTING_USER</id><enabled>N</enabled><name>EXECUTING_USER</name></field><field><id>CLIENT</id><enabled>N</enabled><name>CLIENT</name></field></trans-log-table>
  31 +<perf-log-table><connection/>
  32 +<schema/>
  33 +<table/>
  34 +<interval/>
  35 +<timeout_days/>
  36 +<field><id>ID_BATCH</id><enabled>Y</enabled><name>ID_BATCH</name></field><field><id>SEQ_NR</id><enabled>Y</enabled><name>SEQ_NR</name></field><field><id>LOGDATE</id><enabled>Y</enabled><name>LOGDATE</name></field><field><id>TRANSNAME</id><enabled>Y</enabled><name>TRANSNAME</name></field><field><id>STEPNAME</id><enabled>Y</enabled><name>STEPNAME</name></field><field><id>STEP_COPY</id><enabled>Y</enabled><name>STEP_COPY</name></field><field><id>LINES_READ</id><enabled>Y</enabled><name>LINES_READ</name></field><field><id>LINES_WRITTEN</id><enabled>Y</enabled><name>LINES_WRITTEN</name></field><field><id>LINES_UPDATED</id><enabled>Y</enabled><name>LINES_UPDATED</name></field><field><id>LINES_INPUT</id><enabled>Y</enabled><name>LINES_INPUT</name></field><field><id>LINES_OUTPUT</id><enabled>Y</enabled><name>LINES_OUTPUT</name></field><field><id>LINES_REJECTED</id><enabled>Y</enabled><name>LINES_REJECTED</name></field><field><id>ERRORS</id><enabled>Y</enabled><name>ERRORS</name></field><field><id>INPUT_BUFFER_ROWS</id><enabled>Y</enabled><name>INPUT_BUFFER_ROWS</name></field><field><id>OUTPUT_BUFFER_ROWS</id><enabled>Y</enabled><name>OUTPUT_BUFFER_ROWS</name></field></perf-log-table>
  37 +<channel-log-table><connection/>
  38 +<schema/>
  39 +<table/>
  40 +<timeout_days/>
  41 +<field><id>ID_BATCH</id><enabled>Y</enabled><name>ID_BATCH</name></field><field><id>CHANNEL_ID</id><enabled>Y</enabled><name>CHANNEL_ID</name></field><field><id>LOG_DATE</id><enabled>Y</enabled><name>LOG_DATE</name></field><field><id>LOGGING_OBJECT_TYPE</id><enabled>Y</enabled><name>LOGGING_OBJECT_TYPE</name></field><field><id>OBJECT_NAME</id><enabled>Y</enabled><name>OBJECT_NAME</name></field><field><id>OBJECT_COPY</id><enabled>Y</enabled><name>OBJECT_COPY</name></field><field><id>REPOSITORY_DIRECTORY</id><enabled>Y</enabled><name>REPOSITORY_DIRECTORY</name></field><field><id>FILENAME</id><enabled>Y</enabled><name>FILENAME</name></field><field><id>OBJECT_ID</id><enabled>Y</enabled><name>OBJECT_ID</name></field><field><id>OBJECT_REVISION</id><enabled>Y</enabled><name>OBJECT_REVISION</name></field><field><id>PARENT_CHANNEL_ID</id><enabled>Y</enabled><name>PARENT_CHANNEL_ID</name></field><field><id>ROOT_CHANNEL_ID</id><enabled>Y</enabled><name>ROOT_CHANNEL_ID</name></field></channel-log-table>
  42 +<step-log-table><connection/>
  43 +<schema/>
  44 +<table/>
  45 +<timeout_days/>
  46 +<field><id>ID_BATCH</id><enabled>Y</enabled><name>ID_BATCH</name></field><field><id>CHANNEL_ID</id><enabled>Y</enabled><name>CHANNEL_ID</name></field><field><id>LOG_DATE</id><enabled>Y</enabled><name>LOG_DATE</name></field><field><id>TRANSNAME</id><enabled>Y</enabled><name>TRANSNAME</name></field><field><id>STEPNAME</id><enabled>Y</enabled><name>STEPNAME</name></field><field><id>STEP_COPY</id><enabled>Y</enabled><name>STEP_COPY</name></field><field><id>LINES_READ</id><enabled>Y</enabled><name>LINES_READ</name></field><field><id>LINES_WRITTEN</id><enabled>Y</enabled><name>LINES_WRITTEN</name></field><field><id>LINES_UPDATED</id><enabled>Y</enabled><name>LINES_UPDATED</name></field><field><id>LINES_INPUT</id><enabled>Y</enabled><name>LINES_INPUT</name></field><field><id>LINES_OUTPUT</id><enabled>Y</enabled><name>LINES_OUTPUT</name></field><field><id>LINES_REJECTED</id><enabled>Y</enabled><name>LINES_REJECTED</name></field><field><id>ERRORS</id><enabled>Y</enabled><name>ERRORS</name></field><field><id>LOG_FIELD</id><enabled>N</enabled><name>LOG_FIELD</name></field></step-log-table>
  47 +<metrics-log-table><connection/>
  48 +<schema/>
  49 +<table/>
  50 +<timeout_days/>
  51 +<field><id>ID_BATCH</id><enabled>Y</enabled><name>ID_BATCH</name></field><field><id>CHANNEL_ID</id><enabled>Y</enabled><name>CHANNEL_ID</name></field><field><id>LOG_DATE</id><enabled>Y</enabled><name>LOG_DATE</name></field><field><id>METRICS_DATE</id><enabled>Y</enabled><name>METRICS_DATE</name></field><field><id>METRICS_CODE</id><enabled>Y</enabled><name>METRICS_CODE</name></field><field><id>METRICS_DESCRIPTION</id><enabled>Y</enabled><name>METRICS_DESCRIPTION</name></field><field><id>METRICS_SUBJECT</id><enabled>Y</enabled><name>METRICS_SUBJECT</name></field><field><id>METRICS_TYPE</id><enabled>Y</enabled><name>METRICS_TYPE</name></field><field><id>METRICS_VALUE</id><enabled>Y</enabled><name>METRICS_VALUE</name></field></metrics-log-table>
  52 + </log>
  53 + <maxdate>
  54 + <connection/>
  55 + <table/>
  56 + <field/>
  57 + <offset>0.0</offset>
  58 + <maxdiff>0.0</maxdiff>
  59 + </maxdate>
  60 + <size_rowset>10000</size_rowset>
  61 + <sleep_time_empty>50</sleep_time_empty>
  62 + <sleep_time_full>50</sleep_time_full>
  63 + <unique_connections>N</unique_connections>
  64 + <feedback_shown>Y</feedback_shown>
  65 + <feedback_size>50000</feedback_size>
  66 + <using_thread_priorities>Y</using_thread_priorities>
  67 + <shared_objects_file/>
  68 + <capture_step_performance>N</capture_step_performance>
  69 + <step_performance_capturing_delay>1000</step_performance_capturing_delay>
  70 + <step_performance_capturing_size_limit>100</step_performance_capturing_size_limit>
  71 + <dependencies>
  72 + </dependencies>
  73 + <partitionschemas>
  74 + </partitionschemas>
  75 + <slaveservers>
  76 + </slaveservers>
  77 + <clusterschemas>
  78 + </clusterschemas>
  79 + <created_user>-</created_user>
  80 + <created_date>2021&#x2f;10&#x2f;27 13&#x3a;51&#x3a;08.960</created_date>
  81 + <modified_user>-</modified_user>
  82 + <modified_date>2021&#x2f;10&#x2f;27 13&#x3a;51&#x3a;08.960</modified_date>
  83 + <key_for_session_key>H4sIAAAAAAAAAAMAAAAAAAAAAAA&#x3d;</key_for_session_key>
  84 + <is_key_private>N</is_key_private>
  85 + </info>
  86 + <notepads>
  87 + <notepad>
  88 + <note>TODO&#xff1a;</note>
  89 + <xloc>105</xloc>
  90 + <yloc>283</yloc>
  91 + <width>50</width>
  92 + <heigth>26</heigth>
  93 + <fontname>YaHei Consolas Hybrid</fontname>
  94 + <fontsize>12</fontsize>
  95 + <fontbold>N</fontbold>
  96 + <fontitalic>N</fontitalic>
  97 + <fontcolorred>0</fontcolorred>
  98 + <fontcolorgreen>0</fontcolorgreen>
  99 + <fontcolorblue>0</fontcolorblue>
  100 + <backgroundcolorred>255</backgroundcolorred>
  101 + <backgroundcolorgreen>205</backgroundcolorgreen>
  102 + <backgroundcolorblue>112</backgroundcolorblue>
  103 + <bordercolorred>100</bordercolorred>
  104 + <bordercolorgreen>100</bordercolorgreen>
  105 + <bordercolorblue>100</bordercolorblue>
  106 + <drawshadow>Y</drawshadow>
  107 + </notepad>
  108 + </notepads>
  109 + <connection>
  110 + <name>192.168.168.1_jwgl_dw</name>
  111 + <server>192.168.168.1</server>
  112 + <type>ORACLE</type>
  113 + <access>Native</access>
  114 + <database>orcl</database>
  115 + <port>1521</port>
  116 + <username>jwgl_dw</username>
  117 + <password>Encrypted 2be98afc86aa7f2e4cb13b977d2adabcd</password>
  118 + <servername/>
  119 + <data_tablespace/>
  120 + <index_tablespace/>
  121 + <attributes>
  122 + <attribute><code>FORCE_IDENTIFIERS_TO_LOWERCASE</code><attribute>N</attribute></attribute>
  123 + <attribute><code>FORCE_IDENTIFIERS_TO_UPPERCASE</code><attribute>N</attribute></attribute>
  124 + <attribute><code>IS_CLUSTERED</code><attribute>N</attribute></attribute>
  125 + <attribute><code>PORT_NUMBER</code><attribute>1521</attribute></attribute>
  126 + <attribute><code>PRESERVE_RESERVED_WORD_CASE</code><attribute>N</attribute></attribute>
  127 + <attribute><code>QUOTE_ALL_FIELDS</code><attribute>N</attribute></attribute>
  128 + <attribute><code>SUPPORTS_BOOLEAN_DATA_TYPE</code><attribute>Y</attribute></attribute>
  129 + <attribute><code>SUPPORTS_TIMESTAMP_DATA_TYPE</code><attribute>Y</attribute></attribute>
  130 + <attribute><code>USE_POOLING</code><attribute>N</attribute></attribute>
  131 + </attributes>
  132 + </connection>
  133 + <connection>
  134 + <name>bus_control_variable</name>
  135 + <server>&#x24;&#x7b;v_db_ip&#x7d;</server>
  136 + <type>MYSQL</type>
  137 + <access>Native</access>
  138 + <database>&#x24;&#x7b;v_db_dname&#x7d;</database>
  139 + <port>3306</port>
  140 + <username>&#x24;&#x7b;v_db_uname&#x7d;</username>
  141 + <password>&#x24;&#x7b;v_db_pwd&#x7d;</password>
  142 + <servername/>
  143 + <data_tablespace/>
  144 + <index_tablespace/>
  145 + <attributes>
  146 + <attribute><code>EXTRA_OPTION_MYSQL.characterEncoding</code><attribute>utf8</attribute></attribute>
  147 + <attribute><code>EXTRA_OPTION_MYSQL.defaultFetchSize</code><attribute>500</attribute></attribute>
  148 + <attribute><code>EXTRA_OPTION_MYSQL.useCursorFetch</code><attribute>true</attribute></attribute>
  149 + <attribute><code>FORCE_IDENTIFIERS_TO_LOWERCASE</code><attribute>N</attribute></attribute>
  150 + <attribute><code>FORCE_IDENTIFIERS_TO_UPPERCASE</code><attribute>N</attribute></attribute>
  151 + <attribute><code>IS_CLUSTERED</code><attribute>N</attribute></attribute>
  152 + <attribute><code>PORT_NUMBER</code><attribute>3306</attribute></attribute>
  153 + <attribute><code>PRESERVE_RESERVED_WORD_CASE</code><attribute>N</attribute></attribute>
  154 + <attribute><code>QUOTE_ALL_FIELDS</code><attribute>N</attribute></attribute>
  155 + <attribute><code>STREAM_RESULTS</code><attribute>N</attribute></attribute>
  156 + <attribute><code>SUPPORTS_BOOLEAN_DATA_TYPE</code><attribute>Y</attribute></attribute>
  157 + <attribute><code>SUPPORTS_TIMESTAMP_DATA_TYPE</code><attribute>Y</attribute></attribute>
  158 + <attribute><code>USE_POOLING</code><attribute>N</attribute></attribute>
  159 + </attributes>
  160 + </connection>
  161 + <connection>
  162 + <name>bus_control_&#x516c;&#x53f8;_201</name>
  163 + <server>localhost</server>
  164 + <type>MYSQL</type>
  165 + <access>Native</access>
  166 + <database>control</database>
  167 + <port>3306</port>
  168 + <username>root</username>
  169 + <password>Encrypted </password>
  170 + <servername/>
  171 + <data_tablespace/>
  172 + <index_tablespace/>
  173 + <attributes>
  174 + <attribute><code>EXTRA_OPTION_MYSQL.defaultFetchSize</code><attribute>500</attribute></attribute>
  175 + <attribute><code>EXTRA_OPTION_MYSQL.useCursorFetch</code><attribute>true</attribute></attribute>
  176 + <attribute><code>FORCE_IDENTIFIERS_TO_LOWERCASE</code><attribute>N</attribute></attribute>
  177 + <attribute><code>FORCE_IDENTIFIERS_TO_UPPERCASE</code><attribute>N</attribute></attribute>
  178 + <attribute><code>IS_CLUSTERED</code><attribute>N</attribute></attribute>
  179 + <attribute><code>PORT_NUMBER</code><attribute>3306</attribute></attribute>
  180 + <attribute><code>PRESERVE_RESERVED_WORD_CASE</code><attribute>N</attribute></attribute>
  181 + <attribute><code>QUOTE_ALL_FIELDS</code><attribute>N</attribute></attribute>
  182 + <attribute><code>STREAM_RESULTS</code><attribute>N</attribute></attribute>
  183 + <attribute><code>SUPPORTS_BOOLEAN_DATA_TYPE</code><attribute>Y</attribute></attribute>
  184 + <attribute><code>SUPPORTS_TIMESTAMP_DATA_TYPE</code><attribute>Y</attribute></attribute>
  185 + <attribute><code>USE_POOLING</code><attribute>N</attribute></attribute>
  186 + </attributes>
  187 + </connection>
  188 + <connection>
  189 + <name>bus_control_&#x672c;&#x673a;</name>
  190 + <server>localhost</server>
  191 + <type>MYSQL</type>
  192 + <access>Native</access>
  193 + <database>control</database>
  194 + <port>3306</port>
  195 + <username>root</username>
  196 + <password>Encrypted </password>
  197 + <servername/>
  198 + <data_tablespace/>
  199 + <index_tablespace/>
  200 + <attributes>
  201 + <attribute><code>EXTRA_OPTION_MYSQL.defaultFetchSize</code><attribute>500</attribute></attribute>
  202 + <attribute><code>EXTRA_OPTION_MYSQL.useCursorFetch</code><attribute>true</attribute></attribute>
  203 + <attribute><code>FORCE_IDENTIFIERS_TO_LOWERCASE</code><attribute>N</attribute></attribute>
  204 + <attribute><code>FORCE_IDENTIFIERS_TO_UPPERCASE</code><attribute>N</attribute></attribute>
  205 + <attribute><code>IS_CLUSTERED</code><attribute>N</attribute></attribute>
  206 + <attribute><code>PORT_NUMBER</code><attribute>3306</attribute></attribute>
  207 + <attribute><code>PRESERVE_RESERVED_WORD_CASE</code><attribute>N</attribute></attribute>
  208 + <attribute><code>QUOTE_ALL_FIELDS</code><attribute>N</attribute></attribute>
  209 + <attribute><code>STREAM_RESULTS</code><attribute>Y</attribute></attribute>
  210 + <attribute><code>SUPPORTS_BOOLEAN_DATA_TYPE</code><attribute>Y</attribute></attribute>
  211 + <attribute><code>SUPPORTS_TIMESTAMP_DATA_TYPE</code><attribute>Y</attribute></attribute>
  212 + <attribute><code>USE_POOLING</code><attribute>N</attribute></attribute>
  213 + </attributes>
  214 + </connection>
  215 + <connection>
  216 + <name>JGJW_VM</name>
  217 + <server>192.168.198.240</server>
  218 + <type>ORACLE</type>
  219 + <access>Native</access>
  220 + <database>orcl</database>
  221 + <port>1521</port>
  222 + <username>jwgl</username>
  223 + <password>Encrypted 2be98afc86aa7f2e4cb79ce10d485a8d6</password>
  224 + <servername/>
  225 + <data_tablespace/>
  226 + <index_tablespace/>
  227 + <attributes>
  228 + <attribute><code>FORCE_IDENTIFIERS_TO_LOWERCASE</code><attribute>N</attribute></attribute>
  229 + <attribute><code>FORCE_IDENTIFIERS_TO_UPPERCASE</code><attribute>N</attribute></attribute>
  230 + <attribute><code>IS_CLUSTERED</code><attribute>N</attribute></attribute>
  231 + <attribute><code>PORT_NUMBER</code><attribute>1521</attribute></attribute>
  232 + <attribute><code>PRESERVE_RESERVED_WORD_CASE</code><attribute>N</attribute></attribute>
  233 + <attribute><code>QUOTE_ALL_FIELDS</code><attribute>N</attribute></attribute>
  234 + <attribute><code>SUPPORTS_BOOLEAN_DATA_TYPE</code><attribute>Y</attribute></attribute>
  235 + <attribute><code>SUPPORTS_TIMESTAMP_DATA_TYPE</code><attribute>Y</attribute></attribute>
  236 + <attribute><code>USE_POOLING</code><attribute>N</attribute></attribute>
  237 + </attributes>
  238 + </connection>
  239 + <connection>
  240 + <name>NHJW_VM</name>
  241 + <server>192.168.198.240</server>
  242 + <type>ORACLE</type>
  243 + <access>Native</access>
  244 + <database>orcl</database>
  245 + <port>1521</port>
  246 + <username>nhjw</username>
  247 + <password>Encrypted 2be98afc86aa7f2e4cb79ce10d09aa5cd</password>
  248 + <servername/>
  249 + <data_tablespace/>
  250 + <index_tablespace/>
  251 + <attributes>
  252 + <attribute><code>FORCE_IDENTIFIERS_TO_LOWERCASE</code><attribute>N</attribute></attribute>
  253 + <attribute><code>FORCE_IDENTIFIERS_TO_UPPERCASE</code><attribute>N</attribute></attribute>
  254 + <attribute><code>IS_CLUSTERED</code><attribute>N</attribute></attribute>
  255 + <attribute><code>PORT_NUMBER</code><attribute>1521</attribute></attribute>
  256 + <attribute><code>PRESERVE_RESERVED_WORD_CASE</code><attribute>N</attribute></attribute>
  257 + <attribute><code>QUOTE_ALL_FIELDS</code><attribute>N</attribute></attribute>
  258 + <attribute><code>SUPPORTS_BOOLEAN_DATA_TYPE</code><attribute>Y</attribute></attribute>
  259 + <attribute><code>SUPPORTS_TIMESTAMP_DATA_TYPE</code><attribute>Y</attribute></attribute>
  260 + <attribute><code>USE_POOLING</code><attribute>N</attribute></attribute>
  261 + </attributes>
  262 + </connection>
  263 + <connection>
  264 + <name>PDGJ_VM</name>
  265 + <server>192.168.198.240</server>
  266 + <type>ORACLE</type>
  267 + <access>Native</access>
  268 + <database>orcl</database>
  269 + <port>1521</port>
  270 + <username>pdgj</username>
  271 + <password>Encrypted 2be98afc86aa7f2e4cb79ce10ce96a8d0</password>
  272 + <servername/>
  273 + <data_tablespace/>
  274 + <index_tablespace/>
  275 + <attributes>
  276 + <attribute><code>FORCE_IDENTIFIERS_TO_LOWERCASE</code><attribute>N</attribute></attribute>
  277 + <attribute><code>FORCE_IDENTIFIERS_TO_UPPERCASE</code><attribute>N</attribute></attribute>
  278 + <attribute><code>IS_CLUSTERED</code><attribute>N</attribute></attribute>
  279 + <attribute><code>PORT_NUMBER</code><attribute>1521</attribute></attribute>
  280 + <attribute><code>PRESERVE_RESERVED_WORD_CASE</code><attribute>N</attribute></attribute>
  281 + <attribute><code>QUOTE_ALL_FIELDS</code><attribute>N</attribute></attribute>
  282 + <attribute><code>SUPPORTS_BOOLEAN_DATA_TYPE</code><attribute>Y</attribute></attribute>
  283 + <attribute><code>SUPPORTS_TIMESTAMP_DATA_TYPE</code><attribute>Y</attribute></attribute>
  284 + <attribute><code>USE_POOLING</code><attribute>N</attribute></attribute>
  285 + </attributes>
  286 + </connection>
  287 + <connection>
  288 + <name>repair_dw_mysql_jndi</name>
  289 + <server/>
  290 + <type>MYSQL</type>
  291 + <access>JNDI</access>
  292 + <database>repair_dw_mysql</database>
  293 + <port>1521</port>
  294 + <username/>
  295 + <password>Encrypted </password>
  296 + <servername/>
  297 + <data_tablespace/>
  298 + <index_tablespace/>
  299 + <attributes>
  300 + <attribute><code>EXTRA_OPTION_MYSQL.defaultFetchSize</code><attribute>500</attribute></attribute>
  301 + <attribute><code>EXTRA_OPTION_MYSQL.useCursorFetch</code><attribute>true</attribute></attribute>
  302 + <attribute><code>FORCE_IDENTIFIERS_TO_LOWERCASE</code><attribute>N</attribute></attribute>
  303 + <attribute><code>FORCE_IDENTIFIERS_TO_UPPERCASE</code><attribute>N</attribute></attribute>
  304 + <attribute><code>IS_CLUSTERED</code><attribute>N</attribute></attribute>
  305 + <attribute><code>PORT_NUMBER</code><attribute>1521</attribute></attribute>
  306 + <attribute><code>PRESERVE_RESERVED_WORD_CASE</code><attribute>N</attribute></attribute>
  307 + <attribute><code>QUOTE_ALL_FIELDS</code><attribute>N</attribute></attribute>
  308 + <attribute><code>STREAM_RESULTS</code><attribute>Y</attribute></attribute>
  309 + <attribute><code>SUPPORTS_BOOLEAN_DATA_TYPE</code><attribute>Y</attribute></attribute>
  310 + <attribute><code>SUPPORTS_TIMESTAMP_DATA_TYPE</code><attribute>Y</attribute></attribute>
  311 + <attribute><code>USE_POOLING</code><attribute>N</attribute></attribute>
  312 + </attributes>
  313 + </connection>
  314 + <connection>
  315 + <name>repair_dw&#xff08;&#x672c;&#x673a;&#xff09;</name>
  316 + <server>localhost</server>
  317 + <type>MYSQL</type>
  318 + <access>Native</access>
  319 + <database>ruoyi-vue-3.5</database>
  320 + <port>3306</port>
  321 + <username>root</username>
  322 + <password>Encrypted </password>
  323 + <servername/>
  324 + <data_tablespace/>
  325 + <index_tablespace/>
  326 + <attributes>
  327 + <attribute><code>EXTRA_OPTION_MYSQL.defaultFetchSize</code><attribute>500</attribute></attribute>
  328 + <attribute><code>EXTRA_OPTION_MYSQL.useCursorFetch</code><attribute>true</attribute></attribute>
  329 + <attribute><code>FORCE_IDENTIFIERS_TO_LOWERCASE</code><attribute>N</attribute></attribute>
  330 + <attribute><code>FORCE_IDENTIFIERS_TO_UPPERCASE</code><attribute>N</attribute></attribute>
  331 + <attribute><code>IS_CLUSTERED</code><attribute>N</attribute></attribute>
  332 + <attribute><code>PORT_NUMBER</code><attribute>3306</attribute></attribute>
  333 + <attribute><code>PRESERVE_RESERVED_WORD_CASE</code><attribute>N</attribute></attribute>
  334 + <attribute><code>QUOTE_ALL_FIELDS</code><attribute>N</attribute></attribute>
  335 + <attribute><code>STREAM_RESULTS</code><attribute>Y</attribute></attribute>
  336 + <attribute><code>SUPPORTS_BOOLEAN_DATA_TYPE</code><attribute>Y</attribute></attribute>
  337 + <attribute><code>SUPPORTS_TIMESTAMP_DATA_TYPE</code><attribute>Y</attribute></attribute>
  338 + <attribute><code>USE_POOLING</code><attribute>N</attribute></attribute>
  339 + </attributes>
  340 + </connection>
  341 + <connection>
  342 + <name>repair_real_h2</name>
  343 + <server/>
  344 + <type>H2</type>
  345 + <access>JNDI</access>
  346 + <database>repair_real_h2</database>
  347 + <port>1521</port>
  348 + <username/>
  349 + <password>Encrypted </password>
  350 + <servername/>
  351 + <data_tablespace/>
  352 + <index_tablespace/>
  353 + <attributes>
  354 + <attribute><code>FORCE_IDENTIFIERS_TO_LOWERCASE</code><attribute>N</attribute></attribute>
  355 + <attribute><code>FORCE_IDENTIFIERS_TO_UPPERCASE</code><attribute>N</attribute></attribute>
  356 + <attribute><code>IS_CLUSTERED</code><attribute>N</attribute></attribute>
  357 + <attribute><code>PORT_NUMBER</code><attribute>1521</attribute></attribute>
  358 + <attribute><code>PRESERVE_RESERVED_WORD_CASE</code><attribute>N</attribute></attribute>
  359 + <attribute><code>QUOTE_ALL_FIELDS</code><attribute>N</attribute></attribute>
  360 + <attribute><code>SUPPORTS_BOOLEAN_DATA_TYPE</code><attribute>Y</attribute></attribute>
  361 + <attribute><code>SUPPORTS_TIMESTAMP_DATA_TYPE</code><attribute>Y</attribute></attribute>
  362 + <attribute><code>USE_POOLING</code><attribute>N</attribute></attribute>
  363 + </attributes>
  364 + </connection>
  365 + <connection>
  366 + <name>SNJW_VM</name>
  367 + <server>192.168.198.240</server>
  368 + <type>ORACLE</type>
  369 + <access>Native</access>
  370 + <database>orcl</database>
  371 + <port>1521</port>
  372 + <username>snjw</username>
  373 + <password>Encrypted 2be98afc86aa7f2e4cb79ce10cd9ca5cd</password>
  374 + <servername/>
  375 + <data_tablespace/>
  376 + <index_tablespace/>
  377 + <attributes>
  378 + <attribute><code>FORCE_IDENTIFIERS_TO_LOWERCASE</code><attribute>N</attribute></attribute>
  379 + <attribute><code>FORCE_IDENTIFIERS_TO_UPPERCASE</code><attribute>N</attribute></attribute>
  380 + <attribute><code>IS_CLUSTERED</code><attribute>N</attribute></attribute>
  381 + <attribute><code>PORT_NUMBER</code><attribute>1521</attribute></attribute>
  382 + <attribute><code>PRESERVE_RESERVED_WORD_CASE</code><attribute>N</attribute></attribute>
  383 + <attribute><code>QUOTE_ALL_FIELDS</code><attribute>N</attribute></attribute>
  384 + <attribute><code>SUPPORTS_BOOLEAN_DATA_TYPE</code><attribute>Y</attribute></attribute>
  385 + <attribute><code>SUPPORTS_TIMESTAMP_DATA_TYPE</code><attribute>Y</attribute></attribute>
  386 + <attribute><code>USE_POOLING</code><attribute>N</attribute></attribute>
  387 + </attributes>
  388 + </connection>
  389 + <connection>
  390 + <name>test_control&#xff08;&#x672c;&#x673a;&#xff09;</name>
  391 + <server>127.0.0.1</server>
  392 + <type>MYSQL</type>
  393 + <access>Native</access>
  394 + <database>test_control</database>
  395 + <port>3306</port>
  396 + <username>root</username>
  397 + <password>Encrypted </password>
  398 + <servername/>
  399 + <data_tablespace/>
  400 + <index_tablespace/>
  401 + <attributes>
  402 + <attribute><code>EXTRA_OPTION_MYSQL.defaultFetchSize</code><attribute>500</attribute></attribute>
  403 + <attribute><code>EXTRA_OPTION_MYSQL.useCursorFetch</code><attribute>true</attribute></attribute>
  404 + <attribute><code>FORCE_IDENTIFIERS_TO_LOWERCASE</code><attribute>N</attribute></attribute>
  405 + <attribute><code>FORCE_IDENTIFIERS_TO_UPPERCASE</code><attribute>N</attribute></attribute>
  406 + <attribute><code>IS_CLUSTERED</code><attribute>N</attribute></attribute>
  407 + <attribute><code>PORT_NUMBER</code><attribute>3306</attribute></attribute>
  408 + <attribute><code>PRESERVE_RESERVED_WORD_CASE</code><attribute>N</attribute></attribute>
  409 + <attribute><code>QUOTE_ALL_FIELDS</code><attribute>N</attribute></attribute>
  410 + <attribute><code>STREAM_RESULTS</code><attribute>Y</attribute></attribute>
  411 + <attribute><code>SUPPORTS_BOOLEAN_DATA_TYPE</code><attribute>Y</attribute></attribute>
  412 + <attribute><code>SUPPORTS_TIMESTAMP_DATA_TYPE</code><attribute>Y</attribute></attribute>
  413 + <attribute><code>USE_POOLING</code><attribute>N</attribute></attribute>
  414 + </attributes>
  415 + </connection>
  416 + <connection>
  417 + <name>xlab_mysql_youle</name>
  418 + <server>101.231.124.8</server>
  419 + <type>MYSQL</type>
  420 + <access>Native</access>
  421 + <database>xlab_youle</database>
  422 + <port>45687</port>
  423 + <username>xlab-youle</username>
  424 + <password>Encrypted 2be98afc86aa78a88aa1be369d187a3df</password>
  425 + <servername/>
  426 + <data_tablespace/>
  427 + <index_tablespace/>
  428 + <attributes>
  429 + <attribute><code>EXTRA_OPTION_MYSQL.defaultFetchSize</code><attribute>500</attribute></attribute>
  430 + <attribute><code>EXTRA_OPTION_MYSQL.useCursorFetch</code><attribute>true</attribute></attribute>
  431 + <attribute><code>FORCE_IDENTIFIERS_TO_LOWERCASE</code><attribute>N</attribute></attribute>
  432 + <attribute><code>FORCE_IDENTIFIERS_TO_UPPERCASE</code><attribute>N</attribute></attribute>
  433 + <attribute><code>IS_CLUSTERED</code><attribute>N</attribute></attribute>
  434 + <attribute><code>PORT_NUMBER</code><attribute>45687</attribute></attribute>
  435 + <attribute><code>PRESERVE_RESERVED_WORD_CASE</code><attribute>N</attribute></attribute>
  436 + <attribute><code>QUOTE_ALL_FIELDS</code><attribute>N</attribute></attribute>
  437 + <attribute><code>STREAM_RESULTS</code><attribute>Y</attribute></attribute>
  438 + <attribute><code>SUPPORTS_BOOLEAN_DATA_TYPE</code><attribute>N</attribute></attribute>
  439 + <attribute><code>SUPPORTS_TIMESTAMP_DATA_TYPE</code><attribute>N</attribute></attribute>
  440 + <attribute><code>USE_POOLING</code><attribute>N</attribute></attribute>
  441 + </attributes>
  442 + </connection>
  443 + <connection>
  444 + <name>xlab_mysql_youle&#xff08;&#x672c;&#x673a;&#xff09;</name>
  445 + <server>localhost</server>
  446 + <type>MYSQL</type>
  447 + <access>Native</access>
  448 + <database>xlab_youle</database>
  449 + <port>3306</port>
  450 + <username>root</username>
  451 + <password>Encrypted </password>
  452 + <servername/>
  453 + <data_tablespace/>
  454 + <index_tablespace/>
  455 + <attributes>
  456 + <attribute><code>EXTRA_OPTION_MYSQL.defaultFetchSize</code><attribute>500</attribute></attribute>
  457 + <attribute><code>EXTRA_OPTION_MYSQL.useCursorFetch</code><attribute>true</attribute></attribute>
  458 + <attribute><code>FORCE_IDENTIFIERS_TO_LOWERCASE</code><attribute>N</attribute></attribute>
  459 + <attribute><code>FORCE_IDENTIFIERS_TO_UPPERCASE</code><attribute>N</attribute></attribute>
  460 + <attribute><code>IS_CLUSTERED</code><attribute>N</attribute></attribute>
  461 + <attribute><code>PORT_NUMBER</code><attribute>3306</attribute></attribute>
  462 + <attribute><code>PRESERVE_RESERVED_WORD_CASE</code><attribute>N</attribute></attribute>
  463 + <attribute><code>QUOTE_ALL_FIELDS</code><attribute>N</attribute></attribute>
  464 + <attribute><code>STREAM_RESULTS</code><attribute>Y</attribute></attribute>
  465 + <attribute><code>SUPPORTS_BOOLEAN_DATA_TYPE</code><attribute>N</attribute></attribute>
  466 + <attribute><code>SUPPORTS_TIMESTAMP_DATA_TYPE</code><attribute>N</attribute></attribute>
  467 + <attribute><code>USE_POOLING</code><attribute>N</attribute></attribute>
  468 + </attributes>
  469 + </connection>
  470 + <connection>
  471 + <name>xlab_youle</name>
  472 + <server/>
  473 + <type>MYSQL</type>
  474 + <access>JNDI</access>
  475 + <database>xlab_youle</database>
  476 + <port>1521</port>
  477 + <username/>
  478 + <password>Encrypted </password>
  479 + <servername/>
  480 + <data_tablespace/>
  481 + <index_tablespace/>
  482 + <attributes>
  483 + <attribute><code>FORCE_IDENTIFIERS_TO_LOWERCASE</code><attribute>N</attribute></attribute>
  484 + <attribute><code>FORCE_IDENTIFIERS_TO_UPPERCASE</code><attribute>N</attribute></attribute>
  485 + <attribute><code>IS_CLUSTERED</code><attribute>N</attribute></attribute>
  486 + <attribute><code>PORT_NUMBER</code><attribute>1521</attribute></attribute>
  487 + <attribute><code>PRESERVE_RESERVED_WORD_CASE</code><attribute>N</attribute></attribute>
  488 + <attribute><code>QUOTE_ALL_FIELDS</code><attribute>N</attribute></attribute>
  489 + <attribute><code>STREAM_RESULTS</code><attribute>Y</attribute></attribute>
  490 + <attribute><code>SUPPORTS_BOOLEAN_DATA_TYPE</code><attribute>Y</attribute></attribute>
  491 + <attribute><code>SUPPORTS_TIMESTAMP_DATA_TYPE</code><attribute>Y</attribute></attribute>
  492 + <attribute><code>USE_POOLING</code><attribute>N</attribute></attribute>
  493 + </attributes>
  494 + </connection>
  495 + <connection>
  496 + <name>YGJW_VM</name>
  497 + <server>192.168.198.240</server>
  498 + <type>ORACLE</type>
  499 + <access>Native</access>
  500 + <database>orcl</database>
  501 + <port>1521</port>
  502 + <username>ygjw</username>
  503 + <password>Encrypted 2be98afc86aa7f2e4cb79ce10c795a5cd</password>
  504 + <servername/>
  505 + <data_tablespace/>
  506 + <index_tablespace/>
  507 + <attributes>
  508 + <attribute><code>FORCE_IDENTIFIERS_TO_LOWERCASE</code><attribute>N</attribute></attribute>
  509 + <attribute><code>FORCE_IDENTIFIERS_TO_UPPERCASE</code><attribute>N</attribute></attribute>
  510 + <attribute><code>IS_CLUSTERED</code><attribute>N</attribute></attribute>
  511 + <attribute><code>PORT_NUMBER</code><attribute>1521</attribute></attribute>
  512 + <attribute><code>PRESERVE_RESERVED_WORD_CASE</code><attribute>N</attribute></attribute>
  513 + <attribute><code>QUOTE_ALL_FIELDS</code><attribute>N</attribute></attribute>
  514 + <attribute><code>SUPPORTS_BOOLEAN_DATA_TYPE</code><attribute>Y</attribute></attribute>
  515 + <attribute><code>SUPPORTS_TIMESTAMP_DATA_TYPE</code><attribute>Y</attribute></attribute>
  516 + <attribute><code>USE_POOLING</code><attribute>N</attribute></attribute>
  517 + </attributes>
  518 + </connection>
  519 + <connection>
  520 + <name>&#x516c;&#x53f8;jgjw</name>
  521 + <server>192.168.168.1</server>
  522 + <type>ORACLE</type>
  523 + <access>Native</access>
  524 + <database>orcl</database>
  525 + <port>1521</port>
  526 + <username>jwgl</username>
  527 + <password>Encrypted 2be98afc86aa7f2e4cb79ce10d485a8d6</password>
  528 + <servername/>
  529 + <data_tablespace/>
  530 + <index_tablespace/>
  531 + <attributes>
  532 + <attribute><code>FORCE_IDENTIFIERS_TO_LOWERCASE</code><attribute>N</attribute></attribute>
  533 + <attribute><code>FORCE_IDENTIFIERS_TO_UPPERCASE</code><attribute>N</attribute></attribute>
  534 + <attribute><code>IS_CLUSTERED</code><attribute>N</attribute></attribute>
  535 + <attribute><code>PORT_NUMBER</code><attribute>1521</attribute></attribute>
  536 + <attribute><code>PRESERVE_RESERVED_WORD_CASE</code><attribute>N</attribute></attribute>
  537 + <attribute><code>QUOTE_ALL_FIELDS</code><attribute>N</attribute></attribute>
  538 + <attribute><code>SUPPORTS_BOOLEAN_DATA_TYPE</code><attribute>Y</attribute></attribute>
  539 + <attribute><code>SUPPORTS_TIMESTAMP_DATA_TYPE</code><attribute>Y</attribute></attribute>
  540 + <attribute><code>USE_POOLING</code><attribute>N</attribute></attribute>
  541 + </attributes>
  542 + </connection>
  543 + <connection>
  544 + <name>&#x516c;&#x53f8;snjw</name>
  545 + <server>192.168.168.1</server>
  546 + <type>ORACLE</type>
  547 + <access>Native</access>
  548 + <database>orcl</database>
  549 + <port>1521</port>
  550 + <username>snjw</username>
  551 + <password>Encrypted 2be98afc86aa7f2e4cb79ce10cd9ca5cd</password>
  552 + <servername/>
  553 + <data_tablespace/>
  554 + <index_tablespace/>
  555 + <attributes>
  556 + <attribute><code>FORCE_IDENTIFIERS_TO_LOWERCASE</code><attribute>N</attribute></attribute>
  557 + <attribute><code>FORCE_IDENTIFIERS_TO_UPPERCASE</code><attribute>N</attribute></attribute>
  558 + <attribute><code>IS_CLUSTERED</code><attribute>N</attribute></attribute>
  559 + <attribute><code>PORT_NUMBER</code><attribute>1521</attribute></attribute>
  560 + <attribute><code>PRESERVE_RESERVED_WORD_CASE</code><attribute>N</attribute></attribute>
  561 + <attribute><code>QUOTE_ALL_FIELDS</code><attribute>N</attribute></attribute>
  562 + <attribute><code>SUPPORTS_BOOLEAN_DATA_TYPE</code><attribute>Y</attribute></attribute>
  563 + <attribute><code>SUPPORTS_TIMESTAMP_DATA_TYPE</code><attribute>Y</attribute></attribute>
  564 + <attribute><code>USE_POOLING</code><attribute>N</attribute></attribute>
  565 + </attributes>
  566 + </connection>
  567 + <connection>
  568 + <name>&#x516c;&#x53f8;ygjw</name>
  569 + <server>192.168.168.1</server>
  570 + <type>ORACLE</type>
  571 + <access>Native</access>
  572 + <database>orcl</database>
  573 + <port>1521</port>
  574 + <username>ygjw</username>
  575 + <password>Encrypted 2be98afc86aa7f2e4cb79ce10c795a5cd</password>
  576 + <servername/>
  577 + <data_tablespace/>
  578 + <index_tablespace/>
  579 + <attributes>
  580 + <attribute><code>FORCE_IDENTIFIERS_TO_LOWERCASE</code><attribute>N</attribute></attribute>
  581 + <attribute><code>FORCE_IDENTIFIERS_TO_UPPERCASE</code><attribute>N</attribute></attribute>
  582 + <attribute><code>IS_CLUSTERED</code><attribute>N</attribute></attribute>
  583 + <attribute><code>PORT_NUMBER</code><attribute>1521</attribute></attribute>
  584 + <attribute><code>PRESERVE_RESERVED_WORD_CASE</code><attribute>N</attribute></attribute>
  585 + <attribute><code>QUOTE_ALL_FIELDS</code><attribute>N</attribute></attribute>
  586 + <attribute><code>SUPPORTS_BOOLEAN_DATA_TYPE</code><attribute>Y</attribute></attribute>
  587 + <attribute><code>SUPPORTS_TIMESTAMP_DATA_TYPE</code><attribute>Y</attribute></attribute>
  588 + <attribute><code>USE_POOLING</code><attribute>N</attribute></attribute>
  589 + </attributes>
  590 + </connection>
  591 + <order>
  592 + <hop> <from>http&#x63a5;&#x53e3;&#x8c03;&#x7528;</from><to>json&#x89e3;&#x6790;&#x83b7;&#x53d6;&#x6bcf;&#x8f86;&#x8f66;&#x7684;json&#x4fe1;&#x606f;</to><enabled>Y</enabled> </hop>
  593 + <hop> <from>json&#x89e3;&#x6790;&#x83b7;&#x53d6;&#x6bcf;&#x8f86;&#x8f66;&#x7684;json&#x4fe1;&#x606f;</from><to>json&#x89e3;&#x6790;&#x6bcf;&#x8f86;&#x8f66;</to><enabled>Y</enabled> </hop>
  594 + <hop> <from>&#x83b7;&#x53d6;&#x53c2;&#x6570;</from><to>http&#x63a5;&#x53e3;&#x8c03;&#x7528;</to><enabled>Y</enabled> </hop>
  595 + <hop> <from>&#x83b7;&#x53d6;&#x53c2;&#x6570;</from><to>&#x5199;&#x65e5;&#x5fd7;</to><enabled>Y</enabled> </hop>
  596 + </order>
  597 + <step>
  598 + <name>http&#x63a5;&#x53e3;&#x8c03;&#x7528;</name>
  599 + <type>HTTP</type>
  600 + <description/>
  601 + <distribute>Y</distribute>
  602 + <custom_distribution/>
  603 + <copies>1</copies>
  604 + <partitioning>
  605 + <method>none</method>
  606 + <schema_name/>
  607 + </partitioning>
  608 + <url/>
  609 + <urlInField>Y</urlInField>
  610 + <urlField>url</urlField>
  611 + <encoding>UTF-8</encoding>
  612 + <httpLogin/>
  613 + <httpPassword>Encrypted </httpPassword>
  614 + <proxyHost/>
  615 + <proxyPort/>
  616 + <socketTimeout>-1</socketTimeout>
  617 + <connectionTimeout>-1</connectionTimeout>
  618 + <closeIdleConnectionsTime>-1</closeIdleConnectionsTime>
  619 + <lookup>
  620 + <arg>
  621 + <name>password</name>
  622 + <parameter>password</parameter>
  623 + </arg>
  624 + </lookup>
  625 + <result>
  626 + <name>result</name>
  627 + <code/>
  628 + <response_time/>
  629 + </result>
  630 + <cluster_schema/>
  631 + <remotesteps> <input> </input> <output> </output> </remotesteps> <GUI>
  632 + <xloc>261</xloc>
  633 + <yloc>73</yloc>
  634 + <draw>Y</draw>
  635 + </GUI>
  636 + </step>
  637 +
  638 + <step>
  639 + <name>json&#x89e3;&#x6790;&#x6bcf;&#x8f86;&#x8f66;</name>
  640 + <type>JsonInput</type>
  641 + <description/>
  642 + <distribute>Y</distribute>
  643 + <custom_distribution/>
  644 + <copies>1</copies>
  645 + <partitioning>
  646 + <method>none</method>
  647 + <schema_name/>
  648 + </partitioning>
  649 + <include>N</include>
  650 + <include_field/>
  651 + <rownum>N</rownum>
  652 + <addresultfile>N</addresultfile>
  653 + <readurl>N</readurl>
  654 + <IsIgnoreEmptyFile>N</IsIgnoreEmptyFile>
  655 + <doNotFailIfNoFile>Y</doNotFailIfNoFile>
  656 + <ignoreMissingPath>Y</ignoreMissingPath>
  657 + <rownum_field/>
  658 + <file>
  659 + <name/>
  660 + <filemask/>
  661 + <exclude_filemask/>
  662 + <file_required>N</file_required>
  663 + <include_subfolders>N</include_subfolders>
  664 + </file>
  665 + <fields>
  666 + <field>
  667 + <name>&#x8f66;&#x8f86;&#x81ea;&#x7f16;&#x53f7;</name>
  668 + <path>&#x24;.car_code</path>
  669 + <type>String</type>
  670 + <format/>
  671 + <currency/>
  672 + <decimal/>
  673 + <group/>
  674 + <length>-1</length>
  675 + <precision>-1</precision>
  676 + <trim_type>both</trim_type>
  677 + <repeat>N</repeat>
  678 + </field>
  679 + <field>
  680 + <name>&#x516c;&#x53f8;&#x540d;&#x79f0;</name>
  681 + <path>&#x24;.company</path>
  682 + <type>String</type>
  683 + <format/>
  684 + <currency/>
  685 + <decimal/>
  686 + <group/>
  687 + <length>-1</length>
  688 + <precision>-1</precision>
  689 + <trim_type>both</trim_type>
  690 + <repeat>N</repeat>
  691 + </field>
  692 + <field>
  693 + <name>&#x5206;&#x516c;&#x53f8;&#x540d;&#x79f0;</name>
  694 + <path>&#x24;.branch_company</path>
  695 + <type>String</type>
  696 + <format/>
  697 + <currency/>
  698 + <decimal/>
  699 + <group/>
  700 + <length>-1</length>
  701 + <precision>-1</precision>
  702 + <trim_type>both</trim_type>
  703 + <repeat>N</repeat>
  704 + </field>
  705 + <field>
  706 + <name>&#x8f66;&#x8f86;VIN&#x53f7;</name>
  707 + <path>&#x24;.vin_code</path>
  708 + <type>String</type>
  709 + <format/>
  710 + <currency/>
  711 + <decimal/>
  712 + <group/>
  713 + <length>-1</length>
  714 + <precision>-1</precision>
  715 + <trim_type>both</trim_type>
  716 + <repeat>N</repeat>
  717 + </field>
  718 + <field>
  719 + <name>&#x52a8;&#x529b;&#x7c7b;&#x578b;</name>
  720 + <path>&#x24;.car_energy_type</path>
  721 + <type>String</type>
  722 + <format/>
  723 + <currency/>
  724 + <decimal/>
  725 + <group/>
  726 + <length>-1</length>
  727 + <precision>-1</precision>
  728 + <trim_type>both</trim_type>
  729 + <repeat>N</repeat>
  730 + </field>
  731 + <field>
  732 + <name>&#x8f66;&#x8eab;&#x957f;&#x5ea6;</name>
  733 + <path>&#x24;.car_long</path>
  734 + <type>String</type>
  735 + <format/>
  736 + <currency/>
  737 + <decimal/>
  738 + <group/>
  739 + <length>-1</length>
  740 + <precision>-1</precision>
  741 + <trim_type>both</trim_type>
  742 + <repeat>N</repeat>
  743 + </field>
  744 + <field>
  745 + <name>&#x6295;&#x8fd0;&#x65e5;&#x671f;</name>
  746 + <path>&#x24;.real_use_date</path>
  747 + <type>String</type>
  748 + <format/>
  749 + <currency/>
  750 + <decimal/>
  751 + <group/>
  752 + <length>-1</length>
  753 + <precision>-1</precision>
  754 + <trim_type>both</trim_type>
  755 + <repeat>N</repeat>
  756 + </field>
  757 + </fields>
  758 + <limit>0</limit>
  759 + <IsInFields>Y</IsInFields>
  760 + <IsAFile>N</IsAFile>
  761 + <valueField>json_str</valueField>
  762 + <shortFileFieldName/>
  763 + <pathFieldName/>
  764 + <hiddenFieldName/>
  765 + <lastModificationTimeFieldName/>
  766 + <uriNameFieldName/>
  767 + <rootUriNameFieldName/>
  768 + <extensionFieldName/>
  769 + <sizeFieldName/>
  770 + <cluster_schema/>
  771 + <remotesteps> <input> </input> <output> </output> </remotesteps> <GUI>
  772 + <xloc>450</xloc>
  773 + <yloc>181</yloc>
  774 + <draw>Y</draw>
  775 + </GUI>
  776 + </step>
  777 +
  778 + <step>
  779 + <name>json&#x89e3;&#x6790;&#x83b7;&#x53d6;&#x6bcf;&#x8f86;&#x8f66;&#x7684;json&#x4fe1;&#x606f;</name>
  780 + <type>JsonInput</type>
  781 + <description/>
  782 + <distribute>Y</distribute>
  783 + <custom_distribution/>
  784 + <copies>1</copies>
  785 + <partitioning>
  786 + <method>none</method>
  787 + <schema_name/>
  788 + </partitioning>
  789 + <include>N</include>
  790 + <include_field/>
  791 + <rownum>N</rownum>
  792 + <addresultfile>N</addresultfile>
  793 + <readurl>N</readurl>
  794 + <IsIgnoreEmptyFile>N</IsIgnoreEmptyFile>
  795 + <doNotFailIfNoFile>Y</doNotFailIfNoFile>
  796 + <ignoreMissingPath>Y</ignoreMissingPath>
  797 + <rownum_field/>
  798 + <file>
  799 + <name/>
  800 + <filemask/>
  801 + <exclude_filemask/>
  802 + <file_required>N</file_required>
  803 + <include_subfolders>N</include_subfolders>
  804 + </file>
  805 + <fields>
  806 + <field>
  807 + <name>json_str</name>
  808 + <path>&#x24;.&#x2a;</path>
  809 + <type>String</type>
  810 + <format/>
  811 + <currency/>
  812 + <decimal/>
  813 + <group/>
  814 + <length>-1</length>
  815 + <precision>-1</precision>
  816 + <trim_type>both</trim_type>
  817 + <repeat>N</repeat>
  818 + </field>
  819 + </fields>
  820 + <limit>0</limit>
  821 + <IsInFields>Y</IsInFields>
  822 + <IsAFile>N</IsAFile>
  823 + <valueField>result</valueField>
  824 + <shortFileFieldName/>
  825 + <pathFieldName/>
  826 + <hiddenFieldName/>
  827 + <lastModificationTimeFieldName/>
  828 + <uriNameFieldName/>
  829 + <rootUriNameFieldName/>
  830 + <extensionFieldName/>
  831 + <sizeFieldName/>
  832 + <cluster_schema/>
  833 + <remotesteps> <input> </input> <output> </output> </remotesteps> <GUI>
  834 + <xloc>265</xloc>
  835 + <yloc>181</yloc>
  836 + <draw>Y</draw>
  837 + </GUI>
  838 + </step>
  839 +
  840 + <step>
  841 + <name>&#x5199;&#x65e5;&#x5fd7;</name>
  842 + <type>WriteToLog</type>
  843 + <description/>
  844 + <distribute>Y</distribute>
  845 + <custom_distribution/>
  846 + <copies>1</copies>
  847 + <partitioning>
  848 + <method>none</method>
  849 + <schema_name/>
  850 + </partitioning>
  851 + <loglevel>log_level_basic</loglevel>
  852 + <displayHeader>Y</displayHeader>
  853 + <limitRows>N</limitRows>
  854 + <limitRowsNumber>0</limitRowsNumber>
  855 + <logmessage>&#x5f00;&#x59cb;&#x83b7;&#x53d6; &#x24;&#x7b;ssgs&#x7d; &#x8fdc;&#x7aef;&#x6570;&#x636e;&#xff0c;&#x5e76;&#x5904;&#x7406;&#x8f93;&#x51fa;&#xa;&#x83b7;&#x53d6;&#x6570;&#x636e; api url&#x3d;&#x24;&#x7b;url&#x7d;&#xa;&#x53c2;&#x6570;1&#xff08;&#x5bc6;&#x94a5;&#xff09;password&#x3d;&#x24;&#x7b;password&#x7d;</logmessage>
  856 + <fields>
  857 + </fields>
  858 + <cluster_schema/>
  859 + <remotesteps> <input> </input> <output> </output> </remotesteps> <GUI>
  860 + <xloc>114</xloc>
  861 + <yloc>184</yloc>
  862 + <draw>Y</draw>
  863 + </GUI>
  864 + </step>
  865 +
  866 + <step>
  867 + <name>&#x83b7;&#x53d6;&#x53c2;&#x6570;</name>
  868 + <type>GetVariable</type>
  869 + <description/>
  870 + <distribute>N</distribute>
  871 + <custom_distribution/>
  872 + <copies>1</copies>
  873 + <partitioning>
  874 + <method>none</method>
  875 + <schema_name/>
  876 + </partitioning>
  877 + <fields>
  878 + <field>
  879 + <name>password</name>
  880 + <variable>&#x24;&#x7b;password&#x7d;</variable>
  881 + <type>String</type>
  882 + <format/>
  883 + <currency/>
  884 + <decimal/>
  885 + <group/>
  886 + <length>-1</length>
  887 + <precision>-1</precision>
  888 + <trim_type>none</trim_type>
  889 + </field>
  890 + <field>
  891 + <name>url</name>
  892 + <variable>&#x24;&#x7b;url&#x7d;</variable>
  893 + <type>String</type>
  894 + <format/>
  895 + <currency/>
  896 + <decimal/>
  897 + <group/>
  898 + <length>-1</length>
  899 + <precision>-1</precision>
  900 + <trim_type>none</trim_type>
  901 + </field>
  902 + </fields>
  903 + <cluster_schema/>
  904 + <remotesteps> <input> </input> <output> </output> </remotesteps> <GUI>
  905 + <xloc>114</xloc>
  906 + <yloc>75</yloc>
  907 + <draw>Y</draw>
  908 + </GUI>
  909 + </step>
  910 +
  911 + <step_error_handling>
  912 + </step_error_handling>
  913 + <slave-step-copy-partition-distribution>
  914 +</slave-step-copy-partition-distribution>
  915 + <slave_transformation>N</slave_transformation>
  916 +
  917 +</transformation>
src/main/resources/logback.xml
@@ -159,6 +159,27 @@ @@ -159,6 +159,27 @@
159 <appender-ref ref="DATATOOLS" /> 159 <appender-ref ref="DATATOOLS" />
160 </logger> 160 </logger>
161 161
  162 + <!-- 车辆信息同步输出日志 -->
  163 + <appender name="vehicle_data_sync_log" class="ch.qos.logback.classic.sift.SiftingAppender">
  164 + <!-- 鉴别器,使用MDC赋值 -->
  165 + <discriminator>
  166 + <key>taskLogKey</key>
  167 + <defaultValue>default</defaultValue>
  168 + </discriminator>
  169 + <sift>
  170 + <appender name="sys_job_log_file-${jobLogKey}" class="ch.qos.logback.core.FileAppender">
  171 + <file>${LOG_BASE}/datasync/vehicle/vehicle-data-sync.${taskLogKey}.log</file>
  172 + <append>true</append>
  173 + <encoder charset="UTF-8">
  174 + <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] [%file:%line] %-5level-%msg%n</pattern>
  175 + </encoder>
  176 + </appender>
  177 + </sift>
  178 + </appender>
  179 + <!-- 车辆信息同步任务 -->
  180 + <logger name="com.bsth.service.schedule.datasync.task" level="info">
  181 + <appender-ref ref="vehicle_data_sync_log"/>
  182 + </logger>
162 183
163 <!-- 时刻表,排班计划业务修改日志 --> 184 <!-- 时刻表,排班计划业务修改日志 -->
164 <!--<springProfile name="dev">--> 185 <!--<springProfile name="dev">-->
@@ -344,4 +365,4 @@ @@ -344,4 +365,4 @@
344 <appender-ref ref="STDOUT" /> 365 <appender-ref ref="STDOUT" />
345 <appender-ref ref="FILE" /> 366 <appender-ref ref="FILE" />
346 </root> 367 </root>
347 -</configuration>  
348 \ No newline at end of file 368 \ No newline at end of file
  369 +</configuration>
src/main/resources/static/pages/scheduleApp/Gruntfile.js
@@ -107,6 +107,7 @@ module.exports = function (grunt) { @@ -107,6 +107,7 @@ module.exports = function (grunt) {
107 'module/basicInfo/busInfoManage/route.js', // 车辆基础信息管理模块 107 'module/basicInfo/busInfoManage/route.js', // 车辆基础信息管理模块
108 'module/basicInfo/deviceInfoManage/route.js', // 设备管理模块 108 'module/basicInfo/deviceInfoManage/route.js', // 设备管理模块
109 'module/basicInfo/employeeInfoManage/route.js', // 人员基础信息管理模块 109 'module/basicInfo/employeeInfoManage/route.js', // 人员基础信息管理模块
  110 + 'module/basicInfo/vehicleDataSyncManage/route.js', // 车辆信息同步管理模块
110 'module/core/busConfig/route.js', // 车辆配置模块 111 'module/core/busConfig/route.js', // 车辆配置模块
111 'module/core/busLineInfoStat/route.js', // 线路运营概览模块 112 'module/core/busLineInfoStat/route.js', // 线路运营概览模块
112 'module/core/employeeConfig/route.js', // 人员配置模块 113 'module/core/employeeConfig/route.js', // 人员配置模块
@@ -132,6 +133,7 @@ module.exports = function (grunt) { @@ -132,6 +133,7 @@ module.exports = function (grunt) {
132 'module/basicInfo/busInfoManage/service.js', // 车辆基础信息管理service 133 'module/basicInfo/busInfoManage/service.js', // 车辆基础信息管理service
133 'module/basicInfo/deviceInfoManage/service.js', // 设备信息管理service 134 'module/basicInfo/deviceInfoManage/service.js', // 设备信息管理service
134 'module/basicInfo/employeeInfoManage/service.js', // 人员基础信息管理service 135 'module/basicInfo/employeeInfoManage/service.js', // 人员基础信息管理service
  136 + 'module/basicInfo/vehicleDataSyncManage/service.js', // 车辆信息同步管理service
135 'module/core/busConfig/service.js', // 车辆配置service 137 'module/core/busConfig/service.js', // 车辆配置service
136 'module/core/busLineInfoStat/service.js', // 线路运营概览service 138 'module/core/busLineInfoStat/service.js', // 线路运营概览service
137 'module/core/employeeConfig/service.js', // 人员配置service 139 'module/core/employeeConfig/service.js', // 人员配置service
@@ -490,4 +492,4 @@ module.exports = function (grunt) { @@ -490,4 +492,4 @@ module.exports = function (grunt) {
490 'clean:concat_service', 'concat:service' 492 'clean:concat_service', 'concat:service'
491 ]); 493 ]);
492 494
493 -};  
494 \ No newline at end of file 495 \ No newline at end of file
  496 +};
src/main/resources/static/pages/scheduleApp/module/basicInfo/vehicleDataSyncManage/index.html 0 → 100644
  1 +<div class="page-head">
  2 + <div class="page-title">
  3 + <h1>车辆信息同步管理</h1>
  4 + </div>
  5 +</div>
  6 +
  7 +<ul class="page-breadcrumb breadcrumb">
  8 + <li>
  9 + <a href="/pages/home.html" data-pjax>首页</a>
  10 + <i class="fa fa-circle"></i>
  11 + </li>
  12 + <li>
  13 + <span class="active">基础信息</span>
  14 + <i class="fa fa-circle"></i>
  15 + </li>
  16 + <li>
  17 + <span class="active">车辆信息同步管理</span>
  18 + </li>
  19 +</ul>
  20 +
  21 +<div class="row">
  22 + <div class="col-md-12" ng-controller="VehicleDataSyncManageCtrl as ctrl">
  23 + <style>
  24 + .dropdown-menu {
  25 + border-color: #32c5d2;
  26 + }
  27 + .btn-group > .dropdown-menu:before {
  28 + border-bottom-color: #32c5d2;
  29 + }
  30 + </style>
  31 +
  32 + <div class="portlet light bordered">
  33 + <div class="portlet-title">
  34 + <div class="caption font-dark">
  35 + <i class="fa fa-database font-dark"></i>
  36 + <span class="caption-subject bold uppercase">车辆信息同步日志</span>
  37 + </div>
  38 + </div>
  39 +
  40 + <div class="portlet-body">
  41 + <div ui-view="vehicleDataSyncManage_list"></div>
  42 + </div>
  43 + </div>
  44 +
  45 + </div>
  46 +</div>
src/main/resources/static/pages/scheduleApp/module/basicInfo/vehicleDataSyncManage/list.html 0 → 100644
  1 +<div ng-controller="VehicleDataSyncManageListCtrl as ctrl">
  2 + <div class="fixDiv">
  3 + <table class="table fixTable table-striped table-bordered table-hover table-checkable order-column">
  4 + <thead>
  5 + <tr role="row" class="heading">
  6 + <th style="width:70px;">序号</th>
  7 + <th style="width:150px;">开始时间 </th>
  8 + <th style="width:150px;">结束时间 </th>
  9 + <th >执行耗时(秒)</th>
  10 + <th >同步数量</th>
  11 + <th >新增数量</th>
  12 + <th >更新数量</th>
  13 + <th >错误数量</th>
  14 + <th style="width: 120px;">状态</th>
  15 + <th style="width: 180px;">操作</th>
  16 + </tr>
  17 + <tr role="row" class="filter">
  18 + <td></td>
  19 + <td>
  20 + <div class="input-group">
  21 + <input type="text" class="form-control input-sm"
  22 + name="startDate" placeholder="选择日期..."
  23 + uib-datepicker-popup="yyyy-MM-dd"
  24 + is-open="ctrl.startDate"
  25 + ng-model="ctrl.searchCondition()['startDate_ge']" readonly/>
  26 + <span class="input-group-btn">
  27 + <button type="button" class="btn btn-default btn-sm" ng-click="ctrl.startDate_open()">
  28 + <i class="glyphicon glyphicon-calendar"></i>
  29 + </button>
  30 + </span>
  31 + </div>
  32 + </td>
  33 + <td>
  34 + <div class="input-group">
  35 + <input type="text" class="form-control input-sm"
  36 + name="endDate" placeholder="选择日期..."
  37 + uib-datepicker-popup="yyyy-MM-dd"
  38 + is-open="ctrl.endDate"
  39 + ng-model="ctrl.searchCondition()['endDate_le']" readonly/>
  40 + <span class="input-group-btn">
  41 + <button type="button" class="btn btn-default btn-sm" ng-click="ctrl.endDate_open()">
  42 + <i class="glyphicon glyphicon-calendar"></i>
  43 + </button>
  44 + </span>
  45 + </div>
  46 + </td>
  47 + <td></td>
  48 + <td></td>
  49 + <td></td>
  50 + <td></td>
  51 + <td></td>
  52 + <td></td>
  53 + <td>
  54 + <button class="btn btn-sm green btn-outline filter-submit margin-bottom" style="margin-right: 0;"
  55 + ng-click="ctrl.doPage()">
  56 + <i class="fa fa-search"></i> 搜索
  57 + </button>
  58 + <button class="btn btn-sm red btn-outline filter-cancel"
  59 + ng-click="ctrl.reset()">
  60 + <i class="fa fa-times"></i> 重置
  61 + </button>
  62 + </td>
  63 + </tr>
  64 + </thead>
  65 + <tbody>
  66 + <tr ng-repeat="info in ctrl.page()['content']" class="odd gradeX">
  67 + <td>
  68 + <div>
  69 + <a href="#"
  70 + tooltip-animation="false"
  71 + tooltip-placement="top"
  72 + uib-tooltip="{{'公司/编号:' + info.company + '/' + info.insideCode}}"
  73 + tooltip-class="headClass">
  74 +
  75 + <i class="fa fa-list-ol" aria-hidden="true"></i>
  76 + {{$index + ctrl.page().number * 10 + 1}}
  77 + </a>
  78 + </div>
  79 + </td>
  80 + <td>
  81 + <div>
  82 + <a href="#">
  83 + <span ng-bind="(info.startDate | date: 'yyyy-MM-dd')"></span>
  84 + </a>
  85 + </div>
  86 + <div>
  87 + <a href="#">
  88 + <span ng-bind="(info.startDate | date: 'HH:mm:ss')"></span>
  89 + </a>
  90 + </div>
  91 + </td>
  92 + <td>
  93 + <div>
  94 + <a href="#">
  95 + <span ng-bind="(info.endDate | date: 'yyyy-MM-dd')"></span>
  96 + </a>
  97 + </div>
  98 + <div>
  99 + <a href="#">
  100 + <span ng-bind="(info.endDate | date: 'HH:mm:ss')"></span>
  101 + </a>
  102 + </div>
  103 + </td>
  104 + <td>
  105 + <div>
  106 + <a href="#">
  107 + <i class="fa fa-clock-o" aria-hidden="true"></i>
  108 + <span ng-bind="(info.processSeconds == null ? '0' : info.processSeconds) + '秒'"></span>
  109 + </a>
  110 + </div>
  111 +
  112 + </td>
  113 + <td>
  114 + <div>
  115 + <a href="#">
  116 + <i class="fa fa-info" aria-hidden="true"></i>
  117 + <span ng-bind="(info.syncRowCounts == null ? '0' : info.syncRowCounts) + '条记录'"></span>
  118 + </a>
  119 + </div>
  120 + </td>
  121 + <td>
  122 + <div>
  123 + <a href="#">
  124 + <i class="fa fa-info" aria-hidden="true"></i>
  125 + <span ng-bind="(info.syncInsertCounts == null ? '0' : info.syncInsertCounts) + '条记录'"></span>
  126 + </a>
  127 + </div>
  128 + </td>
  129 + <td>
  130 + <div>
  131 + <a href="#">
  132 + <i class="fa fa-info" aria-hidden="true"></i>
  133 + <span ng-bind="(info.syncUpdateCounts == null ? '0' : info.syncUpdateCounts) + '条记录'"></span>
  134 + </a>
  135 + </div>
  136 + </td>
  137 + <td>
  138 + <div>
  139 + <a href="#">
  140 + <i class="fa fa-info" aria-hidden="true"></i>
  141 + <span ng-bind="(info.syncErrorCounts == null ? '0' : info.syncErrorCounts) + '条记录'"></span>
  142 + </a>
  143 + </div>
  144 + </td>
  145 + <td>
  146 + <a sweetalert
  147 + sweet-options="{title: '同步信息',text:
  148 + '</br>同步开始时间:' + (info.startDate | date: 'yyyy-MM-dd HH:mm:ss') +
  149 + '</br>同步结束时间:' + (info.endDate | date: 'yyyy-MM-dd HH:mm:ss') +
  150 + '</br>执行结果信息:' + info.processMsg,
  151 + html: true,
  152 + type: 'info'}"
  153 + sweet-on-confirm=""
  154 + class="btn btn-info btn-sm"
  155 + ng-if="info.status === '同步准备'">
  156 + <span>同步准备</span>
  157 + <i class="fa fa-spinner" aria-hidden="true"></i>
  158 + </a>
  159 + <a sweetalert
  160 + sweet-options="{title: '同步信息',text:
  161 + '</br>同步开始时间:' + (info.startDate | date: 'yyyy-MM-dd HH:mm:ss') +
  162 + '</br>同步结束时间:' + (info.endDate | date: 'yyyy-MM-dd HH:mm:ss') +
  163 + '</br>执行结果信息:' + info.processMsg,
  164 + html: true,
  165 + type: 'info'}"
  166 + sweet-on-confirm=""
  167 + class="btn btn-danger btn-sm"
  168 + ng-if="info.status === '同步准备失败'">
  169 + <span>同步准备失败</span>
  170 + <i class="fa fa-times" aria-hidden="true"></i>
  171 + </a>
  172 + <a sweetalert
  173 + sweet-options="{title: '同步信息',text:
  174 + '</br>同步开始时间:' + (info.startDate | date: 'yyyy-MM-dd HH:mm:ss') +
  175 + '</br>同步结束时间:' + (info.endDate | date: 'yyyy-MM-dd HH:mm:ss') +
  176 + '</br>执行结果信息:' + info.processMsg,
  177 + html: true,
  178 + type: 'info'}"
  179 + sweet-on-confirm=""
  180 + class="btn btn-primary btn-sm"
  181 + ng-if="info.status === '同步中'">
  182 + <span>同步中</span>
  183 + <i class="fa fa-spinner" aria-hidden="true"></i>
  184 + </a>
  185 + <a sweetalert
  186 + sweet-options="{title: '同步信息',text:
  187 + '</br>同步开始时间:' + (info.startDate | date: 'yyyy-MM-dd HH:mm:ss') +
  188 + '</br>同步结束时间:' + (info.endDate | date: 'yyyy-MM-dd HH:mm:ss') +
  189 + '</br>执行结果信息:' + info.processMsg,
  190 + html: true,
  191 + type: 'info'}"
  192 + sweet-on-confirm=""
  193 + class="btn btn-success btn-sm"
  194 + ng-if="info.status === '同步结束' && info.processMsg.indexOf('成功') >= 0">
  195 + <span>同步结束</span>
  196 + <i class="fa fa-check" aria-hidden="true"></i>
  197 + </a>
  198 + <a sweetalert
  199 + sweet-options="{title: '同步信息',text:
  200 + '</br>同步开始时间:' + (info.startDate | date: 'yyyy-MM-dd HH:mm:ss') +
  201 + '</br>同步结束时间:' + (info.endDate | date: 'yyyy-MM-dd HH:mm:ss') +
  202 + '</br>执行结果信息:' + info.processMsg,
  203 + html: true,
  204 + type: 'info'}"
  205 + sweet-on-confirm=""
  206 + class="btn btn-warning btn-sm"
  207 + ng-if="info.status === '同步结束' && info.processMsg.indexOf('成功') === -1">
  208 + <span>同步结束</span>
  209 + <i class="fa fa-exclamation" aria-hidden="true"></i>
  210 + </a>
  211 + </td>
  212 + <td>
  213 + <!--<a href="details.html?lineId={{obj.id}}" class="btn default blue-stripe btn-sm"> 详细 </a>-->
  214 + <!--<a href="edit.html?lineId={{obj.id}}" class="btn default blue-stripe btn-sm"> 修改 </a>-->
  215 + <button class="btn btn-info btn-sm"
  216 + ng-click="ctrl.getLogFile(info.id)">
  217 + <i class="fa fa-download" aria-hidden="true"></i> 执行日志
  218 + </button>
  219 + </td>
  220 + </tr>
  221 + </tbody>
  222 + </table>
  223 + </div>
  224 +
  225 + <div class="pageBar">
  226 + <div class="pageBarLeft">
  227 + {{'显示从' + ctrl.page()['uiFromRecord'] + '到' + ctrl.page()['uiToRecord'] + ' 共' + ctrl.page()['totalElements'] + '条' + ' 每页显示10条'}}
  228 + </div>
  229 +
  230 + <div class="pageBarRight">
  231 + <uib-pagination total-items="ctrl.page()['totalElements']"
  232 + ng-model="ctrl.page()['uiNumber']"
  233 + ng-change="ctrl.doPage()"
  234 + rotate="false"
  235 + max-size="10"
  236 + boundary-links="true"
  237 + first-text="首页"
  238 + previous-text="上一页"
  239 + next-text="下一页"
  240 + last-text="尾页">
  241 + </uib-pagination>
  242 + </div>
  243 + </div>
  244 +</div>
src/main/resources/static/pages/scheduleApp/module/basicInfo/vehicleDataSyncManage/module.js 0 → 100644
  1 +// 车辆信息同步管理 module
  2 +
  3 +angular.module('ScheduleApp').factory(
  4 + 'VehicleDataSyncManageService',
  5 + [
  6 + 'VehicleDataSyncManageService_g',
  7 + function(service) {
  8 + /** 当前的查询条件信息 */
  9 + var currentSearchCondition = {
  10 + page: 0
  11 + };
  12 + // 当前查询返回的信息
  13 + var currentPage = { // 后台spring data返回的格式
  14 + totalElements: 0,
  15 + number: 0, // 后台返回的页码,spring返回从0开始
  16 + content: [],
  17 +
  18 + uiNumber: 1, // 页面绑定的页码
  19 + uiFromRecord: 0, // 页面绑定,当前页第几条记录
  20 + uiToRecord: 0 // 页面绑定,当前页到第几条记录
  21 + };
  22 +
  23 + // rest查询对象
  24 + var queryClass = service.rest;
  25 +
  26 + return {
  27 + getQueryClass: function() {
  28 + return queryClass;
  29 + },
  30 + /**
  31 + * 获取查询条件信息,
  32 + * 用于给controller用来和页面数据绑定。
  33 + */
  34 + getSearchCondition: function() {
  35 + currentSearchCondition.page = currentPage.uiNumber - 1;
  36 + return currentSearchCondition;
  37 + },
  38 + /**
  39 + * 组装查询参数,返回一个promise查询结果。
  40 + * @param page 数据页对象
  41 + * @return 返回一个 promise
  42 + */
  43 + getPage: function(page) {
  44 + if (page) {
  45 + currentPage.totalElements = page.totalElements;
  46 + currentPage.number = page.number;
  47 + currentPage.content = page.content;
  48 +
  49 + // 计算当前页开始记录,结束记录
  50 + if (page.numberOfElements && page.numberOfElements > 0) {
  51 + currentPage.uiFromRecord = page.number * 10 + 1;
  52 + currentPage.uiToRecord = page.number * 10 + page.numberOfElements;
  53 + }
  54 + }
  55 + return currentPage;
  56 + },
  57 + resetStatus: function() {
  58 + currentSearchCondition = {page: 0};
  59 + currentPage = {
  60 + totalElements: 0,
  61 + number: 0,
  62 + content: [],
  63 + uiNumber: 1,
  64 + uiFromRecord: 0,
  65 + uiToRecord: 0
  66 + };
  67 + },
  68 +
  69 + logFileExportPromise: function(logId) {
  70 + return service.logFileExport.getLog({id: logId}).$promise;
  71 + }
  72 +
  73 + };
  74 + }
  75 + ]
  76 +
  77 +);
  78 +
  79 +// index.html控制器
  80 +angular.module('ScheduleApp').controller(
  81 + 'VehicleDataSyncManageCtrl',
  82 + [
  83 + '$state',
  84 + function($state) {
  85 + var self = this;
  86 +
  87 + // TODO:
  88 + }
  89 + ]
  90 +);
  91 +
  92 +// list.html控制器
  93 +angular.module('ScheduleApp').controller(
  94 + 'VehicleDataSyncManageListCtrl',
  95 + [
  96 + 'VehicleDataSyncManageService',
  97 + 'FileDownload_g',
  98 + function(service, fileDownload) {
  99 + var self = this;
  100 + // 日期 日期控件开关
  101 + self.startDate = false;
  102 + self.startDate_open = function() {
  103 + self.startDate = true;
  104 + };
  105 + self.endDate = false;
  106 + self.endDate_open = function() {
  107 + self.endDate = true;
  108 + };
  109 +
  110 +
  111 + var Logs = service.getQueryClass();
  112 +
  113 + self.page = function() {
  114 + return service.getPage();
  115 + };
  116 +
  117 + self.searchCondition = function() {
  118 + return service.getSearchCondition();
  119 + };
  120 +
  121 + self.doPage = function() {
  122 + var result = Logs.list(self.searchCondition(), function() {
  123 + if (!result.status) {
  124 + service.getPage(result);
  125 + }
  126 + });
  127 + };
  128 + self.reset = function() {
  129 + service.resetStatus();
  130 + var result = Logs.list(self.searchCondition(), function() {
  131 + if (!result.status) {
  132 + service.getPage(result);
  133 + }
  134 + });
  135 + };
  136 +
  137 + self.getLogFile = function(id) {
  138 + var promise = service.logFileExportPromise(id);
  139 + promise.then(
  140 + function(result) {
  141 + fileDownload.downloadFile(result.data, "application/octet-stream", "日志文件.xls");
  142 + },
  143 + function(result) {
  144 + console.log("获取日志文件失败:" + result);
  145 + }
  146 + )
  147 + };
  148 +
  149 + // 查询
  150 + self.doPage();
  151 +
  152 + }
  153 + ]
  154 +);
src/main/resources/static/pages/scheduleApp/module/basicInfo/vehicleDataSyncManage/route.js 0 → 100644
  1 +// ui route 配置
  2 +
  3 +/** 车辆信息同步模块route */
  4 +ScheduleApp.config([
  5 + '$stateProvider',
  6 + '$urlRouterProvider',
  7 + function($stateProvider, $urlRouterProvider) {
  8 + $stateProvider
  9 + .state("vehicleDataSyncManage", { // index页面
  10 + url: '/vehicleDataSyncManage',
  11 + views: {
  12 + "": {
  13 + templateUrl: 'pages/scheduleApp/module/basicInfo/vehicleDataSyncManage/index.html'
  14 + },
  15 + "vehicleDataSyncManage_list@vehicleDataSyncManage": {
  16 + templateUrl: 'pages/scheduleApp/module/basicInfo/vehicleDataSyncManage/list.html'
  17 + }
  18 + },
  19 + resolve: {
  20 + deps: ['$ocLazyLoad', function($ocLazyLoad) {
  21 + return $ocLazyLoad.load({
  22 + name: 'vehicleDataSyncManage_module',
  23 + insertBefore: '#ng_load_plugins_before', // 动态载入模块时放置的位置
  24 + files: [
  25 + "assets/bower_components/angular-ui-select/dist/select.min.css",
  26 + "assets/bower_components/angular-ui-select/dist/select.min.js",
  27 + "assets/bower_components/angular-file-upload/dist/angular-file-upload.min.js",
  28 + "pages/scheduleApp/module/basicInfo/vehicleDataSyncManage/module.js"
  29 + ]
  30 + });
  31 + }]
  32 + }
  33 + })
  34 + }
  35 +]);
src/main/resources/static/pages/scheduleApp/module/basicInfo/vehicleDataSyncManage/service.js 0 → 100644
  1 +// 车辆信息同步service
  2 +angular.module('ScheduleApp').factory(
  3 + 'VehicleDataSyncManageService_g',
  4 + [
  5 + '$resource',
  6 + function($resource) {
  7 + return {
  8 + rest: $resource(
  9 + '/dataSync/vehicle/:id',
  10 + {order: 'startDate', direction: 'DESC', id: '@id'},
  11 + {
  12 + list: {
  13 + method: 'GET',
  14 + params: {
  15 + page: 0
  16 + },
  17 + transformResponse: function(rs) {
  18 + var dst = angular.fromJson(rs);
  19 + if (dst.status == 'SUCCESS') {
  20 + return dst.data;
  21 + } else {
  22 + return dst; // 业务错误留给控制器处理
  23 + }
  24 + }
  25 + },
  26 + get: {
  27 + method: 'GET',
  28 + transformResponse: function(rs) {
  29 + var dst = angular.fromJson(rs);
  30 + if (dst.status == 'SUCCESS') {
  31 + return dst.data;
  32 + } else {
  33 + return dst;
  34 + }
  35 + }
  36 + }
  37 + }
  38 + ),
  39 + logFileExport: $resource(
  40 + '/dataSync/vehicle/logfile/:id',
  41 + {id: '@id'},
  42 + {
  43 + getLog: {
  44 + method: 'GET',
  45 + responseType: "arraybuffer",
  46 + transformResponse: function(data, headers){
  47 + return {data : data};
  48 + }
  49 + }
  50 + }
  51 + )
  52 + };
  53 + }
  54 + ]
  55 +);
src/main/resources/static/pages/scheduleApp/module/common/prj-common-globalservice.js
@@ -184,6 +184,62 @@ angular.module(&#39;ScheduleApp&#39;).factory( @@ -184,6 +184,62 @@ angular.module(&#39;ScheduleApp&#39;).factory(
184 ] 184 ]
185 ); 185 );
186 186
  187 +// 车辆信息同步service
  188 +angular.module('ScheduleApp').factory(
  189 + 'VehicleDataSyncManageService_g',
  190 + [
  191 + '$resource',
  192 + function($resource) {
  193 + return {
  194 + rest: $resource(
  195 + '/dataSync/vehicle/:id',
  196 + {order: 'startDate', direction: 'DESC', id: '@id'},
  197 + {
  198 + list: {
  199 + method: 'GET',
  200 + params: {
  201 + page: 0
  202 + },
  203 + transformResponse: function(rs) {
  204 + var dst = angular.fromJson(rs);
  205 + if (dst.status == 'SUCCESS') {
  206 + return dst.data;
  207 + } else {
  208 + return dst; // 业务错误留给控制器处理
  209 + }
  210 + }
  211 + },
  212 + get: {
  213 + method: 'GET',
  214 + transformResponse: function(rs) {
  215 + var dst = angular.fromJson(rs);
  216 + if (dst.status == 'SUCCESS') {
  217 + return dst.data;
  218 + } else {
  219 + return dst;
  220 + }
  221 + }
  222 + }
  223 + }
  224 + ),
  225 + logFileExport: $resource(
  226 + '/dataSync/vehicle/logfile/:id',
  227 + {id: '@id'},
  228 + {
  229 + getLog: {
  230 + method: 'GET',
  231 + responseType: "arraybuffer",
  232 + transformResponse: function(data, headers){
  233 + return {data : data};
  234 + }
  235 + }
  236 + }
  237 + )
  238 + };
  239 + }
  240 + ]
  241 +);
  242 +
187 // 车辆配置service 243 // 车辆配置service
188 angular.module('ScheduleApp').factory('BusConfigService_g', ['$resource', 'UserPrincipal', function($resource, UserPrincipal) { 244 angular.module('ScheduleApp').factory('BusConfigService_g', ['$resource', 'UserPrincipal', function($resource, UserPrincipal) {
189 return { 245 return {
src/main/resources/static/pages/scheduleApp/module/common/prj-common-ui-route-state.js
@@ -280,6 +280,42 @@ ScheduleApp.config([ @@ -280,6 +280,42 @@ ScheduleApp.config([
280 }) 280 })
281 281
282 }]); 282 }]);
  283 +// ui route 配置
  284 +
  285 +/** 车辆信息同步模块route */
  286 +ScheduleApp.config([
  287 + '$stateProvider',
  288 + '$urlRouterProvider',
  289 + function($stateProvider, $urlRouterProvider) {
  290 + $stateProvider
  291 + .state("vehicleDataSyncManage", { // index页面
  292 + url: '/vehicleDataSyncManage',
  293 + views: {
  294 + "": {
  295 + templateUrl: 'pages/scheduleApp/module/basicInfo/vehicleDataSyncManage/index.html'
  296 + },
  297 + "vehicleDataSyncManage_list@vehicleDataSyncManage": {
  298 + templateUrl: 'pages/scheduleApp/module/basicInfo/vehicleDataSyncManage/list.html'
  299 + }
  300 + },
  301 + resolve: {
  302 + deps: ['$ocLazyLoad', function($ocLazyLoad) {
  303 + return $ocLazyLoad.load({
  304 + name: 'vehicleDataSyncManage_module',
  305 + insertBefore: '#ng_load_plugins_before', // 动态载入模块时放置的位置
  306 + files: [
  307 + "assets/bower_components/angular-ui-select/dist/select.min.css",
  308 + "assets/bower_components/angular-ui-select/dist/select.min.js",
  309 + "assets/bower_components/angular-file-upload/dist/angular-file-upload.min.js",
  310 + "pages/scheduleApp/module/basicInfo/vehicleDataSyncManage/module.js"
  311 + ]
  312 + });
  313 + }]
  314 + }
  315 + })
  316 + }
  317 +]);
  318 +
283 // ui route 配置 319 // ui route 配置
284 320
285 /** 车辆配置模块页面route */ 321 /** 车辆配置模块页面route */