第一次课程提交

This commit is contained in:
Y1NanPing 2025-07-18 16:53:56 +08:00
commit f5a0a1b00d
519 changed files with 9781 additions and 0 deletions

38
common/common-log/pom.xml Normal file
View File

@ -0,0 +1,38 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>common</artifactId>
<groupId>com.atguigu.tingshu</groupId>
<version>1.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>common-log</artifactId>
<dependencies>
<dependency>
<groupId>com.atguigu.tingshu</groupId>
<artifactId>model</artifactId>
<version>1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.atguigu.tingshu</groupId>
<artifactId>common-util</artifactId>
<version>1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,39 @@
package com.atguigu.tingshu.common.annotation;
import com.atguigu.tingshu.common.enums.BusinessType;
import com.atguigu.tingshu.common.enums.OperatorType;
import java.lang.annotation.*;
/**
* 自定义操作日志记录注解
*/
@Target({ElementType.PARAMETER, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Log {
/**
* 模块
*/
public String title() default "";
/**
* 功能
*/
public BusinessType businessType() default BusinessType.OTHER;
/**
* 操作人类别
*/
public OperatorType operatorType() default OperatorType.MANAGE;
/**
* 是否保存请求的参数
*/
public boolean isSaveRequestData() default true;
/**
* 是否保存响应的参数
*/
public boolean isSaveResponseData() default true;
}

View File

@ -0,0 +1,184 @@
package com.atguigu.tingshu.common.aspect;
import com.alibaba.fastjson.JSON;
//import com.atguigu.tingshu.system.client.SysOperLogFeignClient;
import com.atguigu.tingshu.common.annotation.Log;
import com.atguigu.tingshu.common.util.IpUtil;
import com.atguigu.tingshu.model.system.SysOperLog;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpMethod;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.validation.BindingResult;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.multipart.MultipartFile;
import java.util.Collection;
import java.util.Map;
/**
* 操作日志记录处理
*/
@Aspect
@Component
public class LogAspect {
private static final Logger log = LoggerFactory.getLogger(LogAspect.class);
//微服务切换为feign调用接口
//@Resource
//private SysOperLogFeignClient sysOperLogFeignClient;
/**
* 处理完请求后执行
*
* @param joinPoint 切点
*/
@AfterReturning(pointcut = "@annotation(controllerLog)", returning = "jsonResult")
public void doAfterReturning(JoinPoint joinPoint, Log controllerLog, Object jsonResult) {
handleLog(joinPoint, controllerLog, null, jsonResult);
}
/**
* 拦截异常操作
*
* @param joinPoint 切点
* @param e 异常
*/
@AfterThrowing(value = "@annotation(controllerLog)", throwing = "e")
public void doAfterThrowing(JoinPoint joinPoint, Log controllerLog, Exception e) {
handleLog(joinPoint, controllerLog, e, null);
}
protected void handleLog(final JoinPoint joinPoint, Log controllerLog, final Exception e, Object jsonResult) {
try {
RequestAttributes ra = RequestContextHolder.getRequestAttributes();
ServletRequestAttributes sra = (ServletRequestAttributes) ra;
HttpServletRequest request = sra.getRequest();
// *========数据库日志=========*//
SysOperLog operLog = new SysOperLog();
operLog.setStatus(1);
// 请求的地址
String ip = IpUtil.getIpAddress(request);//IpUtil.getIpAddr(ServletUtils.getRequest());
operLog.setOperIp(ip);
operLog.setOperUrl(request.getRequestURI());
if (e != null) {
operLog.setStatus(0);
operLog.setErrorMsg(e.getMessage());
}
// 设置方法名称
String className = joinPoint.getTarget().getClass().getName();
String methodName = joinPoint.getSignature().getName();
operLog.setMethod(className + "." + methodName + "()");
// 设置请求方式
operLog.setRequestMethod(request.getMethod());
// 处理设置注解上的参数
getControllerMethodDescription(joinPoint, controllerLog, operLog, jsonResult);
// 保存数据库
//sysOperLogFeignClient.saveSysLog(operLog);
log.info("操作日志:"+JSON.toJSONString(operLog));
} catch (Exception exp) {
// 记录本地异常日志
log.error("==前置通知异常==");
log.error("异常信息:{}", exp.getMessage());
exp.printStackTrace();
}
}
/**
* 获取注解中对方法的描述信息 用于Controller层注解
*
* @param log 日志
* @param operLog 操作日志
* @throws Exception
*/
public void getControllerMethodDescription(JoinPoint joinPoint, Log log, SysOperLog operLog, Object jsonResult) throws Exception {
// 设置action动作
operLog.setBusinessType(log.businessType().name());
// 设置标题
operLog.setTitle(log.title());
// 设置操作人类别
operLog.setOperatorType(log.operatorType().name());
// 是否需要保存request参数和值
if (log.isSaveRequestData()) {
// 获取参数的信息传入到数据库中
setRequestValue(joinPoint, operLog);
}
// 是否需要保存response参数和值
if (log.isSaveResponseData() && !StringUtils.isEmpty(jsonResult)) {
operLog.setJsonResult(JSON.toJSONString(jsonResult));
}
}
/**
* 获取请求的参数放到log中
*
* @param operLog 操作日志
* @throws Exception 异常
*/
private void setRequestValue(JoinPoint joinPoint, SysOperLog operLog) throws Exception {
String requestMethod = operLog.getRequestMethod();
if (HttpMethod.PUT.name().equals(requestMethod) || HttpMethod.POST.name().equals(requestMethod)) {
String params = argsArrayToString(joinPoint.getArgs());
operLog.setOperParam(params);
}
}
/**
* 参数拼装
*/
private String argsArrayToString(Object[] paramsArray) {
String params = "";
if (paramsArray != null && paramsArray.length > 0) {
for (Object o : paramsArray) {
if (!StringUtils.isEmpty(o) && !isFilterObject(o)) {
try {
Object jsonObj = JSON.toJSON(o);
params += jsonObj.toString() + " ";
} catch (Exception e) {
}
}
}
}
return params.trim();
}
/**
* 判断是否需要过滤的对象
*
* @param o 对象信息
* @return 如果是需要过滤的对象则返回true否则返回false
*/
@SuppressWarnings("rawtypes")
public boolean isFilterObject(final Object o) {
Class<?> clazz = o.getClass();
if (clazz.isArray()) {
return clazz.getComponentType().isAssignableFrom(MultipartFile.class);
} else if (Collection.class.isAssignableFrom(clazz)) {
Collection collection = (Collection) o;
for (Object value : collection) {
return value instanceof MultipartFile;
}
} else if (Map.class.isAssignableFrom(clazz)) {
Map map = (Map) o;
for (Object value : map.entrySet()) {
Map.Entry entry = (Map.Entry) value;
return entry.getValue() instanceof MultipartFile;
}
}
return o instanceof MultipartFile || o instanceof HttpServletRequest || o instanceof HttpServletResponse
|| o instanceof BindingResult;
}
}

View File

@ -0,0 +1,52 @@
package com.atguigu.tingshu.common.enums;
/**
* 业务操作类型
*/
public enum BusinessType {
/**
* 其它
*/
OTHER,
/**
* 新增
*/
INSERT,
/**
* 修改
*/
UPDATE,
/**
* 删除
*/
DELETE,
/**
* 授权
*/
ASSGIN,
/**
* 导出
*/
EXPORT,
/**
* 导入
*/
IMPORT,
/**
* 更新状态
*/
STATUS,
/**
* 清空数据
*/
CLEAN,
}

View File

@ -0,0 +1,21 @@
package com.atguigu.tingshu.common.enums;
/**
* 操作人类别
*/
public enum OperatorType {
/**
* 其它
*/
OTHER,
/**
* 后台用户
*/
MANAGE,
/**
* 手机端用户
*/
MOBILE
}

View File

@ -0,0 +1,47 @@
<?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>common</artifactId>
<groupId>com.atguigu.tingshu</groupId>
<version>1.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>common-util</artifactId>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<scope>provided </scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
</dependency>
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.7.22</version>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,85 @@
package com.atguigu.tingshu.common.result;
import lombok.Data;
/**
* 全局统一返回结果类
*
*/
@Data
public class Result<T> {
//返回码
private Integer code;
//返回消息
private String message;
//返回数据
private T data;
public Result(){}
// 返回数据
protected static <T> Result<T> build(T data) {
Result<T> result = new Result<T>();
if (data != null)
result.setData(data);
return result;
}
public static <T> Result<T> build(T body, Integer code, String message) {
Result<T> result = build(body);
result.setCode(code);
result.setMessage(message);
return result;
}
public static <T> Result<T> build(T body, ResultCodeEnum resultCodeEnum) {
Result<T> result = build(body);
result.setCode(resultCodeEnum.getCode());
result.setMessage(resultCodeEnum.getMessage());
return result;
}
public static<T> Result<T> ok(){
return Result.ok(null);
}
/**
* 操作成功
* @param data baseCategory1List
* @param <T>
* @return
*/
public static<T> Result<T> ok(T data){
Result<T> result = build(data);
return build(data, ResultCodeEnum.SUCCESS);
}
public static<T> Result<T> fail(){
return Result.fail(null);
}
/**
* 操作失败
* @param data
* @param <T>
* @return
*/
public static<T> Result<T> fail(T data){
Result<T> result = build(data);
return build(data, ResultCodeEnum.FAIL);
}
public Result<T> message(String msg){
this.setMessage(msg);
return this;
}
public Result<T> code(Integer code){
this.setCode(code);
return this;
}
}

View File

@ -0,0 +1,59 @@
package com.atguigu.tingshu.common.result;
import lombok.Getter;
/**
* 统一返回结果状态信息类
*
*/
@Getter
public enum ResultCodeEnum {
SUCCESS(200,"成功"),
FAIL(201, "失败"),
SERVICE_ERROR(2012, "服务异常"),
DATA_ERROR(204, "数据异常"),
ILLEGAL_REQUEST(205, "非法请求"),
REPEAT_SUBMIT(206, "重复提交"),
ARGUMENT_VALID_ERROR(210, "参数校验异常"),
SIGN_ERROR(300, "签名错误"),
SIGN_OVERDUE(301, "签名已过期"),
LOGIN_AUTH(208, "未登陆"),
PERMISSION(209, "没有权限"),
ACCOUNT_ERROR(214, "账号不正确"),
PASSWORD_ERROR(215, "密码不正确"),
PHONE_CODE_ERROR(215, "手机验证码不正确"),
LOGIN_MOBLE_ERROR( 216, "账号不正确"),
ACCOUNT_STOP( 216, "账号已停用"),
NODE_ERROR( 217, "该节点下有子节点,不可以删除"),
VOD_FILE_ID_ERROR( 220, "声音媒体id不正确"),
XXL_JOB_ERROR(210, "调度操作失败"),
ACCOUNT_LESS(220, "账户余额不足"),
ACCOUNT_LOCK_ERROR(221, "账户余额锁定失败"),
ACCOUNT_UNLOCK_ERROR(221, "账户余额解锁失败"),
ACCOUNT_MINUSLOCK_ERROR(221, "账户余额扣减失败"),
ACCOUNT_LOCK_REPEAT(221, "重复锁定"),
ACCOUNT_LOCK_RESULT_NULL(221, "锁定账号结果对象为空"),
ORDER_SUBMIT_REPEAT(221, "超时或重复提交订单"),
NO_BUY_NOT_SEE(230, "未购买不能观看"),
EXIST_NO_EXPIRE_LIVE(230, "当前存在未过期直播"),
REPEAT_BUY_ERROR(231, "已经购买过该专辑"),
;
private Integer code;
private String message;
private ResultCodeEnum(Integer code, String message) {
this.code = code;
this.message = message;
}
}

View File

@ -0,0 +1,22 @@
package com.atguigu.tingshu.common.util;
/**
* 获取当前用户信息帮助类
*/
public class AuthContextHolder {
private static ThreadLocal<Long> userId = new ThreadLocal<Long>();
public static void setUserId(Long _userId) {
userId.set(_userId);
}
public static Long getUserId() {
return userId.get();
}
public static void removeUserId() {
userId.remove();
}
}

View File

@ -0,0 +1,31 @@
package com.atguigu.tingshu.common.util;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import java.io.IOException;
import java.math.BigDecimal;
/**
* @description 小数保留2位返回给前端序列化器
*/
public class Decimal2Serializer extends JsonSerializer<Object> {
/**
* 将返回的BigDecimal保留两位小数再返回给前端
* @param value
* @param jsonGenerator
* @param serializerProvider
* @throws IOException
* @throws JsonProcessingException
*/
@Override
public void serialize(Object value, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException, JsonProcessingException {
if (value != null) {
BigDecimal bigDecimal = new BigDecimal(value.toString()).setScale(2,BigDecimal.ROUND_HALF_UP);
jsonGenerator.writeString(bigDecimal.toString());
}
}
}

View File

@ -0,0 +1,38 @@
package com.atguigu.tingshu.common.util;
import java.io.PrintWriter;
import java.io.StringWriter;
/**
* Exception工具类
*/
public class ExceptionUtil {
/**
* 获取异常信息
* @param e 异常
* @return 返回异常信息
*/
public static String getErrorMessage(Exception e){
StringWriter sw = null;
PrintWriter pw = null;
try {
sw = new StringWriter();
pw = new PrintWriter(sw, true);
e.printStackTrace(pw);
}finally {
try {
if(pw != null) {
pw.close();
}
if(sw != null) {
sw.close();
}
} catch (Exception e1) {
e1.printStackTrace();
}
}
return sw.toString();
}
}

View File

@ -0,0 +1,318 @@
//package com.atguigu.tingshu.common.util;
//
//
//import org.apache.commons.io.IOUtils;
//import org.apache.http.Consts;
//import org.apache.http.HttpEntity;
//import org.apache.http.HttpResponse;
//import org.apache.http.NameValuePair;
//import org.apache.http.client.HttpClient;
//import org.apache.http.client.config.RequestConfig;
//import org.apache.http.client.config.RequestConfig.Builder;
//import org.apache.http.client.entity.UrlEncodedFormEntity;
//import org.apache.http.client.methods.HttpGet;
//import org.apache.http.client.methods.HttpPost;
//import org.apache.http.conn.ConnectTimeoutException;
//import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
//import org.apache.http.conn.ssl.SSLContextBuilder;
//import org.apache.http.conn.ssl.TrustStrategy;
//import org.apache.http.conn.ssl.X509HostnameVerifier;
//import org.apache.http.entity.ContentType;
//import org.apache.http.entity.StringEntity;
//import org.apache.http.impl.client.CloseableHttpClient;
//import org.apache.http.impl.client.HttpClients;
//import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
//import org.apache.http.message.BasicNameValuePair;
//import org.springframework.util.StringUtils;
//
//import javax.net.ssl.SSLContext;
//import javax.net.ssl.SSLException;
//import javax.net.ssl.SSLSession;
//import javax.net.ssl.SSLSocket;
//import java.io.IOException;
//import java.net.SocketTimeoutException;
//import java.security.GeneralSecurityException;
//import java.security.cert.CertificateException;
//import java.security.cert.X509Certificate;
//import java.util.ArrayList;
//import java.util.List;
//import java.util.Map;
//import java.util.Map.Entry;
//import java.util.Set;
//
//public class HttpClientUtils {
//
// public static final int connTimeout=10000;
// public static final int readTimeout=10000;
// public static final String charset="UTF-8";
// private static HttpClient client = null;
//
// static {
// PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();
// cm.setMaxTotal(128);
// cm.setDefaultMaxPerRoute(128);
// client = HttpClients.custom().setConnectionManager(cm).build();
// }
//
// public static String postParameters(String url, String parameterStr) throws ConnectTimeoutException, SocketTimeoutException, Exception{
// return post(url,parameterStr,"application/x-www-form-urlencoded",charset,connTimeout,readTimeout);
// }
//
// public static String postParameters(String url, String parameterStr,String charset, Integer connTimeout, Integer readTimeout) throws ConnectTimeoutException, SocketTimeoutException, Exception{
// return post(url,parameterStr,"application/x-www-form-urlencoded",charset,connTimeout,readTimeout);
// }
//
// public static String postParameters(String url, Map<String, String> params) throws ConnectTimeoutException,
// SocketTimeoutException, Exception {
// return postForm(url, params, null, connTimeout, readTimeout);
// }
//
// public static String postParameters(String url, Map<String, String> params, Integer connTimeout,Integer readTimeout) throws ConnectTimeoutException,
// SocketTimeoutException, Exception {
// return postForm(url, params, null, connTimeout, readTimeout);
// }
//
// public static String get(String url) throws Exception {
// return get(url, charset, null, null);
// }
//
// public static String get(String url, String charset) throws Exception {
// return get(url, charset, connTimeout, readTimeout);
// }
//
// /**
// * 发送一个 Post 请求, 使用指定的字符集编码.
// *
// * @param url
// * @param body RequestBody
// * @param mimeType 例如 application/xml "application/x-www-form-urlencoded" a=1&b=2&c=3
// * @param charset 编码
// * @param connTimeout 建立链接超时时间,毫秒.
// * @param readTimeout 响应超时时间,毫秒.
// * @return ResponseBody, 使用指定的字符集编码.
// * @throws ConnectTimeoutException 建立链接超时异常
// * @throws SocketTimeoutException 响应超时
// * @throws Exception
// */
// public static String post(String url, String body, String mimeType,String charset, Integer connTimeout, Integer readTimeout)
// throws ConnectTimeoutException, SocketTimeoutException, Exception {
// HttpClient client = null;
// HttpPost post = new HttpPost(url);
// String result = "";
// try {
// if (!StringUtils.isEmpty(body)) {
// HttpEntity entity = new StringEntity(body, ContentType.create(mimeType, charset));
// post.setEntity(entity);
// }
// // 设置参数
// Builder customReqConf = RequestConfig.custom();
// if (connTimeout != null) {
// customReqConf.setConnectTimeout(connTimeout);
// }
// if (readTimeout != null) {
// customReqConf.setSocketTimeout(readTimeout);
// }
// post.setConfig(customReqConf.build());
//
// HttpResponse res;
// if (url.startsWith("https")) {
// // 执行 Https 请求.
// client = createSSLInsecureClient();
// res = client.execute(post);
// } else {
// // 执行 Http 请求.
// client = HttpClientUtils.client;
// res = client.execute(post);
// }
// result = IOUtils.toString(res.getEntity().getContent(), charset);
// } finally {
// post.releaseConnection();
// if (url.startsWith("https") && client != null&& client instanceof CloseableHttpClient) {
// ((CloseableHttpClient) client).close();
// }
// }
// return result;
// }
//
//
// /**
// * 提交form表单
// *
// * @param url
// * @param params
// * @param connTimeout
// * @param readTimeout
// * @return
// * @throws ConnectTimeoutException
// * @throws SocketTimeoutException
// * @throws Exception
// */
// public static String postForm(String url, Map<String, String> params, Map<String, String> headers, Integer connTimeout,Integer readTimeout) throws ConnectTimeoutException,
// SocketTimeoutException, Exception {
//
// HttpClient client = null;
// HttpPost post = new HttpPost(url);
// try {
// if (params != null && !params.isEmpty()) {
// List<NameValuePair> formParams = new ArrayList<NameValuePair>();
// Set<Entry<String, String>> entrySet = params.entrySet();
// for (Entry<String, String> entry : entrySet) {
// formParams.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
// }
// UrlEncodedFormEntity entity = new UrlEncodedFormEntity(formParams, Consts.UTF_8);
// post.setEntity(entity);
// }
//
// if (headers != null && !headers.isEmpty()) {
// for (Entry<String, String> entry : headers.entrySet()) {
// post.addHeader(entry.getKey(), entry.getValue());
// }
// }
// // 设置参数
// Builder customReqConf = RequestConfig.custom();
// if (connTimeout != null) {
// customReqConf.setConnectTimeout(connTimeout);
// }
// if (readTimeout != null) {
// customReqConf.setSocketTimeout(readTimeout);
// }
// post.setConfig(customReqConf.build());
// HttpResponse res = null;
// if (url.startsWith("https")) {
// // 执行 Https 请求.
// client = createSSLInsecureClient();
// res = client.execute(post);
// } else {
// // 执行 Http 请求.
// client = HttpClientUtils.client;
// res = client.execute(post);
// }
// return IOUtils.toString(res.getEntity().getContent(), "UTF-8");
// } finally {
// post.releaseConnection();
// if (url.startsWith("https") && client != null
// && client instanceof CloseableHttpClient) {
// ((CloseableHttpClient) client).close();
// }
// }
// }
//
//
//
//
// /**
// * 发送一个 GET 请求
// *
// * @param url
// * @param charset
// * @param connTimeout 建立链接超时时间,毫秒.
// * @param readTimeout 响应超时时间,毫秒.
// * @return
// * @throws ConnectTimeoutException 建立链接超时
// * @throws SocketTimeoutException 响应超时
// * @throws Exception
// */
// public static String get(String url, String charset, Integer connTimeout,Integer readTimeout)
// throws ConnectTimeoutException,SocketTimeoutException, Exception {
//
// HttpClient client = null;
// HttpGet get = new HttpGet(url);
// String result = "";
// try {
// // 设置参数
// Builder customReqConf = RequestConfig.custom();
// if (connTimeout != null) {
// customReqConf.setConnectTimeout(connTimeout);
// }
// if (readTimeout != null) {
// customReqConf.setSocketTimeout(readTimeout);
// }
// get.setConfig(customReqConf.build());
//
// HttpResponse res = null;
//
// if (url.startsWith("https")) {
// // 执行 Https 请求.
// client = createSSLInsecureClient();
// res = client.execute(get);
// } else {
// // 执行 Http 请求.
// client = HttpClientUtils.client;
// res = client.execute(get);
// }
//
// result = IOUtils.toString(res.getEntity().getContent(), charset);
// } finally {
// get.releaseConnection();
// if (url.startsWith("https") && client != null && client instanceof CloseableHttpClient) {
// ((CloseableHttpClient) client).close();
// }
// }
// return result;
// }
//
//
// /**
// * response 里获取 charset
// *
// * @param ressponse
// * @return
// */
// @SuppressWarnings("unused")
// private static String getCharsetFromResponse(HttpResponse ressponse) {
// // Content-Type:text/html; charset=GBK
// if (ressponse.getEntity() != null && ressponse.getEntity().getContentType() != null && ressponse.getEntity().getContentType().getValue() != null) {
// String contentType = ressponse.getEntity().getContentType().getValue();
// if (contentType.contains("charset=")) {
// return contentType.substring(contentType.indexOf("charset=") + 8);
// }
// }
// return null;
// }
//
//
//
// /**
// * 创建 SSL连接
// * @return
// * @throws GeneralSecurityException
// */
// private static CloseableHttpClient createSSLInsecureClient() throws GeneralSecurityException {
// try {
// SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() {
// public boolean isTrusted(X509Certificate[] chain,String authType) throws CertificateException {
// return true;
// }
// }).build();
//
// SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext, new X509HostnameVerifier() {
//
// @Override
// public boolean verify(String arg0, SSLSession arg1) {
// return true;
// }
//
// @Override
// public void verify(String host, SSLSocket ssl)
// throws IOException {
// }
//
// @Override
// public void verify(String host, X509Certificate cert)
// throws SSLException {
// }
//
// @Override
// public void verify(String host, String[] cns,
// String[] subjectAlts) throws SSLException {
// }
//
// });
//
// return HttpClients.custom().setSSLSocketFactory(sslsf).build();
//
// } catch (GeneralSecurityException e) {
// throw e;
// }
// }
//}

View File

@ -0,0 +1,82 @@
package com.atguigu.tingshu.common.util;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.http.HttpHeaders;
import org.springframework.http.server.reactive.ServerHttpRequest;
import java.net.InetAddress;
import java.net.UnknownHostException;
/**
* 获取ip地址
*/
public class IpUtil {
public static String getIpAddress(HttpServletRequest request) {
String ipAddress = null;
try {
ipAddress = request.getHeader("x-forwarded-for");
if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
ipAddress = request.getHeader("Proxy-Client-IP");
}
if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
ipAddress = request.getHeader("WL-Proxy-Client-IP");
}
if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
ipAddress = request.getRemoteAddr();
if (ipAddress.equals("127.0.0.1")) {
// 根据网卡取本机配置的IP
InetAddress inet = null;
try {
inet = InetAddress.getLocalHost();
} catch (UnknownHostException e) {
e.printStackTrace();
}
ipAddress = inet.getHostAddress();
}
}
// 对于通过多个代理的情况第一个IP为客户端真实IP,多个IP按照','分割
if (ipAddress != null && ipAddress.length() > 15) { // "***.***.***.***".length()
// = 15
if (ipAddress.indexOf(",") > 0) {
ipAddress = ipAddress.substring(0, ipAddress.indexOf(","));
}
}
} catch (Exception e) {
ipAddress="";
}
// ipAddress = this.getRequest().getRemoteAddr();
return ipAddress;
}
public static String getGatwayIpAddress(ServerHttpRequest request) {
HttpHeaders headers = request.getHeaders();
String ip = headers.getFirst("x-forwarded-for");
if (ip != null && ip.length() != 0 && !"unknown".equalsIgnoreCase(ip)) {
// 多次反向代理后会有多个ip值第一个ip才是真实ip
if (ip.indexOf(",") != -1) {
ip = ip.split(",")[0];
}
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = headers.getFirst("Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = headers.getFirst("WL-Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = headers.getFirst("HTTP_CLIENT_IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = headers.getFirst("HTTP_X_FORWARDED_FOR");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = headers.getFirst("X-Real-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getRemoteAddress().getAddress().getHostAddress();
}
return ip;
}
}

View File

@ -0,0 +1,39 @@
package com.atguigu.tingshu.common.util;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public final class MD5 {
public static String encrypt(String strSrc) {
try {
char hexChars[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8',
'9', 'a', 'b', 'c', 'd', 'e', 'f' };
byte[] bytes = strSrc.getBytes();
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(bytes);
bytes = md.digest();
int j = bytes.length;
char[] chars = new char[j * 2];
int k = 0;
for (int i = 0; i < bytes.length; i++) {
byte b = bytes[i];
chars[k++] = hexChars[b >>> 4 & 0xf];
chars[k++] = hexChars[b & 0xf];
}
return new String(chars);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
throw new RuntimeException("MD5加密出错+" + e);
}
}
public static void main(String[] args) {
String msg = "{\"liveRoomId\":1,\"msgContent\":1,\"msgType\":\"4\",\"timestamp\":1679969941853}";
System.out.println(msg);
msg = msg.replaceAll("\\\\", "");
System.out.println(msg);
System.out.println(MD5.encrypt("111111"));
}
}

View File

@ -0,0 +1,38 @@
package com.atguigu.tingshu.common.util;
import lombok.Getter;
public class MongoUtil {
@Getter
public enum MongoCollectionEnum {
USER_SUBSCRIBE(100,"userSubscribe"),
USER_COLLECT(100,"userCollect"),
USER_LISTEN_PROCESS(100,"userListenProcess"),
COMMENT(100,"comment"),
COMMENT_PRAISE(100,"commentPraise"),
;
private Integer partition;
private String collectionPrefix;
MongoCollectionEnum(Integer partition, String collectionPrefix) {
this.partition = partition;
this.collectionPrefix = collectionPrefix;
}
}
/**
* 获取mongo表名
* @param mongoCollection Collection前缀
* @param userId 用户ID
* @return
*/
public static String getCollectionName(MongoCollectionEnum mongoCollection, Long userId) {
return mongoCollection.getCollectionPrefix() + "_" + userId;
}
}

View File

@ -0,0 +1,65 @@
package com.atguigu.tingshu.common.util;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Random;
/**
* 获取随机数
*
* @author qianyi
*
*/
public class RandomUtil {
private static final Random random = new Random();
private static final DecimalFormat fourdf = new DecimalFormat("0000");
private static final DecimalFormat sixdf = new DecimalFormat("000000");
public static String getFourBitRandom() {
return fourdf.format(random.nextInt(10000));
}
public static String getSixBitRandom() {
return sixdf.format(random.nextInt(1000000));
}
/**
* 给定数组抽取n个数据
*
* @param swQidsList
* @param n
* @return
*/
public static ArrayList getRandom(List list, int n) {
Random random = new Random();
HashMap<Object, Object> hashMap = new HashMap<Object, Object>();
// 生成随机数字并存入HashMap
for (int i = 0; i < list.size(); i++) {
int number = random.nextInt(100) + 1;
hashMap.put(number, i);
}
// 从HashMap导入数组
Object[] robjs = hashMap.values().toArray();
ArrayList r = new ArrayList();
// 遍历数组并打印数据
for (int i = 0; i < n; i++) {
r.add(list.get((int) robjs[i]));
System.out.print(list.get((int) robjs[i]) + "\t");
}
System.out.print("\n");
return r;
}
}

View File

@ -0,0 +1,23 @@
package com.atguigu.tingshu.common.util;
import com.atguigu.tingshu.common.result.Result;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import java.io.IOException;
public class ResponseUtil {
public static void out(HttpServletResponse response, Result r) {
ObjectMapper mapper = new ObjectMapper();
response.setStatus(HttpStatus.OK.value());
response.setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE);
try {
mapper.writeValue(response.getWriter(), r);
} catch (IOException e) {
e.printStackTrace();
}
}
}

View File

@ -0,0 +1,191 @@
package com.atguigu.tingshu.common.util;
import java.util.*;
public class SensitiveWordFilterUtil {
//构建一个DFA算法模型
private static Map sensitiveWordMap = null;
/**
* 敏感词替换
* @param txt
* @return
*/
public static String replaceSensitiveWord(String txt){
if(null == sensitiveWordMap) return txt;
return replaceSensitiveWord(txt, 1, "*");
}
/**
* 读取敏感词库将敏感词放入HashSet中构建一个DFA算法模型<br>
* = {
* isEnd = 0
* = {<br>
* isEnd = 1
* = {isEnd = 0
* = {isEnd = 1}
* }
* = {
* isEnd = 0
* = {
* isEnd = 1
* }
* }
* }
* }
* = {
* isEnd = 0
* = {
* isEnd = 0
* = {
* isEnd = 0
* = {
* isEnd = 1
* }
* }
* }
* }
*/
public static void buildDFAModel(List<String> keyWordList) {
sensitiveWordMap = new HashMap(keyWordList.size()); //初始化敏感词容器减少扩容操作
String key = null;
Map nowMap = null;
Map<String, String> newWorMap = null;
//迭代keyWordSet
Iterator<String> iterator = keyWordList.iterator();
while(iterator.hasNext()){
key = iterator.next(); //关键字
nowMap = sensitiveWordMap;
for(int i = 0 ; i < key.length() ; i++){
char keyChar = key.charAt(i); //转换成char型
Object wordMap = nowMap.get(keyChar); //获取
if(wordMap != null){ //如果存在该key直接赋值
nowMap = (Map) wordMap;
}
else{ //不存在则则构建一个map同时将isEnd设置为0因为他不是最后一个
newWorMap = new HashMap<String,String>();
newWorMap.put("isEnd", "0"); //不是最后一个
nowMap.put(keyChar, newWorMap);
nowMap = newWorMap;
}
if(i == key.length() - 1){
nowMap.put("isEnd", "1"); //最后一个
}
}
}
}
/**
* 获取文字中的敏感词
* @param txt 文字
* @param matchType 匹配规则&nbsp;1最小匹配规则2最大匹配规则
* @return
*/
private static Set<String> getSensitiveWord(String txt , int matchType){
Set<String> sensitiveWordList = new HashSet<String>();
for(int i = 0 ; i < txt.length() ; i++){
int length = CheckSensitiveWord(txt, i, matchType); //判断是否包含敏感字符
if(length > 0){ //存在,加入list中
sensitiveWordList.add(txt.substring(i, i+length));
i = i + length - 1; //减1的原因是因为for会自增
}
}
return sensitiveWordList;
}
/**
* 替换敏感字字符
* @param txt
* @param matchType
* @param replaceChar 替换字符默认*
*/
private static String replaceSensitiveWord(String txt,int matchType,String replaceChar){
String resultTxt = txt;
Set<String> set = getSensitiveWord(txt, matchType); //获取所有的敏感词
Iterator<String> iterator = set.iterator();
String word = null;
String replaceString = null;
while (iterator.hasNext()) {
word = iterator.next();
replaceString = getReplaceChars(replaceChar, word.length());
resultTxt = resultTxt.replaceAll(word, replaceString);
}
return resultTxt;
}
/**
* 获取替换字符串
* @param replaceChar
* @param length
* @return
*/
private static String getReplaceChars(String replaceChar,int length){
String resultReplace = replaceChar;
for(int i = 1 ; i < length ; i++){
resultReplace += replaceChar;
}
return resultReplace;
}
/**
* 检查文字中是否包含敏感字符检查规则如下<br>
* @param txt
* @param beginIndex
* @param matchType
* @return如果存在则返回敏感词字符的长度不存在返回0
*/
private static int CheckSensitiveWord(String txt,int beginIndex,int matchType){
boolean flag = false; //敏感词结束标识位用于敏感词只有1位的情况
int matchFlag = 0; //匹配标识数默认为0
char word = 0;
Map nowMap = sensitiveWordMap;
for(int i = beginIndex; i < txt.length() ; i++){
word = txt.charAt(i);
nowMap = (Map) nowMap.get(word); //获取指定key
if(nowMap != null){ //存在则判断是否为最后一个
matchFlag++; //找到相应key匹配标识+1
if("1".equals(nowMap.get("isEnd"))){ //如果为最后一个匹配规则,结束循环返回匹配标识数
flag = true; //结束标志位为true
if(matchType == 1){ //最小规则直接返回,最大规则还需继续查找
break;
}
}
}
else{ //不存在直接返回
break;
}
}
if(matchFlag < 2 || !flag){ //长度必须大于等于1为词
matchFlag = 0;
}
return matchFlag;
}
public static void main(String[] args) {
//System.out.println("敏感词的数量:" + filter.sensitiveWordMap.size());
String string = "太多的伤感情怀也许只局限于饲养基地 荧幕中的情节,主人公尝试着去用某种方式渐渐的很潇洒地释自杀指南怀那些自己经历的伤感。"
+ "然后法轮功 我们的扮演的角色就是跟随着主人公的喜红客联盟 怒哀乐而过于牵强的把自己的情感也附加于银幕情节中,然后感动就流泪,"
+ "难过就躺在某一个人的怀里尽情的阐述心扉或者手机卡复制器一个人一杯红酒一部电影在夜三级片 深人静的晚上,关上电话静静的发呆着。";
System.out.println("待检测语句字数:" + string.length());
long beginTime = System.currentTimeMillis();
List<String> keyWordSet = new ArrayList<>();
keyWordSet.add("黄色");
keyWordSet.add("自杀");
keyWordSet.add("法轮功");
keyWordSet.add("三级片");
SensitiveWordFilterUtil.buildDFAModel(keyWordSet);
String content = SensitiveWordFilterUtil.replaceSensitiveWord(string);
System.out.println("替换后:" + content);
long endTime = System.currentTimeMillis();
System.out.println("总共消耗时间为:" + (endTime - beginTime));
}
}

View File

@ -0,0 +1,31 @@
package com.atguigu.tingshu.common.util;
import lombok.SneakyThrows;
import org.joda.time.DateTime;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
public class UploadFileUtil {
/**
* 文件上传到临时路径
* @param file
* @return
*/
@SneakyThrows
public static String uploadTempPath(String tempPath, MultipartFile file) {
if (null == file) return "";
String date = new DateTime().toString("yyyyMMdd");
String filePath = tempPath + File.separator + date;
File curFlie = new File(filePath);
if (!curFlie.exists()) {
curFlie.mkdirs();
}
filePath = filePath + File.separator + file.getOriginalFilename();
file.transferTo(new File(filePath));
return filePath;
}
}

22
common/pom.xml Normal file
View File

@ -0,0 +1,22 @@
<?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>tingshu-parent</artifactId>
<groupId>com.atguigu.tingshu</groupId>
<version>1.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>common</artifactId>
<packaging>pom</packaging>
<modules>
<module>service-util</module>
<module>common-util</module>
<module>rabbit-util</module>
<module>common-log</module>
</modules>
</project>

View File

@ -0,0 +1,48 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>common</artifactId>
<groupId>com.atguigu.tingshu</groupId>
<version>1.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>rabbit-util</artifactId>
<version>1.0</version>
<packaging>jar</packaging>
<description>
rabbit-util服务
</description>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--rabbitmq消息队列-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,139 @@
package com.atguigu.tingshu.common.rabbit.config;
import com.alibaba.fastjson.JSON;
import com.atguigu.tingshu.common.rabbit.entity.GuiguCorrelationData;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import java.util.concurrent.TimeUnit;
@Slf4j
@Component
public class RabbitInitConfigApplicationListener implements ApplicationListener<ApplicationReadyEvent> {
@Autowired
private RabbitTemplate rabbitTemplate;
@Autowired
private RedisTemplate redisTemplate;
@Override
public void onApplicationEvent(ApplicationReadyEvent event) {
this.setupCallbacks();
}
private void setupCallbacks() {
/**
* 只确认消息是否正确到达 Exchange ,成功与否都会回调
*
* @param correlation 相关数据 非消息本身业务数据
* @param ack 应答结果
* @param reason 如果发送消息到交换器失败错误原因
*/
this.rabbitTemplate.setConfirmCallback((correlationData, ack, reason) -> {
if (ack) {
//消息到交换器成功
log.info("消息发送到Exchange成功{}", correlationData);
} else {
//消息到交换器失败
log.error("消息发送到Exchange失败{}", reason);
//执行消息重发
this.retrySendMsg(correlationData);
}
});
/**
* 消息没有正确到达队列时触发回调如果正确到达队列不执行
*/
this.rabbitTemplate.setReturnsCallback(returned -> {
log.error("Returned: " + returned.getMessage() + "\nreplyCode: " + returned.getReplyCode()
+ "\nreplyText: " + returned.getReplyText() + "\nexchange/rk: "
+ returned.getExchange() + "/" + returned.getRoutingKey());
//当路由队列失败 也需要重发
//1.构建相关数据对象
String redisKey = returned.getMessage().getMessageProperties().getHeader("spring_returned_message_correlation");
String correlationDataStr = (String) redisTemplate.opsForValue().get(redisKey);
GuiguCorrelationData guiguCorrelationData = JSON.parseObject(correlationDataStr, GuiguCorrelationData.class);
//todo 方式一:如果不考虑延迟消息重发 直接返回
if(guiguCorrelationData.isDelay()){
return;
}
//2.调用消息重发方法
this.retrySendMsg(guiguCorrelationData);
});
}
// /**
// * 消息重新发送
// *
// * @param correlationData
// */
// private void retrySendMsg(CorrelationData correlationData) {
// //获取相关数据
// GuiguCorrelationData gmallCorrelationData = (GuiguCorrelationData) correlationData;
//
// //获取redis中存放重试次数
// //先重发在写会到redis中次数
// int retryCount = gmallCorrelationData.getRetryCount();
// if (retryCount >= 3) {
// //超过最大重试次数
// log.error("生产者超过最大重试次数,将失败的消息存入数据库用人工处理;给管理员发送邮件;给管理员发送短信;");
// return;
// }
// //重发消息
// rabbitTemplate.convertAndSend(gmallCorrelationData.getExchange(), gmallCorrelationData.getRoutingKey(), gmallCorrelationData.getMessage(), gmallCorrelationData);
// //重发次数+1
// retryCount += 1;
// gmallCorrelationData.setRetryCount(retryCount);
// redisTemplate.opsForValue().set(gmallCorrelationData.getId(), JSON.toJSONString(gmallCorrelationData), 10, TimeUnit.MINUTES);
// log.info("进行消息重发!");
// }
/**
* 消息重新发送
*
* @param correlationData
*/
private void retrySendMsg(CorrelationData correlationData) {
//获取相关数据
GuiguCorrelationData gmallCorrelationData = (GuiguCorrelationData) correlationData;
//获取redis中存放重试次数
//先重发在写会到redis中次数
int retryCount = gmallCorrelationData.getRetryCount();
if (retryCount >= 3) {
//超过最大重试次数
log.error("生产者超过最大重试次数,将失败的消息存入数据库用人工处理;给管理员发送邮件;给管理员发送短信;");
return;
}
//重发次数+1
retryCount += 1;
gmallCorrelationData.setRetryCount(retryCount);
redisTemplate.opsForValue().set(gmallCorrelationData.getId(), JSON.toJSONString(gmallCorrelationData), 10, TimeUnit.MINUTES);
log.info("进行消息重发!");
//重发消息
//todo 方式二如果是延迟消息依然需要设置消息延迟时间
if (gmallCorrelationData.isDelay()) {
//延迟消息
rabbitTemplate.convertAndSend(gmallCorrelationData.getExchange(), gmallCorrelationData.getRoutingKey(), gmallCorrelationData.getMessage(), message -> {
message.getMessageProperties().setDelay(gmallCorrelationData.getDelayTime() * 1000);
return message;
}, gmallCorrelationData);
} else {
//普通消息
rabbitTemplate.convertAndSend(gmallCorrelationData.getExchange(), gmallCorrelationData.getRoutingKey(), gmallCorrelationData.getMessage(), gmallCorrelationData);
}
}
}

View File

@ -0,0 +1,80 @@
package com.atguigu.tingshu.common.rabbit.constant;
public class MqConst {
/**
* 专辑
*/
public static final String EXCHANGE_ALBUM = "tingshu.album";
public static final String ROUTING_ALBUM_UPPER = "tingshu.album.upper";
public static final String ROUTING_ALBUM_LOWER = "tingshu.album.lower";
public static final String ROUTING_ALBUM_STAT_UPDATE = "tingshu.album.stat.update";
public static final String ROUTING_ALBUM_ES_STAT_UPDATE = "tingshu.album.es.stat.update";
public static final String ROUTING_ALBUM_RANKING_UPDATE = "tingshu.album.ranking.update";
//队列
public static final String QUEUE_ALBUM_UPPER = "tingshu.album.upper";
public static final String QUEUE_ALBUM_LOWER = "tingshu.album.lower";
public static final String QUEUE_ALBUM_STAT_UPDATE = "tingshu.album.stat.update";
public static final String QUEUE_ALBUM_ES_STAT_UPDATE = "tingshu.album.es.stat.update";
public static final String QUEUE_ALBUM_RANKING_UPDATE = "tingshu.album.ranking.update";
/**
* 声音
*/
public static final String EXCHANGE_TRACK = "tingshu.track";
public static final String ROUTING_TRACK_STAT_UPDATE = "tingshu.track.stat.update";
public static final String QUEUE_TRACK_STAT_UPDATE = "tingshu.track.stat.update";
/**
* 取消订单
*/
//延迟取消订单队列
/**
* 取消订单延迟消息
*/
public static final String EXCHANGE_CANCEL_ORDER = "tingshu.cancel.order";
public static final String ROUTING_CANCEL_ORDER = "tingshu.cancel.order";
public static final String QUEUE_CANCEL_ORDER = "tingshu.cancel.order";
public static final Integer CANCEL_ORDER_DELAY_TIME = 15 * 60;
/**
* 支付
*/
public static final String EXCHANGE_ORDER = "tingshu.order";
public static final String ROUTING_ORDER_PAY_SUCCESS = "tingshu.order.pay.success";
public static final String ROUTING_RECHARGE_PAY_SUCCESS = "tingshu.recharge.pay.success";
public static final String QUEUE_ORDER_PAY_SUCCESS = "tingshu.order.pay.success";
public static final String QUEUE_RECHARGE_PAY_SUCCESS = "tingshu.recharge.pay.success";
/**
* 账户
*/
public static final String EXCHANGE_ACCOUNT = "tingshu.account";
public static final String ROUTING_ACCOUNT_UNLOCK = "tingshu.account.unlock";
public static final String ROUTING_ACCOUNT_MINUS = "tingshu.account.minus";
public static final String QUEUE_ACCOUNT_UNLOCK = "tingshu.account.unlock";
public static final String QUEUE_ACCOUNT_MINUS = "tingshu.account.minus";
/**
* 用户
*/
public static final String EXCHANGE_USER = "tingshu.user";
public static final String ROUTING_USER_PAY_RECORD = "tingshu.user.pay.record";
public static final String ROUTING_USER_REGISTER = "tingshu.user.register";
public static final String ROUTING_USER_VIP_EXPIRE_STATUS = "tingshu.user.vip.expire.status";
public static final String QUEUE_USER_PAY_RECORD = "tingshu.user.pay.record";
public static final String QUEUE_USER_REGISTER = "tingshu.user.register";
public static final String QUEUE_USER_VIP_EXPIRE_STATUS = "tingshu.user.vip.expire.status";
/**
* 热门关键字
*/
public static final String EXCHANGE_KEYWORD = "tingshu.keyword";
public static final String ROUTING_KEYWORD_INPUT = "tingshu.keyword.input";
public static final String ROUTING_KEYWORD_OUT = "tingshu.keyword.out";
public static final String QUEUE_KEYWORD_INPUT = "tingshu.keyword.input";
public static final String QUEUE_KEYWORD_OUT = "tingshu.keyword.out";
}

View File

@ -0,0 +1,21 @@
package com.atguigu.tingshu.common.rabbit.entity;
import lombok.Data;
import org.springframework.amqp.rabbit.connection.CorrelationData;
@Data
public class GuiguCorrelationData extends CorrelationData {
//消息体
private Object message;
//交换机
private String exchange;
//路由键
private String routingKey;
//重试次数
private int retryCount = 0;
//是否延迟消息
private boolean isDelay = false;
//延迟时长
private int delayTime = 10;
}

View File

@ -0,0 +1,74 @@
package com.atguigu.tingshu.common.rabbit.service;
import com.alibaba.fastjson.JSON;
import com.atguigu.tingshu.common.rabbit.entity.GuiguCorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
@Service
public class RabbitService {
@Autowired
private RabbitTemplate rabbitTemplate;
@Autowired
private RedisTemplate redisTemplate;
/**
* 发送消息
*
* @param exchange 交换机
* @param routingKey 路由键
* @param message 消息
*/
public boolean sendMessage(String exchange, String routingKey, Object message) {
//1.创建自定义相关消息对象-包含业务数据本身交换器名称路由键队列类型延迟时间,重试次数
GuiguCorrelationData correlationData = new GuiguCorrelationData();
String uuid = "mq:" + UUID.randomUUID().toString().replaceAll("-", "");
correlationData.setId(uuid);
correlationData.setMessage(message);
correlationData.setExchange(exchange);
correlationData.setRoutingKey(routingKey);
//2.将相关消息存入Redis KeyUUID 相关消息对象 10 分钟
redisTemplate.opsForValue().set(uuid, JSON.toJSONString(correlationData), 10, TimeUnit.MINUTES);
//3.将相关消息封装到发送消息方法中
rabbitTemplate.convertAndSend(exchange, routingKey, message, correlationData);
return true;
}
/**
* 发送延迟消息方法
*
* @param exchange 交换机
* @param routingKey 路由键
* @param message 消息数据
* @param delayTime 延迟时间单位为
*/
public boolean sendDealyMessage(String exchange, String routingKey, Object message, int delayTime) {
//1.创建自定义相关消息对象-包含业务数据本身交换器名称路由键队列类型延迟时间,重试次数
GuiguCorrelationData correlationData = new GuiguCorrelationData();
String uuid = "mq:" + UUID.randomUUID().toString().replaceAll("-", "");
correlationData.setId(uuid);
correlationData.setMessage(message);
correlationData.setExchange(exchange);
correlationData.setRoutingKey(routingKey);
correlationData.setDelay(true);
correlationData.setDelayTime(delayTime);
//2.将相关消息存入Redis KeyUUID 相关消息对象 10 分钟
redisTemplate.opsForValue().set(uuid, JSON.toJSONString(correlationData), 10, TimeUnit.MINUTES);
//3.将相关消息封装到发送消息方法中
rabbitTemplate.convertAndSend(exchange, routingKey, message, message1 -> {
message1.getMessageProperties().setDelay(delayTime * 1000);
return message1;
}, correlationData);
return true;
}
}

View File

@ -0,0 +1,92 @@
<?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>common</artifactId>
<groupId>com.atguigu.tingshu</groupId>
<version>1.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>service-util</artifactId>
<dependencies>
<dependency>
<groupId>com.atguigu.tingshu</groupId>
<artifactId>common-util</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>com.atguigu.tingshu</groupId>
<artifactId>model</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
</dependency>
<!--mysql-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-openapi3-jakarta-spring-boot-starter</artifactId>
</dependency>
<!-- 校验参数 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<!-- redis -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!-- redisson -->
<!-- <dependency>-->
<!-- <groupId>org.redisson</groupId>-->
<!-- <artifactId>redisson-spring-boot-starter</artifactId>-->
<!-- </dependency>-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<!-- 服务调用feign -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
<!-- 服务注册 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!-- 服务配置 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,49 @@
package com.atguigu.tingshu.common.config.knife4j;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.info.Contact;
import io.swagger.v3.oas.models.info.Info;
import org.springdoc.core.models.GroupedOpenApi;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class Knife4jConfig {
@Value("${spring.application.name}")
private String appName;
@Bean
public GroupedOpenApi webApi() {
return GroupedOpenApi.builder()
.group("web-api")
.pathsToMatch("/api/**")
.build();
}
/*后台管理相关文档 接口地址以/admin开头 */
//@Bean
//public GroupedOpenApi adminApi() {
// return GroupedOpenApi.builder()
// .group("admin-api")
// .pathsToMatch("/admin/**")
// .build();
//}
/***
* @description 自定义接口信息
*/
@Bean
public OpenAPI customOpenAPI() {
return new OpenAPI()
.info(new Info()
.title(appName + "听书API接口文档")
.version("1.0")
.description("听书API接口文档")
.contact(new Contact().name("atguigu")));
}
}

View File

@ -0,0 +1,32 @@
package com.atguigu.tingshu.common.config.mybatisPlus;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.annotation.EnableTransactionManagement;
/**
* MybatisPlus配置类
*
*/
@EnableTransactionManagement
@Configuration
@MapperScan("com.atguigu.tingshu.*.mapper")
public class MybatisPlusConfig {
/**
*
* @return
*/
@Bean
public MybatisPlusInterceptor optimisticLockerInnerInterceptor(){
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
//向Mybatis过滤器链中添加分页拦截器
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
return interceptor;
}
}

View File

@ -0,0 +1,39 @@
package com.atguigu.tingshu.common.config.redis;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.*;
/**
* Redis配置类
*/
@Configuration
@EnableCaching
public class RedisConfig {
@Bean
@Primary
public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(redisConnectionFactory);
//String的序列化方式
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
// 使用GenericJackson2JsonRedisSerializer 替换默认序列化(默认采用的是JDK序列化)
GenericJackson2JsonRedisSerializer genericJackson2JsonRedisSerializer = new GenericJackson2JsonRedisSerializer();
//序列号key value
redisTemplate.setKeySerializer(stringRedisSerializer);
redisTemplate.setValueSerializer(genericJackson2JsonRedisSerializer);
redisTemplate.setHashKeySerializer(stringRedisSerializer);
redisTemplate.setHashValueSerializer(genericJackson2JsonRedisSerializer);
redisTemplate.afterPropertiesSet();
return redisTemplate;
}
}

