项目初始化搭建工作

wxpay
LI-CCONG\李聪聪 8 months ago
commit 90260bdc41

34
.gitignore vendored

@ -0,0 +1,34 @@
HELP.md
target/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**/target/
!**/src/test/**/target/
logs
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/
!**/src/main/**/build/
!**/src/test/**/build/
### VS Code ###
.vscode/

@ -0,0 +1,35 @@
<?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">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>cc.yunxi</groupId>
<artifactId>nxhs</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<description>宁夏回收平台小程序-基础包</description>
<artifactId>nxhs-common</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<!-- SpringMVC-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<scope>provided</scope>
</dependency>
<!-- Servlet -->
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-core</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
</project>

@ -0,0 +1,68 @@
package cc.yunxi.common.advice;
import cc.yunxi.common.exception.BadRequestException;
import cc.yunxi.common.exception.CommonException;
import cc.yunxi.common.exception.DbException;
import cc.yunxi.common.domain.CommonResult;
import cc.yunxi.common.utils.WebUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.util.NestedServletException;
import java.net.BindException;
import java.util.stream.Collectors;
@RestControllerAdvice
@Slf4j
public class CommonExceptionAdvice {
@ExceptionHandler(DbException.class)
public Object handleDbException(DbException e) {
log.error("mysql数据库操作异常 -> ", e);
return processResponse(e);
}
@ExceptionHandler(CommonException.class)
public Object handleBadRequestException(CommonException e) {
log.error("自定义异常 -> {} , 异常原因:{} ",e.getClass().getName(), e.getMessage());
log.debug("", e);
return processResponse(e);
}
@ExceptionHandler(MethodArgumentNotValidException.class)
public Object handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
String msg = e.getBindingResult().getAllErrors()
.stream().map(ObjectError::getDefaultMessage)
.collect(Collectors.joining("|"));
log.error("请求参数校验异常 -> {}", msg);
log.debug("", e);
return processResponse(new BadRequestException(msg));
}
@ExceptionHandler(BindException.class)
public Object handleBindException(BindException e) {
log.error("请求参数绑定异常 ->BindException {}", e.getMessage());
log.debug("", e);
return processResponse(new BadRequestException("请求参数格式错误"));
}
@ExceptionHandler(NestedServletException.class)
public Object handleNestedServletException(NestedServletException e) {
log.error("参数异常 -> NestedServletException{}", e.getMessage());
log.debug("", e);
return processResponse(new BadRequestException("请求参数处理异常"));
}
@ExceptionHandler(Exception.class)
public Object handleRuntimeException(Exception e) {
log.error("其他异常 uri : {} -> ", WebUtils.getRequest().getRequestURI(), e);
return processResponse(new CommonException("服务器内部异常", 500));
}
private ResponseEntity<CommonResult<Void>> processResponse(CommonException e){
return ResponseEntity.status(e.getCode()).body(CommonResult.error(e));
}
}

@ -0,0 +1,23 @@
package cc.yunxi.common.config;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.math.BigInteger;
@Configuration
@ConditionalOnClass(ObjectMapper.class)
public class JsonConfig {
@Bean
public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer() {
return jacksonObjectMapperBuilder -> {
// long -> string
jacksonObjectMapperBuilder.serializerByType(Long.class, ToStringSerializer.instance);
jacksonObjectMapperBuilder.serializerByType(BigInteger.class, ToStringSerializer.instance);
};
}
}

@ -0,0 +1,25 @@
package cc.yunxi.common.config;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
@ConditionalOnClass({MybatisPlusInterceptor.class, BaseMapper.class})
public class MyBatisConfig {
@Bean
@ConditionalOnMissingBean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
// 1.分页拦截器
PaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor(DbType.MYSQL);
paginationInnerInterceptor.setMaxLimit(1000L);
interceptor.addInnerInterceptor(paginationInnerInterceptor);
return interceptor;
}
}

