50 changed files with 1502 additions and 21 deletions
			
			
		@ -0,0 +1,13 @@ | 
				
			|||
package com.epmet.dto.form; | 
				
			|||
 | 
				
			|||
import lombok.Data; | 
				
			|||
 | 
				
			|||
@Data | 
				
			|||
public class LogOperationListFormDTO { | 
				
			|||
 | 
				
			|||
    private String condition; | 
				
			|||
 | 
				
			|||
    private Integer pageNo = 1; | 
				
			|||
 | 
				
			|||
    private Integer pageSize = 10; | 
				
			|||
} | 
				
			|||
@ -0,0 +1,53 @@ | 
				
			|||
package com.epmet.dto.region; | 
				
			|||
 | 
				
			|||
import com.fasterxml.jackson.annotation.JsonFormat; | 
				
			|||
import com.fasterxml.jackson.annotation.JsonIgnore; | 
				
			|||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties; | 
				
			|||
import lombok.Data; | 
				
			|||
 | 
				
			|||
import java.util.Date; | 
				
			|||
 | 
				
			|||
/** | 
				
			|||
 * | 
				
			|||
 */ | 
				
			|||
@Data | 
				
			|||
public class LogOperationResultDTO { | 
				
			|||
 | 
				
			|||
    /** | 
				
			|||
     * 大类别。登录login,项目流转project | 
				
			|||
     */ | 
				
			|||
    private String category; | 
				
			|||
    /** | 
				
			|||
     * 类型枚举,小类别。登录login,logout退出,shift_project议题转项目等 | 
				
			|||
     */ | 
				
			|||
    private String type; | 
				
			|||
 | 
				
			|||
    /** | 
				
			|||
     * 类型枚举名称 | 
				
			|||
     */ | 
				
			|||
    private String typeDisplay; | 
				
			|||
 | 
				
			|||
    /** | 
				
			|||
     * 内容 | 
				
			|||
     */ | 
				
			|||
    private String content; | 
				
			|||
 | 
				
			|||
    /** | 
				
			|||
     * 操作目标ID | 
				
			|||
     */ | 
				
			|||
    private String targetId; | 
				
			|||
 | 
				
			|||
    /** | 
				
			|||
     * 操作人ID | 
				
			|||
     */ | 
				
			|||
    private String customerId; | 
				
			|||
    private String operatorId; | 
				
			|||
    private String operatorName; | 
				
			|||
    private String operatorMobile; | 
				
			|||
 | 
				
			|||
    /** | 
				
			|||
     * 操作时间,该时间不是插入数据的时间,而是操作发生的真实时间 | 
				
			|||
     */ | 
				
			|||
    private Long operatingTime; | 
				
			|||
 | 
				
			|||
} | 
				
			|||
@ -0,0 +1,44 @@ | 
				
			|||
//package com.epmet.enums;
 | 
				
			|||
//
 | 
				
			|||
//import lombok.Data;
 | 
				
			|||
//
 | 
				
			|||
///**
 | 
				
			|||
// * 操作日志类型枚举
 | 
				
			|||
// */
 | 
				
			|||
//public enum LogOperationTypeEnum {
 | 
				
			|||
//    LOGIN("login", "登录"),
 | 
				
			|||
//    LOGOUT("logout", "退出登录");
 | 
				
			|||
//
 | 
				
			|||
//    private String type;
 | 
				
			|||
//    private String typeDisplay;
 | 
				
			|||
//
 | 
				
			|||
//    public String getType() {
 | 
				
			|||
//        return type;
 | 
				
			|||
//    }
 | 
				
			|||
//
 | 
				
			|||
//    public String getTypeDisplay() {
 | 
				
			|||
//        return typeDisplay;
 | 
				
			|||
//    }
 | 
				
			|||
//
 | 
				
			|||
//    LogOperationTypeEnum(String type, String typeDisplay) {
 | 
				
			|||
//        this.type = type;
 | 
				
			|||
//        this.typeDisplay = typeDisplay;
 | 
				
			|||
//    }
 | 
				
			|||
//
 | 
				
			|||
//    public static LogOperationTypeEnum get(String type) {
 | 
				
			|||
//        for (LogOperationTypeEnum t : LogOperationTypeEnum.values()) {
 | 
				
			|||
//            if (t.type.equals(type)) {
 | 
				
			|||
//                return t;
 | 
				
			|||
//            }
 | 
				
			|||
//        }
 | 
				
			|||
//        return null;
 | 
				
			|||
//    }
 | 
				
			|||
//
 | 
				
			|||
//    public static String getDisplay(String type) {
 | 
				
			|||
//        LogOperationTypeEnum object = get(type);
 | 
				
			|||
//        if (object == null) {
 | 
				
			|||
//            return null;
 | 
				
			|||
//        }
 | 
				
			|||
//        return object.typeDisplay;
 | 
				
			|||
//    }
 | 
				
			|||
//}
 | 
				
			|||
@ -0,0 +1,46 @@ | 
				
			|||
package com.epmet.controller; | 
				
			|||
 | 
				
			|||
import com.epmet.commons.tools.security.user.LoginUserUtil; | 
				
			|||
import com.epmet.commons.tools.utils.IpUtils; | 
				
			|||
import com.epmet.commons.tools.utils.Result; | 
				
			|||
import com.epmet.commons.tools.validator.ValidatorUtils; | 
				
			|||
import com.epmet.dto.form.LogOperationListFormDTO; | 
				
			|||
import com.epmet.dto.region.LogOperationResultDTO; | 
				
			|||
import com.epmet.service.LogOperationService; | 
				
			|||
import org.springframework.beans.factory.annotation.Autowired; | 
				
			|||
import org.springframework.util.CollectionUtils; | 
				
			|||
import org.springframework.web.bind.annotation.PostMapping; | 
				
			|||
import org.springframework.web.bind.annotation.RequestBody; | 
				
			|||
import org.springframework.web.bind.annotation.RequestMapping; | 
				
			|||
import org.springframework.web.bind.annotation.RestController; | 
				
			|||
 | 
				
			|||
import javax.servlet.http.HttpServletRequest; | 
				
			|||
import java.util.ArrayList; | 
				
			|||
import java.util.List; | 
				
			|||
 | 
				
			|||
@RequestMapping("log/operation") | 
				
			|||
@RestController | 
				
			|||
public class LogOperationController { | 
				
			|||
 | 
				
			|||
    @Autowired | 
				
			|||
    private LogOperationService logOperationService; | 
				
			|||
 | 
				
			|||
    @Autowired | 
				
			|||
    private LoginUserUtil loginUserUtil; | 
				
			|||
 | 
				
			|||
    @PostMapping("/list") | 
				
			|||
    public Result<List<LogOperationResultDTO>> listLogOperations(@RequestBody LogOperationListFormDTO input, HttpServletRequest request) { | 
				
			|||
        ValidatorUtils.validateEntity(input); | 
				
			|||
        String condition = input.getCondition(); | 
				
			|||
        Integer pageNo = input.getPageNo(); | 
				
			|||
        Integer pageSize = input.getPageSize(); | 
				
			|||
 | 
				
			|||
        String customerId = loginUserUtil.getLoginUserCustomerId(); | 
				
			|||
        List<LogOperationResultDTO> resultList = logOperationService.listOperationLogs(condition, customerId, pageNo, pageSize); | 
				
			|||
        if (CollectionUtils.isEmpty(resultList)) { | 
				
			|||
            resultList = new ArrayList<>(); | 
				
			|||
        } | 
				
			|||
        return new Result<List<LogOperationResultDTO>>().ok(resultList); | 
				
			|||
    } | 
				