View File

@ -0,0 +1,72 @@
package com.atguigu.tingshu.common.constant;
public class RedisConstant {
public static final String ALBUM_INFO_PREFIX = "album:info:";
public static final String CACHE_INFO_PREFIX = "cache:info:";
public static final String CACHE_LOCK_SUFFIX = ":lock";
//单位
//单位 尝试获取锁的最大等待时间
public static final long ALBUM_LOCK_WAIT_PX1 = 1;
//单位 锁的持有时间
public static final long ALBUM_LOCK_EXPIRE_PX2 = 3;
public static final long ALBUM_TIMEOUT = 1 * 60 * 60;
// 商品如果在数据库中不存在那么会缓存一个空对象进去但是这个对象是没有用的所以这个对象的过期时间应该不能太长
// 如果太长会占用内存
// 定义变量记录空对象的缓存过期时间
public static final long ALBUM_TEMPORARY_TIMEOUT = 10 * 60;
// 布隆过滤器使用
public static final String ALBUM_BLOOM_FILTER = "album:bloom:filter";
//订单防重流水号前缀
public static final String ORDER_TRADE_NO_PREFIX = "user:trade:";
//订单流水号有效期
public static final int ORDER_TRADE_EXPIRE = 5;
//单位
//单位 尝试获取锁的最大等待时间
public static final long CACHE_LOCK_EXPIRE_PX1 = 1;
//单位 锁的持有时间
public static final long CACHE_LOCK_EXPIRE_PX2 = 1;
public static final long CACHE_TIMEOUT = 24 * 60 * 60;
// 商品如果在数据库中不存在那么会缓存一个空对象进去但是这个对象是没有用的所以这个对象的过期时间应该不能太长
// 如果太长会占用内存
// 定义变量记录空对象的缓存过期时间
public static final long CACHE_TEMPORARY_TIMEOUT = 10 * 60;
//用户登录
public static final String USER_LOGIN_KEY_PREFIX = "user:login:";
public static final String USER_LOGIN_REFRESH_KEY_PREFIX = "user:login:refresh:";
public static final int USER_LOGIN_KEY_TIMEOUT = 60 * 60 * 24 * 100;
public static final int USER_LOGIN_REFRESH_KEY_TIMEOUT = 60 * 60 * 24 * 365;
public static final String RANKING_KEY_PREFIX = "ranking:";
public static final String ALBUM_STAT_ENDTIME = "album:stat:endTime";
//更新声音统计前缀
public static final String USER_TRACK_REPEAT_STAT_PREFIX = "user:track:";
//重复锁定账户
public static final String ACCOUNT_MUTIPLE_CHECK = "account:rechecklock:";
//账户锁定对象
public static final String ACCOUNT_CHECK_DATA = "account:check:";
//重复扣减锁定金额
public static final String ACCOUNT_MUTIPLE_MINUS = "account:deductlock";
//公用的业务标识前缀
public static final String BUSINESS_PREFIX = "biz:";
}