@ -0,0 +1,80 @@
package cc.yunxi.common.domain;
import cc.yunxi.common.exception.CommonException;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Data;
import java.io.Serializable;
import java.util.Objects;
@Data
public class CommonResult<T> implements Serializable {
private static final long serialVersionUID = 215649522478030245L;
private Integer code;
private T data;
private String msg;
/**
* result
*/
public static <T> CommonResult<T> error(CommonResult<?> result) {
return error(result.getCode(), result.getMsg());
}
public static <T> CommonResult<T> error(Integer code, String message) {
CommonResult<T> result = new CommonResult<>();
result.code = code;
result.msg = message;
return result;
}
public static <T> CommonResult<T> success(T data) {
CommonResult<T> result = new CommonResult<>();
result.code = 200;
result.data = data;
result.msg = "";
return result;
}
public static boolean isSuccess(Integer code) {
return Objects.equals(code, 200);
}
@JsonIgnore // 避免 jackson 序列化
public boolean isSuccess() {
return isSuccess(code);
}
@JsonIgnore // 避免 jackson 序列化
public boolean isError() {
return !isSuccess();
}
// ========= 和 Exception 异常体系集成 =========
/**
* {@link CommonException}
*/
public void checkError() throws CommonException {
if (isSuccess()) {
return;
}
// 业务异常
throw new CommonException(code, msg);
}
/**
* {@link CommonException}
* {@link #data}
*/
@JsonIgnore // 避免 jackson 序列化
public T getCheckedData() {
checkError();
return data;
}
public static <T> CommonResult<T> error(CommonException commonException) {
return error(commonException.getCode(), commonException.getMessage());
}
}

@ -0,0 +1,62 @@
package cc.yunxi.common.domain;
import cc.yunxi.common.utils.BeanUtils;
import cc.yunxi.common.utils.CollUtils;
import cc.yunxi.common.utils.Convert;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class PageDTO<T> {
protected Long total;
protected Long pages;
protected List<T> list;
public static <T> PageDTO<T> empty(Long total, Long pages) {
return new PageDTO<>(total, pages, CollUtils.emptyList());
}
public static <T> PageDTO<T> empty(Page<?> page) {
return new PageDTO<>(page.getTotal(), page.getPages(), CollUtils.emptyList());
}
public static <T> PageDTO<T> of(Page<T> page) {
if(page == null){
return new PageDTO<>();
}
if (CollUtils.isEmpty(page.getRecords())) {
return empty(page);
}
return new PageDTO<>(page.getTotal(), page.getPages(), page.getRecords());
}
public static <T,R> PageDTO<T> of(Page<R> page, Function<R, T> mapper) {
if(page == null){
return new PageDTO<>();
}
if (CollUtils.isEmpty(page.getRecords())) {
return empty(page);
}
return new PageDTO<>(page.getTotal(), page.getPages(),
page.getRecords().stream().map(mapper).collect(Collectors.toList()));
}
public static <T> PageDTO<T> of(Page<?> page, List<T> list) {
return new PageDTO<>(page.getTotal(), page.getPages(), list);
}
public static <T, R> PageDTO<T> of(Page<R> page, Class<T> clazz) {
return new PageDTO<>(page.getTotal(), page.getPages(), BeanUtils.copyList(page.getRecords(), clazz));
}
public static <T, R> PageDTO<T> of(Page<R> page, Class<T> clazz, Convert<R, T> convert) {
return new PageDTO<>(page.getTotal(), page.getPages(), BeanUtils.copyList(page.getRecords(), clazz, convert));
}
}

@ -0,0 +1,70 @@
package cc.yunxi.common.domain;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.experimental.Accessors;
import javax.validation.constraints.Min;
@Data
@ApiModel(description = "分页查询条件")
@Accessors(chain = true)
public class PageQuery {
public static final Integer DEFAULT_PAGE_SIZE = 20;
public static final Integer DEFAULT_PAGE_NUM = 1;
@ApiModelProperty("页码")
@Min(value = 1, message = "页码不能小于1")
private Integer pageNo = DEFAULT_PAGE_NUM;
@ApiModelProperty("页码")
@Min(value = 1, message = "每页查询数量不能小于1")
private Integer pageSize = DEFAULT_PAGE_SIZE;
@ApiModelProperty("是否升序")
private Boolean isAsc = true;
@ApiModelProperty("排序方式")
private String sortBy;
public int from(){
return (pageNo - 1) * pageSize;
}
public <T> Page<T> toMpPage(OrderItem... orderItems) {
Page<T> page = new Page<>(pageNo, pageSize);
// 是否手动指定排序方式
if (orderItems != null && orderItems.length > 0) {
for (OrderItem orderItem : orderItems) {
page.addOrder(orderItem);
}
return page;
}
// 前端是否有排序字段
if (StrUtil.isNotEmpty(sortBy)){
OrderItem orderItem = new OrderItem();
orderItem.setAsc(isAsc);
orderItem.setColumn(sortBy);
page.addOrder(orderItem);
}
return page;
}
public <T> Page<T> toMpPage(String defaultSortBy, boolean isAsc) {
if (StringUtils.isBlank(sortBy)){
sortBy = defaultSortBy;
this.isAsc = isAsc;
}
Page<T> page = new Page<>(pageNo, pageSize);
OrderItem orderItem = new OrderItem();
orderItem.setAsc(this.isAsc);
orderItem.setColumn(sortBy);
page.addOrder(orderItem);
return page;
}
public <T> Page<T> toMpPageDefaultSortByCreateTimeDesc() {
return toMpPage("create_time", false);
}
}

