Merge remote-tracking branch 'origin/dev' into dev
This commit is contained in:
@@ -0,0 +1,19 @@
|
||||
package com.jeelowcode.test.alibaba;
|
||||
|
||||
import com.jeelowcode.module.biz.job.AlibabaWorkOrderJob;
|
||||
import com.jeelowcode.tool.framework.test.core.ut.BaseDbAndRedisUnitTest;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
public class WorkOrderSimpleTest extends BaseDbAndRedisUnitTest {
|
||||
|
||||
@Resource
|
||||
private AlibabaWorkOrderJob alibabaWorkOrderJob;
|
||||
|
||||
@Test
|
||||
public void testBuildSql() {
|
||||
System.out.println(alibabaWorkOrderJob.buildSql(null, null));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,157 @@
|
||||
package com.jeelowcode.module.biz.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.jeelowcode.framework.utils.model.global.BaseTenantEntity;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 阿里工单实体类
|
||||
* <p>
|
||||
* 用于存储和管理阿里平台产生的工单信息,包括检查项、整改要求、责任人等相关信息
|
||||
*
|
||||
* @author yangchenjj
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode
|
||||
@TableName("lc_alibaba_work_order")
|
||||
public class AlibabaWorkOrder extends BaseTenantEntity {
|
||||
|
||||
/**
|
||||
* 主键
|
||||
*/
|
||||
@TableId(value = "id", type = IdType.ASSIGN_ID)
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 阿里工单ID
|
||||
*/
|
||||
@TableField("work_order_id")
|
||||
private String workOrderId;
|
||||
|
||||
/**
|
||||
* 园区ID
|
||||
*/
|
||||
@TableField("campus_id")
|
||||
private String campusId;
|
||||
|
||||
/**
|
||||
* 园区名称
|
||||
*/
|
||||
@TableField("campus_name")
|
||||
private String campusName;
|
||||
|
||||
/**
|
||||
* 工单等级
|
||||
*/
|
||||
@TableField("work_order_level")
|
||||
private String workOrderLevel;
|
||||
|
||||
/**
|
||||
* 检查区域
|
||||
*/
|
||||
@TableField("check_area")
|
||||
private String checkArea;
|
||||
|
||||
/**
|
||||
* 检查项
|
||||
*/
|
||||
@TableField("check_item")
|
||||
private String checkItem;
|
||||
|
||||
/**
|
||||
* 检查内容
|
||||
*/
|
||||
@TableField("check_content")
|
||||
private String checkContent;
|
||||
|
||||
/**
|
||||
* 检查人ID
|
||||
*/
|
||||
@TableField("check_person_id")
|
||||
private String checkPersonId;
|
||||
|
||||
/**
|
||||
* 检查人姓名
|
||||
*/
|
||||
@TableField("check_person_name")
|
||||
private String checkPersonName;
|
||||
|
||||
/**
|
||||
* 检查时间
|
||||
*/
|
||||
@TableField("check_time")
|
||||
private LocalDateTime checkTime;
|
||||
|
||||
/**
|
||||
* 检查发现的问题
|
||||
*/
|
||||
@TableField("check_question")
|
||||
private String checkQuestion;
|
||||
|
||||
/**
|
||||
* 整改截止时间
|
||||
*/
|
||||
@TableField("correct_deadline")
|
||||
private LocalDateTime correctDeadline;
|
||||
|
||||
/**
|
||||
* 整改责任人ID
|
||||
*/
|
||||
@TableField("correct_person_id")
|
||||
private String correctPersonId;
|
||||
|
||||
/**
|
||||
* 整改责任人姓名
|
||||
*/
|
||||
@TableField("correct_person_name")
|
||||
private String correctPersonName;
|
||||
|
||||
/**
|
||||
* 整改措施
|
||||
*/
|
||||
@TableField("correct_action")
|
||||
private String correctAction;
|
||||
|
||||
/**
|
||||
* 确认人ID
|
||||
*/
|
||||
@TableField("confirm_person_id")
|
||||
private String confirmPersonId;
|
||||
|
||||
/**
|
||||
* 确认人姓名
|
||||
*/
|
||||
@TableField("confirm_person_name")
|
||||
private String confirmPersonName;
|
||||
|
||||
/**
|
||||
* 修改时间
|
||||
*/
|
||||
@TableField("gmt_modified")
|
||||
private LocalDateTime gmtModified;
|
||||
|
||||
/**
|
||||
* 子表修改时间
|
||||
*/
|
||||
@TableField("gmt_sub_modified")
|
||||
private LocalDateTime gmtSubModified;
|
||||
|
||||
/**
|
||||
* 关联数据修改时间
|
||||
*/
|
||||
@TableField("gmt_relate_modified")
|
||||
private LocalDateTime gmtRelateModified;
|
||||
|
||||
/**
|
||||
* 关联子表修改时间
|
||||
*/
|
||||
@TableField("gmt_relate_sub_modified")
|
||||
private LocalDateTime gmtRelateSubModified;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,514 @@
|
||||
package com.jeelowcode.module.biz.job;
|
||||
|
||||
import cn.hutool.core.date.LocalDateTimeUtil;
|
||||
import com.baomidou.dynamic.datasource.DynamicRoutingDataSource;
|
||||
import com.jeelowcode.module.biz.entity.AlibabaWorkOrder;
|
||||
import com.jeelowcode.module.biz.service.IAlibabaWorkOrderService;
|
||||
import com.jeelowcode.tool.framework.quartz.core.handler.JobHandler;
|
||||
import com.jeelowcode.tool.framework.tenant.core.job.TenantJob;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.sql.DataSource;
|
||||
import java.sql.Connection;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
import static com.jeelowcode.tool.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
||||
|
||||
/**
|
||||
* 从阿里巴巴工单同步任务(包含查询、清洗)
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class AlibabaWorkOrderJob implements JobHandler {
|
||||
|
||||
/**
|
||||
* 阿里数据源名称
|
||||
*/
|
||||
private static final String ALIBABA_DATASOURCE_NAME = "alidb";
|
||||
|
||||
@Resource
|
||||
private IAlibabaWorkOrderService workOrderService;
|
||||
|
||||
@Resource
|
||||
private DynamicRoutingDataSource dynamicRoutingDataSource;
|
||||
|
||||
@Override
|
||||
@TenantJob
|
||||
public String execute(String param) throws Exception {
|
||||
// 拿到系统中的所有的数据源,检查是否有阿里的数据源
|
||||
Map<String, DataSource> dataSources = dynamicRoutingDataSource.getDataSources();
|
||||
if (!dataSources.containsKey(ALIBABA_DATASOURCE_NAME)) {
|
||||
log.error("未找到阿里数据源,请检查数据源配置");
|
||||
return "未找到阿里数据源,请检查数据源配置";
|
||||
}
|
||||
// 查询我数据库中最新的时间点
|
||||
LocalDateTime maxWorkOrderTime = workOrderService.getMaxWorkOrderTime();
|
||||
StringBuilder sqlBuilder = new StringBuilder();
|
||||
if (maxWorkOrderTime == null) {
|
||||
sqlBuilder.append(buildSql(null, null));
|
||||
} else {
|
||||
LocalDateTime endTime = LocalDateTimeUtil.endOfDay(LocalDateTime.now());
|
||||
sqlBuilder.append(buildSql(maxWorkOrderTime, endTime));
|
||||
}
|
||||
// 执行SQL查询数据
|
||||
DataSource dataSource = dataSources.get(ALIBABA_DATASOURCE_NAME);
|
||||
try (Connection connection = dataSource.getConnection();
|
||||
ResultSet resultSet = connection.createStatement().executeQuery(sqlBuilder.toString())) {
|
||||
// 使用连接执行SQL并得到结果
|
||||
List<AlibabaWorkOrder> workOrderList = new ArrayList<>();
|
||||
// 将resultSet解析成List<AlibabaWorkOrder> list
|
||||
while (resultSet.next()) {
|
||||
AlibabaWorkOrder workOrder = new AlibabaWorkOrder();
|
||||
workOrder.setId(resultSet.getLong("id"));
|
||||
workOrder.setWorkOrderId(resultSet.getString("workOrderId"));
|
||||
workOrder.setCampusId(resultSet.getString("campusId"));
|
||||
workOrder.setCampusName(resultSet.getString("campusName"));
|
||||
workOrder.setCheckArea(resultSet.getString("checkArea"));
|
||||
workOrder.setCheckItem(resultSet.getString("checkItem"));
|
||||
workOrder.setCheckContent(resultSet.getString("checkContent"));
|
||||
workOrder.setCheckPersonId(resultSet.getString("checkPersonId"));
|
||||
workOrder.setCheckPersonName(resultSet.getString("checkPersonName"));
|
||||
workOrder.setCheckTime(resultSet.getObject("checkTime", LocalDateTime.class));
|
||||
workOrder.setCheckQuestion(resultSet.getString("checkQuestion"));
|
||||
workOrder.setCorrectAction(resultSet.getString("correctAction"));
|
||||
workOrder.setCorrectPersonId(resultSet.getString("correctPersonId"));
|
||||
workOrder.setCorrectPersonName(resultSet.getString("correctPersonName"));
|
||||
workOrder.setWorkOrderLevel(resultSet.getString("workOrderLevel"));
|
||||
workOrder.setCorrectDeadline(resultSet.getObject("correctDeadline", LocalDateTime.class));
|
||||
workOrder.setConfirmPersonId(resultSet.getString("confirmPersonId"));
|
||||
workOrder.setConfirmPersonName(resultSet.getString("confirmPersonName"));
|
||||
workOrder.setGmtModified(resultSet.getObject("gmtModified", LocalDateTime.class));
|
||||
workOrder.setGmtSubModified(resultSet.getObject("gmtSubModified", LocalDateTime.class));
|
||||
workOrder.setGmtRelateModified(resultSet.getObject("gmtRelateModified", LocalDateTime.class));
|
||||
workOrder.setGmtRelateSubModified(resultSet.getObject("gmtRelateSubModified", LocalDateTime.class));
|
||||
workOrderList.add(workOrder);
|
||||
}
|
||||
|
||||
// 解析得到的数据由服务存储到数据库
|
||||
int num = workOrderService.batchSaveWorkOrder(workOrderList);
|
||||
log.info("同步阿里工单完成,共处理{}条数据", workOrderList.size());
|
||||
log.info("同步阿里工单完成,共成功{}条数据", num);
|
||||
return "同步阿里工单完成,共处理" + num + "条数据";
|
||||
} catch (SQLException e) {
|
||||
log.error("执行SQL查询或解析ResultSet异常", e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建查询SQL
|
||||
*
|
||||
* @param startTime 开始时间
|
||||
* @param endTime 结束时间
|
||||
* @return SQL
|
||||
*/
|
||||
public static String buildSql(LocalDateTime startTime, LocalDateTime endTime) {
|
||||
StringBuilder sqlBuilder = new StringBuilder();
|
||||
sqlBuilder.append("SELECT\n" +
|
||||
" mwoe.ID AS \"id\",\n" +
|
||||
" mwoe.WORK_ORDER_ID AS \"workOrderId\",\n" +
|
||||
" mwoe.CAMPUS_ID AS \"campusId\",\n" +
|
||||
" mwoe.CAMPUS_NAME AS \"campusName\",\n" +
|
||||
" mwoe.REMARK AS \"checkArea\",\n" +
|
||||
" mwoe.OBJ_NAME AS \"checkItem\",\n" +
|
||||
" mwoe.SUB_SOP_SCHEMA AS \"checkContent\",\n" +
|
||||
" mwoe.CREATOR_ID AS \"checkPersonId\",\n" +
|
||||
" mwoe.CREATOR_NAME AS \"checkPersonName\",\n" +
|
||||
" mwoe.GMT_CREATE AS \"checkTime\",\n" +
|
||||
" mwoe.PROCESS_CONTENT AS \"checkQuestion\",\n" +
|
||||
" CONCAT_WS(',', rwoa.PROCESS_CONTENT, rwoa.SUB_SOP_SCHEMA) AS \"correctAction\",\n" +
|
||||
" rwoa.PROCESSOR_ID AS \"correctPersonId\",\n" +
|
||||
" rwoa.PROCESSOR_NAME AS \"correctPersonName\",\n" +
|
||||
" mwoe.\"LEVEL\" AS \"workOrderLevel\",\n" +
|
||||
" rwoa.RESERVED_TIME3 AS \"correctDeadline\",\n" +
|
||||
" rwoa.CONFIRM_PERSON_ID AS \"confirmPersonId\",\n" +
|
||||
" rwoa.CONFIRM_PERSON_NAME AS \"confirmPersonName\",\n" +
|
||||
" mwoe.GMT_MODIFIED AS \"gmtModified\",\n" +
|
||||
" mwoe.SUB_GMT_MODIFIED AS \"gmtSubModified\",\n" +
|
||||
" rwoa.GMT_MODIFIED AS \"gmtRelateModified\",\n" +
|
||||
" rwoa.SUB_GMT_MODIFIED AS \"gmtRelateSubModified\"\n" +
|
||||
"FROM\n" +
|
||||
" (\n" +
|
||||
" SELECT\n" +
|
||||
" mwo.*,\n" +
|
||||
" swo.SOP_SCHEMA AS SUB_SOP_SCHEMA,\n" +
|
||||
" swo.PROCESS_CONTENT AS SUB_PROCESS_CONTENT,\n" +
|
||||
" swo.GMT_MODIFIED AS SUB_GMT_MODIFIED,\n" +
|
||||
" swo.OBJ_NAME AS OBJ_NAME\n" +
|
||||
" FROM\n" +
|
||||
" (\n" +
|
||||
" SELECT\n" +
|
||||
" wo.ID,\n" +
|
||||
" wo.WORK_ORDER_ID,\n" +
|
||||
" wo.CAMPUS_ID,\n" +
|
||||
" c.NAME AS CAMPUS_NAME,\n" +
|
||||
" wo.REMARK,\n" +
|
||||
" wo.CREATOR_ID,\n" +
|
||||
" wo.CREATOR_NAME,\n" +
|
||||
" wo.GMT_CREATE,\n" +
|
||||
" wo.GMT_MODIFIED,\n" +
|
||||
" wo.RESERVED_TIME3,\n" +
|
||||
" CASE\n" +
|
||||
" WHEN wo.\"LEVEL\" = 'P' THEN '重大'\n" +
|
||||
" ELSE '一般'\n" +
|
||||
" END AS \"LEVEL\",\n" +
|
||||
" wo.\"CONFIRM_PERSON_ID\",\n" +
|
||||
" wo.CONFIRM_PERSON_NAME,\n" +
|
||||
" wo.TENANT,\n" +
|
||||
" ml.PROCESSOR_ID,\n" +
|
||||
" ml.PROCESSOR_NAME,\n" +
|
||||
" JSON_VALUE(ml.CONTENT, '$.processedContent') AS PROCESS_CONTENT\n" +
|
||||
" FROM\n" +
|
||||
" \"XCAMPUS_WORKORDER\".\"WORK_ORDER\" wo\n" +
|
||||
" LEFT JOIN (\n" +
|
||||
" SELECT\n" +
|
||||
" *\n" +
|
||||
" FROM\n" +
|
||||
" \"XCAMPUS_WORKORDER\".\"WORK_ORDER_LOG\" wol\n" +
|
||||
" WHERE\n" +
|
||||
" wol.\"OPERATE_NAME\" = '完成'\n" +
|
||||
" ) ml ON wo.\"WORK_ORDER_ID\" = ml.\"WORK_ORDER_ID\"\n" +
|
||||
" LEFT JOIN \"XCAMPUS_SPACECENTER\".\"CAMPUS\" c ON c.UUID = wo.CAMPUS_ID\n" +
|
||||
" WHERE\n" +
|
||||
" wo.PARENT_ID IS NULL\n" +
|
||||
" AND wo.ORDER_TYPE_PATH_NAME = '风险隐患'\n" +
|
||||
" AND wo.TENANT = '1821414781587267584'\n" +
|
||||
" AND EXISTS (\n" +
|
||||
" SELECT\n" +
|
||||
" 1\n" +
|
||||
" FROM\n" +
|
||||
" \"XCAMPUS_WORKORDER\".\"WORK_ORDER\" wo2\n" +
|
||||
" WHERE\n" +
|
||||
" wo.\"WORK_ORDER_ID\" = wo2.\"WORK_ORDER_ID\"\n" +
|
||||
" AND wo2.\"RELATE_WORK_ORDER_ID\" IS NULL\n" +
|
||||
" )\n" +
|
||||
" ) mwo\n" +
|
||||
" LEFT JOIN (\n" +
|
||||
" SELECT\n" +
|
||||
" wo.PARENT_ID,\n" +
|
||||
" LISTAGG(\n" +
|
||||
" REPLACE(\n" +
|
||||
" REPLACE(\n" +
|
||||
" JSON_QUERY(\n" +
|
||||
" wos.SOP_SCHEMA,\n" +
|
||||
" '$[0].sopSchema.componentsTree[0].children[0].children[*].props.label' WITH CONDITIONAL WRAPPER,\n" +
|
||||
" '[',\n" +
|
||||
" ']',\n" +
|
||||
" ','\n" +
|
||||
" ),\n" +
|
||||
" ']',\n" +
|
||||
" ''\n" +
|
||||
" ),\n" +
|
||||
" '[',\n" +
|
||||
" ''\n" +
|
||||
" ),\n" +
|
||||
" ','\n" +
|
||||
" ) WITHIN GROUP (\n" +
|
||||
" ORDER BY\n" +
|
||||
" wo.WORK_ORDER_ID\n" +
|
||||
" ) AS SOP_SCHEMA,\n" +
|
||||
" LISTAGG(\n" +
|
||||
" REPLACE(\n" +
|
||||
" REPLACE(\n" +
|
||||
" JSON_QUERY(\n" +
|
||||
" sl.CONTENT,\n" +
|
||||
" '$.sopInfo.*' WITH CONDITIONAL WRAPPER,\n" +
|
||||
" '[',\n" +
|
||||
" ']',\n" +
|
||||
" ','\n" +
|
||||
" ),\n" +
|
||||
" ']',\n" +
|
||||
" ''\n" +
|
||||
" ),\n" +
|
||||
" '[',\n" +
|
||||
" ''\n" +
|
||||
" ),\n" +
|
||||
" ','\n" +
|
||||
" ) WITHIN GROUP (\n" +
|
||||
" ORDER BY\n" +
|
||||
" wo.WORK_ORDER_ID\n" +
|
||||
" ) AS PROCESS_CONTENT,\n" +
|
||||
" LISTAGG(OBJ_NAME, ',') WITHIN GROUP (\n" +
|
||||
" ORDER BY\n" +
|
||||
" wo.WORK_ORDER_ID\n" +
|
||||
" ) AS OBJ_NAME,\n" +
|
||||
" MAX(wo.GMT_MODIFIED) AS GMT_MODIFIED\n" +
|
||||
" FROM\n" +
|
||||
" \"XCAMPUS_WORKORDER\".\"WORK_ORDER\" wo\n" +
|
||||
" LEFT JOIN (\n" +
|
||||
" SELECT\n" +
|
||||
" *\n" +
|
||||
" FROM\n" +
|
||||
" \"XCAMPUS_WORKORDER\".\"WORK_ORDER_LOG\" wol\n" +
|
||||
" WHERE\n" +
|
||||
" wol.\"OPERATE_NAME\" = '处理'\n" +
|
||||
" ) sl ON wo.\"WORK_ORDER_ID\" = sl.\"WORK_ORDER_ID\"\n" +
|
||||
" LEFT JOIN \"XCAMPUS_WORKORDER\".\"WORK_ORDER_SCHEMA\" wos ON wo.\"WORK_ORDER_ID\" = wos.\"WORK_ORDER_ID\"\n" +
|
||||
" WHERE\n" +
|
||||
" wo.PARENT_ID IN (\n" +
|
||||
" SELECT\n" +
|
||||
" WORK_ORDER_ID\n" +
|
||||
" FROM\n" +
|
||||
" \"XCAMPUS_WORKORDER\".\"WORK_ORDER\"\n" +
|
||||
" WHERE\n" +
|
||||
" ORDER_TYPE_PATH_NAME = '风险隐患'\n" +
|
||||
" )\n" +
|
||||
" AND wo.ORDER_TYPE_PATH_NAME = '系统默认子单类型'\n" +
|
||||
" AND wo.TENANT = '1821414781587267584'\n" +
|
||||
" GROUP BY\n" +
|
||||
" wo.PARENT_ID\n" +
|
||||
" ) swo ON mwo.WORK_ORDER_ID = swo.PARENT_ID\n" +
|
||||
" ) mwoe\n" +
|
||||
" LEFT JOIN (\n" +
|
||||
" SELECT\n" +
|
||||
" rwoe.\"RELATE_WORK_ORDER_ID\",\n" +
|
||||
" LISTAGG(rwoe.\"PROCESS_CONTENT\", ',') WITHIN GROUP (\n" +
|
||||
" ORDER BY\n" +
|
||||
" rwoe.WORK_ORDER_ID\n" +
|
||||
" ) AS PROCESS_CONTENT,\n" +
|
||||
" LISTAGG(rwoe.SUB_PROCESS_CONTENT, ',') WITHIN GROUP (\n" +
|
||||
" ORDER BY\n" +
|
||||
" rwoe.WORK_ORDER_ID\n" +
|
||||
" ) AS SUB_PROCESS_CONTENT,\n" +
|
||||
" LISTAGG(rwoe.SUB_SOP_SCHEMA, ',') WITHIN GROUP (\n" +
|
||||
" ORDER BY\n" +
|
||||
" rwoe.WORK_ORDER_ID\n" +
|
||||
" ) AS SUB_SOP_SCHEMA,\n" +
|
||||
" LISTAGG(rwoe.PROCESSOR_ID, ',') WITHIN GROUP (\n" +
|
||||
" ORDER BY\n" +
|
||||
" rwoe.WORK_ORDER_ID\n" +
|
||||
" ) AS PROCESSOR_ID,\n" +
|
||||
" LISTAGG(rwoe.PROCESSOR_NAME, ',') WITHIN GROUP (\n" +
|
||||
" ORDER BY\n" +
|
||||
" rwoe.WORK_ORDER_ID\n" +
|
||||
" ) AS PROCESSOR_NAME,\n" +
|
||||
" LISTAGG(rwoe.CONFIRM_PERSON_ID, ',') WITHIN GROUP (\n" +
|
||||
" ORDER BY\n" +
|
||||
" rwoe.WORK_ORDER_ID\n" +
|
||||
" ) AS CONFIRM_PERSON_ID,\n" +
|
||||
" LISTAGG(rwoe.CONFIRM_PERSON_NAME, ',') WITHIN GROUP (\n" +
|
||||
" ORDER BY\n" +
|
||||
" rwoe.WORK_ORDER_ID\n" +
|
||||
" ) AS CONFIRM_PERSON_NAME,\n" +
|
||||
" MAX(rwoe.RESERVED_TIME3) AS RESERVED_TIME3,\n" +
|
||||
" MAX(rwoe.GMT_MODIFIED) AS GMT_MODIFIED,\n" +
|
||||
" MAX(rwoe.SUB_GMT_MODIFIED) AS SUB_GMT_MODIFIED\n" +
|
||||
" FROM\n" +
|
||||
" (\n" +
|
||||
" SELECT\n" +
|
||||
" rwo.*,\n" +
|
||||
" swo.SOP_SCHEMA AS SUB_SOP_SCHEMA,\n" +
|
||||
" swo.PROCESS_CONTENT AS SUB_PROCESS_CONTENT,\n" +
|
||||
" swo.GMT_MODIFIED AS SUB_GMT_MODIFIED,\n" +
|
||||
" swo.OBJ_NAME AS OBJ_NAME\n" +
|
||||
" FROM\n" +
|
||||
" (\n" +
|
||||
" SELECT\n" +
|
||||
" wo.ID,\n" +
|
||||
" wo.WORK_ORDER_ID,\n" +
|
||||
" wo.CAMPUS_ID,\n" +
|
||||
" c.NAME AS CAMPUS_NAME,\n" +
|
||||
" wo.REMARK,\n" +
|
||||
" wo.CREATOR_ID,\n" +
|
||||
" wo.CREATOR_NAME,\n" +
|
||||
" wo.GMT_CREATE,\n" +
|
||||
" wo.GMT_MODIFIED,\n" +
|
||||
" wo.RESERVED_TIME3,\n" +
|
||||
" CASE\n" +
|
||||
" WHEN wo.\"LEVEL\" = 'P' THEN '重大'\n" +
|
||||
" ELSE '一般'\n" +
|
||||
" END AS \"LEVEL\",\n" +
|
||||
" wo.\"CONFIRM_PERSON_ID\",\n" +
|
||||
" wo.CONFIRM_PERSON_NAME,\n" +
|
||||
" wo.TENANT,\n" +
|
||||
" wo.RELATE_WORK_ORDER_ID,\n" +
|
||||
" ml.PROCESSOR_ID,\n" +
|
||||
" ml.PROCESSOR_NAME,\n" +
|
||||
" JSON_VALUE(ml.CONTENT, '$.processedContent') AS PROCESS_CONTENT\n" +
|
||||
" FROM\n" +
|
||||
" \"XCAMPUS_WORKORDER\".\"WORK_ORDER\" wo\n" +
|
||||
" LEFT JOIN (\n" +
|
||||
" SELECT\n" +
|
||||
" *\n" +
|
||||
" FROM\n" +
|
||||
" \"XCAMPUS_WORKORDER\".\"WORK_ORDER_LOG\" wol\n" +
|
||||
" WHERE\n" +
|
||||
" wol.\"OPERATE_NAME\" = '完成'\n" +
|
||||
" ) ml ON wo.\"WORK_ORDER_ID\" = ml.\"WORK_ORDER_ID\"\n" +
|
||||
" LEFT JOIN \"XCAMPUS_SPACECENTER\".\"CAMPUS\" c ON c.UUID = wo.CAMPUS_ID\n" +
|
||||
" WHERE\n" +
|
||||
" wo.PARENT_ID IS NULL\n" +
|
||||
" AND wo.ORDER_TYPE_PATH_NAME = '风险隐患'\n" +
|
||||
" AND wo.TENANT = '1821414781587267584'\n" +
|
||||
" AND EXISTS (\n" +
|
||||
" SELECT\n" +
|
||||
" 1\n" +
|
||||
" FROM\n" +
|
||||
" \"XCAMPUS_WORKORDER\".\"WORK_ORDER\" wo2\n" +
|
||||
" WHERE\n" +
|
||||
" wo.\"WORK_ORDER_ID\" = wo2.\"WORK_ORDER_ID\"\n" +
|
||||
" AND wo2.\"RELATE_WORK_ORDER_ID\" IS NOT NULL\n" +
|
||||
" )\n" +
|
||||
" ) rwo\n" +
|
||||
" LEFT JOIN (\n" +
|
||||
" SELECT\n" +
|
||||
" wo.PARENT_ID,\n" +
|
||||
" LISTAGG(\n" +
|
||||
" REPLACE(\n" +
|
||||
" REPLACE(\n" +
|
||||
" JSON_QUERY(\n" +
|
||||
" wos.SOP_SCHEMA,\n" +
|
||||
" '$[0].sopSchema.componentsTree[0].children[0].children[*].props.label' WITH CONDITIONAL WRAPPER,\n" +
|
||||
" '[',\n" +
|
||||
" ']',\n" +
|
||||
" ','\n" +
|
||||
" ),\n" +
|
||||
" ']',\n" +
|
||||
" ''\n" +
|
||||
" ),\n" +
|
||||
" '[',\n" +
|
||||
" ''\n" +
|
||||
" ),\n" +
|
||||
" ','\n" +
|
||||
" ) WITHIN GROUP (\n" +
|
||||
" ORDER BY\n" +
|
||||
" wo.WORK_ORDER_ID\n" +
|
||||
" ) AS SOP_SCHEMA,\n" +
|
||||
" LISTAGG(\n" +
|
||||
" REPLACE(\n" +
|
||||
" REPLACE(\n" +
|
||||
" JSON_QUERY(\n" +
|
||||
" sl.CONTENT,\n" +
|
||||
" '$.sopInfo.*' WITH CONDITIONAL WRAPPER,\n" +
|
||||
" '[',\n" +
|
||||
" ']',\n" +
|
||||
" ','\n" +
|
||||
" ),\n" +
|
||||
" ']',\n" +
|
||||
" ''\n" +
|
||||
" ),\n" +
|
||||
" '[',\n" +
|
||||
" ''\n" +
|
||||
" ),\n" +
|
||||
" ','\n" +
|
||||
" ) WITHIN GROUP (\n" +
|
||||
" ORDER BY\n" +
|
||||
" wo.WORK_ORDER_ID\n" +
|
||||
" ) AS PROCESS_CONTENT,\n" +
|
||||
" LISTAGG(OBJ_NAME, ',') WITHIN GROUP (\n" +
|
||||
" ORDER BY\n" +
|
||||
" wo.WORK_ORDER_ID\n" +
|
||||
" ) AS OBJ_NAME,\n" +
|
||||
" MAX(wo.GMT_MODIFIED) AS GMT_MODIFIED\n" +
|
||||
" FROM\n" +
|
||||
" \"XCAMPUS_WORKORDER\".\"WORK_ORDER\" wo\n" +
|
||||
" LEFT JOIN (\n" +
|
||||
" SELECT\n" +
|
||||
" *\n" +
|
||||
" FROM\n" +
|
||||
" \"XCAMPUS_WORKORDER\".\"WORK_ORDER_LOG\" wol\n" +
|
||||
" WHERE\n" +
|
||||
" wol.\"OPERATE_NAME\" = '处理'\n" +
|
||||
" ) sl ON wo.\"WORK_ORDER_ID\" = sl.\"WORK_ORDER_ID\"\n" +
|
||||
" LEFT JOIN \"XCAMPUS_WORKORDER\".\"WORK_ORDER_SCHEMA\" wos ON wo.\"WORK_ORDER_ID\" = wos.\"WORK_ORDER_ID\"\n" +
|
||||
" WHERE\n" +
|
||||
" wo.PARENT_ID IN (\n" +
|
||||
" SELECT\n" +
|
||||
" WORK_ORDER_ID\n" +
|
||||
" FROM\n" +
|
||||
" \"XCAMPUS_WORKORDER\".\"WORK_ORDER\"\n" +
|
||||
" WHERE\n" +
|
||||
" ORDER_TYPE_PATH_NAME = '风险隐患'\n" +
|
||||
" )\n" +
|
||||
" AND wo.ORDER_TYPE_PATH_NAME = '系统默认子单类型'\n" +
|
||||
" AND wo.TENANT = '1821414781587267584'\n" +
|
||||
" GROUP BY\n" +
|
||||
" wo.PARENT_ID\n" +
|
||||
" ) swo ON rwo.WORK_ORDER_ID = swo.PARENT_ID\n" +
|
||||
" ) rwoe\n" +
|
||||
" GROUP BY\n" +
|
||||
" rwoe.\"RELATE_WORK_ORDER_ID\"\n" +
|
||||
" ) rwoa ON mwoe.WORK_ORDER_ID = rwoa.RELATE_WORK_ORDER_ID\n");
|
||||
// 如果时间参数存在并且合法,则添加时间条件
|
||||
if (Objects.nonNull(startTime) && Objects.nonNull(endTime) && startTime.isBefore(endTime)) {
|
||||
String formattedStart = LocalDateTimeUtil.format(startTime, FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND);
|
||||
String formattedEnd = LocalDateTimeUtil.format(endTime, FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND);
|
||||
|
||||
sqlBuilder.append("WHERE\n" +
|
||||
" (\n" +
|
||||
" mwoe.GMT_MODIFIED BETWEEN TO_DATE(\n" +
|
||||
" NVL(\n" +
|
||||
" '" + formattedStart + "',\n" +
|
||||
" TO_CHAR(SYSDATE, 'YYYY-MM-DD') || ' 00:00:00'\n" +
|
||||
" ),\n" +
|
||||
" 'YYYY-MM-DD HH24:MI:SS'\n" +
|
||||
" )\n" +
|
||||
" AND TO_DATE(\n" +
|
||||
" NVL(\n" +
|
||||
" '" + formattedEnd + "',\n" +
|
||||
" TO_CHAR(SYSDATE, 'YYYY-MM-DD') || ' 23:59:59'\n" +
|
||||
" ),\n" +
|
||||
" 'YYYY-MM-DD HH24:MI:SS'\n" +
|
||||
" )\n" +
|
||||
" )\n" +
|
||||
" OR (\n" +
|
||||
" mwoe.SUB_GMT_MODIFIED BETWEEN TO_DATE(\n" +
|
||||
" NVL(\n" +
|
||||
" '" + formattedStart + "',\n" +
|
||||
" TO_CHAR(SYSDATE, 'YYYY-MM-DD') || ' 00:00:00'\n" +
|
||||
" ),\n" +
|
||||
" 'YYYY-MM-DD HH24:MI:SS'\n" +
|
||||
" )\n" +
|
||||
" AND TO_DATE(\n" +
|
||||
" NVL(\n" +
|
||||
" '" + formattedEnd + "',\n" +
|
||||
" TO_CHAR(SYSDATE, 'YYYY-MM-DD') || ' 23:59:59'\n" +
|
||||
" ),\n" +
|
||||
" 'YYYY-MM-DD HH24:MI:SS'\n" +
|
||||
" )\n" +
|
||||
" )\n" +
|
||||
" OR (\n" +
|
||||
" rwoa.GMT_MODIFIED BETWEEN TO_DATE(\n" +
|
||||
" NVL(\n" +
|
||||
" '" + formattedStart + "',\n" +
|
||||
" TO_CHAR(SYSDATE, 'YYYY-MM-DD') || ' 00:00:00'\n" +
|
||||
" ),\n" +
|
||||
" 'YYYY-MM-DD HH24:MI:SS'\n" +
|
||||
" )\n" +
|
||||
" AND TO_DATE(\n" +
|
||||
" NVL(\n" +
|
||||
" '" + formattedEnd + "',\n" +
|
||||
" TO_CHAR(SYSDATE, 'YYYY-MM-DD') || ' 23:59:59'\n" +
|
||||
" ),\n" +
|
||||
" 'YYYY-MM-DD HH24:MI:SS'\n" +
|
||||
" )\n" +
|
||||
" )\n" +
|
||||
" OR (\n" +
|
||||
" rwoa.SUB_GMT_MODIFIED BETWEEN TO_DATE(\n" +
|
||||
" NVL(\n" +
|
||||
" '" + formattedStart + "',\n" +
|
||||
" TO_CHAR(SYSDATE, 'YYYY-MM-DD') || ' 00:00:00'\n" +
|
||||
" ),\n" +
|
||||
" 'YYYY-MM-DD HH24:MI:SS'\n" +
|
||||
" )\n" +
|
||||
" AND TO_DATE(\n" +
|
||||
" NVL(\n" +
|
||||
" '" + formattedEnd + "',\n" +
|
||||
" TO_CHAR(SYSDATE, 'YYYY-MM-DD') || ' 23:59:59'\n" +
|
||||
" ),\n" +
|
||||
" 'YYYY-MM-DD HH24:MI:SS'\n" +
|
||||
" )\n" +
|
||||
" )");
|
||||
}
|
||||
return sqlBuilder.toString();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package com.jeelowcode.module.biz.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.jeelowcode.module.biz.entity.AlibabaWorkOrder;
|
||||
import com.jeelowcode.tool.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 阿里工单Mapper
|
||||
*/
|
||||
public interface AlibabaWorkOrderMapper extends BaseMapper<AlibabaWorkOrder> {
|
||||
|
||||
/**
|
||||
* 根据工单ID查询工单信息
|
||||
*
|
||||
* @param workOrderId 工单ID
|
||||
* @return 工单信息
|
||||
*/
|
||||
default AlibabaWorkOrder selectByWorkOrderId(String workOrderId) {
|
||||
return selectOne(new LambdaQueryWrapperX<AlibabaWorkOrder>()
|
||||
.eq(AlibabaWorkOrder::getWorkOrderId, workOrderId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询最大更新时间
|
||||
*
|
||||
* @return 最大更新时间
|
||||
*/
|
||||
LocalDateTime selectMaxUpdateTime();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package com.jeelowcode.module.biz.service;
|
||||
|
||||
import com.jeelowcode.module.biz.entity.AlibabaWorkOrder;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 阿里工单服务
|
||||
*/
|
||||
public interface IAlibabaWorkOrderService {
|
||||
|
||||
/**
|
||||
* 保存阿里工单
|
||||
*
|
||||
* @param workOrder 阿里工单
|
||||
* @return 影响行数
|
||||
*/
|
||||
int saveWorkOrder(AlibabaWorkOrder workOrder);
|
||||
|
||||
/**
|
||||
* 批量保存阿里工单
|
||||
*
|
||||
* @param workOrders 阿里工单
|
||||
* @return 影响行数
|
||||
*/
|
||||
int batchSaveWorkOrder(List<AlibabaWorkOrder> workOrders);
|
||||
|
||||
/**
|
||||
* 获取最大工单时间
|
||||
*
|
||||
* @return 最大工单时间
|
||||
*/
|
||||
LocalDateTime getMaxWorkOrderTime();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
package com.jeelowcode.module.biz.service.impl;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.util.IdUtil;
|
||||
import com.jeelowcode.module.biz.entity.AlibabaWorkOrder;
|
||||
import com.jeelowcode.module.biz.mapper.AlibabaWorkOrderMapper;
|
||||
import com.jeelowcode.module.biz.service.IAlibabaWorkOrderService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* 阿里工单服务实现类
|
||||
*
|
||||
* @author yangchenjj
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
public class AlibabaWorkOrderServiceImpl implements IAlibabaWorkOrderService {
|
||||
|
||||
@Resource
|
||||
private AlibabaWorkOrderMapper baseMapper;
|
||||
|
||||
/**
|
||||
* 保存工单信息
|
||||
* <p>根据工单对象的状态和数据库中的现有记录,决定执行插入或更新操作</p>
|
||||
*
|
||||
* @param workOrder 工单对象,包含要保存的工单信息
|
||||
* @return 返回操作影响的行数,0表示保存失败
|
||||
*/
|
||||
@Override
|
||||
public int saveWorkOrder(AlibabaWorkOrder workOrder) {
|
||||
// 检查工单对象及工单ID是否为空
|
||||
if (Objects.isNull(workOrder)) return 0;
|
||||
if (Objects.isNull(workOrder.getWorkOrderId())) return 0;
|
||||
|
||||
// 判断工单ID是否为空,为空表示新增工单
|
||||
if (Objects.isNull(workOrder.getId())) {
|
||||
// 先检查工单id是否有重复
|
||||
AlibabaWorkOrder dbWorkOrder = baseMapper.selectByWorkOrderId(workOrder.getWorkOrderId());
|
||||
if (Objects.nonNull(dbWorkOrder)) {
|
||||
// 如果工单已存在,则更新工单信息
|
||||
return baseMapper.updateById(workOrder.setId(dbWorkOrder.getId()));
|
||||
} else {
|
||||
// 如果工单不存在,则插入新的工单信息
|
||||
return baseMapper.insert(workOrder.setId(IdUtil.getSnowflakeNextId()));
|
||||
}
|
||||
} else {
|
||||
// 工单ID不为空,可能是更新操作
|
||||
|
||||
// 先确定数据库中是否有工单信息,如果有则更新,如果没有则插入
|
||||
AlibabaWorkOrder dbWorkOrder1 = baseMapper.selectById(workOrder.getId());
|
||||
AlibabaWorkOrder dbWorkOrder2 = baseMapper.selectByWorkOrderId(workOrder.getWorkOrderId());
|
||||
|
||||
// dbWorkOrder2优先,如果dbWorkOrder2不为空则尽量使用dbWorkOrder2
|
||||
if (Objects.isNull(dbWorkOrder2) && Objects.isNull(dbWorkOrder1)) {
|
||||
// 如果dbWorkOrder1和dbWorkOrder2都为空,则插入
|
||||
return baseMapper.insert(workOrder);
|
||||
} else {
|
||||
// 如果dbWorkOrder1和dbWorkOrder2至少有一个不为空
|
||||
if (Objects.nonNull(dbWorkOrder2)) {
|
||||
workOrder.setId(dbWorkOrder2.getId());
|
||||
} else {
|
||||
workOrder.setId(dbWorkOrder1.getId());
|
||||
}
|
||||
// 更新工单信息
|
||||
return baseMapper.updateById(workOrder);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量保存工单信息
|
||||
* <p>使用并行流处理多个工单的保存操作,提高处理效率</p>
|
||||
*
|
||||
* @param workOrders 工单对象列表
|
||||
* @return 返回成功保存的工单数量
|
||||
*/
|
||||
@Override
|
||||
public int batchSaveWorkOrder(List<AlibabaWorkOrder> workOrders) {
|
||||
// 检查工单列表是否为空
|
||||
if (CollUtil.isEmpty(workOrders)) return 0;
|
||||
// 使用并行流处理每个工单,并统计成功保存的工单数量
|
||||
return workOrders.parallelStream()
|
||||
.mapToInt(this::saveWorkOrder).sum();
|
||||
}
|
||||
|
||||
@Override
|
||||
public LocalDateTime getMaxWorkOrderTime() {
|
||||
return baseMapper.selectMaxUpdateTime();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.jeelowcode.module.biz.mapper.AlibabaWorkOrderMapper">
|
||||
|
||||
<!-- 查询最大更新时间 -->
|
||||
<select id="selectMaxUpdateTime" resultType="java.time.LocalDateTime">
|
||||
select greatest(
|
||||
max(gmt_modified),
|
||||
max(gmt_sub_modified),
|
||||
max(gmt_relate_modified),
|
||||
max(gmt_relate_sub_modified)
|
||||
)
|
||||
from lc_alibaba_work_order
|
||||
</select>
|
||||
|
||||
</mapper>
|
||||
@@ -16,13 +16,13 @@ import org.springframework.test.context.jdbc.Sql;
|
||||
|
||||
/**
|
||||
* 依赖内存 DB + Redis 的单元测试
|
||||
*
|
||||
* <p>
|
||||
* 相比 {@link BaseDbUnitTest} 来说,额外增加了内存 Redis
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE, classes = BaseDbAndRedisUnitTest.Application.class)
|
||||
@ActiveProfiles("unit-test") // 设置使用 application-unit-test 配置文件
|
||||
@ActiveProfiles("local") // 设置使用 application-unit-test 配置文件
|
||||
@Sql(scripts = "/sql/clean.sql", executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD) // 每个单元测试结束后,清理 DB
|
||||
public class BaseDbAndRedisUnitTest {
|
||||
|
||||
|
||||
Reference in New Issue
Block a user