View File

@ -0,0 +1,74 @@
package com.atguigu.tingshu.common.constant;
public class SystemConstant {
//专辑付费类型 0101-免费0102-vip免费0103-付费
public static final String ALBUM_PAY_TYPE_FREE="0101"; // 免费
public static final String ALBUM_PAY_TYPE_VIPFREE="0102"; // vip免费
public static final String ALBUM_PAY_TYPE_REQUIRE="0103"; // 付费
//专辑价格类型 0201-单集 0202-整专辑
public static final String ALBUM_PRICE_TYPE_ONE="0201"; // 单级
public static final String ALBUM_PRICE_TYPE_ALL="0202"; // 整专辑
//专辑状态 0301-审核通过 0302-审核不通过
public static final String ALBUM_STATUS_PASS="0301"; // 审核通过
public static final String ALBUM_STATUS_NO_PASS="0302"; // 审核不通过
//专辑统计 0401-播放量 0402-订阅量 0403-购买量 0403-评论数
public static final String ALBUM_STAT_PLAY="0401"; // 播放量
public static final String ALBUM_STAT_SUBSCRIBE="0402"; // 订阅量
public static final String ALBUM_STAT_BUY="0403"; // 购买量
public static final String ALBUM_STAT_COMMENT="0404"; // 评论数
//声音状态 0501-审核通过 0502"-审核不通过
public static final String TRACK_STATUS_PASS="0501"; // 审核通过
public static final String TRACK_STATUS_NO_PASS="0502"; // 审核不通过
//声音来源 0601-用户原创 0602-上传
public static final String TRACK_SOURCE_USER="0601"; // 用户原创
public static final String TRACK_SOURCE_UPLOAD="0602"; // 上传
// 声音统计 0701-播放量 0702-收藏量 0703-点赞量 0704-评论数
public static final String TRACK_STAT_PLAY="0701"; // 播放量
public static final String TRACK_STAT_COLLECT="0702"; // 收藏量
public static final String TRACK_STAT_PRAISE="0703"; // 点赞量
public static final String TRACK_STAT_COMMENT="0704"; // 评论数
//用户状态 0801-正常 0802-锁定
public static final String USER_STATUS_NORMAL="0801"; // 正常
public static final String USER_STATUS_LOCK="0802"; // 锁定
//订单状态 0901-正常 0902-已支付 0903-已取消
public static final String ORDER_STATUS_UNPAID="0901"; // 未支付
public static final String ORDER_STATUS_PAID="0902"; // 已支付
public static final String ORDER_STATUS_CANCEL="0903"; // 已取消
//订单付款项目类型 1001-专辑 1002-声音 1003-vip会员
public static final String ORDER_ITEM_TYPE_ALBUM="1001"; // 专辑
public static final String ORDER_ITEM_TYPE_TRACK="1002"; // 声音
public static final String ORDER_ITEM_TYPE_VIP="1003"; // vip会员
//订单支付方式 1101-微信 1102-支付宝 1103-账户余额
public static final String ORDER_PAY_WAY_WEIXIN="1101"; // 微信
public static final String ORDER_PAY_WAY_ALIPAY="1102"; // 支付宝
public static final String ORDER_PAY_ACCOUNT="1103"; // 账户余额
//账号交易类型 1201-充值 1202-锁定 1203-解锁 1204-消费
public static final String ACCOUNT_TRADE_TYPE_DEPOSIT="1201"; // 充值
public static final String ACCOUNT_TRADE_TYPE_LOCK="1202"; // 锁定
public static final String ACCOUNT_TRADE_TYPE_UNLOCK="1203"; // 解锁
public static final String ACCOUNT_TRADE_TYPE_MINUS="1204"; // 消费
//支付类型 1301-订单 1302-充值
public static final String PAYMENT_TYPE_ORDER="1301"; // 订单
public static final String PAYMENT_TYPE_RECHARGE="1302"; // 充值
//支付表支付状态 1401-未支付 1402-已支付
public static final String PAYMENT_STATUS_UNPAID="1401"; // 未支付
public static final String PAYMENT_STATUS_PAID="1402"; // 已支付
//订单减免类型 1405-专辑折扣 1406-VIP服务折
public static final String ORDER_DERATE_ALBUM_DISCOUNT="1405"; // 专辑折扣
public static final String ORDER_DERATE_VIP_SERVICE_DISCOUNT="1406"; // VIP服务折扣
}

