diff --git a/admin/pom.xml b/admin/pom.xml new file mode 100644 index 0000000..957eac6 --- /dev/null +++ b/admin/pom.xml @@ -0,0 +1,37 @@ + + + com.xun + admin-ui + 1.0.0 + + 4.0.0 + admin + jar + admin + + + + + com.xun + common + 1.0.0 + + + + + ${project.artifactId} + + + org.springframework.boot + spring-boot-maven-plugin + + + org.apache.maven.plugins + maven-surefire-plugin + + true + + + + + \ No newline at end of file diff --git a/admin/src/main/java/io/AdminApplication.java b/admin/src/main/java/io/AdminApplication.java new file mode 100644 index 0000000..adce6d3 --- /dev/null +++ b/admin/src/main/java/io/AdminApplication.java @@ -0,0 +1,17 @@ +package io; +import org.mybatis.spring.annotation.MapperScan; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; +import org.springframework.context.annotation.ComponentScan; + +@SpringBootApplication +@ComponentScan(basePackages = {"io.service","common"}) // 扫描多个包 +@MapperScan(basePackages = {"io.dao","common.dao"}) +public class AdminApplication extends SpringBootServletInitializer { + + public static void main(String[] args) { + SpringApplication.run(AdminApplication.class, args); + } + +} diff --git a/admin/src/main/java/io/config/SwaggerConfig.java b/admin/src/main/java/io/config/SwaggerConfig.java new file mode 100644 index 0000000..01eb2a8 --- /dev/null +++ b/admin/src/main/java/io/config/SwaggerConfig.java @@ -0,0 +1,36 @@ +package io.config; + +import common.constant.Constant; +import io.swagger.v3.oas.models.OpenAPI; +import io.swagger.v3.oas.models.info.Info; +import io.swagger.v3.oas.models.security.SecurityRequirement; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import java.util.ArrayList; +import java.util.List; +@Configuration +public class SwaggerConfig { + @Bean + public OpenAPI createRestApi() { + return new OpenAPI() + .info(apiInfo()) + .security(security()); + } + + private Info apiInfo() { + return new Info() + .title("系统") + .description("api文档") + .version("5.x"); + } + + private List security() { + SecurityRequirement key = new SecurityRequirement(); + key.addList(Constant.TOKEN_HEADER, Constant.TOKEN_HEADER); + + List list = new ArrayList<>(); + list.add(key); + return list; + } + +} diff --git a/admin/src/main/java/io/controller/HelloController.java b/admin/src/main/java/io/controller/HelloController.java new file mode 100644 index 0000000..a485f06 --- /dev/null +++ b/admin/src/main/java/io/controller/HelloController.java @@ -0,0 +1,13 @@ +package io.controller; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class HelloController { + + @GetMapping("/") + public String hello() { + return "Hello, World!"; + } +} \ No newline at end of file diff --git a/admin/src/main/java/io/controller/UserController.java b/admin/src/main/java/io/controller/UserController.java new file mode 100644 index 0000000..ddcd437 --- /dev/null +++ b/admin/src/main/java/io/controller/UserController.java @@ -0,0 +1,30 @@ +package io.controller; + +import common.page.PageData; +import common.utils.Result; +import io.domain.UserEntity; +import io.service.UserService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; +import java.util.HashMap; +/** + * 登录接口 + */ +@RestController +@RequestMapping("api") +public class UserController { + @Autowired + private UserService userService; + + @GetMapping("login") + @Operation(summary = "登录") + public Result login() { + + HashMap map = new HashMap<>(); + PageData page = userService.page(map); + return new Result().ok(page); + } + +} diff --git a/admin/src/main/java/io/dao/UserDao.java b/admin/src/main/java/io/dao/UserDao.java new file mode 100644 index 0000000..2da7ce3 --- /dev/null +++ b/admin/src/main/java/io/dao/UserDao.java @@ -0,0 +1,15 @@ +package io.dao; + + +import common.dao.BaseDao; +import io.domain.UserEntity; +import org.apache.ibatis.annotations.Mapper; + +/** + * 用户 + * + */ +@Mapper +public interface UserDao extends BaseDao { + +} diff --git a/admin/src/main/java/io/domain/UserEntity.java b/admin/src/main/java/io/domain/UserEntity.java new file mode 100644 index 0000000..9a21fc9 --- /dev/null +++ b/admin/src/main/java/io/domain/UserEntity.java @@ -0,0 +1,19 @@ +package io.domain; + + +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +@Data +@TableName("tb_user") +public class UserEntity { + + private Long id; + + private String username; + private String password; + private String createDate; + private String nickName; + private String introduce; + +} diff --git a/admin/src/main/java/io/exception/XunExceptionHandler.java b/admin/src/main/java/io/exception/XunExceptionHandler.java new file mode 100644 index 0000000..49a9603 --- /dev/null +++ b/admin/src/main/java/io/exception/XunExceptionHandler.java @@ -0,0 +1,42 @@ +package io.exception; + +import common.exception.XunException; +import common.utils.Result; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.dao.DuplicateKeyException; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.RestControllerAdvice; + +/** + * 异常处理器 + */ +@RestControllerAdvice +public class XunExceptionHandler { + private static final Logger logger = LoggerFactory.getLogger(XunExceptionHandler.class); + + /** + * 处理自定义异常 + */ + @ExceptionHandler(XunException.class) + public Result handleRenException(XunException ex){ + Result result = new Result(); + result.error(ex.getCode(), ex.getMsg()); + + return result; + } + + @ExceptionHandler(DuplicateKeyException.class) + public Result handleDuplicateKeyException(DuplicateKeyException ex){ + Result result = new Result(); + result.error("数据库中已存在该记录!"); + return result; + } + + @ExceptionHandler(Exception.class) + public Result handleException(Exception ex){ + logger.error(ex.getMessage(), ex); + + return new Result().error(ex.getMessage()); + } +} diff --git a/admin/src/main/java/io/service/UserService.java b/admin/src/main/java/io/service/UserService.java new file mode 100644 index 0000000..e1eb2a6 --- /dev/null +++ b/admin/src/main/java/io/service/UserService.java @@ -0,0 +1,11 @@ +package io.service; + +import common.service.BaseService; +import common.service.CrudService; +import io.domain.UserEntity; + +/** + * 用户 + */ +public interface UserService extends CrudService { +} diff --git a/admin/src/main/java/io/service/impl/UserServiceImpl.java b/admin/src/main/java/io/service/impl/UserServiceImpl.java new file mode 100644 index 0000000..0d924fc --- /dev/null +++ b/admin/src/main/java/io/service/impl/UserServiceImpl.java @@ -0,0 +1,6 @@ +package io.service.impl; + +import common.service.CrudService; +import io.domain.UserEntity; +public interface UserServiceImpl extends CrudService { +} diff --git a/admin/src/main/resources/application-dev.yml b/admin/src/main/resources/application-dev.yml new file mode 100644 index 0000000..9d9b165 --- /dev/null +++ b/admin/src/main/resources/application-dev.yml @@ -0,0 +1,41 @@ +spring: + datasource: + druid: + #MySQL + driver-class-name: com.mysql.cj.jdbc.Driver + url: jdbc:mysql://192.168.15.2:3306/bs_movies?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&nullCatalogMeansCurrent=true + username: root + password: minxianrui + initial-size: 10 + max-active: 100 + min-idle: 10 + max-wait: 6000 + pool-prepared-statements: true + max-pool-prepared-statement-per-connection-size: 20 + time-between-eviction-runs-millis: 60000 + min-evictable-idle-time-millis: 300000 + test-while-idle: true + test-on-borrow: false + test-on-return: false + stat-view-servlet: + enabled: true + url-pattern: /druid/* +mybatis-plus: + mapper-locations: classpath*:/mapper/**/*.xml + typeAliasesPackage: io.entity + global-config: + db-config: + id-type: AUTO + banner: false + configuration: + map-underscore-to-camel-case: true + cache-enabled: false + call-setters-on-nulls: true + jdbc-type-for-null: 'null' + configuration-properties: + prefix: + blobType: BLOB + boolValue: TRUE +upload: + path: D:\\code\\security\\upload\\ + url: https://bs.oss.xunyingcloud.cn/upload/movies/ \ No newline at end of file diff --git a/admin/src/main/resources/application.yml b/admin/src/main/resources/application.yml new file mode 100644 index 0000000..d5d7b2d --- /dev/null +++ b/admin/src/main/resources/application.yml @@ -0,0 +1,19 @@ +# Tomcat +server: + tomcat: + uri-encoding: UTF-8 + threads: + max: 1000 + min-spare: 30 + port: 8086 +spring: + profiles: + active: dev + mvc: + pathmatch: + matching-strategy: ANT_PATH_MATCHER + servlet: + multipart: + max-file-size: 100MB + max-request-size: 100MB + enabled: true diff --git a/common/pom.xml b/common/pom.xml new file mode 100644 index 0000000..3d563ca --- /dev/null +++ b/common/pom.xml @@ -0,0 +1,15 @@ + + + com.xun + admin-ui + 1.0.0 + + 4.0.0 + common + jar + common + + + ${project.artifactId} + + \ No newline at end of file diff --git a/common/src/main/java/common/constant/Constant.java b/common/src/main/java/common/constant/Constant.java new file mode 100644 index 0000000..84c134b --- /dev/null +++ b/common/src/main/java/common/constant/Constant.java @@ -0,0 +1,119 @@ +package common.constant; + +/** + * 常量 + * + + */ +public interface Constant { + /** + * 成功 + */ + int SUCCESS = 1; + /** + * 失败 + */ + int FAIL = 0; + /** + * 菜单根节点标识 + */ + Long MENU_ROOT = 0L; + /** + * 部门根节点标识 + */ + Long DEPT_ROOT = 0L; + /** + * 升序 + */ + String ASC = "asc"; + /** + * 降序 + */ + String DESC = "desc"; + /** + * 创建时间字段名 + */ + String CREATE_DATE = "create_date"; + + /** + * 数据权限过滤 + */ + String SQL_FILTER = "sqlFilter"; + /** + * 当前页码 + */ + String PAGE = "page"; + /** + * 每页显示记录数 + */ + String LIMIT = "limit"; + /** + * 排序字段 + */ + String ORDER_FIELD = "orderField"; + /** + * 排序方式 + */ + String ORDER = "order"; + /** + * token header + */ + String TOKEN_HEADER = "token"; + + /** + * 云存储配置KEY + */ + String CLOUD_STORAGE_CONFIG_KEY = "CLOUD_STORAGE_CONFIG_KEY"; + + /** + * 定时任务状态 + */ + enum ScheduleStatus { + /** + * 暂停 + */ + PAUSE(0), + /** + * 正常 + */ + NORMAL(1); + + private int value; + + ScheduleStatus(int value) { + this.value = value; + } + + public int getValue() { + return value; + } + } + + /** + * 云服务商 + */ + enum CloudService { + /** + * 七牛云 + */ + QINIU(1), + /** + * 阿里云 + */ + ALIYUN(2), + /** + * 腾讯云 + */ + QCLOUD(3); + + private int value; + + CloudService(int value) { + this.value = value; + } + + public int getValue() { + return value; + } + } +} diff --git a/common/src/main/java/common/dao/BaseDao.java b/common/src/main/java/common/dao/BaseDao.java new file mode 100644 index 0000000..fcfdef2 --- /dev/null +++ b/common/src/main/java/common/dao/BaseDao.java @@ -0,0 +1,10 @@ +package common.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** + * 基础Dao + */ +public interface BaseDao extends BaseMapper { + +} diff --git a/common/src/main/java/common/exception/ErrorCode.java b/common/src/main/java/common/exception/ErrorCode.java new file mode 100644 index 0000000..4e04cf7 --- /dev/null +++ b/common/src/main/java/common/exception/ErrorCode.java @@ -0,0 +1,18 @@ +package common.exception; + +/** + * 错误编码,由5位数字组成,前2位为模块编码,后3位为业务编码 + *