@ -0,0 +1,16 @@
package cc.yunxi.common.exception;
public class BadRequestException extends CommonException{
public BadRequestException(String message) {
super(message, 400);
}
public BadRequestException(String message, Throwable cause) {
super(message, cause, 400);
}
public BadRequestException(Throwable cause) {
super(cause, 400);
}
}

@ -0,0 +1,16 @@
package cc.yunxi.common.exception;
public class BizIllegalException extends CommonException{
public BizIllegalException(String message) {
super(message, 500);
}
public BizIllegalException(String message, Throwable cause) {
super(message, cause, 500);
}
public BizIllegalException(Throwable cause) {
super(cause, 500);
}
}

@ -0,0 +1,27 @@
package cc.yunxi.common.exception;
import lombok.Getter;
@Getter
public class CommonException extends RuntimeException{
private int code;
public CommonException(String message, int code) {
super(message);
this.code = code;
}
public CommonException(int code, String message) {
super(message);
this.code = code;
}
public CommonException(String message, Throwable cause, int code) {
super(message, cause);
this.code = code;
}
public CommonException(Throwable cause, int code) {
super(cause);
this.code = code;
}
}

@ -0,0 +1,16 @@
package cc.yunxi.common.exception;
public class DbException extends CommonException{
public DbException(String message) {
super(message, 500);
}
public DbException(String message, Throwable cause) {
super(message, cause, 500);
}
public DbException(Throwable cause) {
super(cause, 500);
}
}

@ -0,0 +1,16 @@
package cc.yunxi.common.exception;
public class ForbiddenException extends CommonException{
public ForbiddenException(String message) {
super(message, 403);
}
public ForbiddenException(String message, Throwable cause) {
super(message, cause, 403);
}
public ForbiddenException(Throwable cause) {
super(cause, 403);
}
}

@ -0,0 +1,16 @@
package cc.yunxi.common.exception;
public class UnauthorizedException extends CommonException{
public UnauthorizedException(String message) {
super(message, 401);
}
public UnauthorizedException(String message, Throwable cause) {
super(message, cause, 401);
}
public UnauthorizedException(Throwable cause) {
super(cause, 401);
}
}

@ -0,0 +1,59 @@
package cc.yunxi.common.utils;
import cn.hutool.core.bean.BeanUtil;
import java.util.List;
import java.util.stream.Collectors;
/**
* hutool BeanUtilbean
*/
public class BeanUtils extends BeanUtil {
/**
* 使
*
* @param source
* @param clazz class
* @param convert
* @param <R>
* @param <T>
* @return
*/
public static <R, T> T copyBean(R source, Class<T> clazz, Convert<R, T> convert) {
T target = copyBean(source, clazz);
if (convert != null) {
convert.convert(source, target);
}
return target;
}
/**
* 使
*
* @param source
* @param clazz class
* @param <R>
* @param <T>
* @return
*/
public static <R, T> T copyBean(R source, Class<T> clazz){
if (source == null) {
return null;
}
return toBean(source, clazz);
}
public static <R, T> List<T> copyList(List<R> list, Class<T> clazz) {
if (list == null || list.size() == 0) {
return CollUtils.emptyList();
}
return copyToList(list, clazz);
}
public static <R, T> List<T> copyList(List<R> list, Class<T> clazz, Convert<R, T> convert) {
if (list == null || list.size() == 0) {
return CollUtils.emptyList();
}
return list.stream().map(r -> copyBean(r, clazz, convert)).collect(Collectors.toList());
}
}