View File

@ -0,0 +1,45 @@
package com.atguigu.tingshu.common.execption;
import com.atguigu.tingshu.common.result.ResultCodeEnum;
import lombok.Data;
/**
* 自定义全局异常类
*
*/
@Data
public class GuiguException extends RuntimeException {
private Integer code;
private String message;
/**
* 通过状态码和错误消息创建异常对象
* @param code
* @param message
*/
public GuiguException(Integer code, String message) {
super(message);
this.code = code;
this.message = message;
}
/**
* 接收枚举类型对象
* @param resultCodeEnum
*/
public GuiguException(ResultCodeEnum resultCodeEnum) {
super(resultCodeEnum.getMessage());
this.code = resultCodeEnum.getCode();
this.message = resultCodeEnum.getMessage();
}
@Override
public String toString() {
return "GuliException{" +
"code=" + code +
", message=" + this.getMessage() +
'}';
}
}

View File

@ -0,0 +1,83 @@
package com.atguigu.tingshu.common.handler;
import com.atguigu.tingshu.common.execption.GuiguException;
import com.atguigu.tingshu.common.result.Result;
import com.atguigu.tingshu.common.result.ResultCodeEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 全局异常处理类
*/
@Slf4j
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(Exception.class)
@ResponseBody
public Result error(Exception e) {
log.error("触发Exception异常拦截:{}", e);
return Result.fail();
}
/**
* 自定义异常处理方法
*
* @param e
* @return
*/
@ExceptionHandler(GuiguException.class)
@ResponseBody
public Result error(GuiguException e) {
log.error("触发GuiguException异常拦截:{}", e);
return Result.build(null, e.getCode(), e.getMessage());
}
@ExceptionHandler({IllegalArgumentException.class})
@ResponseBody
public Result llegalArgumentException(Exception e) {
log.error("触发异常拦截: " + e.getMessage(), e);
return Result.build(null, ResultCodeEnum.ARGUMENT_VALID_ERROR);
}
@ExceptionHandler(value = BindException.class)
@ResponseBody
public Result error(BindException exception) {
BindingResult result = exception.getBindingResult();
Map<String, Object> errorMap = new HashMap<>();
List<FieldError> fieldErrors = result.getFieldErrors();
fieldErrors.forEach(error -> {
log.error("field: " + error.getField() + ", msg:" + error.getDefaultMessage());
errorMap.put(error.getField(), error.getDefaultMessage());
});
log.error("触发BindException异常拦截: {}" + errorMap);
return Result.build(errorMap, ResultCodeEnum.ARGUMENT_VALID_ERROR);
}
@ExceptionHandler(value = MethodArgumentNotValidException.class)
@ResponseBody
public Result error(MethodArgumentNotValidException exception) {
BindingResult result = exception.getBindingResult();
Map<String, Object> errorMap = new HashMap<>();
List<FieldError> fieldErrors = result.getFieldErrors();
fieldErrors.forEach(error -> {
log.error("field: " + error.getField() + ", msg:" + error.getDefaultMessage());
errorMap.put(error.getField(), error.getDefaultMessage());
});
log.error("触发MethodArgumentNotValidException异常拦截: {}" + errorMap);
return Result.build(errorMap, ResultCodeEnum.ARGUMENT_VALID_ERROR);
}
}

