From 4ef214d0cafbbe8e8c87008d698e4f254c7bcd3a Mon Sep 17 00:00:00 2001 From: pepsi Date: Sat, 17 Sep 2022 10:04:14 +0800 Subject: [PATCH] init xlog project --- .gitignore | 39 ++++ pom.xml | 81 +++++++ xlog-api/pom.xml | 55 +++++ .../java/cn/axzo/xlog/api/OperateLogApi.java | 21 ++ .../cn/axzo/xlog/api/dto/OperateLogReq.java | 126 +++++++++++ xlog-server/pom.xml | 156 +++++++++++++ .../cn/axzo/xlog/server/XlogApplication.java | 43 ++++ .../xlog/server/config/MybatisPlusConfig.java | 47 ++++ .../server/config/OperateLogMqConsumer.java | 44 ++++ .../xlog/server/config/RabbitMqConfig.java | 41 ++++ .../server/controller/BaseController.java | 10 + .../controller/api/OperateLogController.java | 20 ++ .../axzo/xlog/server/entity/BaseEntity.java | 39 ++++ .../server/entity/OperateLogRecordEntity.java | 143 ++++++++++++ .../java/cn/axzo/xlog/server/enums/IEnum.java | 28 +++ .../axzo/xlog/server/enums/IdentityType.java | 52 +++++ .../axzo/xlog/server/enums/LogGradeEnum.java | 32 +++ .../server/exception/ServiceException.java | 18 ++ .../xlog/server/mapper/OperateLogMapper.java | 15 ++ .../repository/OperateLogRepository.java | 17 ++ .../impl/OperateLogRepositoryImpl.java | 27 +++ .../server/service/OperateLogService.java | 26 +++ .../service/converter/EntityConverter.java | 15 ++ .../service/impl/OperateLogServiceImpl.java | 63 ++++++ xlog-server/src/main/resources/bootstrap.yml | 41 ++++ .../src/main/resources/logback-spring.xml | 210 ++++++++++++++++++ .../resources/mapper/OperateLogMapper.xml | 7 + .../xlog/server/XlogApplicationTestBase.java | 16 ++ .../server/config/RabbitMqConsumerTest.java | 51 +++++ .../server/service/OperateLogServiceTest.java | 64 ++++++ 30 files changed, 1547 insertions(+) create mode 100644 .gitignore create mode 100644 pom.xml create mode 100644 xlog-api/pom.xml create mode 100644 xlog-api/src/main/java/cn/axzo/xlog/api/OperateLogApi.java create mode 100644 xlog-api/src/main/java/cn/axzo/xlog/api/dto/OperateLogReq.java create mode 100644 xlog-server/pom.xml create mode 100644 xlog-server/src/main/java/cn/axzo/xlog/server/XlogApplication.java create mode 100644 xlog-server/src/main/java/cn/axzo/xlog/server/config/MybatisPlusConfig.java create mode 100644 xlog-server/src/main/java/cn/axzo/xlog/server/config/OperateLogMqConsumer.java create mode 100644 xlog-server/src/main/java/cn/axzo/xlog/server/config/RabbitMqConfig.java create mode 100644 xlog-server/src/main/java/cn/axzo/xlog/server/controller/BaseController.java create mode 100644 xlog-server/src/main/java/cn/axzo/xlog/server/controller/api/OperateLogController.java create mode 100644 xlog-server/src/main/java/cn/axzo/xlog/server/entity/BaseEntity.java create mode 100644 xlog-server/src/main/java/cn/axzo/xlog/server/entity/OperateLogRecordEntity.java create mode 100644 xlog-server/src/main/java/cn/axzo/xlog/server/enums/IEnum.java create mode 100644 xlog-server/src/main/java/cn/axzo/xlog/server/enums/IdentityType.java create mode 100644 xlog-server/src/main/java/cn/axzo/xlog/server/enums/LogGradeEnum.java create mode 100644 xlog-server/src/main/java/cn/axzo/xlog/server/exception/ServiceException.java create mode 100644 xlog-server/src/main/java/cn/axzo/xlog/server/mapper/OperateLogMapper.java create mode 100644 xlog-server/src/main/java/cn/axzo/xlog/server/repository/OperateLogRepository.java create mode 100644 xlog-server/src/main/java/cn/axzo/xlog/server/repository/impl/OperateLogRepositoryImpl.java create mode 100644 xlog-server/src/main/java/cn/axzo/xlog/server/service/OperateLogService.java create mode 100644 xlog-server/src/main/java/cn/axzo/xlog/server/service/converter/EntityConverter.java create mode 100644 xlog-server/src/main/java/cn/axzo/xlog/server/service/impl/OperateLogServiceImpl.java create mode 100644 xlog-server/src/main/resources/bootstrap.yml create mode 100644 xlog-server/src/main/resources/logback-spring.xml create mode 100644 xlog-server/src/main/resources/mapper/OperateLogMapper.xml create mode 100644 xlog-server/src/test/java/cn/axzo/xlog/server/XlogApplicationTestBase.java create mode 100644 xlog-server/src/test/java/cn/axzo/xlog/server/config/RabbitMqConsumerTest.java create mode 100644 xlog-server/src/test/java/cn/axzo/xlog/server/service/OperateLogServiceTest.java diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a66b8e2 --- /dev/null +++ b/.gitignore @@ -0,0 +1,39 @@ +HELP.md +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ + +application-local.yml +*.log + +rebel.xml +.flattened-pom.xml \ No newline at end of file diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..93c8775 --- /dev/null +++ b/pom.xml @@ -0,0 +1,81 @@ + + 4.0.0 + + xlog-api + xlog-server + + + + cn.axzo.infra + axzo-parent + 2.4.13 + + + cn.axzo.xlog + xlog + 1.0.0-SNAPSHOT + pom + + xlog + http://maven.apache.org + + + UTF-8 + 1.4.2.Final + 2.0.0-SNAPSHOT + 2.0.0-SNAPSHOT + + + + + + cn.axzo.infra + axzo-bom + ${axzo-bom.version} + pom + import + + + + cn.axzo.infra + axzo-dependencies + ${axzo-dependencies.version} + pom + import + + + + + + + org.projectlombok + lombok + provided + + + + + ${project.artifactId} + + + org.apache.maven.plugins + maven-compiler-plugin + + + + org.projectlombok + lombok + ${lombok.version} + + + org.mapstruct + mapstruct-processor + ${mapstruct.version} + + + + + + + diff --git a/xlog-api/pom.xml b/xlog-api/pom.xml new file mode 100644 index 0000000..fc1512c --- /dev/null +++ b/xlog-api/pom.xml @@ -0,0 +1,55 @@ + + + + xlog + cn.axzo.xlog + 1.0.0-SNAPSHOT + ../pom.xml + + + 4.0.0 + + xlog-api + jar + + xlog-api + http://maven.apache.org + + + UTF-8 + + + + + + javax.validation + validation-api + + + + org.hibernate.validator + hibernate-validator + + + + org.springframework.cloud + spring-cloud-starter-openfeign + + + + com.fasterxml.jackson.core + jackson-databind + + + + cn.axzo.framework + axzo-common + + + + + + + + diff --git a/xlog-api/src/main/java/cn/axzo/xlog/api/OperateLogApi.java b/xlog-api/src/main/java/cn/axzo/xlog/api/OperateLogApi.java new file mode 100644 index 0000000..b0663f6 --- /dev/null +++ b/xlog-api/src/main/java/cn/axzo/xlog/api/OperateLogApi.java @@ -0,0 +1,21 @@ +package cn.axzo.xlog.api; + +import cn.axzo.xlog.api.dto.OperateLogReq; +import cn.azxo.framework.common.model.CommonResponse; +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; + +/*** + * @author: pepsi + * @description: TODO + * @date: 2022/9/16 + */ +@FeignClient(name = "xlog", url = "http://xlog:10999") +public interface OperateLogApi { + + @PostMapping("/api/operateLog/create") + CommonResponse operateLogCreate(@RequestBody OperateLogReq req); + + +} diff --git a/xlog-api/src/main/java/cn/axzo/xlog/api/dto/OperateLogReq.java b/xlog-api/src/main/java/cn/axzo/xlog/api/dto/OperateLogReq.java new file mode 100644 index 0000000..35ce911 --- /dev/null +++ b/xlog-api/src/main/java/cn/axzo/xlog/api/dto/OperateLogReq.java @@ -0,0 +1,126 @@ +package cn.axzo.xlog.api.dto; + +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.experimental.Accessors; + +import javax.validation.constraints.NotNull; +import java.util.Date; + +/*** + * @author: pepsi + * @description: 操作日志信息 + * @date: 2022/9/15 + */ +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +@Accessors(chain = true) +public class OperateLogReq { + /** + * 调用方服务名 + */ + private String serviceName; + + /** + * 功能Code + */ + private String featureCode; + + /** + * 功能name + */ + private String featureName; + + /** + * 日志等级 为空默认P4 请参照 {@link cn.axzo.xlog.api.enums.LogGradeEnum} + */ + private Integer logGrade = 4; + + /** + * 操作时间 + */ + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + private Date operateTime; + + /** + * 操作人安心筑Id + */ + @NotNull(message = "操作人Id不能为空") + private Long identityId; + + /** + * 人员类型 1:工人 2:班组长 3:从业人员..实际情况拓展 + * 请参照 {@link cn.axzo.xlog.api.enums.IdentityType} + */ + @NotNull(message = "人员类型身份不能为空") + private Integer identityType; + /** + * 所属工作台Id + */ + private Long workspaceId; + + /** + * 所属单位Id + */ + private Long ouId; + + /** + * 终端类型:token认证返回的terminal字段即可 + */ + private String terminal; + /** + * 操作人Ip + */ + private String operateUserIp; + + /** + * 操作前数据 + */ + private String operateBefore; + + /** + * 操作后数据 + */ + private String operateAfter; + + /** + * 操作参数 + */ + private String operateParam; + + /** + * 内容摘要 + */ + private String contentSummary; + + /** + * 拓展字段 按需使用 + */ + private String logExt; + + /** + * 资源id 预防更小范围数据权限预留字段 + */ + private Long resourceId; + + /** + * 资源类型 预防更小范围数据权限预留字段 + */ + private Integer resourceType; + + /** + * 操作类型 1:add 2:add_batch 3:update 4:update_batch 5:delete 6:delete_batch + */ + @NotNull(message = "操作类型不能为空") + private Integer operateType; + + /** + * 操作表名 + */ + private String operateTable; +} diff --git a/xlog-server/pom.xml b/xlog-server/pom.xml new file mode 100644 index 0000000..2042180 --- /dev/null +++ b/xlog-server/pom.xml @@ -0,0 +1,156 @@ + + + xlog + cn.axzo.xlog + 1.0.0-SNAPSHOT + ../pom.xml + + + 4.0.0 + + xlog-server + jar + + xlog-server + http://maven.apache.org + + + UTF-8 + + + + + + org.springframework.cloud + spring-cloud-starter-bootstrap + + + + + org.springframework.boot + spring-boot-starter + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.springframework.boot + spring-boot-starter-validation + + + + org.springframework.boot + spring-boot-starter-amqp + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-config + + + + + cn.axzo.framework + axzo-common + 2.0.0-SNAPSHOT + + + + cn.axzo.xlog + xlog-api + 1.0.0-SNAPSHOT + + + + + mysql + mysql-connector-java + 8.0.30 + runtime + + + + + com.baomidou + mybatis-plus-boot-starter + + + + + org.projectlombok + lombok + + + + com.github.xiaoymin + knife4j-spring-boot-starter + 3.0.3 + + + + com.alibaba + fastjson + + + + org.mapstruct + mapstruct + 1.4.2.Final + + + + org.mapstruct + mapstruct-processor + 1.4.2.Final + provided + + + + + org.springframework.boot + spring-boot-starter-test + test + + + + junit + junit + test + + + + + + ${project.artifactId} + + + org.springframework.boot + spring-boot-maven-plugin + + + + org.apache.maven.plugins + maven-compiler-plugin + + + + org.projectlombok + lombok + ${lombok.version} + + + org.mapstruct + mapstruct-processor + ${mapstruct.version} + + + + + + + diff --git a/xlog-server/src/main/java/cn/axzo/xlog/server/XlogApplication.java b/xlog-server/src/main/java/cn/axzo/xlog/server/XlogApplication.java new file mode 100644 index 0000000..f5dbc63 --- /dev/null +++ b/xlog-server/src/main/java/cn/axzo/xlog/server/XlogApplication.java @@ -0,0 +1,43 @@ +package cn.axzo.xlog.server; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.client.discovery.EnableDiscoveryClient; +import org.springframework.cloud.openfeign.EnableFeignClients; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.core.env.Environment; + +/*** + * @author: pepsi + * @description: TODO + * @date: 2022/9/16 + */ +@EnableFeignClients(basePackages = { + +}) +@EnableDiscoveryClient +@SpringBootApplication(scanBasePackages = "cn.axzo") +public class XlogApplication { + private static final Logger logger = LoggerFactory.getLogger(XlogApplication.class); + + public static void main(String[] args) { + ConfigurableApplicationContext context = SpringApplication.run(XlogApplication.class, args); + Environment env = context.getEnvironment(); + logger.info("Application 【{}】 is running on 【{}】 environment!\n\t" + + "MySQL: \t{}\t username:{}\t\n\t" + + "Redis: \t{}:{}\t database:{}\t\n\t" + + "RabbitMQ: \t{}\t username:{},\t\n", + env.getProperty("spring.application.name"), + env.getProperty("spring.profiles.active"), + env.getProperty("spring.datasource.url"), + env.getProperty("spring.datasource.username"), + env.getProperty("spring.redis.host"), + env.getProperty("spring.redis.port"), + env.getProperty("spring.redis.database"), + env.getProperty("spring.rabbitmq.addresses"), + env.getProperty("spring.rabbitmq.username")); + } + +} diff --git a/xlog-server/src/main/java/cn/axzo/xlog/server/config/MybatisPlusConfig.java b/xlog-server/src/main/java/cn/axzo/xlog/server/config/MybatisPlusConfig.java new file mode 100644 index 0000000..ff17f23 --- /dev/null +++ b/xlog-server/src/main/java/cn/axzo/xlog/server/config/MybatisPlusConfig.java @@ -0,0 +1,47 @@ +package cn.axzo.xlog.server.config; + +import cn.axzo.xlog.server.entity.BaseEntity; +import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler; +import org.apache.ibatis.reflection.MetaObject; +import org.mybatis.spring.annotation.MapperScan; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.transaction.annotation.EnableTransactionManagement; + +import java.util.Date; + +/** + * @author + */ +@EnableTransactionManagement +@MapperScan(value = {"cn.axzo.**.mapper"}) +@Configuration +public class MybatisPlusConfig { + + private static final String SYSTEM_TENANT_ID = "agency_id"; + + + @Bean + public MetaObjectHandler EntityMetaObjectHandler() { + return new MetaObjectHandler() { + @Override + public void insertFill(MetaObject metaObject) { + Object entity = metaObject.getOriginalObject(); + if (entity instanceof BaseEntity) { + //默认有值不覆盖 + this.fillStrategy(metaObject, "createAt", new Date()); + this.fillStrategy(metaObject, "updateAt", new Date()); + } + } + + @Override + public void updateFill(MetaObject metaObject) { + Object entity = metaObject.getOriginalObject(); + if (entity instanceof BaseEntity) { + //强制覆盖 + this.setFieldValByName("updateAt", new Date(), metaObject); + } + } + }; + } +} diff --git a/xlog-server/src/main/java/cn/axzo/xlog/server/config/OperateLogMqConsumer.java b/xlog-server/src/main/java/cn/axzo/xlog/server/config/OperateLogMqConsumer.java new file mode 100644 index 0000000..d72be45 --- /dev/null +++ b/xlog-server/src/main/java/cn/axzo/xlog/server/config/OperateLogMqConsumer.java @@ -0,0 +1,44 @@ +package cn.axzo.xlog.server.config; + +import cn.axzo.xlog.api.dto.OperateLogReq; +import cn.axzo.xlog.server.service.OperateLogService; +import com.alibaba.fastjson.JSONObject; +import com.rabbitmq.client.Channel; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.amqp.core.Message; +import org.springframework.amqp.rabbit.annotation.RabbitListener; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; +import java.io.IOException; +import java.nio.charset.StandardCharsets; + +/*** + * @author: pepsi + * @description: 消费rabbit推过来的操作日志数据 + * @date: 2022/9/15 + */ +@Component +public class OperateLogMqConsumer { + private final Logger logger = LoggerFactory.getLogger(OperateLogMqConsumer.class); + + @Resource + private OperateLogService operateLogService; + + @RabbitListener(queues = RabbitMqConfig.OPERATE_LOG_QUEUE_NAME) + public void consumerOprlogs(Message message, Channel channel) throws IOException { + String msg = new String(message.getBody(), StandardCharsets.UTF_8); + try { + OperateLogReq operateLogReq = JSONObject.parseObject(msg, OperateLogReq.class); + operateLogService.insertOperaLog(operateLogReq); + } catch (Exception e) { + logger.error("handle operate log failed.", e); + //todo 失败处理 + } finally { + channel.basicAck(message.getMessageProperties().getDeliveryTag(), false); + } + } + + +} diff --git a/xlog-server/src/main/java/cn/axzo/xlog/server/config/RabbitMqConfig.java b/xlog-server/src/main/java/cn/axzo/xlog/server/config/RabbitMqConfig.java new file mode 100644 index 0000000..3594bb0 --- /dev/null +++ b/xlog-server/src/main/java/cn/axzo/xlog/server/config/RabbitMqConfig.java @@ -0,0 +1,41 @@ +package cn.axzo.xlog.server.config; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.amqp.core.Binding; +import org.springframework.amqp.core.BindingBuilder; +import org.springframework.amqp.core.DirectExchange; +import org.springframework.amqp.core.Queue; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/*** + * @author: pepsi + * @description: TODO + * @date: 2022/9/16 + */ +@Configuration +public class RabbitMqConfig { + private final Logger logger = LoggerFactory.getLogger(RabbitMqConfig.class); + // 操作日志队列 + public static final String OPERATE_LOG_QUEUE_NAME = "unified.operate.log"; + public static final String OPERATE_LOG_EXCHANGE = "unified.operate.log.exchange"; + public static final String OPERATE_LOG_ROUTING_KEY = "unified.operate.log.routingKey"; + + @Bean + public Queue operateLogQueue() { + return new Queue(OPERATE_LOG_QUEUE_NAME, true); + } + + @Bean + public DirectExchange operateLogExchange() { + return new DirectExchange(OPERATE_LOG_EXCHANGE, true, false); + } + + @Bean + public Binding operateLogBindingDirect(DirectExchange exchange, Queue oprlogeQueue) { + Binding binding = BindingBuilder.bind(oprlogeQueue).to(exchange).with(OPERATE_LOG_ROUTING_KEY); + logger.info("rabbitmq queue:[{}] binding exchange:[{}] success.", oprlogeQueue.getName(), exchange.getName()); + return binding; + } +} diff --git a/xlog-server/src/main/java/cn/axzo/xlog/server/controller/BaseController.java b/xlog-server/src/main/java/cn/axzo/xlog/server/controller/BaseController.java new file mode 100644 index 0000000..119d723 --- /dev/null +++ b/xlog-server/src/main/java/cn/axzo/xlog/server/controller/BaseController.java @@ -0,0 +1,10 @@ +package cn.axzo.xlog.server.controller; + +/*** + * @author: pepsi + * @description: TODO + * @date: 2022/9/16 + */ +public abstract class BaseController { + +} diff --git a/xlog-server/src/main/java/cn/axzo/xlog/server/controller/api/OperateLogController.java b/xlog-server/src/main/java/cn/axzo/xlog/server/controller/api/OperateLogController.java new file mode 100644 index 0000000..f66488d --- /dev/null +++ b/xlog-server/src/main/java/cn/axzo/xlog/server/controller/api/OperateLogController.java @@ -0,0 +1,20 @@ +package cn.axzo.xlog.server.controller.api; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/*** + * @author: pepsi + * @description: TODO + * @date: 2022/9/16 + */ +@RestController +@RequestMapping("/api") +public class OperateLogController { + + private Logger logger = LoggerFactory.getLogger(OperateLogController.class); + + +} diff --git a/xlog-server/src/main/java/cn/axzo/xlog/server/entity/BaseEntity.java b/xlog-server/src/main/java/cn/axzo/xlog/server/entity/BaseEntity.java new file mode 100644 index 0000000..21c67d8 --- /dev/null +++ b/xlog-server/src/main/java/cn/axzo/xlog/server/entity/BaseEntity.java @@ -0,0 +1,39 @@ +package cn.axzo.xlog.server.entity; + +import com.alibaba.fastjson.annotation.JSONField; +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.extension.activerecord.Model; +import lombok.Getter; +import lombok.Setter; + +import java.util.Date; + +/** + * @Author: liyong.tian + * @Date: 2022/9/5 + * @Description: + */ +@Getter +@Setter +public abstract class BaseEntity> extends Model { + + @TableId(value = "id", type = IdType.AUTO) + private Long id; + + /** + * 是否删除:0否 1是 + */ + @TableField(value = "is_delete", fill = FieldFill.INSERT) + private Integer isDelete = 0; + + @TableField(value = "create_at", fill = FieldFill.INSERT) + @JSONField(format = "yyyy-MM-dd HH:mm:ss") + private Date createAt; + + @TableField(value = "update_at", fill = FieldFill.INSERT_UPDATE) + @JSONField(format = "yyyy-MM-dd HH:mm:ss") + private Date updateAt; +} \ No newline at end of file diff --git a/xlog-server/src/main/java/cn/axzo/xlog/server/entity/OperateLogRecordEntity.java b/xlog-server/src/main/java/cn/axzo/xlog/server/entity/OperateLogRecordEntity.java new file mode 100644 index 0000000..cb7ce8e --- /dev/null +++ b/xlog-server/src/main/java/cn/axzo/xlog/server/entity/OperateLogRecordEntity.java @@ -0,0 +1,143 @@ +package cn.axzo.xlog.server.entity; + +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +import java.util.Date; + +/** + * 操作日志 + * + * @author tanjie@axzo.cn + * @date 2022/06/30 14:01 + */ +@Getter +@Setter +@ToString +@EqualsAndHashCode(callSuper = true) +@TableName("unified_log_record") +public class OperateLogRecordEntity extends BaseEntity { + /** + * 调用方服务名 + */ + private String serviceName; + + /** + * 功能名称 + */ + private String featureName; + + /** + * 功能名称code + */ + private String featureCode; + + /** + * 日志等级 0:p0 1:p1 2:p2 3:p3 4:p4 + */ + private Integer logGrade; + + /** + * 操作时间 + */ + private Date operateTime; + + /** + * 所属终端 + */ + private String terminal; + + /** + * 操作人id + */ + private Long identityId; + + /** + * 操作人名字 + */ + private String identityUserName; + + /** + * 操作人手机号 + */ + private String identityUserPhone; + + /** + * 操作人类型-与档案域一致 1:工人 2:班组长 3:从业人员 4:监管人员 5:运营人员 + */ + private Integer identityType; + + /** + * 工作台id + */ + private Long workspaceId; + + /** + * 单位id + */ + private Long ouId; + + /** + * 工作台名字 + */ + private String workspaceName; + + /** + * 单位名字 + */ + private String ouName; + + /** + * 资源id 预防更小范围数据权限预留字段 + */ + private Long resourceId; + + /** + * 资源类型 预防更小范围数据权限预留字段 + */ + private Integer resourceType; + + /** + * 操作类型 1:add 2:add_batch 3:update 4:update_batch 5:delete 6:delete_batch + */ + private Integer operateType; + + /** + * 操作人ip + */ + private String operateUserIp; + + /** + * 操作表名 + */ + private String operateTable; + + /** + * 操作前内容 + */ + private String operateBefore; + + /** + * 操作后内容 + */ + private String operateAfter; + + /** + * 操作参数 + */ + private String operateParam; + + /** + * 内容摘要 + */ + private String contentSummary; + + /** + * 日志拓展内容 + */ + private String logExt; +} + diff --git a/xlog-server/src/main/java/cn/axzo/xlog/server/enums/IEnum.java b/xlog-server/src/main/java/cn/axzo/xlog/server/enums/IEnum.java new file mode 100644 index 0000000..9a51e6b --- /dev/null +++ b/xlog-server/src/main/java/cn/axzo/xlog/server/enums/IEnum.java @@ -0,0 +1,28 @@ +package cn.axzo.xlog.server.enums; + +/** + * 项目名称:pudge + * 类 名 称:AbstractEnum + * 类 描 述:TODO + * 创建时间:2022/7/14 12:26 + * 创 建 人:xuyaozuo + */ +public interface IEnum { + + Integer getCode(); + + String getMessage(); + + static & IEnum> T enumFromCode(Class enumType, Integer code) { + T defaultEnum = null; + for (T c : enumType.getEnumConstants()) { + if (c.getCode().equals(code)) { + return c; + } + if (c.getCode().equals(0)) { + defaultEnum = c; + } + } + return defaultEnum; + } +} diff --git a/xlog-server/src/main/java/cn/axzo/xlog/server/enums/IdentityType.java b/xlog-server/src/main/java/cn/axzo/xlog/server/enums/IdentityType.java new file mode 100644 index 0000000..8145669 --- /dev/null +++ b/xlog-server/src/main/java/cn/axzo/xlog/server/enums/IdentityType.java @@ -0,0 +1,52 @@ +package cn.axzo.xlog.server.enums; + +import cn.axzo.xlog.server.exception.ServiceException; +import com.baomidou.mybatisplus.annotation.EnumValue; +import com.fasterxml.jackson.annotation.JsonValue; +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * 人员身份类型枚举 + * + * @author xuyaozuo + * @since 2022/5/9 21:59 + */ +@Getter +@AllArgsConstructor +public enum IdentityType implements IEnum { + + /*人员身份类型*/ + NOT_SUPPORT(0, "NOT_SUPPORT", "无效类型"), + WORKER(1, "WORKER", "工人"), + WORKER_LEADER(2, "WORKER_LEADER", "班组长"), + PRACTITIONER(3, "PRACTITIONER", "从业人员"), + REGULATOR(4, "REGULATOR", "监管人员"), + OPERATOR(5, "OPERATOR", "运营人员"), + ; + @EnumValue + @JsonValue + private final Integer code; + private final String message; + private final String desc; + + public static IdentityType getIdentityType(Integer code) { + IdentityType[] values = values(); + for (IdentityType item : values) { + if (item.getCode().equals(code)) { + return item; + } + } + throw new ServiceException("档案身份类型不匹配 code:" + code); + } + + public static IdentityType getIdentityType(String message) { + IdentityType[] values = values(); + for (IdentityType item : values) { + if (item.getMessage().equals(message)) { + return item; + } + } + throw new ServiceException("档案身份类型不匹配 message:" + message); + } +} diff --git a/xlog-server/src/main/java/cn/axzo/xlog/server/enums/LogGradeEnum.java b/xlog-server/src/main/java/cn/axzo/xlog/server/enums/LogGradeEnum.java new file mode 100644 index 0000000..92bda8e --- /dev/null +++ b/xlog-server/src/main/java/cn/axzo/xlog/server/enums/LogGradeEnum.java @@ -0,0 +1,32 @@ +package cn.axzo.xlog.server.enums; + +import lombok.Getter; + +/** + * @author : liuchuntao + * @date : 2022/6/28 15:53 + * @description : 日志等级 + */ +@Getter +public enum LogGradeEnum { + + P0(0, "P0"), + + P1(1, "P1"), + + P2(2, "P2"), + + P3(3, "P3"), + + P4(4, "P4"); + + public final Integer value; + + public final String desc; + + LogGradeEnum(Integer value, String desc) { + this.value = value; + this.desc = desc; + } + +} diff --git a/xlog-server/src/main/java/cn/axzo/xlog/server/exception/ServiceException.java b/xlog-server/src/main/java/cn/axzo/xlog/server/exception/ServiceException.java new file mode 100644 index 0000000..3d8a3d6 --- /dev/null +++ b/xlog-server/src/main/java/cn/axzo/xlog/server/exception/ServiceException.java @@ -0,0 +1,18 @@ +package cn.axzo.xlog.server.exception; + +/** + * @author Smile + * 服务异常 + */ +public class ServiceException extends RuntimeException { + + public ServiceException(String msg) { + super(msg); + } + + public static void error(boolean condition, String msg) { + if (!condition) { + throw new ServiceException(msg); + } + } +} diff --git a/xlog-server/src/main/java/cn/axzo/xlog/server/mapper/OperateLogMapper.java b/xlog-server/src/main/java/cn/axzo/xlog/server/mapper/OperateLogMapper.java new file mode 100644 index 0000000..8624c97 --- /dev/null +++ b/xlog-server/src/main/java/cn/axzo/xlog/server/mapper/OperateLogMapper.java @@ -0,0 +1,15 @@ +package cn.axzo.xlog.server.mapper; + +import cn.axzo.xlog.server.entity.OperateLogRecordEntity; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; + +/*** + * @author: pepsi + * @description: TODO + * @date: 2022/9/15 + */ +@Mapper +public interface OperateLogMapper extends BaseMapper { + +} diff --git a/xlog-server/src/main/java/cn/axzo/xlog/server/repository/OperateLogRepository.java b/xlog-server/src/main/java/cn/axzo/xlog/server/repository/OperateLogRepository.java new file mode 100644 index 0000000..532a3bd --- /dev/null +++ b/xlog-server/src/main/java/cn/axzo/xlog/server/repository/OperateLogRepository.java @@ -0,0 +1,17 @@ +package cn.axzo.xlog.server.repository; + +import cn.axzo.xlog.server.entity.OperateLogRecordEntity; + +/*** + * @author: pepsi + * @description: TODO + * @date: 2022/9/15 + */ +public interface OperateLogRepository { + + /** + * @param user + * @return + */ + OperateLogRecordEntity save(OperateLogRecordEntity user); +} diff --git a/xlog-server/src/main/java/cn/axzo/xlog/server/repository/impl/OperateLogRepositoryImpl.java b/xlog-server/src/main/java/cn/axzo/xlog/server/repository/impl/OperateLogRepositoryImpl.java new file mode 100644 index 0000000..337c8b7 --- /dev/null +++ b/xlog-server/src/main/java/cn/axzo/xlog/server/repository/impl/OperateLogRepositoryImpl.java @@ -0,0 +1,27 @@ +package cn.axzo.xlog.server.repository.impl; + +import cn.axzo.xlog.server.entity.OperateLogRecordEntity; +import cn.axzo.xlog.server.mapper.OperateLogMapper; +import cn.axzo.xlog.server.repository.OperateLogRepository; +import org.springframework.stereotype.Repository; + +import javax.annotation.Resource; + +/*** + * @author: pepsi + * @description: TODO + * @date: 2022/9/15 + */ +@Repository +public class OperateLogRepositoryImpl implements OperateLogRepository { + + @Resource + private OperateLogMapper mapper; + + @Override + public OperateLogRecordEntity save(OperateLogRecordEntity logRecordEntity) { + mapper.insert(logRecordEntity); + return logRecordEntity; + } + +} diff --git a/xlog-server/src/main/java/cn/axzo/xlog/server/service/OperateLogService.java b/xlog-server/src/main/java/cn/axzo/xlog/server/service/OperateLogService.java new file mode 100644 index 0000000..0bbe9b8 --- /dev/null +++ b/xlog-server/src/main/java/cn/axzo/xlog/server/service/OperateLogService.java @@ -0,0 +1,26 @@ +package cn.axzo.xlog.server.service; + +import cn.axzo.xlog.api.dto.OperateLogReq; +import cn.axzo.xlog.server.entity.OperateLogRecordEntity; + +/*** + * @author: pepsi + * @description: TODO + * @date: 2022/9/15 + */ +public interface OperateLogService { + + /** + * @param operateLogReq + * @return + */ + boolean insertOperaLog(OperateLogReq operateLogReq); + + /** + * 字段补全 + * + * @param operateLogReq + * @return + */ + OperateLogRecordEntity fieldFill(OperateLogReq operateLogReq); +} diff --git a/xlog-server/src/main/java/cn/axzo/xlog/server/service/converter/EntityConverter.java b/xlog-server/src/main/java/cn/axzo/xlog/server/service/converter/EntityConverter.java new file mode 100644 index 0000000..5728c38 --- /dev/null +++ b/xlog-server/src/main/java/cn/axzo/xlog/server/service/converter/EntityConverter.java @@ -0,0 +1,15 @@ +package cn.axzo.xlog.server.service.converter; + +import java.util.List; + +/** + * @Author: liyong.tian + * @Date: 2022/9/5 + * @Description: + */ +public interface EntityConverter { + + V toVm(E var); + + List toVm(List var); +} diff --git a/xlog-server/src/main/java/cn/axzo/xlog/server/service/impl/OperateLogServiceImpl.java b/xlog-server/src/main/java/cn/axzo/xlog/server/service/impl/OperateLogServiceImpl.java new file mode 100644 index 0000000..a5e4a1e --- /dev/null +++ b/xlog-server/src/main/java/cn/axzo/xlog/server/service/impl/OperateLogServiceImpl.java @@ -0,0 +1,63 @@ +package cn.axzo.xlog.server.service.impl; + +import cn.axzo.xlog.api.dto.OperateLogReq; +import cn.axzo.xlog.server.entity.OperateLogRecordEntity; +import cn.axzo.xlog.server.enums.IdentityType; +import cn.axzo.xlog.server.repository.OperateLogRepository; +import cn.axzo.xlog.server.service.OperateLogService; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; + +/*** + * @author: pepsi + * @description: TODO + * @date: 2022/9/15 + */ +@Service +public class OperateLogServiceImpl implements OperateLogService { + @Resource + private OperateLogRepository operateLogRepository; + + @Override + public boolean insertOperaLog(OperateLogReq operateLogReq) { + //调用接口字段补全 + OperateLogRecordEntity record = fieldFill(operateLogReq); + //落库 + operateLogRepository.save(record); + return true; + } + + @Override + public OperateLogRecordEntity fieldFill(OperateLogReq req) { + //补充 termimnal identityType featureName + IdentityType type = IdentityType.getIdentityType(req.getIdentityType()); + OperateLogRecordEntity unifiedLogRecord = new OperateLogRecordEntity(); + unifiedLogRecord.setServiceName(req.getServiceName()); + + unifiedLogRecord.setFeatureCode(req.getFeatureCode()); + unifiedLogRecord.setFeatureName(req.getFeatureName()); + unifiedLogRecord.setLogGrade(req.getLogGrade()); + unifiedLogRecord.setOperateTime(req.getOperateTime()); + unifiedLogRecord.setTerminal(req.getTerminal()); + unifiedLogRecord.setIdentityId(req.getIdentityId()); + //不用 enums + unifiedLogRecord.setIdentityType(type.getCode()); + unifiedLogRecord.setWorkspaceId(req.getWorkspaceId()); + unifiedLogRecord.setOuId(req.getOuId()); + unifiedLogRecord.setOperateUserIp(req.getOperateUserIp()); + unifiedLogRecord.setOperateBefore(req.getOperateBefore()); + unifiedLogRecord.setOperateAfter(req.getOperateAfter()); + unifiedLogRecord.setOperateParam(req.getOperateParam()); + unifiedLogRecord.setContentSummary(req.getContentSummary()); + unifiedLogRecord.setLogExt(req.getLogExt()); + unifiedLogRecord.setResourceId(req.getResourceId()); + unifiedLogRecord.setOperateTable(req.getOperateTable()); + unifiedLogRecord.setOperateType(req.getOperateType()); + unifiedLogRecord.setResourceType(req.getResourceType()); + + //todo 缓存方式 + 通过接口方式调用 workspaceApi、profileApi获取name、单位等信息, + + return unifiedLogRecord; + } +} diff --git a/xlog-server/src/main/resources/bootstrap.yml b/xlog-server/src/main/resources/bootstrap.yml new file mode 100644 index 0000000..01fb2c0 --- /dev/null +++ b/xlog-server/src/main/resources/bootstrap.yml @@ -0,0 +1,41 @@ +spring: + application: + name: xlog + cloud: + nacos: + config: + server-addr: ${NACOS_HOST:test1-nacos.axzo.cn}:${NACOS_PORT:80} + file-extension: yaml + namespace: ${NACOS_NAMESPACE_ID:6b278234-1409-4054-beb7-4bbc0def8e54} + prefix: ${spring.application.name} + profiles: + active: ${NACOS_PROFILES_ACTIVE:test1} + main: + allow-bean-definition-overriding: true + datasource: + hikari: + pool-name: xlog_HikariCP + minimum-idle: 2 + idle-timeout: 120000 + maximum-pool-size: 20 + auto-commit: true + max-lifetime: 1200000 + connection-timeout: 600000 + connection-test-query: SELECT 1 +mybatis-plus: + type-aliases-package: cn.axzo.xlog.domain + configuration: + auto-mapping-behavior: full + map-underscore-to-camel-case: true + log-impl: org.apache.ibatis.logging.stdout.StdOutImpl #这个配置会将执行的sql打印出来,在开发或测试的时候可以用 + #配置扫描xml + mapper-locations: classpath*:mapper/**/*.xml + global-config: + db-config: + id-type: auto + logic-delete-value: 1 #逻辑已删除值(默认为 1) + logic-not-delete-value: 0 #逻辑未删除值(默认为 0) + logic-delete-field: is_delete #逻辑删除字段 +logging: + level: + root: DEBUG \ No newline at end of file diff --git a/xlog-server/src/main/resources/logback-spring.xml b/xlog-server/src/main/resources/logback-spring.xml new file mode 100644 index 0000000..6dd3968 --- /dev/null +++ b/xlog-server/src/main/resources/logback-spring.xml @@ -0,0 +1,210 @@ + + + + + + + + + + + + + + + + + + + + ${PROJECT_NAME} + + + ${LOG_PATH}/error.log + + ${LOG_PATH}/error/error-%d{yyyy-MM-dd}.%i.log + + 30MB + + ${MAX_HISTORY} + + 1GB + + true + + + true + + + ${FILE_LOG_PATTERN} + utf-8 + + + + error + ACCEPT + DENY + + + + + + ${LOG_PATH}/warn.log + + ${LOG_PATH}/warn/warn-%d{yyyy-MM-dd}.%i.log + + 30MB + + ${MAX_HISTORY} + + 1GB + + true + + + true + + + ${FILE_LOG_PATTERN} + utf-8 + + + + warn + ACCEPT + DENY + + + + + + ${LOG_PATH}/info.log + + ${LOG_PATH}/info/info-%d{yyyy-MM-dd}.%i.log + + 30MB + + ${MAX_HISTORY} + + 1GB + + true + + + true + + + ${FILE_LOG_PATTERN} + utf-8 + + + + + info + ACCEPT + DENY + + + + + + ${LOG_PATH}/debug.log + + ${LOG_PATH}/debug/debug-%d{yyyy-MM-dd}.%i.log + + 30MB + + ${MAX_HISTORY} + + 1GB + + true + + + true + + + ${FILE_LOG_PATTERN} + utf-8 + + + + + debug + ACCEPT + DENY + + + + + + + ${LOG_PATTERN} + utf-8 + + + + info + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/xlog-server/src/main/resources/mapper/OperateLogMapper.xml b/xlog-server/src/main/resources/mapper/OperateLogMapper.xml new file mode 100644 index 0000000..7f2ba97 --- /dev/null +++ b/xlog-server/src/main/resources/mapper/OperateLogMapper.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/xlog-server/src/test/java/cn/axzo/xlog/server/XlogApplicationTestBase.java b/xlog-server/src/test/java/cn/axzo/xlog/server/XlogApplicationTestBase.java new file mode 100644 index 0000000..cab822f --- /dev/null +++ b/xlog-server/src/test/java/cn/axzo/xlog/server/XlogApplicationTestBase.java @@ -0,0 +1,16 @@ +package cn.axzo.xlog.server; + +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +/*** + * @author: pepsi + * @description: TODO + * @date: 2022/9/16 + */ +@RunWith(SpringRunner.class) +@SpringBootTest +public class XlogApplicationTestBase { + +} diff --git a/xlog-server/src/test/java/cn/axzo/xlog/server/config/RabbitMqConsumerTest.java b/xlog-server/src/test/java/cn/axzo/xlog/server/config/RabbitMqConsumerTest.java new file mode 100644 index 0000000..d268a76 --- /dev/null +++ b/xlog-server/src/test/java/cn/axzo/xlog/server/config/RabbitMqConsumerTest.java @@ -0,0 +1,51 @@ +package cn.axzo.xlog.server.config; + +import cn.axzo.xlog.api.dto.OperateLogReq; +import cn.axzo.xlog.server.XlogApplicationTestBase; +import com.alibaba.fastjson.JSONObject; +import org.junit.Test; +import org.springframework.amqp.rabbit.core.RabbitTemplate; + +import javax.annotation.Resource; +import java.util.Date; + +/*** + * @author: pepsi + * @description: TODO + * @date: 2022/9/16 + */ +public class RabbitMqConsumerTest extends XlogApplicationTestBase { + + @Resource + private RabbitTemplate rabbitTemplate; + + @Test + public void sendMsg() throws InterruptedException { + for (int i = 0; i < 10; i++) { + OperateLogReq reqData = new OperateLogReq(); + reqData.setLogGrade(1); + reqData.setLogExt("test"); + reqData.setIdentityId(1L); + reqData.setOperateAfter("test"); + reqData.setOperateParam("test"); + reqData.setFeatureCode("test"); + reqData.setOperateTable("test"); + reqData.setOperateType(1); + reqData.setContentSummary("test"); + reqData.setOperateTime(new Date()); + reqData.setServiceName("test"); + reqData.setOuId(1L); + reqData.setOperateUserIp("test"); + reqData.setWorkspaceId(1L); + reqData.setResourceType(1); + reqData.setIdentityType(1); + reqData.setTerminal("test"); + reqData.setOperateBefore("test"); + reqData.setFeatureName("test"); + reqData.setResourceId(1L); + rabbitTemplate.convertAndSend(RabbitMqConfig.OPERATE_LOG_QUEUE_NAME, JSONObject.toJSONString(reqData)); + System.out.println("send msg success"); + } + Thread.sleep(1000 * 10); + } +} diff --git a/xlog-server/src/test/java/cn/axzo/xlog/server/service/OperateLogServiceTest.java b/xlog-server/src/test/java/cn/axzo/xlog/server/service/OperateLogServiceTest.java new file mode 100644 index 0000000..4d0f281 --- /dev/null +++ b/xlog-server/src/test/java/cn/axzo/xlog/server/service/OperateLogServiceTest.java @@ -0,0 +1,64 @@ +package cn.axzo.xlog.server.service; + +import cn.axzo.xlog.api.dto.OperateLogReq; +import cn.axzo.xlog.server.XlogApplicationTestBase; +import cn.axzo.xlog.server.entity.OperateLogRecordEntity; +import com.alibaba.fastjson.JSONObject; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.springframework.beans.factory.annotation.Autowired; + +import java.util.Date; + +/*** + * @author: pepsi + * @description: TODO + * @date: 2022/9/16 + */ +public class OperateLogServiceTest extends XlogApplicationTestBase { + + private OperateLogReq reqData; + + @Autowired + private OperateLogService operateLogService; + + @Before + public void initreqDataData() { + reqData = new OperateLogReq(); + reqData.setLogGrade(1); + reqData.setLogExt("test"); + reqData.setIdentityId(1L); + reqData.setOperateAfter("test"); + reqData.setOperateParam("test"); + reqData.setFeatureCode("test"); + reqData.setOperateTable("test"); + reqData.setOperateType(1); + reqData.setContentSummary("test"); + reqData.setOperateTime(new Date()); + reqData.setServiceName("test"); + reqData.setOuId(1L); + reqData.setOperateUserIp("test"); + reqData.setWorkspaceId(1L); + reqData.setResourceType(1); + reqData.setIdentityType(1); + reqData.setTerminal("test"); + reqData.setOperateBefore("test"); + reqData.setFeatureName("test"); + reqData.setResourceId(1L); + System.out.println(JSONObject.toJSONString(reqData)); + } + + @Test + public void testFieldFill() { + OperateLogRecordEntity entity = operateLogService.fieldFill(reqData); + Assert.assertEquals(reqData.getLogGrade(), entity.getLogGrade()); + } + + @Test + public void testInsert() { + boolean res = operateLogService.insertOperaLog(reqData); + Assert.assertTrue(res); + } + +}