@ -0,0 +1,72 @@
package cc.yunxi.common.utils;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.collection.IterUtil;
import cn.hutool.core.util.NumberUtil;
import java.util.*;
import java.util.stream.Collectors;
/**
* hutool
*/
public class CollUtils extends CollectionUtil {
public static <T> List<T> emptyList() {
return Collections.emptyList();
}
public static <T> Set<T> emptySet() {
return Collections.emptySet();
}
public static <K,V> Map<K, V> emptyMap() {
return Collections.emptyMap();
}
public static <T> Set<T> singletonSet(T t) {
return Collections.singleton(t);
}
public static <T> List<T> singletonList(T t) {
return Collections.singletonList(t);
}
public static List<Integer> convertToInteger(List<String> originList){
return CollUtils.isNotEmpty(originList) ? originList.stream().map(NumberUtil::parseInt).collect(Collectors.toList()) : null;
}
public static List<Long> convertToLong(List<String> originLIst){
return CollUtils.isNotEmpty(originLIst) ? originLIst.stream().map(NumberUtil::parseLong).collect(Collectors.toList()) : null;
}
/**
* conjunction IterableIterator
* @param collection
* @param conjunction
* @param <T>
* @return
* See Also: IterUtil.join(Iterator, CharSequence)
*/
public static <T> String join(Collection<T> collection, CharSequence conjunction) {
if (null == collection || collection.isEmpty()) {
return null;
}
return IterUtil.join(collection.iterator(), conjunction);
}
public static <T> String joinIgnoreNull(Collection<T> collection, CharSequence conjunction) {
if (null == collection || collection.isEmpty()) {
return null;
}
StringBuilder sb = new StringBuilder();
for (T t : collection) {
if(t == null) continue;
sb.append(t).append(",");
}
if(sb.length() <= 0){
return null;
}
return sb.deleteCharAt(sb.length() - 1).toString();
}
}

@ -0,0 +1,8 @@
package cc.yunxi.common.utils;
/**
*
**/
public interface Convert<R,T>{
void convert(R origin, T target);
}

@ -0,0 +1,28 @@
package cc.yunxi.common.utils;
public class UserContext {
private static final ThreadLocal<Long> tl = new ThreadLocal<>();
/**
* ThreadLocal
* @param userId id
*/
public static void setUser(Long userId) {
tl.set(userId);
}
/**
*
* @return id
*/
public static Long getUser() {
return tl.get();
}
/**
*
*/
public static void removeUser(){
tl.remove();
}
}

@ -0,0 +1,151 @@
package cc.yunxi.common.utils;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Collection;
import java.util.Map;
@Slf4j
public class WebUtils {
/**
* ServletRequestAttributes
*
* @return ServletRequestAttributes
*/
public static ServletRequestAttributes getServletRequestAttributes() {
RequestAttributes ra = RequestContextHolder.getRequestAttributes();
if (ra == null) {
return null;
}
return (ServletRequestAttributes) ra;
}
/**
* request
*
* @return HttpServletRequest
*/
public static HttpServletRequest getRequest() {
ServletRequestAttributes servletRequestAttributes = getServletRequestAttributes();
return servletRequestAttributes == null ? null : servletRequestAttributes.getRequest();
}
/**
* response
*
* @return HttpServletResponse
*/
public static HttpServletResponse getResponse() {
ServletRequestAttributes servletRequestAttributes = getServletRequestAttributes();
return servletRequestAttributes == null ? null : servletRequestAttributes.getResponse();
}
/**
* request header
*
* @param headerName
* @return
*/
public static String getHeader(String headerName) {
HttpServletRequest request = getRequest();
if (request == null) {
return null;
}
return getRequest().getHeader(headerName);
}
public static void setResponseHeader(String key, String value){
HttpServletResponse response = getResponse();
if (response == null) {
return;
}
response.setHeader(key, value);
}
public static boolean isSuccess() {
HttpServletResponse response = getResponse();
return response != null && response.getStatus() < 300;
}
/**
* key1=value1&key2=value2
* key使 key1value1key2value2value3 key1=value1&key2=value2,value3
*
* @param request
* @return
*/
public static String getParameters(HttpServletRequest request) {
Map<String, String[]> parameterMap = request.getParameterMap();
return getParameters(parameterMap);
}
/**
* key1=value1&key2=value2
* key使 key1value1key2value2value3 key1=value1&key2=value2,value3
*
* @param queries
* @return
*/
public static <T> String getParameters(final Map<String, T> queries) {
StringBuilder buffer = new StringBuilder();
for (Map.Entry<String, T> entry : queries.entrySet()) {
if(entry.getValue() instanceof String[]){
buffer.append(entry.getKey()).append(String.join(",", ((String[])entry.getValue())))
.append("&");
}else if(entry.getValue() instanceof Collection){
buffer.append(entry.getKey()).append(
CollUtil.join(((Collection<String>)entry.getValue()),",")
).append("&");
}
}
return buffer.length() > 0 ? buffer.substring(0, buffer.length() - 1) : StrUtil.EMPTY;
}
/**
* urluri
*
* @param url
* @return
*/
public static String getUri(String url){
if(StringUtils.isEmpty(url)) {
return null;
}
String uri = url;
//uri中去掉 http:// 或者https
if(uri.contains("http://") ){
uri = uri.replace("http://", StrUtil.EMPTY);
}else if(uri.contains("https://")){
uri = uri.replace("https://", StrUtil.EMPTY);
}
int endIndex = uri.length(); //uri 在url中的最后一个字符的序号+1
if(uri.contains("?")){
endIndex = uri.indexOf("?");
}
return uri.substring(uri.indexOf("/"), endIndex);
}
public static String getRemoteAddr() {
HttpServletRequest request = getRequest();
if (request == null) {
return "";
}
return request.getRemoteAddr();
}
// public static CookieBuilder cookieBuilder(){
// return new CookieBuilder(getRequest(), getResponse());
// }
}