View File

@ -0,0 +1,25 @@
package com.atguigu.tingshu.common.interceptor;
import feign.RequestInterceptor;
import feign.RequestTemplate;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
@Component
public class FeignInterceptor implements RequestInterceptor {
public void apply(RequestTemplate requestTemplate){
// 获取请求对象
RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
//异步编排 MQ消费者端 null
if(null != requestAttributes) {
ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes)requestAttributes;
HttpServletRequest request = servletRequestAttributes.getRequest();
String token = request.getHeader("token");
requestTemplate.header("token", token);
}
}
}

58
model/pom.xml Normal file
View File

@ -0,0 +1,58 @@
<?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>tingshu-parent</artifactId>
<groupId>com.atguigu.tingshu</groupId>
<version>1.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>model</artifactId>
<dependencies>
<!--lombok用来简化实体类-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>com.atguigu.tingshu</groupId>
<artifactId>common-util</artifactId>
<version>1.0</version>
<scope>provided </scope>
</dependency>
<!-- <dependency>-->
<!-- <groupId>com.github.xiaoymin</groupId>-->
<!-- <artifactId>knife4j-spring-boot-starter</artifactId>-->
<!-- <scope>provided </scope>-->
<!-- </dependency>-->
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-openapi3-jakarta-spring-boot-starter</artifactId>
<scope>provided </scope>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<scope>provided </scope>
</dependency>
<!-- 校验参数 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
<scope>provided </scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
<scope>provided </scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
<scope>provided </scope>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,38 @@
package com.atguigu.tingshu.model.account;
import com.atguigu.tingshu.model.base.BaseEntity;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.math.BigDecimal;
@Data
@Schema(description = "RechargeInfo")
@TableName("recharge_info")
public class RechargeInfo extends BaseEntity {
private static final long serialVersionUID = 1L;
@Schema(description = "用户ID")
@TableField("user_id")
private Long userId;
@Schema(description = "充值订单编号")
@TableField("order_no")
private String orderNo;
@Schema(description = "充值状态0901-未支付 0902-已支付 0903-已取消")
@TableField("recharge_status")
private String rechargeStatus;
@Schema(description = "充值金额")
@TableField("recharge_amount")
private BigDecimal rechargeAmount;
@Schema(description = "支付方式1101-微信 1102-支付宝")
@TableField("pay_way")
private String payWay;
}

