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 extends Serializable> 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 extends Serializable> 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