commit 90260bdc41c906acb3d8fb32f9c95b9e5868400e
Author: LI-CCONG\李聪聪 <1441652193@qq.com>
Date: Wed Feb 28 09:09:25 2024 +0800
项目初始化搭建工作
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..5eda243
--- /dev/null
+++ b/.gitignore
@@ -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/
diff --git a/nxhs-common/pom.xml b/nxhs-common/pom.xml
new file mode 100644
index 0000000..c177837
--- /dev/null
+++ b/nxhs-common/pom.xml
@@ -0,0 +1,35 @@
+
+
+ 4.0.0
+
+ cc.yunxi
+ nxhs
+ 0.0.1-SNAPSHOT
+
+ 宁夏回收平台小程序-基础包
+ nxhs-common
+
+
+ 8
+ 8
+ UTF-8
+
+
+
+
+
+ org.springframework
+ spring-webmvc
+ provided
+
+
+
+ org.apache.tomcat.embed
+ tomcat-embed-core
+ provided
+
+
+
+
\ No newline at end of file
diff --git a/nxhs-common/src/main/java/cc/yunxi/common/advice/CommonExceptionAdvice.java b/nxhs-common/src/main/java/cc/yunxi/common/advice/CommonExceptionAdvice.java
new file mode 100644
index 0000000..d2a4eab
--- /dev/null
+++ b/nxhs-common/src/main/java/cc/yunxi/common/advice/CommonExceptionAdvice.java
@@ -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> processResponse(CommonException e){
+ return ResponseEntity.status(e.getCode()).body(CommonResult.error(e));
+ }
+}
diff --git a/nxhs-common/src/main/java/cc/yunxi/common/config/JsonConfig.java b/nxhs-common/src/main/java/cc/yunxi/common/config/JsonConfig.java
new file mode 100644
index 0000000..758aa26
--- /dev/null
+++ b/nxhs-common/src/main/java/cc/yunxi/common/config/JsonConfig.java
@@ -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);
+ };
+ }
+}
\ No newline at end of file
diff --git a/nxhs-common/src/main/java/cc/yunxi/common/config/MyBatisConfig.java b/nxhs-common/src/main/java/cc/yunxi/common/config/MyBatisConfig.java
new file mode 100644
index 0000000..5efd7fc
--- /dev/null
+++ b/nxhs-common/src/main/java/cc/yunxi/common/config/MyBatisConfig.java
@@ -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;
+ }
+}
\ No newline at end of file
diff --git a/nxhs-common/src/main/java/cc/yunxi/common/domain/CommonResult.java b/nxhs-common/src/main/java/cc/yunxi/common/domain/CommonResult.java
new file mode 100644
index 0000000..dd02972
--- /dev/null
+++ b/nxhs-common/src/main/java/cc/yunxi/common/domain/CommonResult.java
@@ -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 implements Serializable {
+
+ private static final long serialVersionUID = 215649522478030245L;
+ private Integer code;
+ private T data;
+ private String msg;
+
+ /**
+ * 将传入的 result 对象,转换成另外一个泛型结果的对象
+ */
+ public static CommonResult error(CommonResult> result) {
+ return error(result.getCode(), result.getMsg());
+ }
+
+ public static CommonResult error(Integer code, String message) {
+ CommonResult result = new CommonResult<>();
+ result.code = code;
+ result.msg = message;
+ return result;
+ }
+
+ public static CommonResult success(T data) {
+ CommonResult 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 CommonResult error(CommonException commonException) {
+ return error(commonException.getCode(), commonException.getMessage());
+ }
+}
diff --git a/nxhs-common/src/main/java/cc/yunxi/common/domain/PageDTO.java b/nxhs-common/src/main/java/cc/yunxi/common/domain/PageDTO.java
new file mode 100644
index 0000000..b601d97
--- /dev/null
+++ b/nxhs-common/src/main/java/cc/yunxi/common/domain/PageDTO.java
@@ -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 {
+ protected Long total;
+ protected Long pages;
+ protected List list;
+
+ public static PageDTO empty(Long total, Long pages) {
+ return new PageDTO<>(total, pages, CollUtils.emptyList());
+ }
+ public static PageDTO empty(Page> page) {
+ return new PageDTO<>(page.getTotal(), page.getPages(), CollUtils.emptyList());
+ }
+
+ public static PageDTO of(Page 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 PageDTO of(Page page, Function 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 PageDTO of(Page> page, List list) {
+ return new PageDTO<>(page.getTotal(), page.getPages(), list);
+ }
+
+ public static PageDTO of(Page page, Class clazz) {
+ return new PageDTO<>(page.getTotal(), page.getPages(), BeanUtils.copyList(page.getRecords(), clazz));
+ }
+
+ public static PageDTO of(Page page, Class clazz, Convert convert) {
+ return new PageDTO<>(page.getTotal(), page.getPages(), BeanUtils.copyList(page.getRecords(), clazz, convert));
+ }
+}
diff --git a/nxhs-common/src/main/java/cc/yunxi/common/domain/PageQuery.java b/nxhs-common/src/main/java/cc/yunxi/common/domain/PageQuery.java
new file mode 100644
index 0000000..4786586
--- /dev/null
+++ b/nxhs-common/src/main/java/cc/yunxi/common/domain/PageQuery.java
@@ -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 Page toMpPage(OrderItem... orderItems) {
+ Page 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 Page toMpPage(String defaultSortBy, boolean isAsc) {
+ if (StringUtils.isBlank(sortBy)){
+ sortBy = defaultSortBy;
+ this.isAsc = isAsc;
+ }
+ Page page = new Page<>(pageNo, pageSize);
+ OrderItem orderItem = new OrderItem();
+ orderItem.setAsc(this.isAsc);
+ orderItem.setColumn(sortBy);
+ page.addOrder(orderItem);
+ return page;
+ }
+ public Page toMpPageDefaultSortByCreateTimeDesc() {
+ return toMpPage("create_time", false);
+ }
+}
diff --git a/nxhs-common/src/main/java/cc/yunxi/common/exception/BadRequestException.java b/nxhs-common/src/main/java/cc/yunxi/common/exception/BadRequestException.java
new file mode 100644
index 0000000..f38c1f0
--- /dev/null
+++ b/nxhs-common/src/main/java/cc/yunxi/common/exception/BadRequestException.java
@@ -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);
+ }
+}
diff --git a/nxhs-common/src/main/java/cc/yunxi/common/exception/BizIllegalException.java b/nxhs-common/src/main/java/cc/yunxi/common/exception/BizIllegalException.java
new file mode 100644
index 0000000..5f12286
--- /dev/null
+++ b/nxhs-common/src/main/java/cc/yunxi/common/exception/BizIllegalException.java
@@ -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);
+ }
+}
diff --git a/nxhs-common/src/main/java/cc/yunxi/common/exception/CommonException.java b/nxhs-common/src/main/java/cc/yunxi/common/exception/CommonException.java
new file mode 100644
index 0000000..aeb31d2
--- /dev/null
+++ b/nxhs-common/src/main/java/cc/yunxi/common/exception/CommonException.java
@@ -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;
+ }
+}
diff --git a/nxhs-common/src/main/java/cc/yunxi/common/exception/DbException.java b/nxhs-common/src/main/java/cc/yunxi/common/exception/DbException.java
new file mode 100644
index 0000000..e37c346
--- /dev/null
+++ b/nxhs-common/src/main/java/cc/yunxi/common/exception/DbException.java
@@ -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);
+ }
+}
diff --git a/nxhs-common/src/main/java/cc/yunxi/common/exception/ForbiddenException.java b/nxhs-common/src/main/java/cc/yunxi/common/exception/ForbiddenException.java
new file mode 100644
index 0000000..9b91fae
--- /dev/null
+++ b/nxhs-common/src/main/java/cc/yunxi/common/exception/ForbiddenException.java
@@ -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);
+ }
+}
diff --git a/nxhs-common/src/main/java/cc/yunxi/common/exception/UnauthorizedException.java b/nxhs-common/src/main/java/cc/yunxi/common/exception/UnauthorizedException.java
new file mode 100644
index 0000000..c0d642e
--- /dev/null
+++ b/nxhs-common/src/main/java/cc/yunxi/common/exception/UnauthorizedException.java
@@ -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);
+ }
+}
diff --git a/nxhs-common/src/main/java/cc/yunxi/common/utils/BeanUtils.java b/nxhs-common/src/main/java/cc/yunxi/common/utils/BeanUtils.java
new file mode 100644
index 0000000..3b58e53
--- /dev/null
+++ b/nxhs-common/src/main/java/cc/yunxi/common/utils/BeanUtils.java
@@ -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 的BeanUtil,增加了bean转换时自定义转换器的功能
+ */
+public class BeanUtils extends BeanUtil {
+
+ /**
+ * 将原对象转换成目标对象,对于字段不匹配的字段可以使用转换器处理
+ *
+ * @param source 原对象
+ * @param clazz 目标对象的class
+ * @param convert 转换器
+ * @param 原对象类型
+ * @param 目标对象类型
+ * @return 目标对象
+ */
+ public static T copyBean(R source, Class clazz, Convert convert) {
+ T target = copyBean(source, clazz);
+ if (convert != null) {
+ convert.convert(source, target);
+ }
+ return target;
+ }
+ /**
+ * 将原对象转换成目标对象,对于字段不匹配的字段可以使用转换器处理
+ *
+ * @param source 原对象
+ * @param clazz 目标对象的class
+ * @param 原对象类型
+ * @param 目标对象类型
+ * @return 目标对象
+ */
+ public static T copyBean(R source, Class clazz){
+ if (source == null) {
+ return null;
+ }
+ return toBean(source, clazz);
+ }
+
+ public static List copyList(List list, Class clazz) {
+ if (list == null || list.size() == 0) {
+ return CollUtils.emptyList();
+ }
+ return copyToList(list, clazz);
+ }
+
+ public static List copyList(List list, Class clazz, Convert convert) {
+ if (list == null || list.size() == 0) {
+ return CollUtils.emptyList();
+ }
+ return list.stream().map(r -> copyBean(r, clazz, convert)).collect(Collectors.toList());
+ }
+}
\ No newline at end of file
diff --git a/nxhs-common/src/main/java/cc/yunxi/common/utils/CollUtils.java b/nxhs-common/src/main/java/cc/yunxi/common/utils/CollUtils.java
new file mode 100644
index 0000000..4a59281
--- /dev/null
+++ b/nxhs-common/src/main/java/cc/yunxi/common/utils/CollUtils.java
@@ -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 List emptyList() {
+ return Collections.emptyList();
+ }
+
+ public static Set emptySet() {
+ return Collections.emptySet();
+ }
+
+ public static Map emptyMap() {
+ return Collections.emptyMap();
+ }
+
+ public static Set singletonSet(T t) {
+ return Collections.singleton(t);
+ }
+
+ public static List singletonList(T t) {
+ return Collections.singletonList(t);
+ }
+
+ public static List convertToInteger(List originList){
+ return CollUtils.isNotEmpty(originList) ? originList.stream().map(NumberUtil::parseInt).collect(Collectors.toList()) : null;
+ }
+
+ public static List convertToLong(List originLIst){
+ return CollUtils.isNotEmpty(originLIst) ? originLIst.stream().map(NumberUtil::parseLong).collect(Collectors.toList()) : null;
+ }
+
+ /**
+ * 以 conjunction 为分隔符将集合转换为字符串 如果集合元素为数组、Iterable或Iterator,则递归组合其为字符串
+ * @param collection 集合
+ * @param conjunction 分隔符
+ * @param 集合元素类型
+ * @return 连接后的字符串
+ * See Also: IterUtil.join(Iterator, CharSequence)
+ */
+ public static String join(Collection collection, CharSequence conjunction) {
+ if (null == collection || collection.isEmpty()) {
+ return null;
+ }
+ return IterUtil.join(collection.iterator(), conjunction);
+ }
+
+ public static String joinIgnoreNull(Collection 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();
+ }
+}
\ No newline at end of file
diff --git a/nxhs-common/src/main/java/cc/yunxi/common/utils/Convert.java b/nxhs-common/src/main/java/cc/yunxi/common/utils/Convert.java
new file mode 100644
index 0000000..751fb65
--- /dev/null
+++ b/nxhs-common/src/main/java/cc/yunxi/common/utils/Convert.java
@@ -0,0 +1,8 @@
+package cc.yunxi.common.utils;
+
+/**
+ * 对原对象进行计算,设置到目标对象中
+ **/
+public interface Convert{
+ void convert(R origin, T target);
+}
\ No newline at end of file
diff --git a/nxhs-common/src/main/java/cc/yunxi/common/utils/UserContext.java b/nxhs-common/src/main/java/cc/yunxi/common/utils/UserContext.java
new file mode 100644
index 0000000..bdd0ec7
--- /dev/null
+++ b/nxhs-common/src/main/java/cc/yunxi/common/utils/UserContext.java
@@ -0,0 +1,28 @@
+package cc.yunxi.common.utils;
+
+public class UserContext {
+ private static final ThreadLocal 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();
+ }
+}
diff --git a/nxhs-common/src/main/java/cc/yunxi/common/utils/WebUtils.java b/nxhs-common/src/main/java/cc/yunxi/common/utils/WebUtils.java
new file mode 100644
index 0000000..d135cb2
--- /dev/null
+++ b/nxhs-common/src/main/java/cc/yunxi/common/utils/WebUtils.java
@@ -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对应多个值,中间使用逗号隔开例如 key1对应value1,key2对应value2,value3, key1=value1&key2=value2,value3
+ *
+ * @param request
+ * @return 返回拼接字符串
+ */
+ public static String getParameters(HttpServletRequest request) {
+ Map parameterMap = request.getParameterMap();
+ return getParameters(parameterMap);
+ }
+
+ /**
+ * 获取请求地址中的请求参数组装成 key1=value1&key2=value2
+ * 如果key对应多个值,中间使用逗号隔开例如 key1对应value1,key2对应value2,value3, key1=value1&key2=value2,value3
+ *
+ * @param queries
+ * @return
+ */
+ public static String getParameters(final Map queries) {
+ StringBuilder buffer = new StringBuilder();
+ for (Map.Entry 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)entry.getValue()),",")
+ ).append("&");
+ }
+ }
+ return buffer.length() > 0 ? buffer.substring(0, buffer.length() - 1) : StrUtil.EMPTY;
+ }
+
+ /**
+ * 获取请求url中的uri
+ *
+ * @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());
+// }
+}
diff --git a/nxhs-common/src/main/resources/META-INF/spring.factories b/nxhs-common/src/main/resources/META-INF/spring.factories
new file mode 100644
index 0000000..c6577d8
--- /dev/null
+++ b/nxhs-common/src/main/resources/META-INF/spring.factories
@@ -0,0 +1,3 @@
+org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
+ cc.yunxi.common.config.MyBatisConfig,\
+ cc.yunxi.common.config.JsonConfig
\ No newline at end of file
diff --git a/nxhs-service/pom.xml b/nxhs-service/pom.xml
new file mode 100644
index 0000000..959e9da
--- /dev/null
+++ b/nxhs-service/pom.xml
@@ -0,0 +1,34 @@
+
+
+ 4.0.0
+
+ cc.yunxi
+ nxhs
+ 0.0.1-SNAPSHOT
+
+
+ nxhs-service
+
+
+ 8
+ 8
+ UTF-8
+
+
+
+
+
+ cc.yunxi
+ nxhs-common
+ 0.0.1-SNAPSHOT
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+
+
\ No newline at end of file
diff --git a/nxhs-service/src/main/java/cc/yunxi/NxhsApplication.java b/nxhs-service/src/main/java/cc/yunxi/NxhsApplication.java
new file mode 100644
index 0000000..f802f5b
--- /dev/null
+++ b/nxhs-service/src/main/java/cc/yunxi/NxhsApplication.java
@@ -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);
+ }
+}
diff --git a/nxhs-service/src/main/java/cc/yunxi/controller/TestController.java b/nxhs-service/src/main/java/cc/yunxi/controller/TestController.java
new file mode 100644
index 0000000..2306994
--- /dev/null
+++ b/nxhs-service/src/main/java/cc/yunxi/controller/TestController.java
@@ -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 success() {
+ return CommonResult.success("ok");
+ }
+
+
+ @ApiOperation("测试接口失败")
+ @GetMapping("/test02")
+ public CommonResult failed() {
+ throw new BadRequestException("error");
+ }
+}
diff --git a/nxhs-service/src/main/java/cc/yunxi/domain/po/Test.java b/nxhs-service/src/main/java/cc/yunxi/domain/po/Test.java
new file mode 100644
index 0000000..8c2faeb
--- /dev/null
+++ b/nxhs-service/src/main/java/cc/yunxi/domain/po/Test.java
@@ -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;
+
+ /**
+ * sku商品id
+ */
+ private Integer age;
+}
diff --git a/nxhs-service/src/main/java/cc/yunxi/mapper/TestMapper.java b/nxhs-service/src/main/java/cc/yunxi/mapper/TestMapper.java
new file mode 100644
index 0000000..deb50b0
--- /dev/null
+++ b/nxhs-service/src/main/java/cc/yunxi/mapper/TestMapper.java
@@ -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 {
+}
diff --git a/nxhs-service/src/main/java/cc/yunxi/service/ITestService.java b/nxhs-service/src/main/java/cc/yunxi/service/ITestService.java
new file mode 100644
index 0000000..15708f9
--- /dev/null
+++ b/nxhs-service/src/main/java/cc/yunxi/service/ITestService.java
@@ -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 {
+}
diff --git a/nxhs-service/src/main/java/cc/yunxi/service/impl/TestServiceImpl.java b/nxhs-service/src/main/java/cc/yunxi/service/impl/TestServiceImpl.java
new file mode 100644
index 0000000..404ffcf
--- /dev/null
+++ b/nxhs-service/src/main/java/cc/yunxi/service/impl/TestServiceImpl.java
@@ -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 implements ITestService {
+}
diff --git a/nxhs-service/src/main/resources/application-dev.yml b/nxhs-service/src/main/resources/application-dev.yml
new file mode 100644
index 0000000..24e8843
--- /dev/null
+++ b/nxhs-service/src/main/resources/application-dev.yml
@@ -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 # 密码为空时,请将本行注释
diff --git a/nxhs-service/src/main/resources/application.yml b/nxhs-service/src/main/resources/application.yml
new file mode 100644
index 0000000..561895f
--- /dev/null
+++ b/nxhs-service/src/main/resources/application.yml
@@ -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
\ No newline at end of file
diff --git a/nxhs-service/src/main/resources/logback-spring.xml b/nxhs-service/src/main/resources/logback-spring.xml
new file mode 100644
index 0000000..50ea71c
--- /dev/null
+++ b/nxhs-service/src/main/resources/logback-spring.xml
@@ -0,0 +1,219 @@
+
+
+
+
+
+
+ logback
+
+
+
+
+
+
+
+
+ debug
+
+
+ ${CONSOLE_LOG_PATTERN}
+
+ UTF-8
+
+
+
+
+
+
+
+
+
+ ${log.path}/log_debug.log
+
+
+ %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n
+ UTF-8
+
+
+
+
+
+
+
+ ${log.path}/debug/log-debug-%d{yyyy-MM-dd_HH-mm}.%i.log
+
+
+ 100MB
+
+ 30
+
+ 20GB
+
+
+
+ debug
+ ACCEPT
+ DENY
+
+
+
+
+
+
+ ${log.path}/log_info.log
+
+
+ %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n
+ UTF-8
+
+
+
+
+
+
+ ${log.path}/info/log-info-%d{yyyy-MM-dd}.%i.log
+
+
+ 100MB
+
+ 30
+
+ 20GB
+
+
+
+
+
+ info
+ ACCEPT
+ DENY
+
+
+
+
+
+
+ ${log.path}/log_warn.log
+
+
+ %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n
+ UTF-8
+
+
+
+
+
+
+ ${log.path}/warn/log-warn-%d{yyyy-MM-dd}.%i.log
+
+
+ 100MB
+
+ 30
+
+ 20GB
+
+
+
+ warn
+ ACCEPT
+ DENY
+
+
+
+
+
+
+
+ ${log.path}/log_error.log
+
+
+ %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n
+ UTF-8
+
+
+
+
+
+
+ ${log.path}/error/log-error-%d{yyyy-MM-dd}.%i.log
+
+
+ 100MB
+
+ 30
+
+ 20GB
+
+
+
+ ERROR
+ ACCEPT
+ DENY
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/nxhs-service/src/test/java/cc/yunxi/NxhsApplicationTest.java b/nxhs-service/src/test/java/cc/yunxi/NxhsApplicationTest.java
new file mode 100644
index 0000000..c706e6c
--- /dev/null
+++ b/nxhs-service/src/test/java/cc/yunxi/NxhsApplicationTest.java
@@ -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 list = testService.list();
+ System.out.println(list);
+ }
+}
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..ad93d1a
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,137 @@
+
+
+ 4.0.0
+ cc.yunxi
+ nxhs
+ 0.0.1-SNAPSHOT
+ pom
+ nxhs
+ 宁夏回收平台小程序
+
+
+
+
+ nxhs-common
+ nxhs-service
+
+
+
+ 1.8
+ UTF-8
+ UTF-8
+ 2.7.6
+ 3.4.3
+ 5.8.11
+
+
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-dependencies
+ ${spring-boot.version}
+ pom
+ import
+
+
+
+
+
+
+
+
+ com.mysql
+ mysql-connector-j
+ runtime
+
+
+ com.baomidou
+ mybatis-plus-boot-starter
+ ${mybatis-plus.version}
+
+
+
+ org.springframework.boot
+ spring-boot-starter-data-redis
+
+
+
+ com.fasterxml.jackson.dataformat
+ jackson-dataformat-xml
+
+
+
+ org.projectlombok
+ lombok
+ true
+
+
+ cn.hutool
+ hutool-all
+ ${hutool.version}
+
+
+
+ org.hibernate.validator
+ hibernate-validator
+
+
+
+ com.github.xiaoymin
+ knife4j-openapi2-spring-boot-starter
+ 4.1.0
+
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.8.1
+
+
+ 1.8
+ UTF-8
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+ ${spring-boot.version}
+
+ cc.yunxi.nxhsapp.NxhsAppApplication
+ true
+
+
+
+ repackage
+
+ repackage
+
+
+
+
+
+
+
+
+
+
+ alimaven
+ aliyun maven
+ http://maven.aliyun.com/nexus/content/groups/public/
+
+
+
+