View File

@ -0,0 +1,42 @@
package com.atguigu.tingshu.model.account;
import com.atguigu.tingshu.model.base.BaseEntity;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.math.BigDecimal;
@Data
@Schema(description = "UserAccount")
@TableName("user_account")
public class UserAccount extends BaseEntity {
private static final long serialVersionUID = 1L;
@Schema(description = "用户id")
@TableField("user_id")
private Long userId;
@Schema(description = "账户总金额")
@TableField("total_amount")
private BigDecimal totalAmount;
@Schema(description = "锁定金额")
@TableField("lock_amount")
private BigDecimal lockAmount;
@Schema(description = "可用金额")
@TableField("available_amount")
private BigDecimal availableAmount;
@Schema(description = "总收入")
@TableField("total_income_amount")
private BigDecimal totalIncomeAmount;
@Schema(description = "总支出")
@TableField("total_pay_amount")
private BigDecimal totalPayAmount;
}

View File

@ -0,0 +1,38 @@
package com.atguigu.tingshu.model.account;
import com.atguigu.tingshu.model.base.BaseEntity;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.math.BigDecimal;
@Data
@Schema(description = "UserAccountDetail")
@TableName("user_account_detail")
public class UserAccountDetail extends BaseEntity {
private static final long serialVersionUID = 1L;
@Schema(description = "用户id")
@TableField("user_id")
private Long userId;
@Schema(description = "交易标题")
@TableField("title")
private String title;
@Schema(description = "交易类型1201-充值 1202-锁定 1203-解锁 1204-消费")
@TableField("trade_type")
private String tradeType;
@Schema(description = "金额")
@TableField("amount")
private BigDecimal amount;
@Schema(description = "订单编号")
@TableField("order_no")
private String orderNo;
}

View File

@ -0,0 +1,35 @@
package com.atguigu.tingshu.model.album;
import com.atguigu.tingshu.model.base.BaseEntity;
import com.baomidou.mybatisplus.annotation.TableField;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
@Data
@Schema(description = "专辑属性值")
public class AlbumAttributeValue extends BaseEntity {
private static final long serialVersionUID = 1L;
@Schema(description = "专辑id")
private Long albumId;
@NotNull(message = "属性id不能为空")
@Schema(description = "属性id")
private Long attributeId;
@NotNull(message = "属性值id不能为空")
@Schema(description = "属性值id")
private Long valueId;
@Schema(description = "属性名称")
@TableField(exist = false)
private String attributeName;
@Schema(description = "属性值名称")
@TableField(exist = false)
private String valueName;
}

View File

@ -0,0 +1,106 @@
package com.atguigu.tingshu.model.album;
import com.atguigu.tingshu.model.base.BaseEntity;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.math.BigDecimal;
import java.util.List;
@Data
@Schema(description = "AlbumInfo")
@TableName("album_info")
public class AlbumInfo extends BaseEntity {
private static final long serialVersionUID = 1L;
@Schema(description = "用户id")
@TableField("user_id")
private Long userId;
@Schema(description = "标题")
@TableField("album_title")
private String albumTitle;
@Schema(description = "三级分类id")
@TableField("category3_id")
private Long category3Id;
@Schema(description = "专辑简介")
@TableField("album_intro")
private String albumIntro;
@Schema(description = "专辑封面原图尺寸不固定最大尺寸为960*960像素")
@TableField("cover_url")
private String coverUrl;
@Schema(description = "专辑包含声音总数")
@TableField("include_track_count")
private Integer includeTrackCount;
@Schema(description = "专辑是否完结0-否1-完结;")
@TableField("is_finished")
private String isFinished;
@Schema(description = "预计更新多少集")
@TableField("estimated_track_count")
private Integer estimatedTrackCount;
@Schema(description = "专辑简介,富文本")
@TableField("album_rich_intro")
private String albumRichIntro;
@Schema(description = "专辑评分")
@TableField("quality_score")
private String qualityScore;
@Schema(description = "付费类型: 0101-免费、0102-vip免费、0103-付费")
@TableField("pay_type")
private String payType;
@Schema(description = "价格类型: 0201-单集 0202-整专辑")
@TableField("price_type")
private String priceType;
@Schema(description = "原价")
@TableField("price")
private BigDecimal price;
@Schema(description = "0.1-9.9 不打折 -1")
@TableField("discount")
private BigDecimal discount;
@Schema(description = "0.1-9.9 不打折 -1")
@TableField("vip_discount")
private BigDecimal vipDiscount;
@Schema(description = "免费试听集数")
@TableField("tracks_for_free")
private Integer tracksForFree;
@Schema(description = "每集免费试听秒数")
@TableField("seconds_for_free")
private Integer secondsForFree;
@Schema(description = "购买须知,富文本")
@TableField("buy_notes")
private String buyNotes;
@Schema(description = "专辑卖点,富文本")
@TableField("selling_point")
private String sellingPoint;
@Schema(description = "是否公开0-否 1-是")
@TableField("is_open")
private String isOpen;
@Schema(description = "状态")
@TableField("status")
private String status;
@Schema(description = "属性值集合")
@TableField(exist = false)
private List<AlbumAttributeValue> albumAttributeValueVoList;
}

View File

@ -0,0 +1,28 @@
package com.atguigu.tingshu.model.album;
import com.atguigu.tingshu.model.base.BaseEntity;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Data
@Schema(description = "AlbumStat")
@TableName("album_stat")
public class AlbumStat extends BaseEntity {
private static final long serialVersionUID = 1L;
@Schema(description = "专辑id")
@TableField("album_id")
private Long albumId;
@Schema(description = "统计类型")
@TableField("stat_type")
private String statType;
@Schema(description = "统计数目")
@TableField("stat_num")
private Integer statNum;
}

View File

@ -0,0 +1,29 @@
package com.atguigu.tingshu.model.album;
import com.atguigu.tingshu.model.base.BaseEntity;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.util.List;
@Data
@Schema(description = "BaseAttribute")
@TableName("base_attribute")
public class BaseAttribute extends BaseEntity {
private static final long serialVersionUID = 1L;
@Schema(description = "一级分类id")
@TableField("category1_id")
private Long category1Id;
@Schema(description = "属性显示名称")
@TableField("attribute_name")
private String attributeName;
@TableField(exist = false)
private List<BaseAttributeValue> attributeValueList;
}

View File

@ -0,0 +1,24 @@
package com.atguigu.tingshu.model.album;
import com.atguigu.tingshu.model.base.BaseEntity;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Data
@Schema(description = "BaseAttributeValue")
@TableName("base_attribute_value")
public class BaseAttributeValue extends BaseEntity {
private static final long serialVersionUID = 1L;
@Schema(description = "属性id")
@TableField("attribute_id")
private Long attributeId;
@Schema(description = "属性值名称")
@TableField("value_name")
private String valueName;
}

View File

@ -0,0 +1,24 @@
package com.atguigu.tingshu.model.album;
import com.atguigu.tingshu.model.base.BaseEntity;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Data
@Schema(description = "BaseCategory1")
@TableName("base_category1")
public class BaseCategory1 extends BaseEntity {
private static final long serialVersionUID = 1L;
@Schema(description = "分类名称")
@TableField("name")
private String name;
@Schema(description = "排序")
@TableField("order_num")
private Integer orderNum;
}

View File

@ -0,0 +1,28 @@
package com.atguigu.tingshu.model.album;
import com.atguigu.tingshu.model.base.BaseEntity;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Data
@Schema(description = "BaseCategory2")
@TableName("base_category2")
public class BaseCategory2 extends BaseEntity {
private static final long serialVersionUID = 1L;
@Schema(description = "二级分类名称")
@TableField("name")
private String name;
@Schema(description = "一级分类编号")
@TableField("category1_id")
private Long category1Id;
@Schema(description = "orderNum")
@TableField("order_num")
private Integer orderNum;
}

View File

@ -0,0 +1,31 @@
package com.atguigu.tingshu.model.album;
import com.atguigu.tingshu.model.base.BaseEntity;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Data
@Schema(description = "BaseCategory3")
@TableName("base_category3")
public class BaseCategory3 extends BaseEntity {
private static final long serialVersionUID = 1L;
@Schema(description = "三级分类名称")
@TableField("name")
private String name;
@Schema(description = "二级分类编号")
@TableField("category2_id")
private Long category2Id;
@Schema(description = "排序")
@TableField("order_num")
private Integer orderNum;
@Schema(description = "是否置顶")
@TableField("is_top")
private Integer isTop;
}

View File

@ -0,0 +1,50 @@
//
//
package com.atguigu.tingshu.model.album;
import com.atguigu.tingshu.model.base.BaseEntity;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
/**
* <p>
* BaseCategoryView
* </p>
*
* @author atguigu
*/
@Data
@Schema(description = "分类视图")
@TableName("base_category_view")
public class BaseCategoryView extends BaseEntity {
private static final long serialVersionUID = 1L;
@Schema(description = "一级分类编号")
@TableField("category1_id")
private Long category1Id;
@Schema(description = "一级分类名称")
@TableField("category1_name")
private String category1Name;
@Schema(description = "二级分类编号")
@TableField("category2_id")
private Long category2Id;
@Schema(description = "二级分类名称")
@TableField("category2_name")
private String category2Name;
@Schema(description = "三级分类编号")
@TableField("category3_id")
private Long category3Id;
@Schema(description = "三级分类名称")
@TableField("category3_name")
private String category3Name;
}

View File

@ -0,0 +1,28 @@
package com.atguigu.tingshu.model.album;
import com.atguigu.tingshu.model.base.BaseEntity;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Data
@Schema(description = "BaseDic")
@TableName("base_dic")
public class BaseDic extends BaseEntity {
private static final long serialVersionUID = 1L;
@Schema(description = "code")
@TableField("code")
private String code;
@Schema(description = "编码名称")
@TableField("dic_name")
private String dicName;
@Schema(description = "父编号")
@TableField("parent_code")
private String parentCode;
}

View File