@ -0,0 +1,3 @@
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
cc.yunxi.common.config.MyBatisConfig,\
cc.yunxi.common.config.JsonConfig

@ -0,0 +1,34 @@
<?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">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>cc.yunxi</groupId>
<artifactId>nxhs</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>nxhs-service</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<!--common-->
<dependency>
<groupId>cc.yunxi</groupId>
<artifactId>nxhs-common</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<!--web-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
</project>

@ -0,0 +1,13 @@
package cc.yunxi;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@MapperScan("cc.yunxi.mapper")
@SpringBootApplication
public class NxhsApplication {
public static void main(String[] args) {
SpringApplication.run(NxhsApplication.class, args);
}
}

@ -0,0 +1,30 @@
package cc.yunxi.controller;
import cc.yunxi.common.domain.CommonResult;
import cc.yunxi.common.exception.BadRequestException;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@Api(tags = "测试接口")
@RestController
@RequestMapping("/test")
@RequiredArgsConstructor
public class TestController {
@ApiOperation("测试接口成功")
@GetMapping("/test01")
public CommonResult<String> success() {
return CommonResult.success("ok");
}
@ApiOperation("测试接口失败")
@GetMapping("/test02")
public CommonResult<String> failed() {
throw new BadRequestException("error");
}
}

@ -0,0 +1,35 @@
package cc.yunxi.domain.po;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.io.Serializable;
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("test")
public class Test implements Serializable {
private static final long serialVersionUID = 1L;
/**
* id
*/
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
/**
* id
*/
private String name;
/**
* skuid
*/
private Integer age;
}

@ -0,0 +1,10 @@
package cc.yunxi.mapper;
import cc.yunxi.domain.po.Test;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* mapper
*/
public interface TestMapper extends BaseMapper<Test> {
}

@ -0,0 +1,10 @@
package cc.yunxi.service;
import cc.yunxi.domain.po.Test;
import com.baomidou.mybatisplus.extension.service.IService;
/**
*
*/
public interface ITestService extends IService<Test> {
}

@ -0,0 +1,14 @@
package cc.yunxi.service.impl;
import cc.yunxi.domain.po.Test;
import cc.yunxi.mapper.TestMapper;
import cc.yunxi.service.ITestService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
/**
*
*/
@Service
public class TestServiceImpl extends ServiceImpl<TestMapper, Test> implements ITestService {
}

@ -0,0 +1,14 @@
server:
port: 8808
spring:
datasource:
url: jdbc:mysql://222.71.165.188:3309/jnpf_ningxia?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghai
driver-class-name: com.mysql.cj.jdbc.Driver
username: root
password: linus,.123
redis:
database: 1
host: 222.71.165.188
port: 6379
password: qweasd,.123 # 密码为空时,请将本行注释

