REQ-3540: 添加entity

This commit is contained in:
yanglin 2025-03-10 12:37:54 +08:00
parent ad9c1811e1
commit a594b4d2bd
11 changed files with 421 additions and 0 deletions

View File

@ -0,0 +1,7 @@
package cn.axzo.nanopart.doc.api.autoconfig;
import org.springframework.cloud.openfeign.EnableFeignClients;
@EnableFeignClients("cn.axzo.nanopart.doc")
public class DocAutoConfiguration {
}

View File

@ -0,0 +1,2 @@
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
cn.axzo.nanopart.doc.api.autoconfig.DocAutoConfiguration

View File

@ -0,0 +1,41 @@
package cn.axzo.nanopart.doc.dao;
import org.springframework.stereotype.Repository;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import cn.axzo.nanopart.doc.entity.DocLog;
import cn.axzo.nanopart.doc.mapper.DocLogMapper;
import cn.axzo.nanopart.doc.utils.BizAssertions;
/**
* @author yanglin
*/
@Repository
public class EssLogDao extends ServiceImpl<DocLogMapper, DocLog> {
public void logRequest(String context, Object subject, Object request) {
log(context, subject, "request", request);
}
public void log(String context, Object subject, Object... logContents) {
log(null, context, subject, logContents);
}
public void log(Exception exception, String context, Object subject, Object... logContents) {
DocLog log = new DocLog();
log.setContext(context);
log.setSubject(String.valueOf(subject));
log.setError(exception);
if (logContents != null && logContents.length > 0) {
BizAssertions.assertTrue(logContents.length % 2 == 0, "logContents must be even");
for (int i = 0; i < logContents.length; i += 2) {
BizAssertions.assertTrue(logContents[i] instanceof String, "logContents key must be String");
log.addLogContent((String) logContents[i], logContents[i + 1]);
}
}
save(log);
}
}

View File

@ -0,0 +1,73 @@
package cn.axzo.nanopart.doc.entity;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.extension.handlers.FastjsonTypeHandler;
import com.google.common.base.Throwables;
import cn.axzo.nanopart.doc.http.RequestNoInterceptor;
import cn.axzo.nanopart.doc.utils.YesOrNo;
import cn.axzo.pokonyan.config.mybatisplus.BaseEntity;
import lombok.Getter;
import lombok.Setter;
/**
* @author yanglin
*/
@Setter
@Getter
@TableName(value = "doc_log", autoResultMap = true)
public class DocLog extends BaseEntity<DocLog> {
/**
* 上下文
*/
private String context;
/**
* 主体
*/
private String subject;
/**
* 腾讯返回的请求id
*/
private String requestNo;
/**
* 是否异常
*/
private YesOrNo isError;
/**
* 日志内容
*/
@TableField(typeHandler = FastjsonTypeHandler.class)
private JSONObject logContent;
public void addLogContent(String key, Object value) {
if (logContent == null)
initializeLogContent();
logContent.put(key, value);
}
private void initializeLogContent() {
logContent = new JSONObject();
this.requestNo = RequestNoInterceptor.getRequestNo();
}
public void setError(Exception exception) {
if (exception == null)
return;
setIsError(YesOrNo.YES);
addLogContent("exception", Throwables.getStackTraceAsString(exception));
}
@Override
public String toString() {
return JSON.toJSONString(this);
}
}

View File

@ -0,0 +1,24 @@
package cn.axzo.nanopart.doc.http;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import lombok.RequiredArgsConstructor;
/**
* @author yanglin
*/
@Configuration
@RequiredArgsConstructor
public class EssWebMvcConfigurer implements WebMvcConfigurer {
private final RequestNoInterceptor requestNoInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(requestNoInterceptor)
.addPathPatterns("/**");
}
}

View File

@ -0,0 +1,45 @@
package cn.axzo.nanopart.doc.http;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import cn.axzo.nanopart.doc.utils.UUIDUtil;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import lombok.NonNull;
/**
* @author yanglin
*/
@Component
public class RequestNoInterceptor implements HandlerInterceptor {
private static final ThreadLocal<String> REQUEST_NO = new ThreadLocal<>();
@Override
public boolean preHandle(@NonNull HttpServletRequest request, @NonNull HttpServletResponse response,
@NonNull Object handler) {
REQUEST_NO.set(UUIDUtil.uuidString());
return true;
}
@Override
public void postHandle(@NonNull HttpServletRequest request, @NonNull HttpServletResponse response,
@NonNull Object handler, ModelAndView modelAndView) {
REQUEST_NO.remove();
}
@Override
public void afterCompletion(@NonNull HttpServletRequest request, @NonNull HttpServletResponse response,
@NonNull Object handler, Exception ex) {
REQUEST_NO.remove();
}
public static String getRequestNo() {
return REQUEST_NO.get();
}
}

View File

@ -0,0 +1,12 @@
package cn.axzo.nanopart.doc.mapper;
import cn.axzo.nanopart.doc.entity.DocLog;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
/**
* @author yanglin
*/
@Mapper
public interface DocLogMapper extends BaseMapper<DocLog> {
}

View File