			|||
 | 
				
			|||
} | 
				
			|||
@ -0,0 +1,33 @@ | 
				
			|||
/** | 
				
			|||
 * Copyright 2018 人人开源 https://www.renren.io
 | 
				
			|||
 * <p> | 
				
			|||
 * This program is free software: you can redistribute it and/or modify | 
				
			|||
 * it under the terms of the GNU General Public License as published by | 
				
			|||
 * the Free Software Foundation, either version 3 of the License, or | 
				
			|||
 * (at your option) any later version. | 
				
			|||
 * <p> | 
				
			|||
 * This program is distributed in the hope that it will be useful, | 
				
			|||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
				
			|||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
				
			|||
 * GNU General Public License for more details. | 
				
			|||
 * <p> | 
				
			|||
 * You should have received a copy of the GNU General Public License | 
				
			|||
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
				
			|||
 */ | 
				
			|||
 | 
				
			|||
package com.epmet.dao; | 
				
			|||
 | 
				
			|||
import com.epmet.commons.mybatis.dao.BaseDao; | 
				
			|||
import com.epmet.entity.LogOperationEntity; | 
				
			|||
import org.apache.ibatis.annotations.Mapper; | 
				
			|||
 | 
				
			|||
/** | 
				
			|||
 * 操作日指标 | 
				
			|||
 * | 
				
			|||
 * @author generator generator@elink-cn.com | 
				
			|||
 * @since v1.0.0 2021-06-07 | 
				
			|||
 */ | 
				
			|||
@Mapper | 
				
			|||
public interface LogOperationDao extends BaseDao<LogOperationEntity> { | 
				
			|||
	 | 
				
			|||
} | 
				
			|||
@ -0,0 +1,89 @@ | 
				
			|||
/** | 
				
			|||
 * Copyright 2018 人人开源 https://www.renren.io
 | 
				
			|||
 * <p> | 
				
			|||
 * This program is free software: you can redistribute it and/or modify | 
				
			|||
 * it under the terms of the GNU General Public License as published by | 
				
			|||
 * the Free Software Foundation, either version 3 of the License, or | 
				
			|||
 * (at your option) any later version. | 
				
			|||
 * <p> | 
				
			|||
 * This program is distributed in the hope that it will be useful, | 
				
			|||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
				
			|||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
				
			|||
 * GNU General Public License for more details. | 
				
			|||
 * <p> | 
				
			|||
 * You should have received a copy of the GNU General Public License | 
				
			|||
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
				
			|||
 */ | 
				
			|||
 | 
				
			|||
package com.epmet.entity; | 
				
			|||
 | 
				
			|||
import com.baomidou.mybatisplus.annotation.TableName; | 
				
			|||
 | 
				
			|||
import com.epmet.commons.mybatis.entity.BaseEpmetEntity; | 
				
			|||
import lombok.Data; | 
				
			|||
import lombok.EqualsAndHashCode; | 
				
			|||
 | 
				
			|||
import java.util.Date; | 
				
			|||
 | 
				
			|||
/** | 
				
			|||
 * 操作日指标 | 
				
			|||
 * | 
				
			|||
 * @author generator generator@elink-cn.com | 
				
			|||
 * @since v1.0.0 2021-06-07 | 
				
			|||
 */ | 
				
			|||
@Data | 
				
			|||
@EqualsAndHashCode(callSuper=false) | 
				
			|||
@TableName("log_operation") | 
				
			|||
public class LogOperationEntity extends BaseEpmetEntity { | 
				
			|||
 | 
				
			|||
	private static final long serialVersionUID = 1L; | 
				
			|||
 | 
				
			|||
	/** | 
				
			|||
	 * 大类别。登录login,项目流转project | 
				
			|||
	 */ | 
				
			|||
	private String category; | 
				
			|||
    /** | 
				
			|||
     * 类型枚举,小类别。登录login,logout退出,shift_project议题转项目等 | 
				
			|||
     */ | 
				
			|||
	private String type; | 
				
			|||
 | 
				
			|||
	private String typeDisplay; | 
				
			|||
 | 
				
			|||
	private String ip; | 
				
			|||
 | 
				
			|||
	private String fromApp; | 
				
			|||
 | 
				
			|||
	private String fromClient; | 
				
			|||
 | 
				
			|||
    /** | 
				
			|||
     * 内容 | 
				
			|||
     */ | 
				
			|||
	private String content; | 
				
			|||
 | 
				
			|||
    /** | 
				
			|||
     * 操作目标ID | 
				
			|||
     */ | 
				
			|||
	private String targetId; | 
				
			|||
 | 
				
			|||
	private String customerId; | 
				
			|||
 | 
				
			|||
    /** | 
				
			|||
     * 操作人ID | 
				
			|||
     */ | 
				
			|||
	private String operatorId; | 
				
			|||
	/** | 
				
			|||
	 * 操作人姓名 | 
				
			|||
	 */ | 
				
			|||
	private String operatorName; | 
				
			|||
 | 
				
			|||
	/** | 
				
			|||
	 * 操作人手机号 | 
				
			|||
	 */ | 
				
			|||
	private String operatorMobile; | 
				
			|||
 | 
				
			|||
    /** | 
				
			|||
     * 操作时间,该时间不是插入数据的时间,而是操作发生的真实时间 | 
				
			|||
     */ | 
				
			|||
	private Date operatingTime; | 
				
			|||
 | 
				
			|||
} | 
				
			|||
@ -0,0 +1,68 @@ | 
				
			|||
package com.epmet.mq.listener; | 
				
			|||
 | 
				
			|||
import com.epmet.commons.rocketmq.constants.ConsomerGroupConstants; | 
				
			|||
import com.epmet.commons.rocketmq.constants.TopicConstants; | 
				
			|||
import com.epmet.commons.tools.enums.EnvEnum; | 
				
			|||
import com.epmet.mq.listener.listener.AuthOperationLogListener; | 
				
			|||
import com.epmet.mq.listener.listener.ProjectOperationLogListener; | 
				
			|||
import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer; | 
				
			|||
import org.apache.rocketmq.client.consumer.listener.MessageListenerConcurrently; | 
				
			|||
import org.apache.rocketmq.client.exception.MQClientException; | 
				
			|||
import org.apache.rocketmq.common.protocol.heartbeat.MessageModel; | 
				
			|||
import org.springframework.beans.factory.annotation.Value; | 
				
			|||
import org.springframework.stereotype.Component; | 
				
			|||
 | 
				
			|||
import javax.annotation.PostConstruct; | 
				
			|||
 | 
				
			|||
@Component | 
				
			|||
public class RocketMQConsumerRegister { | 
				
			|||
    @Value("${spring.profiles.active}") | 
				
			|||
    private String env; | 
				
			|||
    @Value("${rocketmq.name-server}") | 
				
			|||
    private String nameServer; | 
				
			|||
 | 
				
			|||
    /** | 
				
			|||
     * @return | 
				
			|||
     * @Description 注册监听器 | 
				
			|||
     * @author wxz | 
				
			|||
     * @date 2021.03.03 16:09 | 
				
			|||
     */ | 
				
			|||
    @PostConstruct | 
				