@ -0,0 +1,71 @@
server:
port: 8080
spring:
application:
name: nxhs-service
profiles:
active: dev
datasource:
url: jdbc:mysql://127.0.0.1:3306/nxhs?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghai
driver-class-name: com.mysql.cj.jdbc.Driver
username: root
password: 123456
redis:
database: 1 #缓存库编号
host: 127.0.0.1
port: 6379
password: 123456 # 密码为空时,请将本行注释
timeout: 3000 #超时时间(单位:秒)
lettuce: #Lettuce为Redis的Java驱动包
pool:
max-active: 8 # 连接池最大连接数
max-wait: -1ms # 连接池最大阻塞等待时间(使用负值表示没有限制)
min-idle: 0 # 连接池中的最小空闲连接
max-idle: 8 # 连接池中的最大空闲连接
mybatis-plus:
configuration:
default-enum-type-handler: com.baomidou.mybatisplus.core.handlers.MybatisEnumTypeHandler
global-config:
db-config:
update-strategy: not_null
id-type: auto
type-aliases-package: cc.yunxi.domain.po # 指定实体对象扫描包, 简化xml中resultType路径
logging:
level:
cc.yunxi: debug
pattern:
dateformat: yyyy-MM-dd HH:mm:ss:SSS
file:
path: "logs/${spring.application.name}"
knife4j:
enable: true
openapi:
title: 宁夏回收平台
description: "宁夏回收平台接口文档"
email: ccongli@yunxi.cc
concat: 虎哥
url: https://www.cjyx.cc
version: v1.0.0
group:
default:
group-name: default
api-rule: package
api-rule-resources:
- cc.yunxi.controller
#hm:
# jwt:
# location: classpath:hmall.jks
# alias: hmall
# password: hmall123
# tokenTTL: 30m
# auth:
# excludePaths:
# - /search/**
# - /users/login
# - /items/**
# - /hi
# keytool -genkeypair -alias hmall -keyalg RSA -keypass hmall123 -keystore hmall.jks -storepass hmall123