@ -0,0 +1,159 @@
package cn.axzo.nanopart.doc.utils;
import cn.axzo.basics.common.exception.ServiceException;
import cn.axzo.basics.common.util.AssertUtil;
import cn.axzo.framework.domain.web.result.ApiListResult;
import cn.axzo.framework.domain.web.result.ApiResult;
import cn.azxo.framework.common.model.CommonResponse;
import cn.hutool.http.HttpStatus;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.helpers.MessageFormatter;
import java.util.Collection;
import java.util.List;
import java.util.Objects;
/**
* @author yanglin
*/
@Slf4j
public class BizAssertions {
public static ServiceException fail(String message, Object... args) {
return new ServiceException(MessageFormatter.arrayFormat(message, args).getMessage());
}
public static ServiceException fail(Exception e, String message, Object... args) {
return new ServiceException(MessageFormatter.arrayFormat(message, args).getMessage(), e);
}
/**
* 断言集合为空
*/
public static void assertEmpty(Collection<?> actual, String message, Object... args) {
AssertUtil.isEmpty(actual, MessageFormatter.arrayFormat(message, args).getMessage());
}
/**
* 断言为NULL
*/
public static void assertNull(Object actual, String message, Object... args) {
AssertUtil.isNull(actual, MessageFormatter.arrayFormat(message, args).getMessage());
}
/**
* 断言不为NULL
*/
public static void assertNotNull(Object actual, String message, Object... args) {
AssertUtil.notNull(actual, MessageFormatter.arrayFormat(message, args).getMessage());
}
/**
* 断言集合不为空
*/
public static void assertNotEmpty(Collection<?> actual, String message, Object... args) {
AssertUtil.notEmpty(actual, MessageFormatter.arrayFormat(message, args).getMessage());
}
/**
* 断言数组不为空
*/
public static <T> void assertNotEmpty(T[] actual, String message, Object... args) {
AssertUtil.notEmpty(actual, MessageFormatter.arrayFormat(message, args).getMessage());
}
/**
* 断言值为真
*/
public static void assertTrue(boolean actual, String message, Object... args) {
AssertUtil.isTrue(actual, MessageFormatter.arrayFormat(message, args).getMessage());
}
/**
* 断言值不为真
*/
public static void assertFalse(boolean actual, String message, Object... args) {
AssertUtil.isFalse(actual, MessageFormatter.arrayFormat(message, args).getMessage());
}
/**
* 断言值2个值是否equals
*/
public static void assertEquals(Object expected, Object actual, String message, Object... args) {
if (!Objects.equals(expected, actual)) {
throw new ServiceException(MessageFormatter.arrayFormat(message, args).getMessage());
}
}
/**
* 断言值2个值是否不equals
*/
public static void assertNotEquals(Object expected, Object actual, String message, Object... args) {
if (Objects.equals(expected, actual)) {
throw new ServiceException(MessageFormatter.arrayFormat(message, args).getMessage());
}
}
public static void assertNotBlank(String content, String message, Object... args) {
if (StringUtils.isBlank(content)) {
throw new ServiceException(MessageFormatter.arrayFormat(message, args).getMessage());
}
}
public static void assertBlank(String content, String message, Object... args) {
if (StringUtils.isNotBlank(content)) {
throw new ServiceException(MessageFormatter.arrayFormat(message, args).getMessage());
}
}
private static String messageOrTemplateMessage(String message, String template, Object... args) {
if (message != null) {
return message;
}
return MessageFormatter.arrayFormat(template, args).getMessage();
}
public static <T> T assertResponse(CommonResponse<T> response) {
return assertResponse(response, "error resp={}", JSON.toJSONString(response));
}
public static <T> T assertResponse(CommonResponse<T> response, String message, Object... args) {
if (response == null || response.getCode() != HttpStatus.HTTP_OK) {
ServiceException e = new ServiceException(
messageOrTemplateMessage(response == null ? null : response.getMsg(), message, args));
log.warn("remote call response with error", e);
throw e;
}
return response.getData();
}
public static <T> T assertResponse(ApiResult<T> response) {
return assertResponse(response, "error resp={}", JSON.toJSONString(response));
}
public static <T> T assertResponse(ApiResult<T> response, String message, Object... args) {
if (!response.isSuccess()) {
ServiceException e = new ServiceException(messageOrTemplateMessage(response.getMsg(), message, args));
log.warn("remote call response with error", e);
throw e;
}
return response.getData();
}
public static <T> List<T> assertResponse(ApiListResult<T> response) {
return assertResponse(response, "error resp={}", JSON.toJSONString(response));
}
public static <T> List<T> assertResponse(ApiListResult<T> response, String message, Object... args) {
if (!response.isSuccess()) {
ServiceException e = new ServiceException(messageOrTemplateMessage(response.getMsg(), message, args));
log.warn("remote call response with error", e);
throw e;
}
return response.getData();
}
}

View File

@ -0,0 +1,20 @@
package cn.axzo.nanopart.doc.utils;
import org.springframework.transaction.annotation.Transactional;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @author yanglin
*/
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.TYPE, ElementType.METHOD })
@Transactional(rollbackFor = Exception.class)
public @interface BizTransactional {
}

View File

@ -0,0 +1,26 @@
package cn.axzo.nanopart.doc.utils;
import java.util.UUID;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
/**
* UUID生成器
*
* @author cold_blade
* @date 2023/10/5
* @version 1.0
*/
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public final class UUIDUtil {
public static String uuidString() {
String str = UUID.randomUUID().toString();
return str.replaceAll("-", "");
}
public static String uuidRawString() {
return UUID.randomUUID().toString();
}
}

View File

@ -150,6 +150,18 @@
<version>2.0.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>cn.axzo.nanopart</groupId>
<artifactId>doc-api</artifactId>
<version>2.0.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>cn.axzo.nanopart</groupId>
<artifactId>doc-server</artifactId>
<version>2.0.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>cn.axzo.im.center</groupId>
<artifactId>im-center-api</artifactId>