			|||
    public void registerAllListeners() { | 
				
			|||
        try { | 
				
			|||
            if (!EnvEnum.LOCAL.getCode().equals(env)) { | 
				
			|||
                register(nameServer, ConsomerGroupConstants.AUTH_OPERATION_LOG_GROUP, MessageModel.CLUSTERING, TopicConstants.AUTH, "*", new AuthOperationLogListener()); | 
				
			|||
                register(nameServer, ConsomerGroupConstants.PROJECT_OPERATION_LOG_GROUP, MessageModel.CLUSTERING, TopicConstants.PROJECT_CHANGED, "*", new ProjectOperationLogListener()); | 
				
			|||
            } | 
				
			|||
        } catch (MQClientException e) { | 
				
			|||
            e.printStackTrace(); | 
				
			|||
        } | 
				
			|||
    } | 
				
			|||
 | 
				
			|||
    public void register(String nameServer, String group, MessageModel messageModel, String topic, String subException, MessageListenerConcurrently listener) throws MQClientException { | 
				
			|||
        // 实例化消费者
 | 
				
			|||
        DefaultMQPushConsumer consumer = new DefaultMQPushConsumer(group); | 
				
			|||
 | 
				
			|||
        // 设置NameServer的地址
 | 
				
			|||
        consumer.setNamesrvAddr(nameServer); | 
				
			|||
        consumer.setMessageModel(messageModel); | 
				
			|||
        consumer.setInstanceName(buildInstanceName()); | 
				
			|||
        // 订阅一个或者多个Topic,以及Tag来过滤需要消费的消息
 | 
				
			|||
        consumer.subscribe(topic, subException); | 
				
			|||
        // 注册回调实现类来处理从broker拉取回来的消息
 | 
				
			|||
        consumer.registerMessageListener(listener); | 
				
			|||
        // 启动消费者实例
 | 
				
			|||
        consumer.start(); | 
				
			|||
    } | 
				
			|||
 | 
				
			|||
    private String buildInstanceName() { | 
				
			|||
        String instanceName = ""; | 
				
			|||
        for (int i = 0; i < 4; i++) { | 
				
			|||
            int t = (int) (Math.random() * 10); | 
				
			|||
            instanceName = instanceName.concat(t + ""); | 
				
			|||
        } | 
				
			|||
 | 
				
			|||
        return instanceName; | 
				
			|||
    } | 
				
			|||
 | 
				
			|||
} | 
				
			|||
@ -0,0 +1,63 @@ | 
				
			|||
package com.epmet.mq.listener.bean.log; | 
				
			|||
 | 
				
			|||
import com.epmet.commons.tools.constant.ServiceConstant; | 
				
			|||
import com.epmet.commons.tools.exception.EpmetErrorCode; | 
				
			|||
import com.epmet.commons.tools.feign.ResultDataResolver; | 
				
			|||
import com.epmet.commons.tools.utils.Result; | 
				
			|||
import com.epmet.commons.tools.utils.SpringContextUtils; | 
				
			|||
import com.epmet.dto.CustomerStaffDTO; | 
				
			|||
import com.epmet.feign.EpmetUserOpenFeignClient; | 
				
			|||
 | 
				
			|||
/** | 
				
			|||
 * 操作日志帮助类 单例 | 
				
			|||
 */ | 
				
			|||
public class LogOperationHelper implements ResultDataResolver { | 
				
			|||
 | 
				
			|||
    private EpmetUserOpenFeignClient userOpenFeignClient; | 
				
			|||
 | 
				
			|||
    private LogOperationHelper() { | 
				
			|||
    } | 
				
			|||
 | 
				
			|||
    /** | 
				
			|||
     * @Description 利用类只能加载一次的特性,保证类静态变量只能生成一份,实现单例 | 
				
			|||
     * @return | 
				
			|||
     * @author wxz | 
				
			|||
     * @date 2021.06.09 16:55 | 
				
			|||
    */ | 
				
			|||
    private static class SingletonInnerClass { | 
				
			|||
        public static LogOperationHelper instance = new LogOperationHelper(); | 
				
			|||
    } | 
				
			|||
 | 
				
			|||
    /** | 
				
			|||
     * @Description 获取实例 | 
				
			|||
     * @return | 
				
			|||
     * @author wxz | 
				
			|||
     * @date 2021.06.09 16:54 | 
				
			|||
    */ | 
				
			|||
    public static LogOperationHelper getInstance() { | 
				
			|||
        return SingletonInnerClass.instance; | 
				
			|||
    } | 
				
			|||
 | 
				
			|||
    /** | 
				
			|||
     * @Description 获取操作人信息 | 
				
			|||
     * @return | 
				
			|||
     * @author wxz | 
				
			|||
     * @date 2021.06.09 16:57 | 
				
			|||
    */ | 
				
			|||
    public OperatorInfo getOperatorInfo(String userId) { | 
				
			|||
        if (userOpenFeignClient == null) { | 
				
			|||
            synchronized (this) { | 
				
			|||
                if (userOpenFeignClient == null) { | 
				
			|||
                    userOpenFeignClient = SpringContextUtils.getBean(EpmetUserOpenFeignClient.class); | 
				
			|||
                } | 
				
			|||
            } | 
				
			|||
        } | 
				
			|||
 | 
				
			|||
        CustomerStaffDTO form = new CustomerStaffDTO(); | 
				
			|||
        form.setUserId(userId); | 
				
			|||
        Result<CustomerStaffDTO> result = userOpenFeignClient.getCustomerStaffInfoByUserId(form); | 
				
			|||
        CustomerStaffDTO staffInfo = getResultDataOrThrowsException(result, ServiceConstant.EPMET_ADMIN_SERVER, EpmetErrorCode.SERVER_ERROR.getCode(), | 
				
			|||
                "调用epmet-user服务获取staff信息发生异常"); | 
				
			|||
        return new OperatorInfo(staffInfo.getCustomerId(), staffInfo.getMobile(), staffInfo.getRealName()); | 
				
			|||
    } | 
				
			|||
} | 
				
			|||
@ -0,0 +1,12 @@ | 
				
			|||
package com.epmet.mq.listener.bean.log; | 
				
			|||
 | 
				
			|||
import lombok.AllArgsConstructor; | 
				
			|||
import lombok.Data; | 
				
			|||
 | 
				
			|||
@Data | 
				
			|||
@AllArgsConstructor | 
				
			|||
public class OperatorInfo { | 
				
			|||
    private String customerId; | 
				
			|||
    private String mobile; | 
				
			|||
    private String name; | 
				
			|||
} | 
				
			|||
@ -0,0 +1,95 @@ | 
				
			|||
package com.epmet.mq.listener.listener; | 
				
			|||
 | 
				
			|||
import com.alibaba.fastjson.JSON; | 
				
			|||
import com.epmet.auth.constants.AuthOperationEnum; | 
				
			|||
import com.epmet.commons.rocketmq.messages.LoginMQMsg; | 
				
			|||
import com.epmet.commons.tools.constant.ServiceConstant; | 
				
			|||
import com.epmet.commons.tools.distributedlock.DistributedLock; | 
				
			|||
import com.epmet.commons.tools.exception.EpmetErrorCode; | 
				
			|||
import com.epmet.commons.tools.exception.ExceptionUtils; | 
				
			|||
import com.epmet.commons.tools.exception.RenException; | 
				
			|||
import com.epmet.commons.tools.feign.ResultDataResolver; | 
				
			|||
import com.epmet.commons.tools.utils.IpUtils; | 
				
			|||
import com.epmet.commons.tools.utils.Result; | 
				
			|||
import com.epmet.commons.tools.utils.SpringContextUtils; | 
				
			|||
import com.epmet.dto.CustomerStaffDTO; | 
				
			|||