@ -0,0 +1,81 @@
package com.atguigu.tingshu.model.album;
import com.atguigu.tingshu.model.base.BaseEntity;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.math.BigDecimal;
@Data
@Schema(description = "TrackInfo")
@TableName("track_info")
public class TrackInfo extends BaseEntity {
private static final long serialVersionUID = 1L;
@Schema(description = "用户id")
@TableField("user_id")
private Long userId;
@Schema(description = "专辑id")
@TableField("album_id")
private Long albumId;
@Schema(description = "声音标题")
@TableField("track_title")
private String trackTitle;
@Schema(description = "声音在专辑中的排序值从0开始依次递增值越小排序越前")
@TableField("order_num")
private Integer orderNum;
@Schema(description = "声音简介")
@TableField("track_intro")
private String trackIntro;
@Schema(description = "声音简介,富文本")
@TableField("track_rich_intro")
private String trackRichIntro;
@Schema(description = "声音封面图url")
@TableField("cover_url")
private String coverUrl;
@Schema(description = "声音媒体时长,单位秒")
@TableField("media_duration")
private BigDecimal mediaDuration;
@Schema(description = "媒体文件的唯一标识")
@TableField("media_file_id")
private String mediaFileId;
@Schema(description = "媒体播放地址")
@TableField("media_url")
private String mediaUrl;
@Schema(description = "音频文件大小,单位字节")
@TableField("media_size")
private Long mediaSize;
@Schema(description = "声音媒体类型")
@TableField("media_type")
private String mediaType;
@Schema(description = "声音来源1-用户原创2-上传")
@TableField("source")
private String source;
@Schema(description = "状态")
@TableField("status")
private String status;
@Schema(description = "是否公开0-否 1-是")
@TableField("is_open")
private String isOpen;
@Schema(description = "发起审核任务ID")
@TableField("review_task_id")
private String reviewTaskId;
}

View File

@ -0,0 +1,28 @@
package com.atguigu.tingshu.model.album;
import com.atguigu.tingshu.model.base.BaseEntity;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Data
@Schema(description = "TrackStat")
@TableName("track_stat")
public class TrackStat extends BaseEntity {
private static final long serialVersionUID = 1L;
@Schema(description = "声音id")
@TableField("track_id")
private Long trackId;
@Schema(description = "统计类型")
@TableField("stat_type")
private String statType;
@Schema(description = "统计数目")
@TableField("stat_num")
private Integer statNum;
}

View File

@ -0,0 +1,36 @@
package com.atguigu.tingshu.model.base;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
@Data
public class BaseEntity implements Serializable {
@TableId(type = IdType.AUTO)
private Long id;
@TableField("create_time")
private Date createTime;
@JsonIgnore
@TableField("update_time")
private Date updateTime;
@JsonIgnore
@TableLogic
@TableField("is_deleted")
private Integer isDeleted;
@JsonIgnore
@TableField(exist = false)
private Map<String,Object> param = new HashMap<>();
}

View File

@ -0,0 +1,55 @@
package com.atguigu.tingshu.model.comment;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import org.springframework.data.annotation.Id;
import org.springframework.data.annotation.Transient;
import org.springframework.data.mongodb.core.mapping.Document;
import java.util.Date;
import java.util.List;
@Data
@Schema(description = "专辑评论")
@Document
public class Comment {
@Schema(description = "id")
@Id
private String id;
@Schema(description = "专辑id")
private Long albumId;
@Schema(description = "用户id")
private Long userId;
@Schema(description = "发表评论用户的昵称,已脱敏")
private String nickname;
@Schema(description = "发表评论用户的头像图片地址")
private String avatarUrl;
@Schema(description = "评论内容")
private String content;
@Schema(description = "被回复的评论id")
private String replyCommentId;
@Schema(description = "点赞数量")
private Integer praiseCount = 0;
@Schema(description = "评论中对专辑的评分 十分制建议采用五星制如10分显示五颗星7分显示三颗半星")
private Integer albumCommentScore;
@Schema(description = "创建时间")
private Date createTime;
@Schema(description = "当前用户是否点赞")
@Transient
private Boolean isPraise;
@Schema(description = "回复评论列表")
@Transient //被该注解标注的将不会被录入到数据库中只作为普通的javaBean属性
private List<Comment> replyCommentList;
}

View File

@ -0,0 +1,39 @@
package com.atguigu.tingshu.model.comment;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
import java.util.Date;
/**
* <p>
* CommentPraise
* </p>
*
* @author atguigu
*/
@Data
@Schema(description = "专辑评论点赞")
@Document
public class CommentPraise {
@Schema(description = "id")
@Id
private String id;
@Schema(description = "动态id")
private Long albumId;
@Schema(description = "评论id")
private String commentId;
@Schema(description = "点赞者id")
private Long userId;
@Schema(description = "创建时间")
private Date createTime;
}

View File

@ -0,0 +1,44 @@
package com.atguigu.tingshu.model.dispatch;
import com.atguigu.tingshu.model.base.BaseEntity;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Data
@Schema(description = "XxlJobConfig")
@TableName("xxl_job_config")
public class XxlJobConfig extends BaseEntity {
private static final long serialVersionUID = 1L;
@Schema(description = "调度任务标题")
@TableField("title")
private String title;
@Schema(description = "调度执行handler")
@TableField("executor_handler")
private String executorHandler;
@Schema(description = "调度任务参数")
@TableField("executor_param")
private String executorParam;
@Schema(description = "调度表达式")
@TableField("cron")
private String cron;
@Schema(description = "备注")
@TableField("remark")
private String remark;
@Schema(description = "任务状态 0失败 1成功")
@TableField("status")
private Integer status;
@Schema(description = "xxl任务平台id")
@TableField("xxl_job_id")
private Long xxlJobId;
}

View File

@ -0,0 +1,32 @@
package com.atguigu.tingshu.model.dispatch;
import com.atguigu.tingshu.model.base.BaseEntity;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Data
@Schema(description = "XxlJobLog")
@TableName("xxl_job_log")
public class XxlJobLog extends BaseEntity {
private static final long serialVersionUID = 1L;
@Schema(description = "任务配置id")
@TableField("job_config_id")
private Long jobConfigId;
@Schema(description = "任务状态 0失败 1成功")
@TableField("status")
private Integer status;
@Schema(description = "失败信息")
@TableField("error")
private String error;
@Schema(description = "耗时(单位:毫秒)")
@TableField("times")
private Integer times;
}

View File

@ -0,0 +1,14 @@
package com.atguigu.tingshu.model.live;
import lombok.Data;
@Data
public class FromUser {
//用户id
private Long userId;
//昵称
private String nickname;
//头像地址
private String avatarUrl;
}

View File

@ -0,0 +1,74 @@
package com.atguigu.tingshu.model.live;
import com.atguigu.tingshu.model.base.BaseEntity;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.util.Date;
@Data
@Schema(description = "LiveRoom")
@TableName("live_room")
public class LiveRoom extends BaseEntity {
private static final long serialVersionUID = 1L;
@Schema(description = "用户id")
@TableField("user_id")
private Long userId;
@Schema(description = "直播间封面")
@TableField("cover_url")
private String coverUrl;
@Schema(description = "直播标题")
@TableField("live_title")
private String liveTitle;
@Schema(description = "当前直播场次的总访问人次")
@TableField("view_count")
private Integer viewCount;
@Schema(description = "直播状态:1-直播正在进行2-直播结束")
@TableField("status")
private String status;
@Schema(description = "直播间标签id")
@TableField("tag_id")
private String tagId;
@Schema(description = "直播应用名称")
@TableField("app_name")
private String appName;
@Schema(description = "直播流名称")
@TableField("stream_name")
private String streamName;
@Schema(description = "过期时间")
@TableField("expire_time")
private Date expireTime;
@Schema(description = "推流地址")
@TableField("push_url")
private String pushUrl;
@Schema(description = "播放地址")
@TableField("play_url")
private String playUrl;
@Schema(description = "经度")
@TableField("longitude")
private String longitude;
@Schema(description = "纬度")
@TableField("latitude")
private String latitude;
@Schema(description = "位置")
@TableField("location")
private String location;
}

View File

@ -0,0 +1,28 @@
package com.atguigu.tingshu.model.live;
import com.atguigu.tingshu.model.base.BaseEntity;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Data
@Schema(description = "LiveTag")
@TableName("live_tag")
public class LiveTag extends BaseEntity {
private static final long serialVersionUID = 1L;
@Schema(description = "标签名称")
@TableField("name")
private String name;
@Schema(description = "标签图标url")
@TableField("icon_url")
private String iconUrl;
@Schema(description = "排序")
@TableField("order_num")
private Integer orderNum;
}

View File

@ -0,0 +1,49 @@
package com.atguigu.tingshu.model.live;
import lombok.Data;
import lombok.Getter;
/**
* 这里我们就不能使用简单的文本消息进行消息的发送了我们使用json进行消息的发送
* 所以需要先创建一个消息对象里面包含了消息发送者消息接受者消息类型单聊还是群聊还是就是消息如下
*/
@Data
public class SocketMsg {
@Getter
public enum MsgTypeEnum {
HEART_BEAT("0","心跳信息"),
PUBLIC_MSG("1","公共聊天消息"),
JOIN_CHAT("2","加入聊天室"),
CLOSE_SOCKET("3","退出聊天室"),
ONLINE_NUM("4","在线用户数"),
TOKEN_INVALID("-1","token无效"),
;
private String code;
private String data;
MsgTypeEnum(String code, String data) {
this.code = code;
this.data = data;
}
}
//直播房间id
private Long liveRoomId;
// //消息体
// private MsgBody msgBody;
//消息类型
private String msgType;
//消息内容
private Object msgContent;
//发送者
private FromUser fromUser;
//时间戳
private Long timestamp;
}

View File

@ -0,0 +1,34 @@
package com.atguigu.tingshu.model.order;
import com.atguigu.tingshu.model.base.BaseEntity;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.math.BigDecimal;
@Data
@Schema(description = "OrderDerate")
@TableName("order_derate")
public class OrderDerate extends BaseEntity {
private static final long serialVersionUID = 1L;
@Schema(description = "订单id")
@TableField("order_id")
private Long orderId;
@Schema(description = "订单减免类型 1405-专辑折扣 1406-VIP服务折")
@TableField("derate_type")
private String derateType;
@Schema(description = "减免金额")
@TableField("derate_amount")
private BigDecimal derateAmount;
@Schema(description = "备注")
@TableField("remarks")
private String remarks;
}

View File

@ -0,0 +1,38 @@
package com.atguigu.tingshu.model.order;
import com.atguigu.tingshu.model.base.BaseEntity;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.math.BigDecimal;
@Data
@Schema(description = "OrderDetail")
@TableName("order_detail")
public class OrderDetail extends BaseEntity {
private static final long serialVersionUID = 1L;
@Schema(description = "订单id")
@TableField("order_id")
private Long orderId;
@Schema(description = "付费项目id")
@TableField("item_id")
private Long itemId;
@Schema(description = "付费项目名称")
@TableField("item_name")
private String itemName;
@Schema(description = "付费项目图片url")
@TableField("item_url")
private String itemUrl;
@Schema(description = "付费项目价格")
@TableField("item_price")
private BigDecimal itemPrice;
}

View File

@ -0,0 +1,69 @@
package com.atguigu.tingshu.model.order;
import com.atguigu.tingshu.model.base.BaseEntity;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.math.BigDecimal;
import java.util.List;
@Data
@Schema(description = "OrderInfo")
@TableName("order_info")
public class OrderInfo extends BaseEntity {
private static final long serialVersionUID = 1L;
@Schema(description = "用户ID")
@TableField("user_id")
private Long userId;
@Schema(description = "订单标题")
@TableField("order_title")
private String orderTitle;
@Schema(description = "订单号")
@TableField("order_no")
private String orderNo;
@Schema(description = "订单状态0901-未支付 0902-已支付 0903-已取消")
@TableField("order_status")
private String orderStatus;
@Schema(description = "订单原始金额")
@TableField("original_amount")
private BigDecimal originalAmount;
@Schema(description = "减免总金额")
@TableField("derate_amount")
private BigDecimal derateAmount;
@Schema(description = "订单总价")
@TableField("order_amount")
private BigDecimal orderAmount;
@Schema(description = "付款项目类型: 1001-专辑 1002-声音 1003-vip会员")
@TableField("item_type")
private String itemType;
@Schema(description = "支付方式1101-微信 1102-支付宝 1103-账户余额")
@TableField("pay_way")
private String payWay;
@Schema(description = "订单明细列表")
@TableField(exist = false)
private List<OrderDetail> orderDetailList;
@Schema(description = "订单减免明细列表")
@TableField(exist = false)
private List<OrderDerate> orderDerateList;
@TableField(exist = false)
private String orderStatusName;
@TableField(exist = false)
private String payWayName;
}