+ * 如:10001(10代表系统模块,001代表业务代码) + *

+ */ +public interface ErrorCode { + int INTERNAL_SERVER_ERROR = 500; + int UNAUTHORIZED = 401; + int NOT_NULL = 500; + + int ACCOUNT_PASSWORD_ERROR = 10004; + + int IDENTIFIER_NOT_NULL = 10006; + +} diff --git a/common/src/main/java/common/exception/XunException.java b/common/src/main/java/common/exception/XunException.java new file mode 100644 index 0000000..5218cb0 --- /dev/null +++ b/common/src/main/java/common/exception/XunException.java @@ -0,0 +1,46 @@ +package common.exception; + +import java.util.Arrays; + +/** + * 自定义异常 + * + */ +public class XunException extends RuntimeException { + private static final long serialVersionUID = 1L; + + private int code; + private String msg; + + public XunException(int code, String... params) { + this.code = code; + this.msg = Arrays.toString(params); + } + + public XunException(String msg) { + super(msg); + this.code = 500; + this.msg = msg; + } + + public XunException(String msg, Throwable e) { + super(msg, e); + this.code = ErrorCode.INTERNAL_SERVER_ERROR; + this.msg = msg; + } + public String getMsg() { + return msg; + } + + public void setMsg(String msg) { + this.msg = msg; + } + + public int getCode() { + return code; + } + public void setCode(int code) { + this.code = code; + } + +} diff --git a/common/src/main/java/common/page/PageData.java b/common/src/main/java/common/page/PageData.java new file mode 100644 index 0000000..8546e8b --- /dev/null +++ b/common/src/main/java/common/page/PageData.java @@ -0,0 +1,32 @@ +package common.page; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.io.Serializable; +import java.util.List; + +/** + * 分页工具类 + */ +@Data +@Schema(title = "分页数据") +public class PageData implements Serializable { + private static final long serialVersionUID = 1L; + + @Schema(title = "总记录数") + private int total; + + @Schema(title = "列表数据") + private List list; + + /** + * 分页 + * @param list 列表数据 + * @param total 总记录数 + */ + public PageData(List list, long total) { + this.list = list; + this.total = (int)total; + } +} diff --git a/common/src/main/java/common/service/BaseService.java b/common/src/main/java/common/service/BaseService.java new file mode 100644 index 0000000..9ce0fb0 --- /dev/null +++ b/common/src/main/java/common/service/BaseService.java @@ -0,0 +1,106 @@ +package common.service; + +import com.baomidou.mybatisplus.core.conditions.Wrapper; + +import java.io.Serializable; +import java.util.Collection; + +/** + * 基础服务接口,所有Service接口都要继承 + */ +public interface BaseService { + Class currentModelClass(); + + /** + *

+ * 插入一条记录(选择字段,策略插入) + *

+ * + * @param entity 实体对象 + */ + boolean insert(T entity); + + /** + *

+ * 插入(批量),该方法不支持 Oracle、SQL Server + *

+ * + * @param entityList 实体对象集合 + */ + boolean insertBatch(Collection entityList); + + /** + *

+ * 插入(批量),该方法不支持 Oracle、SQL Server + *

+ * + * @param entityList 实体对象集合 + * @param batchSize 插入批次数量 + */ + boolean insertBatch(Collection entityList, int batchSize); + + /** + *

+ * 根据 ID 选择修改 + *

+ * + * @param entity 实体对象 + */ + boolean updateById(T entity); + + /** + *

+ * 根据 whereEntity 条件,更新记录 + *

+ * + * @param entity 实体对象 + * @param updateWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper} + */ + boolean update(T entity, Wrapper updateWrapper); + + /** + *

+ * 根据ID 批量更新 + *

+ * + * @param entityList 实体对象集合 + */ + boolean updateBatchById(Collection entityList); + + /** + *

+ * 根据ID 批量更新 + *

+ * + * @param entityList 实体对象集合 + * @param batchSize 更新批次数量 + */ + boolean updateBatchById(Collection entityList, int batchSize); + + /** + *

+ * 根据 ID 查询 + *

+ * + * @param id 主键ID + */ + T selectById(Serializable id); + + /** + *

+ * 根据 ID 删除 + *

+ * + * @param id 主键ID + */ + boolean deleteById(Serializable id); + + /** + *

+ * 删除(根据ID 批量删除) + *

+ * + * @param idList 主键ID列表 + */ + boolean deleteBatchIds(Collection idList); +} diff --git a/common/src/main/java/common/service/CrudService.java b/common/src/main/java/common/service/CrudService.java new file mode 100644 index 0000000..16b9c3d --- /dev/null +++ b/common/src/main/java/common/service/CrudService.java @@ -0,0 +1,27 @@ +package common.service; + + + +import common.page.PageData; + +import java.util.List; +import java.util.Map; + +/** + * CRUD基础服务接口 + */ +public interface CrudService extends BaseService { + + PageData page(Map params); + + List list(Map params); + + D get(Long id); + + void save(D dto); + + void update(D dto); + + void delete(Long[] ids); + +} diff --git a/common/src/main/java/common/service/impl/BaseServiceImpl.java b/common/src/main/java/common/service/impl/BaseServiceImpl.java new file mode 100644 index 0000000..00b0108 --- /dev/null +++ b/common/src/main/java/common/service/impl/BaseServiceImpl.java @@ -0,0 +1,210 @@ +package common.service.impl; + +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.Wrapper; +import com.baomidou.mybatisplus.core.enums.SqlMethod; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.core.metadata.OrderItem; +import com.baomidou.mybatisplus.core.toolkit.Constants; +import com.baomidou.mybatisplus.core.toolkit.ReflectionKit; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.toolkit.SqlHelper; +import common.constant.Constant; +import common.page.PageData; +import common.service.BaseService; +import common.utils.ConvertUtils; +import org.apache.ibatis.binding.MapperMethod; +import org.apache.ibatis.logging.Log; +import org.apache.ibatis.logging.LogFactory; +import org.apache.ibatis.session.SqlSession; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.transaction.annotation.Transactional; +import java.io.Serializable; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.function.BiConsumer; + +/** + * 基础服务类,所有Service都要继承 + * + + */ +public abstract class BaseServiceImpl, T> implements BaseService { + @Autowired + protected M baseDao; + protected Log log = LogFactory.getLog(getClass()); + + /** + * 获取分页对象 + * @param params 分页查询参数 + * @param defaultOrderField 默认排序字段 + * @param isAsc 排序方式 + */ + protected IPage getPage(Map params, String defaultOrderField, boolean isAsc) { + //分页参数 + long curPage = 1; + long limit = 10; + + if (params.get(Constant.PAGE) != null) { + curPage = Long.parseLong((String) params.get(Constant.PAGE)); + } + if (params.get(Constant.LIMIT) != null) { + limit = Long.parseLong((String) params.get(Constant.LIMIT)); + } + + //分页对象 + Page page = new Page<>(curPage, limit); + + //分页参数 + params.put(Constant.PAGE, page); + + //排序字段 + String orderField = (String) params.get(Constant.ORDER_FIELD); + String order = (String) params.get(Constant.ORDER); + + //前端字段排序 + if (StrUtil.isNotBlank(orderField) && StrUtil.isNotBlank(order)) { + if (Constant.ASC.equalsIgnoreCase(order)) { + return page.addOrder(OrderItem.asc(orderField)); + } else { + return page.addOrder(OrderItem.desc(orderField)); + } + } + + //没有排序字段,则不排序 + if (StrUtil.isBlank(defaultOrderField)) { + return page; + } + + //默认排序 + if (isAsc) { + page.addOrder(OrderItem.asc(defaultOrderField)); + } else { + page.addOrder(OrderItem.desc(defaultOrderField)); + } + + return page; + } + + protected PageData getPageData(List list, long total, Class target) { + List targetList = ConvertUtils.sourceToTarget(list, target); + + return new PageData<>(targetList, total); + } + + protected PageData getPageData(IPage page, Class target) { + return getPageData(page.getRecords(), page.getTotal(), target); + } + + protected void paramsToLike(Map params, String... likes) { + for (String like : likes) { + String val = (String) params.get(like); + if (StrUtil.isNotBlank(val)) { + params.put(like, "%" + val + "%"); + } else { + params.put(like, null); + } + } + } + + /** + *

+ * 判断数据库操作是否成功 + *

+ *

+ * 注意!! 该方法为 Integer 判断,不可传入 int 基本类型 + *

+ * + * @param result 数据库操作返回影响条数 + * @return boolean + */ + protected static boolean retBool(Integer result) { + return SqlHelper.retBool(result); + } + + protected Class currentMapperClass() { + return (Class) ReflectionKit.getSuperClassGenericType(this.getClass(), BaseServiceImpl.class, 0); + } + + @Override + public Class currentModelClass() { + return (Class) ReflectionKit.getSuperClassGenericType(this.getClass(), BaseServiceImpl.class, 1); + } + + protected String getSqlStatement(SqlMethod sqlMethod) { + return SqlHelper.getSqlStatement(this.currentMapperClass(), sqlMethod); + } + + @Override + public boolean insert(T entity) { + return BaseServiceImpl.retBool(baseDao.insert(entity)); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public boolean insertBatch(Collection entityList) { + return insertBatch(entityList, 100); + } + + /** + * 批量插入 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public boolean insertBatch(Collection entityList, int batchSize) { + String sqlStatement = getSqlStatement(SqlMethod.INSERT_ONE); + return executeBatch(entityList, batchSize, (sqlSession, entity) -> sqlSession.insert(sqlStatement, entity)); + } + + /** + * 执行批量操作 + */ + protected boolean executeBatch(Collection list, int batchSize, BiConsumer consumer) { + return SqlHelper.executeBatch(this.currentModelClass(), this.log, list, batchSize, consumer); + } + + + @Override + public boolean updateById(T entity) { + return BaseServiceImpl.retBool(baseDao.updateById(entity)); + } + + @Override + public boolean update(T entity, Wrapper updateWrapper) { + return BaseServiceImpl.retBool(baseDao.update(entity, updateWrapper)); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public boolean updateBatchById(Collection entityList) { + return updateBatchById(entityList, 30); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public boolean updateBatchById(Collection entityList, int batchSize) { + String sqlStatement = getSqlStatement(SqlMethod.UPDATE_BY_ID); + return executeBatch(entityList, batchSize, (sqlSession, entity) -> { + MapperMethod.ParamMap param = new MapperMethod.ParamMap<>(); + param.put(Constants.ENTITY, entity); + sqlSession.update(sqlStatement, param); + }); + } + + @Override + public T selectById(Serializable id) { + return baseDao.selectById(id); + } + + @Override + public boolean deleteById(Serializable id) { + return SqlHelper.retBool(baseDao.deleteById(id)); + } + + @Override + public boolean deleteBatchIds(Collection idList) { + return SqlHelper.retBool(baseDao.deleteBatchIds(idList)); + } +} diff --git a/common/src/main/java/common/service/impl/CrudServiceImpl.java b/common/src/main/java/common/service/impl/CrudServiceImpl.java new file mode 100644 index 0000000..55b3a53 --- /dev/null +++ b/common/src/main/java/common/service/impl/CrudServiceImpl.java @@ -0,0 +1,71 @@ +package common.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.core.toolkit.ReflectionKit; +import common.page.PageData; +import common.service.CrudService; +import common.utils.ConvertUtils; +import org.springframework.beans.BeanUtils; +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +/** + * CRUD基础服务类 + * + + */ +public abstract class CrudServiceImpl, T, D> extends BaseServiceImpl implements CrudService { + + protected Class currentDtoClass() { + return (Class)ReflectionKit.getSuperClassGenericType(getClass(), CrudServiceImpl.class, 2); + } + + @Override + public PageData page(Map params) { + IPage page = baseDao.selectPage( + getPage(params, null, false), + getWrapper(params) + ); + + return getPageData(page, currentDtoClass()); + } + + @Override + public List list(Map params) { + List entityList = baseDao.selectList(getWrapper(params)); + + return ConvertUtils.sourceToTarget(entityList, currentDtoClass()); + } + + public abstract QueryWrapper getWrapper(Map params); + + @Override + public D get(Long id) { + T entity = baseDao.selectById(id); + + return ConvertUtils.sourceToTarget(entity, currentDtoClass()); + } + + @Override + public void save(D dto) { + T entity = ConvertUtils.sourceToTarget(dto, currentModelClass()); + insert(entity); + + //copy主键值到dto + BeanUtils.copyProperties(entity, dto); + } + + @Override + public void update(D dto) { + T entity = ConvertUtils.sourceToTarget(dto, currentModelClass()); + updateById(entity); + } + + @Override + public void delete(Long[] ids) { + baseDao.deleteBatchIds(Arrays.asList(ids)); + } +} diff --git a/common/src/main/java/common/utils/ConvertUtils.java b/common/src/main/java/common/utils/ConvertUtils.java new file mode 100644 index 0000000..c3f0a71 --- /dev/null +++ b/common/src/main/java/common/utils/ConvertUtils.java @@ -0,0 +1,51 @@ +package common.utils; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.BeanUtils; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +/** + * 转换工具类 + * + */ +public class ConvertUtils { + private static Logger logger = LoggerFactory.getLogger(ConvertUtils.class); + + public static T sourceToTarget(Object source, Class target){ + if(source == null){ + return null; + } + T targetObject = null; + try { + targetObject = target.newInstance(); + BeanUtils.copyProperties(source, targetObject); + } catch (Exception e) { + logger.error("convert error ", e); + } + + return targetObject; + } + + public static List sourceToTarget(Collection sourceList, Class target){ + if(sourceList == null){ + return null; + } + + List targetList = new ArrayList<>(sourceList.size()); + try { + for(Object source : sourceList){ + T targetObject = target.newInstance(); + BeanUtils.copyProperties(source, targetObject); + targetList.add(targetObject); + } + }catch (Exception e){ + logger.error("convert error ", e); + } + + return targetList; + } +} diff --git a/common/src/main/java/common/utils/Result.java b/common/src/main/java/common/utils/Result.java new file mode 100644 index 0000000..60ca84d --- /dev/null +++ b/common/src/main/java/common/utils/Result.java @@ -0,0 +1,75 @@ +package common.utils; + +import common.exception.ErrorCode; +import io.swagger.v3.oas.annotations.media.Schema; +import java.io.Serializable; + +/** + * 响应数据 + * + + * @since 1.0.0 + */ +@Schema(title = "响应") +public class Result implements Serializable { + private static final long serialVersionUID = 1L; + /** + * 编码:0表示成功,其他值表示失败 + */ + @Schema(title = "编码:0表示成功,其他值表示失败") + private int code = 0; + /** + * 消息内容 + */ + @Schema(title = "消息内容") + private String msg = "success"; + /** + * 响应数据 + */ + @Schema(title = "响应数据") + private T data; + + public Result ok(T data) { + this.setData(data); + return this; + } + public boolean success(){ + return code == 0; + } + + public Result error(int code, String msg) { + this.code = code; + this.msg = msg; + return this; + } + + public Result error(String msg) { + this.code = ErrorCode.INTERNAL_SERVER_ERROR; + this.msg = msg; + return this; + } + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public String getMsg() { + return msg; + } + + public void setMsg(String msg) { + this.msg = msg; + } + + public T getData() { + return data; + } + + public void setData(T data) { + this.data = data; + } +} diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..cdd71d1 --- /dev/null +++ b/pom.xml @@ -0,0 +1,102 @@ + + 4.0.0 + com.xun + admin-ui + 1.0.0 + pom + + shop + 后台模板 + + org.springframework.boot + spring-boot-starter-parent + 3.2.6 + + + + common + admin + + + + + UTF-8 + UTF-8 + 17 + 1.2.21 + 3.5.5 + 3.0.3 + 5.8.29 + 4.5.0 + 1.18.24 + + + + + org.springframework.boot + spring-boot-starter-web + + + + com.mysql + mysql-connector-j + + + com.alibaba + druid-spring-boot-3-starter + ${druid.version} + + + com.baomidou + mybatis-plus-boot-starter + ${mybatisplus.version} + + + org.mybatis + mybatis-spring + ${mybatis.spring} + + + cn.hutool + hutool-all + ${hutool.version} + + + + com.github.xiaoymin + knife4j-openapi3-jakarta-spring-boot-starter + ${knife4j.version} + + + org.projectlombok + lombok + ${lombok.version} + + + + + + + public + aliyun nexus + https://maven.aliyun.com/repository/public/ + + true + + + + + + public + aliyun nexus + https://maven.aliyun.com/repository/public/ + + true + + + false + + + + \ No newline at end of file