import com.epmet.entity.LogOperationEntity; | 
				
			|||
import com.epmet.feign.EpmetUserOpenFeignClient; | 
				
			|||
import com.epmet.mq.listener.bean.log.LogOperationHelper; | 
				
			|||
import com.epmet.mq.listener.bean.log.OperatorInfo; | 
				
			|||
import com.epmet.service.LogOperationService; | 
				
			|||
import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyContext; | 
				
			|||
import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyStatus; | 
				
			|||
import org.apache.rocketmq.client.consumer.listener.MessageListenerConcurrently; | 
				
			|||
import org.apache.rocketmq.common.message.MessageExt; | 
				
			|||
import org.redisson.api.RLock; | 
				
			|||
import org.slf4j.Logger; | 
				
			|||
import org.slf4j.LoggerFactory; | 
				
			|||
 | 
				
			|||
import java.util.List; | 
				
			|||
import java.util.concurrent.TimeUnit; | 
				
			|||
 | 
				
			|||
/** | 
				
			|||
 * @author wxz | 
				
			|||
 * @Description 登录操作日志监听器 | 
				
			|||
 | 
				
			|||
 * @return | 
				
			|||
 * @date 2021.06.07 16:12 | 
				
			|||
 */ | 
				
			|||
public class AuthOperationLogListener implements MessageListenerConcurrently { | 
				
			|||
 | 
				
			|||
    private Logger logger = LoggerFactory.getLogger(getClass()); | 
				
			|||
 | 
				
			|||
    @Override | 
				
			|||
    public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs, ConsumeConcurrentlyContext context) { | 
				
			|||
        try { | 
				
			|||
            msgs.forEach(msg -> consumeMessage(msg)); | 
				
			|||
        } catch (Exception e) { | 
				
			|||
            logger.error(ExceptionUtils.getErrorStackTrace(e)); | 
				
			|||
            return ConsumeConcurrentlyStatus.RECONSUME_LATER; | 
				
			|||
        } | 
				
			|||
        return ConsumeConcurrentlyStatus.CONSUME_SUCCESS; | 
				
			|||
    } | 
				
			|||
 | 
				
			|||
    private void consumeMessage(MessageExt messageExt) { | 
				
			|||
        String tags = messageExt.getTags(); | 
				
			|||
        String msg = new String(messageExt.getBody()); | 
				
			|||
        logger.info("认证操作日志监听器-收到消息内容:{}", msg); | 
				
			|||
        LoginMQMsg msgObj = JSON.parseObject(msg, LoginMQMsg.class); | 
				
			|||
 | 
				
			|||
        //获取操作人信息
 | 
				
			|||
        OperatorInfo operatorInfo = LogOperationHelper.getInstance().getOperatorInfo(msgObj.getUserId()); | 
				
			|||
        LogOperationEntity logEntity = new LogOperationEntity(); | 
				
			|||
        logEntity.setCategory(messageExt.getTopic()); | 
				
			|||
        logEntity.setType(tags); | 
				
			|||
        logEntity.setTypeDisplay(AuthOperationEnum.getDisplay(tags)); | 
				
			|||
        logEntity.setIp(msgObj.getIp()); | 
				
			|||
        logEntity.setFromApp(msgObj.getFromApp()); | 
				
			|||
        logEntity.setFromClient(msgObj.getFromClient()); | 
				
			|||
        logEntity.setTargetId(""); | 
				
			|||
        logEntity.setCustomerId(operatorInfo.getCustomerId()); | 
				
			|||
        logEntity.setOperatorId(msgObj.getUserId()); | 
				
			|||
        logEntity.setOperatorName(operatorInfo.getName()); | 
				
			|||
        logEntity.setOperatorMobile(operatorInfo.getMobile()); | 
				
			|||
        logEntity.setOperatingTime(msgObj.getLoginTime()); | 
				
			|||
        logEntity.setContent("成功登录系统"); | 
				
			|||
 | 
				
			|||
        DistributedLock distributedLock = null; | 
				
			|||
        RLock lock = null; | 
				
			|||
        try { | 
				
			|||
            distributedLock = SpringContextUtils.getBean(DistributedLock.class); | 
				
			|||
            lock = distributedLock.getLock(String.format("lock:auth_operation_log:%s:%s", logEntity.getType(), logEntity.getOperatorId()), | 
				
			|||
                    30L, 30L, TimeUnit.SECONDS); | 
				
			|||
            SpringContextUtils.getBean(LogOperationService.class).log(logEntity); | 
				
			|||
        } catch (RenException e) { | 
				
			|||
            // 如果是我们手动抛出的异常,说明在业务可控范围内。目前不需要MQ重试
 | 
				
			|||
            logger.error("【RocketMQ】添加操作日志失败:".concat(ExceptionUtils.getErrorStackTrace(e))); | 
				
			|||
        } catch (Exception e) { | 
				
			|||
            // 不是我们自己抛出的异常,可以让MQ重试
 | 
				
			|||
            logger.error("【RocketMQ】添加操作日志失败:".concat(ExceptionUtils.getErrorStackTrace(e))); | 
				
			|||
            throw e; | 
				
			|||
        } finally { | 
				
			|||
            distributedLock.unLock(lock); | 
				
			|||
        } | 
				
			|||
    } | 
				
			|||
} | 
				
			|||
@ -0,0 +1,110 @@ | 
				
			|||
package com.epmet.mq.listener.listener; | 
				
			|||
 | 
				
			|||
import com.alibaba.fastjson.JSON; | 
				
			|||
import com.epmet.commons.rocketmq.messages.LoginMQMsg; | 
				
			|||
import com.epmet.commons.rocketmq.messages.ProjectChangedMQMsg; | 
				
			|||
import com.epmet.commons.tools.distributedlock.DistributedLock; | 
				
			|||
import com.epmet.commons.tools.exception.ExceptionUtils; | 
				
			|||
import com.epmet.commons.tools.exception.RenException; | 
				
			|||
import com.epmet.commons.tools.utils.SpringContextUtils; | 
				
			|||
import com.epmet.entity.LogOperationEntity; | 
				
			|||
import com.epmet.mq.listener.bean.log.LogOperationHelper; | 
				
			|||
import com.epmet.mq.listener.bean.log.OperatorInfo; | 
				
			|||
import com.epmet.service.LogOperationService; | 
				
			|||
import org.apache.commons.lang3.StringUtils; | 
				
			|||
import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyContext; | 
				
			|||
import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyStatus; | 
				
			|||
import org.apache.rocketmq.client.consumer.listener.MessageListenerConcurrently; | 
				
			|||
import org.apache.rocketmq.common.message.MessageExt; | 
				
			|||
import org.redisson.api.RLock; | 
				
			|||
import org.slf4j.Logger; | 
				
			|||
import org.slf4j.LoggerFactory; | 
				
			|||
 | 
				
			|||
import java.util.List; | 
				
			|||
import java.util.concurrent.TimeUnit; | 
				
			|||
 | 
				
			|||
/** | 
				
			|||
 * @author wxz | 
				
			|||
 * @Description 项目操作日志监听器 | 
				
			|||
 | 
				
			|||
 * @return | 
				
			|||
 * @date 2021.06.08 22.21 | 
				
			|||
 */ | 
				
			|||
public class ProjectOperationLogListener implements MessageListenerConcurrently { | 
				
			|||
 | 
				
			|||
    private Logger logger = LoggerFactory.getLogger(getClass()); | 
				
			|||
 | 
				
			|||
    @Override | 
				