@ -0,0 +1,219 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- 日志级别从低到高分为TRACE < DEBUG < INFO < WARN < ERROR < FATAL如果设置为WARN则低于WARN的信息都不会输出 -->
<!-- scan:当此属性设置为true时配置文件如果发生改变将会被重新加载默认值为true -->
<!-- scanPeriod:设置监测配置文件是否有修改的时间间隔如果没有给出时间单位默认单位是毫秒。当scan为true时此属性生效。默认的时间间隔为1分钟。 -->
<!-- debug:当此属性设置为true时将打印出logback内部日志信息实时查看logback运行状态。默认值为false。 -->
<configuration scan="true" scanPeriod="10 seconds">
<contextName>logback</contextName>
<!-- name的值是变量的名称value的值时变量定义的值。通过定义的值会被插入到logger上下文中。定义变量后可以使“${}”来使用变量-->
<!-- <property name="CONSOLE_LOG_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg %n"/>-->
<springProperty scope="context" name="log.path" source="logging.file.path"/>
<property name="CONSOLE_LOG_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} %highlight(%-5level) --- [%15.15(%thread)] %cyan(%-40.40(%logger{40})) : %msg%n"/>
<!--输出到控制台-->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<!--此日志appender是为开发使用只配置最底级别控制台输出的日志级别是大于或等于此级别的日志信息-->
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>debug</level>
</filter>
<encoder>
<Pattern>${CONSOLE_LOG_PATTERN}</Pattern>
<!-- 设置字符集 -->
<charset>UTF-8</charset>
</encoder>
</appender>
<!--输出到文件-->
<!-- 时间滚动输出 level为 DEBUG 日志 -->
<appender name="DEBUG_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 正在记录的日志文件的路径及文件名 -->
<!--先将今天的日志保存在这个文件中-->
<file>${log.path}/log_debug.log</file>
<!--日志文件输出格式 %-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n
%d{HH: mm:ss.SSS}——日志输出时间
%thread——输出日志的进程名字这在Web应用以及异步任务处理中很有用
%-5level——日志级别并且使用5个字符靠左对齐
%logger{36}——日志输出者的名字
%msg——日志消息
%n——平台的换行符
-->
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
<charset>UTF-8</charset> <!-- 设置字符集 -->
</encoder>
<!-- 日志记录器的滚动策略,按日期,按大小记录 -->
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!-- rollover daily -->
<!--如果第二天输出日志,会将当天的日志记录在<file>${log.path}/log_debug.log</file>,然后将昨天的日志归档到下面的文件中-->
<!--以分钟切分 %d{yyyy-MM-dd_HH-mm}-->
<fileNamePattern>${log.path}/debug/log-debug-%d{yyyy-MM-dd_HH-mm}.%i.log</fileNamePattern>
<!-- each file should be at most 100MB, keep 60 days worth of history, but at most 20GB -->
<!--单个日志文件最大100M到了这个值就会再创建一个日志文件日志文件的名字最后+1-->
<maxFileSize>100MB</maxFileSize>
<!--日志文件保留天数-->
<maxHistory>30</maxHistory>
<!--所有的日志文件最大20G超过就会删除旧的日志-->
<totalSizeCap>20GB</totalSizeCap>
</rollingPolicy>
<!--
此日志文件只记录debug级别的
onMatch和onMismatch都有三个属性值分别为Accept、DENY和NEUTRAL
onMatch="ACCEPT" 表示匹配该级别及以上
onMatch="DENY" 表示不匹配该级别及以上
onMatch="NEUTRAL" 表示该级别及以上的由下一个filter处理如果当前是最后一个则表示匹配该级别及以上
onMismatch="ACCEPT" 表示匹配该级别以下
onMismatch="NEUTRAL" 表示该级别及以下的由下一个filter处理如果当前是最后一个则不匹配该级别以下的
onMismatch="DENY" 表示不匹配该级别以下的
-->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>debug</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- 时间滚动输出 level为 INFO 日志 -->
<appender name="INFO_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 正在记录的日志文件的路径及文件名 -->
<file>${log.path}/log_info.log</file>
<!--日志文件输出格式-->
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
<charset>UTF-8</charset>
</encoder>
<!-- 日志记录器的滚动策略,按日期,按大小记录 -->
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!-- rollover daily -->
<!--如果第二天输出日志,会将当天的日志记录在<file>${log.path}/log_debug.log</file>,然后将昨天的日志归档到下面的文件中-->
<!--以分钟切分 %d{yyyy-MM-dd_HH-mm}-->
<fileNamePattern>${log.path}/info/log-info-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<!-- each file should be at most 100MB, keep 60 days worth of history, but at most 20GB -->
<!--单个日志文件最大100M到了这个值就会再创建一个日志文件日志文件的名字最后+1-->
<maxFileSize>100MB</maxFileSize>
<!--日志文件保留天数-->
<maxHistory>30</maxHistory>
<!--所有的日志文件最大20G超过就会删除旧的日志-->
<totalSizeCap>20GB</totalSizeCap>
</rollingPolicy>
<!--SizeAndTimeBasedRollingPolicy配置更灵活,所以改用SizeAndTimeBasedRollingPolicy-->
<!--<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
&lt;!&ndash; 每天日志归档路径以及格式 &ndash;&gt;
<fileNamePattern>${log.path}/info/log-info-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>100MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
&lt;!&ndash;日志文件保留天数&ndash;&gt;
<maxHistory>15</maxHistory>
</rollingPolicy>-->
<!-- 此日志文件只记录info级别的 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>info</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- 时间滚动输出 level为 WARN 日志 -->
<appender name="WARN_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 正在记录的日志文件的路径及文件名 -->
<file>${log.path}/log_warn.log</file>
<!--日志文件输出格式-->
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
<charset>UTF-8</charset> <!-- 此处设置字符集 -->
</encoder>
<!-- 日志记录器的滚动策略,按日期,按大小记录 -->
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!-- rollover daily -->
<!--如果第二天输出日志,会将当天的日志记录在<file>${log.path}/log_debug.log</file>,然后将昨天的日志归档到下面的文件中-->
<!--以分钟切分 %d{yyyy-MM-dd_HH-mm}-->
<fileNamePattern>${log.path}/warn/log-warn-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<!-- each file should be at most 100MB, keep 60 days worth of history, but at most 20GB -->
<!--单个日志文件最大100M到了这个值就会再创建一个日志文件日志文件的名字最后+1-->
<maxFileSize>100MB</maxFileSize>
<!--日志文件保留天数-->
<maxHistory>30</maxHistory>
<!--所有的日志文件最大20G超过就会删除旧的日志-->
<totalSizeCap>20GB</totalSizeCap>
</rollingPolicy>
<!-- 此日志文件只记录warn级别的 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>warn</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- 时间滚动输出 level为 ERROR 日志 -->
<appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 正在记录的日志文件的路径及文件名 -->
<file>${log.path}/log_error.log</file>
<!--日志文件输出格式-->
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
<charset>UTF-8</charset> <!-- 此处设置字符集 -->
</encoder>
<!-- 日志记录器的滚动策略,按日期,按大小记录 -->
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!-- rollover daily -->
<!--如果第二天输出日志,会将当天的日志记录在<file>${log.path}/log_debug.log</file>,然后将昨天的日志归档到下面的文件中-->
<!--以分钟切分 %d{yyyy-MM-dd_HH-mm}-->
<fileNamePattern>${log.path}/error/log-error-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<!-- each file should be at most 100MB, keep 60 days worth of history, but at most 20GB -->
<!--单个日志文件最大100M到了这个值就会再创建一个日志文件日志文件的名字最后+1-->
<maxFileSize>100MB</maxFileSize>
<!--日志文件保留天数-->
<maxHistory>30</maxHistory>
<!--所有的日志文件最大20G超过就会删除旧的日志-->
<totalSizeCap>20GB</totalSizeCap>
</rollingPolicy>
<!-- 此日志文件只记录ERROR级别的 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>ERROR</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!--root配置必须在appender下边-->
<!--root节点是对所有appender的管理,添加哪个appender就会打印哪个appender的日志-->
<!--root节点的level是总的日志级别控制,如果appender的日志级别设定比root的高,会按照appender的日志级别打印日志,-->
<!--如果appender的日志级别比root的低,会按照root设定的日志级别进行打印日志-->
<!--也就是说root设定的日志级别是最低限制,如果root设定级别为最高ERROR,那么所有appender只能打印最高级别的日志-->
<!-- <root level="INFO">-->
<!-- <appender-ref ref="STDOUT" />-->
<!-- <appender-ref ref="DEBUG_FILE" />-->
<!-- <appender-ref ref="INFO_FILE" />-->
<!-- <appender-ref ref="WARN_FILE" />-->
<!-- <appender-ref ref="ERROR_FILE" />-->
<!-- </root>-->
<!--name:用来指定受此loger约束的某一个包或者具体的某一个类。-->
<!--addtivity:是否向上级loger传递打印信息。默认是true。-->
<!-- <logger name="com.pikaiqu.logbackdemo.LogbackdemoApplicationTests" level="debug" additivity="false">-->
<!-- <appender-ref ref="STDOUT" />-->
<!-- <appender-ref ref="INFO_FILE" />-->
<!-- </logger>-->
<!--配置多环境日志输出 可以在application.properties中配置选择哪个profiles : spring.profiles.active=dev-->
<!--生产环境:输出到文件-->
<springProfile name="pro">
<root level="info">
<appender-ref ref="DEBUG_FILE" />
<appender-ref ref="INFO_FILE" />
<appender-ref ref="ERROR_FILE" />
<appender-ref ref="WARN_FILE" />
</root>
</springProfile>
<!--开发环境:打印控制台-->
<springProfile name="dev">
<root level="info">
<appender-ref ref="STDOUT" />
<appender-ref ref="DEBUG_FILE" />
</root>
</springProfile>
</configuration>