View File

@ -0,0 +1,59 @@
package com.atguigu.tingshu.model.payment;
import com.atguigu.tingshu.model.base.BaseEntity;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.math.BigDecimal;
import java.util.Date;
@Data
@Schema(description = "PaymentInfo")
@TableName("payment_info")
public class PaymentInfo extends BaseEntity {
private static final long serialVersionUID = 1L;
@Schema(description = "用户id")
@TableField("user_id")
private Long userId;
@Schema(description = "支付类型1301-订单 1302-充值")
@TableField("payment_type")
private String paymentType;
@Schema(description = "订单号")
@TableField("order_no")
private String orderNo;
@Schema(description = "付款方式1101-微信 1102-支付宝")
@TableField("pay_way")
private String payWay;
@Schema(description = "交易编号(微信或支付)")
@TableField("out_trade_no")
private String outTradeNo;
@Schema(description = "支付金额")
@TableField("amount")
private BigDecimal amount;
@Schema(description = "交易内容")
@TableField("content")
private String content;
@Schema(description = "支付状态1401-未支付 1402-已支付")
@TableField("payment_status")
private String paymentStatus;
@Schema(description = "回调时间")
@TableField("callback_time")
private Date callbackTime;
@Schema(description = "回调信息")
@TableField("callback_content")
private String callbackContent;
}

View File

@ -0,0 +1,89 @@
package com.atguigu.tingshu.model.search;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import lombok.Data;
import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.DateFormat;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.annotations.FieldType;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
@Data
@Document(indexName = "albuminfo")
@JsonIgnoreProperties(ignoreUnknown = true)//目的防止json字符串转成实体对象时因未识别字段报错
public class AlbumInfoIndex implements Serializable {
private static final long serialVersionUID = 1L;
// 专辑Id
@Id
private Long id;
// es 中能分词的字段这个字段数据类型必须是 textkeyword 不分词 analyzer = "ik_max_word"
@Field(type = FieldType.Text, analyzer = "ik_max_word")
private String albumTitle;
@Field(type = FieldType.Text, analyzer = "ik_max_word")
private String albumIntro;
@Field(type = FieldType.Keyword)
private String announcerName;
//专辑封面
@Field(type = FieldType.Keyword, index = false)
private String coverUrl;
//专辑包含声音总数
@Field(type = FieldType.Long, index = false)
private Integer includeTrackCount;
//专辑是否完结0-1-完结
@Field(type = FieldType.Long, index = false)
private String isFinished;
//付费类型免费vip免费付费
@Field(type = FieldType.Keyword, index = false)
private String payType;
@Field(type = FieldType.Date,format = DateFormat.date_time, pattern = "yyyy-MM-dd HH:mm:ss")
private Date createTime; //
@Field(type = FieldType.Long)
private Long category1Id;
@Field(type = FieldType.Long)
private Long category2Id;
@Field(type = FieldType.Long)
private Long category3Id;
//播放量
@Field(type = FieldType.Integer)
private Integer playStatNum = 0;
//订阅量
@Field(type = FieldType.Integer)
private Integer subscribeStatNum = 0;
//购买量
@Field(type = FieldType.Integer)
private Integer buyStatNum = 0;
//评论数
@Field(type = FieldType.Integer)
private Integer commentStatNum = 0;
// 商品的热度
@Field(type = FieldType.Double)
private Double hotScore = 0d;
//专辑属性值
// Nested 支持嵌套查询
@Field(type = FieldType.Nested)
private List<AttributeValueIndex> attributeValueIndexList;
}

View File

@ -0,0 +1,18 @@
package com.atguigu.tingshu.model.search;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.annotations.FieldType;
@Data
@Schema(description = "专辑属性值")
public class AttributeValueIndex {
@Field(type = FieldType.Long)
private Long attributeId;
@Field(type = FieldType.Long)
private Long valueId;
}

View File

@ -0,0 +1,32 @@
package com.atguigu.tingshu.model.search;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import lombok.Data;
import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.CompletionField;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.annotations.FieldType;
import org.springframework.data.elasticsearch.core.suggest.Completion;
@Data
@Document(indexName = "suggestinfo")
@JsonIgnoreProperties(ignoreUnknown = true)//目的防止json字符串转成实体对象时因未识别字段报错
public class SuggestIndex {
@Id
private String id;
@Field(type = FieldType.Text, analyzer = "standard")
private String title;
@CompletionField(analyzer = "standard", searchAnalyzer = "standard", maxInputLength = 20)
private Completion keyword;
@CompletionField(analyzer = "standard", searchAnalyzer = "standard", maxInputLength = 20)
private Completion keywordPinyin;
@CompletionField(analyzer = "standard", searchAnalyzer = "standard", maxInputLength = 20)
private Completion keywordSequence;
}

View File

@ -0,0 +1,50 @@
package com.atguigu.tingshu.model.system;
import com.atguigu.tingshu.model.base.BaseEntity;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.util.List;
@Data
@Schema(description = "部门")
@TableName("sys_dept")
public class SysDept extends BaseEntity {
private static final long serialVersionUID = 1L;
@Schema(description = "部门名称")
@TableField("name")
private String name;
@Schema(description = "上级部门id")
@TableField("parent_id")
private Long parentId;
@Schema(description = "树结构")
@TableField("tree_path")
private String treePath;
@Schema(description = "排序")
@TableField("sort_value")
private Integer sortValue;
@Schema(description = "负责人")
@TableField("leader")
private String leader;
@Schema(description = "电话")
@TableField("phone")
private String phone;
@Schema(description = "状态1正常 0停用")
@TableField("status")
private Integer status;
@Schema(description = "下级部门")
@TableField(exist = false)
private List<SysDept> children;
}

View File

@ -0,0 +1,38 @@
package com.atguigu.tingshu.model.system;
import com.atguigu.tingshu.model.base.BaseEntity;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.util.Date;
@Data
@Schema(description = "SysLoginLog")
@TableName("sys_login_log")
public class SysLoginLog extends BaseEntity {
private static final long serialVersionUID = 1L;
@Schema(description = "用户账号")
@TableField("username")
private String username;
@Schema(description = "登录IP地址")
@TableField("ipaddr")
private String ipaddr;
@Schema(description = "登录状态0成功 1失败")
@TableField("status")
private Integer status;
@Schema(description = "提示信息")
@TableField("msg")
private String msg;
@Schema(description = "访问时间")
@TableField("access_time")
private Date accessTime;
}

View File

@ -0,0 +1,61 @@
package com.atguigu.tingshu.model.system;
import com.atguigu.tingshu.model.base.BaseEntity;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.util.List;
@Data
@Schema(description = "菜单")
@TableName("sys_menu")
public class SysMenu extends BaseEntity {
private static final long serialVersionUID = 1L;
@Schema(description = "所属上级")
@TableField("parent_id")
private Long parentId;
@Schema(description = "名称")
@TableField("name")
private String name;
@Schema(description = "类型(1:菜单,2:按钮)")
@TableField("type")
private Integer type;
@Schema(description = "路由地址")
@TableField("path")
private String path;
@Schema(description = "组件路径")
@TableField("component")
private String component;
@Schema(description = "权限标识")
@TableField("perms")
private String perms;
@Schema(description = "图标")
@TableField("icon")
private String icon;
@Schema(description = "排序")
@TableField("sort_value")
private Integer sortValue;
@Schema(description = "状态(0:禁止,1:正常)")
@TableField("status")
private Integer status;
// 下级列表
@TableField(exist = false)
private List<SysMenu> children;
//是否选中
@TableField(exist = false)
private boolean isSelect;
}

View File

@ -0,0 +1,74 @@
package com.atguigu.tingshu.model.system;
import com.atguigu.tingshu.model.base.BaseEntity;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.util.Date;
@Data
@Schema(description = "SysOperLog")
@TableName("sys_oper_log")
public class SysOperLog extends BaseEntity {
private static final long serialVersionUID = 1L;
@Schema(description = "模块标题")
@TableField("title")
private String title;
@Schema(description = "业务类型0其它 1新增 2修改 3删除")
@TableField("business_type")
private String businessType;
@Schema(description = "方法名称")
@TableField("method")
private String method;
@Schema(description = "请求方式")
@TableField("request_method")
private String requestMethod;
@Schema(description = "操作类别0其它 1后台用户 2手机端用户")
@TableField("operator_type")
private String operatorType;
@Schema(description = "操作人员")
@TableField("oper_name")
private String operName;
@Schema(description = "部门名称")
@TableField("dept_name")
private String deptName;
@Schema(description = "请求URL")
@TableField("oper_url")
private String operUrl;
@Schema(description = "主机地址")
@TableField("oper_ip")
private String operIp;
@Schema(description = "请求参数")
@TableField("oper_param")
private String operParam;
@Schema(description = "返回参数")
@TableField("json_result")
private String jsonResult;
@Schema(description = "操作状态0正常 1异常")
@TableField("status")
private Integer status;
@Schema(description = "错误消息")
@TableField("error_msg")
private String errorMsg;
@Schema(description = "操作时间")
@TableField("oper_time")
private Date operTime;
}

View File

@ -0,0 +1,32 @@
package com.atguigu.tingshu.model.system;
import com.atguigu.tingshu.model.base.BaseEntity;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Data
@Schema(description = "岗位")
@TableName("sys_post")
public class SysPost extends BaseEntity {
private static final long serialVersionUID = 1L;
@Schema(description = "岗位编码")
@TableField("post_code")
private String postCode;
@Schema(description = "岗位名称")
@TableField("name")
private String name;
@Schema(description = "显示顺序")
@TableField("description")
private String description;
@Schema(description = "状态1正常 0停用")
@TableField("status")
private Integer status;
}

View File

@ -0,0 +1,31 @@
package com.atguigu.tingshu.model.system;
import com.atguigu.tingshu.model.base.BaseEntity;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Data
@Schema(description = "角色")
@TableName("sys_role")
public class SysRole extends BaseEntity {
private static final long serialVersionUID = 1L;
//@NotBlank(message = "角色名称不能为空")
@Schema(description = "角色名称")
@TableField("role_name")
private String roleName;
@Schema(description = "角色编码")
@TableField("role_code")
private String roleCode;
@Schema(description = "描述")
@TableField("description")
private String description;
}

View File

@ -0,0 +1,25 @@
package com.atguigu.tingshu.model.system;
import com.atguigu.tingshu.model.base.BaseEntity;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Data
@Schema(description = "角色菜单")
@TableName("sys_role_menu")
public class SysRoleMenu extends BaseEntity {
private static final long serialVersionUID = 1L;
@Schema(description = "角色id")
@TableField("role_id")
private Long roleId;
@Schema(description = "菜单id")
@TableField("menu_id")
private Long menuId;
}

View File

@ -0,0 +1,66 @@
package com.atguigu.tingshu.model.system;
import com.atguigu.tingshu.model.base.BaseEntity;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.util.List;
@Data
@Schema(description = "用户")
@TableName("sys_user")
public class SysUser extends BaseEntity {
private static final long serialVersionUID = 1L;
@Schema(description = "用户名")
@TableField("username")
private String username;
@Schema(description = "密码")
@TableField("password")
private String password;
@Schema(description = "姓名")
@TableField("name")
private String name;
@Schema(description = "手机")
@TableField("phone")
private String phone;
@Schema(description = "头像地址")
@TableField("head_url")
private String headUrl;
@Schema(description = "部门id")
@TableField("dept_id")
private Long deptId;
@Schema(description = "岗位id")
@TableField("post_id")
private Long postId;
@Schema(description = "描述")
@TableField("description")
private String description;
@Schema(description = "状态1正常 0停用")
@TableField("status")
private Integer status;
@TableField(exist = false)
private List<SysRole> roleList;
//岗位
@TableField(exist = false)
private String postName;
//部门
@TableField(exist = false)
private String deptName;
@TableField(exist = false)
List<String> userPermsList;
}

View File

@ -0,0 +1,24 @@
package com.atguigu.tingshu.model.system;
import com.atguigu.tingshu.model.base.BaseEntity;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Data
@Schema(description = "用户角色")
@TableName("sys_user_role")
public class SysUserRole extends BaseEntity {
private static final long serialVersionUID = 1L;
@Schema(description = "角色id")
@TableField("role_id")
private Long roleId;
@Schema(description = "用户id")
@TableField("user_id")
private Long userId;
}

Some files were not shown because too many files have changed in this diff Show More