			|||
    public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs, ConsumeConcurrentlyContext context) { | 
				
			|||
        try { | 
				
			|||
            msgs.forEach(msg -> consumeMessage(msg)); | 
				
			|||
        } catch (Exception e) { | 
				
			|||
            logger.error(ExceptionUtils.getErrorStackTrace(e)); | 
				
			|||
            return ConsumeConcurrentlyStatus.RECONSUME_LATER; | 
				
			|||
        } | 
				
			|||
        return ConsumeConcurrentlyStatus.CONSUME_SUCCESS; | 
				
			|||
    } | 
				
			|||
 | 
				
			|||
    private void consumeMessage(MessageExt messageExt) { | 
				
			|||
        //String tags = messageExt.getTags();
 | 
				
			|||
        String msg = new String(messageExt.getBody()); | 
				
			|||
        logger.info("项目变动操作日志监听器-收到消息内容:{}", msg); | 
				
			|||
        ProjectChangedMQMsg msgObj = JSON.parseObject(msg, ProjectChangedMQMsg.class); | 
				
			|||
 | 
				
			|||
        String content = StringUtils.isBlank(msgObj.getOperationBrief()) ? "" : msgObj.getOperationBrief(); | 
				
			|||
 | 
				
			|||
        OperatorInfo operatorInfo = LogOperationHelper.getInstance().getOperatorInfo(msgObj.getOperatorId()); | 
				
			|||
 | 
				
			|||
        LogOperationEntity logEntity = new LogOperationEntity(); | 
				
			|||
        logEntity.setCategory(messageExt.getTopic()); | 
				
			|||
        logEntity.setType(msgObj.getOperation()); | 
				
			|||
        logEntity.setTypeDisplay(getOperationTypeDisplay(msgObj.getOperation())); | 
				
			|||
        logEntity.setTargetId(msgObj.getProjectId()); | 
				
			|||
        logEntity.setIp(msgObj.getIp()); | 
				
			|||
        logEntity.setFromApp(msgObj.getFromApp()); | 
				
			|||
        logEntity.setFromClient(msgObj.getFromClient()); | 
				
			|||
        logEntity.setCustomerId(operatorInfo.getCustomerId()); | 
				
			|||
        logEntity.setOperatorId(msgObj.getOperatorId()); | 
				
			|||
        logEntity.setOperatorMobile(operatorInfo.getMobile()); | 
				
			|||
        logEntity.setOperatorName(operatorInfo.getName()); | 
				
			|||
        logEntity.setOperatingTime(msgObj.getOperatingTime()); | 
				
			|||
        logEntity.setContent(content); | 
				
			|||
 | 
				
			|||
        DistributedLock distributedLock = null; | 
				
			|||
        RLock lock = null; | 
				
			|||
        try { | 
				
			|||
            distributedLock = SpringContextUtils.getBean(DistributedLock.class); | 
				
			|||
            lock = distributedLock.getLock(String.format("lock:project_operation_log:%s:%s", logEntity.getType(), logEntity.getTargetId()), | 
				
			|||
                    30L, 30L, TimeUnit.SECONDS); | 
				
			|||
            SpringContextUtils.getBean(LogOperationService.class).log(logEntity); | 
				
			|||
        } catch (RenException e) { | 
				
			|||
            // 如果是我们手动抛出的异常,说明在业务可控范围内。目前不需要MQ重试
 | 
				
			|||
            logger.error("【RocketMQ】添加操作日志失败:".concat(ExceptionUtils.getErrorStackTrace(e))); | 
				
			|||
        } catch (Exception e) { | 
				
			|||
            // 不是我们自己抛出的异常,可以让MQ重试
 | 
				
			|||
            logger.error("【RocketMQ】添加操作日志失败:".concat(ExceptionUtils.getErrorStackTrace(e))); | 
				
			|||
            throw e; | 
				
			|||
        } finally { | 
				
			|||
            distributedLock.unLock(lock); | 
				
			|||
        } | 
				
			|||
    } | 
				
			|||
 | 
				
			|||
    private String getOperationTypeDisplay(String type) { | 
				
			|||
        switch (type) { | 
				
			|||
            case "response": | 
				
			|||
                return "项目响应处理"; | 
				
			|||
            case "issue_shift_project": | 
				
			|||
                return "议题转项目"; | 
				
			|||
            case "close": | 
				
			|||
                return "项目结案"; | 
				
			|||
            case "return": | 
				
			|||
                return "项目退回"; | 
				
			|||
            case "transfer": | 
				
			|||
                return "项目吹哨"; | 
				
			|||
            case "created": | 
				
			|||
                return "项目立项"; | 
				
			|||
            default: | 
				
			|||
                return null; | 
				
			|||
        } | 
				
			|||
    } | 
				
			|||
} | 
				
			|||
@ -0,0 +1,28 @@ | 
				
			|||
package com.epmet.service; | 
				
			|||
 | 
				
			|||
import com.epmet.dto.region.LogOperationResultDTO; | 
				
			|||
import com.epmet.entity.LogOperationEntity; | 
				
			|||
 | 
				
			|||
import java.util.List; | 
				
			|||
 | 
				
			|||
/** | 
				
			|||
 * 操作日志 | 
				
			|||
 */ | 
				
			|||
public interface LogOperationService { | 
				
			|||
 | 
				
			|||
    /** | 
				
			|||
     * @Description 记录日志 | 
				
			|||
     * @return | 
				
			|||
     * @author wxz | 
				
			|||
     * @date 2021.06.07 21:56 | 
				
			|||
    */ | 
				
			|||
    void log(LogOperationEntity msg); | 
				
			|||
 | 
				
			|||
    /** | 
				
			|||
     * @Description 查询操作日志 列表 | 
				
			|||
     * @return | 
				
			|||
     * @author wxz | 
				
			|||
     * @date 2021.06.07 21:56 | 
				
			|||
    */ | 
				
			|||
    List<LogOperationResultDTO> listOperationLogs(String condition, String customerId, Integer pageNo, Integer pageSize); | 
				
			|||
} | 
				
			|||
@ -0,0 +1,181 @@ | 
				
			|||
package com.epmet.service.impl; | 
				
			|||
 | 
				
			|||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; | 
				
			|||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; | 
				
			|||
import com.baomidou.mybatisplus.core.metadata.IPage; | 
				
			|||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; | 
				
			|||
import com.epmet.auth.constants.AuthOperationEnum; | 
				
			|||
import com.epmet.commons.tools.constant.ServiceConstant; | 
				
			|||
import com.epmet.commons.tools.exception.EpmetErrorCode; | 
				
			|||
import com.epmet.commons.tools.feign.ResultDataResolver; | 
				
			|||
import com.epmet.commons.tools.utils.Result; | 
				
			|||
import com.epmet.dao.LogOperationDao; | 
				
			|||
import com.epmet.dto.CustomerStaffDTO; | 
				
			|||
import com.epmet.dto.form.CustomerStaffFormDTO; | 
				
			|||
import com.epmet.dto.region.LogOperationResultDTO; | 
				
			|||
import com.epmet.entity.LogOperationEntity; | 
				
			|||
import com.epmet.feign.EpmetUserOpenFeignClient; | 
				
			|||
import com.epmet.service.LogOperationService; | 
				
			|||
import org.apache.commons.lang3.StringUtils; | 
				
			|||
import org.springframework.beans.factory.annotation.Autowired; | 
				
			|||
import org.springframework.stereotype.Service; | 
				
			|||
import org.springframework.util.CollectionUtils; | 
				
			|||
 | 
				
			|||