@ -0,0 +1,21 @@
package cc.yunxi;
import cc.yunxi.service.ITestService;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import javax.annotation.Resource;
import java.util.List;
@SpringBootTest
public class NxhsApplicationTest {
@Resource
ITestService testService;
@Test
void test01() {
List<cc.yunxi.domain.po.Test> list = testService.list();
System.out.println(list);
}
}

@ -0,0 +1,137 @@
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>cc.yunxi</groupId>
<artifactId>nxhs</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<name>nxhs</name>
<description>宁夏回收平台小程序</description>
<!-- 子模块 -->
<modules>
<module>nxhs-common</module>
<module>nxhs-service</module>
</modules>
<properties>
<java.version>1.8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<spring-boot.version>2.7.6</spring-boot.version>
<mybatis-plus.version>3.4.3</mybatis-plus.version>
<hutool.version>5.8.11</hutool.version>
</properties>
<!-- 版本统一管理 -->
<dependencyManagement>
<dependencies>
<!-- SpringBoot 标准依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!-- 数据库相关依赖 -->
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>${mybatis-plus.version}</version>
</dependency>
<!--redis-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!--json处理-->
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
</dependency>
<!-- 常用扩展 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>${hutool.version}</version>
</dependency>
<!-- validator -->
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
</dependency>
<!-- swagger -->
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-openapi2-spring-boot-starter</artifactId>
<version>4.1.0</version>
</dependency>
<!-- 测试 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring-boot.version}</version>
<configuration>
<mainClass>cc.yunxi.nxhsapp.NxhsAppApplication</mainClass>
<skip>true</skip>
</configuration>
<executions>
<execution>
<id>repackage</id>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>alimaven</id>
<name>aliyun maven</name>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
</repository>
</repositories>
</project>
Loading…
Cancel
Save