import java.util.*; | 
				
			|||
import java.util.stream.Collectors; | 
				
			|||
 | 
				
			|||
@Service | 
				
			|||
public class LogOperationServiceImpl implements LogOperationService, ResultDataResolver { | 
				
			|||
 | 
				
			|||
    @Autowired | 
				
			|||
    private LogOperationDao logOperationDao; | 
				
			|||
 | 
				
			|||
    @Autowired | 
				
			|||
    private EpmetUserOpenFeignClient userOpenFeignClient; | 
				
			|||
 | 
				
			|||
    @Override | 
				
			|||
    public void log(LogOperationEntity msg) { | 
				
			|||
        LambdaQueryWrapper<LogOperationEntity> w = new LambdaQueryWrapper<>(); | 
				
			|||
        w.eq(LogOperationEntity::getType, msg.getType()); | 
				
			|||
        w.eq(LogOperationEntity::getTargetId, msg.getTargetId()); | 
				
			|||
        w.eq(LogOperationEntity::getOperatorId, msg.getOperatorId()); | 
				
			|||
        w.eq(LogOperationEntity::getOperatingTime, msg.getOperatingTime()); | 
				
			|||
 | 
				
			|||
        Integer existsCount = logOperationDao.selectCount(w); | 
				
			|||
        if (existsCount > 0) { | 
				
			|||
            // 该日志已存在,不做任何操作
 | 
				
			|||
            return; | 
				
			|||
        } | 
				
			|||
        logOperationDao.insert(msg); | 
				
			|||
    } | 
				
			|||
 | 
				
			|||
    @Override | 
				
			|||
    public List<LogOperationResultDTO> listOperationLogs(String condition, String customerId, Integer pageNo, Integer pageSize) { | 
				
			|||
        // 1.条件查询
 | 
				
			|||
        //List<LogOperationResultDTO> logDtos = listByOperatorMobile(condition, customerId, pageNo, pageSize);
 | 
				
			|||
        //if (CollectionUtils.isEmpty(logDtos)) {
 | 
				
			|||
        //    logDtos = listByOperatorName(condition, pageNo, pageSize);
 | 
				
			|||
        //}
 | 
				
			|||
        //
 | 
				
			|||
        //if (CollectionUtils.isEmpty(logDtos)) {
 | 
				
			|||
        //    return new ArrayList<>();
 | 
				
			|||
        //}
 | 
				
			|||
 | 
				
			|||
        // 2.直接分页查询
 | 
				
			|||
        // 条件查询,排序
 | 
				
			|||
        LambdaQueryWrapper<LogOperationEntity> w = new LambdaQueryWrapper<>(); | 
				
			|||
        if (StringUtils.isNotBlank(condition)) { | 
				
			|||
            w.like(LogOperationEntity::getOperatorName, condition) | 
				
			|||
                    .or() | 
				
			|||
                    .like(LogOperationEntity::getOperatorMobile, condition); | 
				
			|||
        } | 
				
			|||
        w.eq(LogOperationEntity::getCustomerId, customerId); | 
				
			|||
        w.orderByDesc(LogOperationEntity::getOperatingTime); | 
				
			|||
        IPage<LogOperationEntity> iPage = logOperationDao.selectPage(new Page<>(pageNo, pageSize), w); | 
				
			|||
        List<LogOperationEntity> logEntities = iPage.getRecords(); | 
				
			|||
        Set<String> userIds = logEntities.stream().map(l -> l.getOperatorId()).collect(Collectors.toSet()); | 
				
			|||
 | 
				
			|||
        return convertLogOperationEntity2DTO(logEntities, getStaffMapByUserIds(userIds)); | 
				
			|||
    } | 
				
			|||
 | 
				
			|||
    private Map<String, CustomerStaffDTO> getStaffMapByUserIds(Set<String> userIds) { | 
				
			|||
        CustomerStaffFormDTO form = new CustomerStaffFormDTO(); | 
				
			|||
        form.setUserIds(new ArrayList<>(userIds)); | 
				
			|||
        Result<List<CustomerStaffDTO>> result = userOpenFeignClient.list(form); | 
				
			|||
        List<CustomerStaffDTO> staffs = getResultDataOrThrowsException(result, ServiceConstant.EPMET_USER_SERVER, EpmetErrorCode.SERVER_ERROR.getCode(), "调用user服务发生异常"); | 
				
			|||
 | 
				
			|||
        HashMap<String, CustomerStaffDTO> staffMap = new HashMap<>(); | 
				
			|||
        staffs.forEach(s -> { | 
				
			|||
            staffMap.put(s.getUserId(), s); | 
				
			|||
        }); | 
				
			|||
 | 
				
			|||
        return staffMap; | 
				
			|||
    } | 
				
			|||
 | 
				
			|||
    /** | 
				
			|||
     * 通过操作人手机号查询操作日志列表 | 
				
			|||
     * | 
				
			|||
     * @param operatorMobile | 
				
			|||
     * @param customerId | 
				
			|||
     */ | 
				
			|||
    private List<LogOperationResultDTO> listByOperatorMobile(String operatorMobile, String customerId, Integer pageNo, Integer pageSize) { | 
				
			|||
        CustomerStaffFormDTO form = new CustomerStaffFormDTO(); | 
				
			|||
        form.setCustomerId(customerId); | 
				
			|||
        form.setMobile(operatorMobile); | 
				
			|||
        Result<List<CustomerStaffDTO>> result = userOpenFeignClient.list(form); | 
				
			|||
        List<CustomerStaffDTO> staffs = getResultDataOrThrowsException(result, ServiceConstant.EPMET_USER_SERVER, EpmetErrorCode.SERVER_ERROR.getCode(), "调用user服务发生异常"); | 
				
			|||
 | 
				
			|||
        if (staffs.size() == 0) { | 
				
			|||
            return null; | 
				
			|||
        } | 
				
			|||
        CustomerStaffDTO staff = staffs.get(0); | 
				
			|||
 | 
				
			|||
        QueryWrapper<LogOperationEntity> w = new QueryWrapper<>(); | 
				
			|||
        w.lambda() | 
				
			|||
                .eq(LogOperationEntity::getOperatorId, staff.getUserId()) | 
				
			|||
                .eq(LogOperationEntity::getDelFlag, 0) | 
				
			|||
                .orderByDesc(LogOperationEntity::getOperatingTime); | 
				
			|||
 | 
				
			|||
        IPage<LogOperationEntity> iPage = logOperationDao.selectPage(new Page<>(pageNo, pageSize), w); | 
				
			|||
 | 
				
			|||
        HashMap<String, CustomerStaffDTO> staffMap = new HashMap<>(); | 
				
			|||
        staffMap.put(staff.getUserId(), staff); | 
				
			|||
 | 
				
			|||
        return convertLogOperationEntity2DTO(iPage.getRecords(), staffMap); | 
				
			|||
    } | 
				
			|||
 | 
				
			|||
    /** | 
				
			|||
     * @Description 通过操作人姓名查询操作日志列表 | 
				
			|||
     * @return | 
				
			|||
     * @author wxz | 
				
			|||
     * @date 2021.06.08 11:12 | 
				
			|||
    */ | 
				
			|||
    private List<LogOperationResultDTO> listByOperatorName(String operatorName, Integer pageNo, Integer pageSize) { | 
				
			|||
        CustomerStaffFormDTO form = new CustomerStaffFormDTO(); | 
				
			|||
        form.setRealName(operatorName); | 
				
			|||
        Result<List<CustomerStaffDTO>> result = userOpenFeignClient.list(form); | 
				
			|||
        List<CustomerStaffDTO> staffs = getResultDataOrThrowsException(result, ServiceConstant.EPMET_USER_SERVER, EpmetErrorCode.SERVER_ERROR.getCode(), "调用user服务查询工作人员信息发生异常"); | 
				
			|||
 | 
				
			|||
        List<String> userIds = new ArrayList<>(); | 
				
			|||
        HashMap<String, CustomerStaffDTO> staffMap = new HashMap<String, CustomerStaffDTO>(); | 
				
			|||
        staffs.forEach(s -> { | 
				
			|||
            staffMap.put(s.getUserId(), s); | 
				
			|||
            userIds.add(s.getUserId()); | 
				
			|||
        }); | 
				
			|||
 | 
				
			|||
        if (CollectionUtils.isEmpty(userIds)) { | 
				
			|||
            return new ArrayList<>(); | 
				
			|||
        } | 
				
			|||
        LambdaQueryWrapper<LogOperationEntity> w = new LambdaQueryWrapper<>(); | 
				
			|||
        w.in(LogOperationEntity::getOperatorId, userIds); | 
				
			|||
        w.eq(LogOperationEntity::getDelFlag, 0); | 
				
			|||
        w.orderByDesc(LogOperationEntity::getOperatingTime); | 
				
			|||
 | 
				
			|||
        IPage<LogOperationEntity> iPage = logOperationDao.selectPage(new Page<>(pageNo, pageSize), w); | 
				
			|||
 | 
				
			|||
        return convertLogOperationEntity2DTO(iPage.getRecords(), staffMap); | 
				
			|||
    } | 
				
			|||
 | 
				
			|||
    /** | 
				
			|||
     * @Description 将操作日志entity转化为dto列表 | 
				
			|||
     * @return | 
				
			|||
     * @author wxz | 
				
			|||
     * @date 2021.06.08 11:12 | 
				
			|||
    */ | 
				
			|||
    private List<LogOperationResultDTO>  convertLogOperationEntity2DTO(List<LogOperationEntity> logOperationEntities, Map<String, CustomerStaffDTO> staffMap) { | 
				
			|||
        return logOperationEntities.stream().map(l -> { | 
				
			|||
            LogOperationResultDTO ldto = new LogOperationResultDTO(); | 
				
			|||
            ldto.setCategory(l.getCategory()); | 
				
			|||
            ldto.setContent(l.getContent()); | 
				
			|||
            ldto.setOperatingTime(l.getOperatingTime().getTime()/1000); | 
				
			|||
            ldto.setOperatorId(l.getOperatorId()); | 
				
			|||
            ldto.setTargetId(l.getTargetId()); | 
				
			|||
            ldto.setType(l.getType()); | 
				
			|||
            ldto.setTypeDisplay(l.getTypeDisplay()); | 
				
			|||
            ldto.setCustomerId(l.getCustomerId()); | 
				
			|||
            ldto.setOperatorMobile(staffMap.get(l.getOperatorId()).getMobile()); | 
				
			|||
            ldto.setOperatorName(staffMap.get(l.getOperatorId()).getRealName()); | 
				
			|||
            return ldto; | 
				
			|||
        }).collect(Collectors.toList()); | 
				
			|||
    } | 
				
			|||
} | 
				
			|||
@ -0,0 +1,21 @@ | 
				
			|||
CREATE TABLE `log_operation` ( | 
				
			|||
  `ID` varchar(64) NOT NULL COMMENT '主键ID', | 
				
			|||
  `TYPE` varchar(64) NOT NULL COMMENT '动作类型枚举', | 
				
			|||
  `TYPE_DISPLAY` varchar(64) NOT NULL COMMENT '操作类型中文展示', | 
				
			|||
  `CONTENT` varchar(512) NOT NULL COMMENT '内容', | 
				
			|||
  `CATEGORY` varchar(64) NOT NULL COMMENT '操作类型大类。例如login和logout都属于login大类。项目立项,项目流转,项目结案都属于项目大类', | 
				
			|||
  `IP` varchar(15) NOT NULL COMMENT 'IP地址', | 
				
			|||
  `FROM_APP` varchar(10) NOT NULL COMMENT '所用的APP', | 
				
			|||
  `FROM_CLIENT` varchar(10) NOT NULL COMMENT '所用的client', | 
				
			|||
  `TARGET_ID` varchar(64) NOT NULL COMMENT '操作目标ID', | 
				
			|||
  `OPERATOR_ID` varchar(64) NOT NULL COMMENT '操作人ID', | 
				
			|||
  `OPERATOR_NAME` varchar(15) NOT NULL COMMENT '操作者姓名', | 
				
			|||
  `OPERATOR_MOBILE` varchar(11) NOT NULL COMMENT '操作者电话', | 
				
			|||
  `OPERATING_TIME` datetime NOT NULL COMMENT '操作时间,该时间不是插入数据的时间,而是操作发生的真实时间', | 
				
			|||
  `DEL_FLAG` int(11) NOT NULL DEFAULT '0' COMMENT '删除标识 0.未删除 1.已删除', | 
				
			|||
  `REVISION` int(11) NOT NULL COMMENT '乐观锁', | 
				
			|||
  `CREATED_BY` varchar(32) NOT NULL COMMENT '创建人', | 
				
			|||
  `CREATED_TIME` datetime NOT NULL COMMENT '创建时间', | 
				
			|||
  `UPDATED_BY` varchar(32) NOT NULL COMMENT '更新人', | 
				
			|||
  `UPDATED_TIME` datetime NOT NULL COMMENT '更新时间' | 
				
			|||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='操作日指标' | 
				
			|||
@ -0,0 +1 @@ | 
				
			|||
alter table log_operation add CUSTOMER_ID varchar(64) comment '客户id' not null after OPERATOR_ID; | 
				
			|||
@ -0,0 +1,30 @@ | 
				
			|||
<?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.epmet.dao.LogOperationDao"> | 
				
			|||
 | 
				
			|||
    <resultMap type="com.epmet.entity.LogOperationEntity" id="logOperationMap"> | 
				
			|||
        <result property="id" column="ID"/> | 
				
			|||
        <result property="type" column="TYPE"/> | 
				
			|||
        <result property="typeDisplay" column="TYPE_DISPLAY"/> | 
				
			|||
        <result property="content" column="CONTENT"/> | 
				
			|||
        <result property="targetId" column="TARGET_ID"/> | 
				
			|||
        <result property="ip" column="IP"/> | 
				
			|||
        <result property="fromApp" column="FROM_APP"/> | 
				
			|||
        <result property="fromClient" column="FROM_CLIENT"/> | 
				
			|||
        <result property="category" column="CATEGORY"/> | 
				
			|||
        <result property="customerId" column="CUSTOMER_ID"/> | 
				
			|||
        <result property="operatorId" column="OPERATOR_ID"/> | 
				
			|||
        <result property="operatorName" column="OPERATOR_NAME"/> | 
				
			|||
        <result property="operatorMobile" column="OPERATOR_MOBILE"/> | 
				
			|||
        <result property="operatingTime" column="OPERATING_TIME"/> | 
				
			|||
        <result property="delFlag" column="DEL_FLAG"/> | 
				
			|||
        <result property="revision" column="REVISION"/> | 
				
			|||
        <result property="createdBy" column="CREATED_BY"/> | 
				
			|||
        <result property="createdTime" column="CREATED_TIME"/> | 
				
			|||
        <result property="updatedBy" column="UPDATED_BY"/> | 
				
			|||
        <result property="updatedTime" column="UPDATED_TIME"/> | 
				
			|||
    </resultMap> | 
				
			|||
 | 
				
			|||
 | 
				
			|||
</mapper> | 
				
			|||
@ -0,0 +1,14 @@ | 
				
			|||
<?xml version="1.0" encoding="UTF-8"?> | 
				
			|||
<project xmlns="http://maven.apache.org/POM/4.0.0" | 
				
			|||
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | 
				
			|||
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | 
				
			|||
    <parent> | 
				
			|||
        <artifactId>epmet-cloud</artifactId> | 
				
			|||
        <groupId>com.epmet</groupId> | 
				
			|||
        <version>2.0.0</version> | 
				
			|||
    </parent> | 
				
			|||
    <modelVersion>4.0.0</modelVersion> | 
				
			|||
 | 
				
			|||
    <artifactId>epmet-auth-client</artifactId> | 
				
			|||
 | 
				
			|||
</project> | 
				
			|||
@ -0,0 +1,9 @@ | 
				
			|||
package com.epmet.auth.constants; | 
				
			|||
 | 
				
			|||
/** | 
				
			|||
 * 认证操作常量 | 
				
			|||
 */ | 
				
			|||
public interface AuthOperationConstants { | 
				
			|||
    String LOGIN = "login"; | 
				
			|||
    String LOGOUT = "logout"; | 
				
			|||
} | 
				
			|||
@ -0,0 +1,43 @@ | 
				
			|||
package com.epmet.auth.constants; | 
				
			|||
 | 
				
			|||
/** | 
				
			|||
 * 认证操作枚举 | 
				
			|||
 */ | 
				
			|||
public enum AuthOperationEnum { | 
				
			|||
 | 
				
			|||
    LOGIN(AuthOperationConstants.LOGIN, "登录"), | 
				
			|||
    LOGOUT(AuthOperationConstants.LOGOUT, "退出"); | 
				
			|||
 | 
				
			|||
    private String operationType; | 
				
			|||
    private String operationDisplay; | 
				
			|||
 | 
				
			|||
    AuthOperationEnum(String operationType, String operationDisplay) { | 
				
			|||
        this.operationType = operationType; | 
				
			|||
        this.operationDisplay = operationDisplay; | 
				
			|||
    } | 
				
			|||
 | 
				
			|||
    public String getOperationType() { | 
				
			|||
        return operationType; | 
				
			|||
    } | 
				
			|||
 | 
				
			|||
    public String getOperationDisplay() { | 
				
			|||
        return operationDisplay; | 
				
			|||
    } | 
				
			|||
 | 
				
			|||
    public static AuthOperationEnum get(String operationType) { | 
				
			|||
        for (AuthOperationEnum e : AuthOperationEnum.values()) { | 
				
			|||
            if (e.getOperationType().equals(operationType)) { | 
				
			|||
                return e; | 
				
			|||
            } | 
				
			|||
        } | 
				
			|||
        return null; | 
				
			|||
    } | 
				
			|||
 | 
				
			|||
    public static String getDisplay(String operationType) { | 
				
			|||
        AuthOperationEnum obj = get(operationType); | 
				
			|||
        if (obj == null) { | 
				
			|||
            return null; | 
				
			|||
        } | 
				
			|||
        return obj.getOperationDisplay(); | 
				
			|||
    } | 
				
			|||
} | 
				
			|||
@ -0,0 +1,26 @@ | 
				
			|||
package com.epmet.commons.rocketmq.messages; | 
				
			|||
 | 
				
			|||
import lombok.Data; | 
				
			|||
 | 
				
			|||
import java.util.Date; | 
				
			|||
 | 
				
			|||
@Data | 
				
			|||
public class LoginMQMsg { | 
				
			|||
 | 
				
			|||
    /** | 
				
			|||
     * 谁登录 | 
				
			|||
     */ | 
				
			|||
    private String userId; | 
				
			|||
    private String appId; | 
				
			|||
    /** | 
				
			|||
     * 什么时间登录的 | 
				
			|||
     */ | 
				
			|||
    private Date loginTime; | 
				
			|||
 | 
				
			|||
    private String ip; | 
				
			|||
 | 
				
			|||
    private String fromApp; | 
				
			|||
 | 
				
			|||
    private String fromClient; | 
				
			|||
 | 
				
			|||
} | 
				
			|||
@ -0,0 +1,50 @@ | 
				
			|||
package com.epmet.commons.tools.feign; | 
				
			|||
 | 
				
			|||
import com.epmet.commons.tools.exception.EpmetErrorCode; | 
				
			|||
import com.epmet.commons.tools.exception.RenException; | 
				
			|||
import com.epmet.commons.tools.utils.Result; | 
				
			|||
import org.apache.commons.lang3.StringUtils; | 
				
			|||
 | 
				
			|||
/** | 
				
			|||
 * Feign请求结果解析器 | 
				
			|||
 */ | 
				
			|||
public interface ResultDataResolver { | 
				
			|||
 | 
				
			|||
    /** | 
				
			|||
     * @Description 获取Result种的data,如果失败(返回result为null或者result.success为false),那么返回null | 
				
			|||
     * @return | 
				
			|||
     * @author wxz | 
				
			|||
     * @date 2021.06.07 22:45 | 
				
			|||
    */ | 
				
			|||
    //default <R> R tryGetResultData(Result<R> result, String targetServiceName) {
 | 
				
			|||
    //    Logger logger = LoggerFactory.getLogger(ResultDataResolver.class);
 | 
				
			|||
    //    if (result == null) {
 | 
				
			|||
    //        logger.error("调用{}服务发生错误,返回Result为null", targetServiceName);
 | 
				
			|||
    //        return null;
 | 
				
			|||
    //    }
 | 
				
			|||
    //    if (!result.success()) {
 | 
				
			|||
    //        logger.error("调用{}服务发生错误,错误信息:{}", targetServiceName, result.getInternalMsg());
 | 
				
			|||
    //        return null;
 | 
				
			|||
    //    }
 | 
				
			|||
    //    return result.getData();
 | 
				
			|||
    //}
 | 
				
			|||
 | 
				
			|||
    /** | 
				
			|||
     * @Description 获取Result种的data,如果失败(返回result为null或者result.success为false),那么抛出异常 | 
				
			|||
     * @return | 
				
			|||
     * @author wxz | 
				
			|||
     * @date 2021.06.07 22:45 | 
				
			|||
     */ | 
				
			|||
    default <R> R getResultDataOrThrowsException(Result<R> result, String targetServiceName, Integer errorCode, String errorInternalMsg) { | 
				
			|||
        if (result == null) { | 
				
			|||
            throw new RenException(EpmetErrorCode.SERVER_ERROR.getCode(), "调用{}服务发生错误,返回Result为null", targetServiceName); | 
				
			|||
        } | 
				
			|||
        if (!result.success()) { | 
				
			|||
            Integer finalErrorCode = errorCode == null ? result.getCode() : errorCode; | 
				
			|||
            String finalErrorInternalMsg = StringUtils.isBlank(errorInternalMsg) ? result.getInternalMsg() : errorInternalMsg; | 
				
			|||
            throw new RenException(finalErrorCode, finalErrorInternalMsg); | 
				
			|||
        } | 
				
			|||
        return result.getData(); | 
				
			|||
    } | 
				
			|||
 | 
				
			|||
} | 
				
			|||
					Loading…
					
					
				
		Reference in new issue