Преглед на файлове

Merge remote-tracking branch 'origin/excel' into dev

toby преди 1 година
родител
ревизия
a194104300
променени са 21 файла, в които са добавени 931 реда и са изтрити 6 реда
  1. 10 0
      common/common-core/src/main/java/com/iohao/mmo/common/config/GameCode.java
  2. 7 0
      logic/a-logic-common/pom.xml
  3. 95 0
      logic/a-logic-common/src/main/java/com/iohao/mmo/common/kit/Result.java
  4. 5 1
      logic/all-logic/pom.xml
  5. 45 0
      logic/excel-logic/pom.xml
  6. 39 0
      logic/excel-logic/src/main/java/com/iohao/mmo/excel/config/SpringDocConfig.java
  7. 78 0
      logic/excel-logic/src/main/java/com/iohao/mmo/excel/controller/ExcelController.java
  8. 41 0
      logic/excel-logic/src/main/java/com/iohao/mmo/excel/dto/DemoExcelDTO.java
  9. 30 0
      logic/excel-logic/src/main/java/com/iohao/mmo/excel/dto/converter/StatusConverter.java
  10. 32 0
      logic/excel-logic/src/main/java/com/iohao/mmo/excel/entity/DemoExcel.java
  11. 51 0
      logic/excel-logic/src/main/java/com/iohao/mmo/excel/kit/ConvertKit.java
  12. 67 0
      logic/excel-logic/src/main/java/com/iohao/mmo/excel/kit/ExcelKit.java
  13. 53 0
      logic/excel-logic/src/main/java/com/iohao/mmo/excel/kit/GenericsKit.java
  14. 87 0
      logic/excel-logic/src/main/java/com/iohao/mmo/excel/listener/ExcelDataCustomListener.java
  15. 77 0
      logic/excel-logic/src/main/java/com/iohao/mmo/excel/listener/ExcelDataListener.java
  16. 68 0
      logic/excel-logic/src/main/java/com/iohao/mmo/excel/service/BaseService.java
  17. 21 0
      logic/excel-logic/src/main/java/com/iohao/mmo/excel/service/DemoExcelService.java
  18. 60 0
      logic/excel-logic/src/main/java/com/iohao/mmo/excel/service/impl/BaseServiceImpl.java
  19. 60 0
      logic/excel-logic/src/main/java/com/iohao/mmo/excel/service/impl/DemoExcelServiceImpl.java
  20. 0 5
      one-application/src/main/java/com/iohao/mmo/OneApplication.java
  21. 5 0
      pom.xml

+ 10 - 0
common/common-core/src/main/java/com/iohao/mmo/common/config/GameCode.java

@@ -41,6 +41,8 @@ public enum GameCode implements MsgExceptionInfo {
     objNotFound(4, "操作对象错误"),
     /** 可分配属性点不足 */
     allotNotEnough(5, "分配异常,属性点不足"),
+    /** 系统错误 */
+    internalServerError(5, "系统错误,请联系管理员")
     ;
 
     /** 消息码 */
@@ -52,4 +54,12 @@ public enum GameCode implements MsgExceptionInfo {
         this.code = code;
         this.msg = msg;
     }
+    public static GameCode getByCode(int code){
+        for(GameCode gameCode : GameCode.values()){
+            if(gameCode.getCode()==code)            {
+                return gameCode;
+            }
+        }
+        return null;
+    }
 }

+ 7 - 0
logic/a-logic-common/pom.xml

@@ -68,5 +68,12 @@
             <artifactId>javafaker</artifactId>
             <version>${javafaker.version}</version>
         </dependency>
+
+        <!-- https://mvnrepository.com/artifact/com.alibaba.fastjson2/fastjson2 -->
+        <dependency>
+            <groupId>com.alibaba.fastjson2</groupId>
+            <artifactId>fastjson2</artifactId>
+            <version>2.0.38</version>
+        </dependency>
     </dependencies>
 </project>

+ 95 - 0
logic/a-logic-common/src/main/java/com/iohao/mmo/common/kit/Result.java

@@ -0,0 +1,95 @@
+package com.iohao.mmo.common.kit;
+
+import com.iohao.mmo.common.config.GameCode;
+import java.io.Serializable;
+
+/**
+ * 响应数据
+ *
+ * @author 唐斌
+ * @since 1.0.0
+ */
+public class Result<T> implements Serializable {
+    private static final long serialVersionUID = 1L;
+    /**
+     * 编码:0表示成功,其他值表示失败
+     */
+    private int code = 0;
+    /**
+     * 消息内容
+     */
+    private String msg = "success";
+    /**
+     * 响应数据
+     */
+    private T data;
+    /**
+     * 扩展字段
+     */
+    private String ext;
+
+    public Result<T> ok(T data) {
+        this.setData(data);
+        return this;
+    }
+
+    public boolean success(){
+        return code == 0 ? true : false;
+    }
+
+    public Result<T> error() {
+        this.code = GameCode.internalServerError.getCode();
+        this.msg = GameCode.internalServerError.getMsg();
+        return this;
+    }
+
+    public Result<T> error(int code) {
+        this.code = code;
+        GameCode gameCode = GameCode.getByCode(this.code);
+        this.msg = gameCode==null?"":gameCode.getMsg();
+        return this;
+    }
+
+    public Result<T> error(int code, String msg) {
+        this.code = code;
+        this.msg = msg;
+        return this;
+    }
+
+    public Result<T> error(String msg) {
+        this.code = GameCode.internalServerError.getCode();
+        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;
+    }
+
+    public String getExt() {
+        return ext;
+    }
+    public void setExt(String ext) {
+        this.ext = ext;
+    }
+}

+ 5 - 1
logic/all-logic/pom.xml

@@ -59,7 +59,11 @@
             <artifactId>equip-logic</artifactId>
             <version>${project.parent.version}</version>
         </dependency>
-
+        <dependency>
+            <groupId>com.iohao.mmo</groupId>
+            <artifactId>excel-logic</artifactId>
+            <version>${project.parent.version}</version>
+        </dependency>
     </dependencies>
 
 </project>

+ 45 - 0
logic/excel-logic/pom.xml

@@ -0,0 +1,45 @@
+<?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>com.iohao.mmo</groupId>
+        <artifactId>game</artifactId>
+        <version>1.0-SNAPSHOT</version>
+        <relativePath>../../pom.xml</relativePath>
+    </parent>
+
+    <artifactId>excel-logic</artifactId>
+
+    <properties>
+        <maven.compiler.source>17</maven.compiler.source>
+        <maven.compiler.target>17</maven.compiler.target>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+    </properties>
+    <dependencies>
+        <!-- 游戏逻辑服通用模块 -->
+        <dependency>
+            <groupId>com.iohao.mmo</groupId>
+            <artifactId>a-logic-common</artifactId>
+            <version>${project.parent.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+        </dependency>
+        <!-- easyexcel -->
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>easyexcel</artifactId>
+            <version>${easyexcel.version}</version>
+        </dependency>
+        <!-- springdoc -->
+        <dependency>
+            <groupId>org.springdoc</groupId>
+            <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
+            <version>${springdoc.version}</version>
+        </dependency>
+    </dependencies>
+</project>

+ 39 - 0
logic/excel-logic/src/main/java/com/iohao/mmo/excel/config/SpringDocConfig.java

@@ -0,0 +1,39 @@
+package com.iohao.mmo.excel.config;
+
+import io.swagger.v3.oas.models.Components;
+import io.swagger.v3.oas.models.ExternalDocumentation;
+import io.swagger.v3.oas.models.OpenAPI;
+import io.swagger.v3.oas.models.info.Info;
+import io.swagger.v3.oas.models.info.License;
+import io.swagger.v3.oas.models.security.SecurityRequirement;
+import io.swagger.v3.oas.models.security.SecurityScheme;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * SpringDoc API文档相关配置
+ * Created by macro on 2022/3/4.
+ */
+@Configuration
+public class SpringDocConfig {
+    private static final String SECURITY_SCHEME_NAME = "BearerAuth";
+    @Bean
+    public OpenAPI mallTinyOpenAPI() {
+        return new OpenAPI()
+                .info(new Info().title("接口文档标题")
+                        .description("Excel 演示")
+                        .version("v1.0.0")
+                        .license(new License().name("excel demo").url("https://www.baidu.com/")))
+                .externalDocs(new ExternalDocumentation()
+                        .description("这里可以放介绍外链")
+                        .url("https://www.baidu.com/"))
+                .addSecurityItem(new SecurityRequirement().addList(SECURITY_SCHEME_NAME))
+                .components(new Components()
+                        .addSecuritySchemes(SECURITY_SCHEME_NAME,
+                                new SecurityScheme()
+                                        .name(SECURITY_SCHEME_NAME)
+                                        .type(SecurityScheme.Type.HTTP)
+                                        .scheme("bearer")
+                                        .bearerFormat("JWT")));
+    }
+}

+ 78 - 0
logic/excel-logic/src/main/java/com/iohao/mmo/excel/controller/ExcelController.java

@@ -0,0 +1,78 @@
+package com.iohao.mmo.excel.controller;
+
+import com.alibaba.excel.EasyExcel;
+import com.iohao.mmo.common.kit.Result;
+import com.iohao.mmo.excel.dto.DemoExcelDTO;
+import com.iohao.mmo.excel.entity.DemoExcel;
+import com.iohao.mmo.excel.kit.ExcelKit;
+import com.iohao.mmo.excel.listener.ExcelDataCustomListener;
+import com.iohao.mmo.excel.listener.ExcelDataListener;
+import com.iohao.mmo.excel.service.DemoExcelService;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import jakarta.servlet.http.HttpServletResponse;
+import lombok.AllArgsConstructor;
+import org.springframework.http.MediaType;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+import java.time.LocalTime;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author 渔民小镇
+ * @date 2023-08-29
+ */
+@AllArgsConstructor
+@RestController
+@RequestMapping("/excel")
+@Tag(name = "ExcelController", description = "excel示例")
+public class ExcelController {
+    private final DemoExcelService demoExcelService;
+    @GetMapping("/index")
+    public String index(@RequestParam("name") @Parameter(description = "名字")String name) {
+        return name + ", say - " + LocalTime.now().getSecond();
+    }
+
+    /**
+     * 通用导出示例
+     * @param params
+     * @param response
+     * @throws Exception
+     */
+    @Operation(summary = "通用导出示例",description = "通用导出示例")
+    @GetMapping("exportdemo")
+    public void exportDemo(@RequestParam Map<String, Object> params, HttpServletResponse response) throws Exception{
+        List<DemoExcel> list = demoExcelService.list(params,DemoExcel.class);
+        ExcelKit.exportExcelToTarget(response, null, "Excel示例", list, DemoExcelDTO.class);
+    }
+
+    /**
+     * 通用导入示例
+     * @param file
+     * @return
+     * @throws Exception
+     */
+    @PostMapping(value = "importdemo", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
+    @Operation(summary = "通用导入示例",description = "通用导入示例")
+    public Result importDemo(@RequestPart("file") @Parameter(description = "文件")MultipartFile file) throws Exception {
+        //通用读取
+        EasyExcel.read(file.getInputStream(), DemoExcelDTO.class, new ExcelDataListener<>(demoExcelService)).sheet(0).doRead();
+        return new Result().ok("导入成功!");
+    }
+
+    /**
+     * 导入数据自定义处理示例
+     * @param file
+     * @return
+     * @throws Exception
+     */
+    @PostMapping(value = "importcustom", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
+    @Operation(summary = "导入数据自定义处理示例",description = "导入数据自定义处理示例")
+    public Result importCustom(@RequestPart("file") @Parameter(description = "文件")MultipartFile file) throws Exception {
+        //自定义读取
+        EasyExcel.read(file.getInputStream(), DemoExcelDTO.class, new ExcelDataCustomListener<>(demoExcelService)).sheet(0).doRead();
+        return new Result().ok("导入成功!");
+    }
+}

+ 41 - 0
logic/excel-logic/src/main/java/com/iohao/mmo/excel/dto/DemoExcelDTO.java

@@ -0,0 +1,41 @@
+package com.iohao.mmo.excel.dto;
+
+import com.alibaba.excel.annotation.ExcelProperty;
+import com.alibaba.excel.annotation.format.DateTimeFormat;
+import com.alibaba.excel.annotation.write.style.ColumnWidth;
+import com.alibaba.excel.annotation.write.style.ContentRowHeight;
+import com.alibaba.excel.annotation.write.style.HeadRowHeight;
+import com.iohao.mmo.excel.dto.converter.StatusConverter;
+import lombok.Data;
+import java.util.Date;
+
+/**
+ * Excel示例类(匹配表格)
+ *
+ * @author Toby javatangbin@163.com
+ */
+@Data
+@ContentRowHeight(20)
+@HeadRowHeight(20)
+@ColumnWidth(25)
+public class DemoExcelDTO {
+    @ColumnWidth(20)
+    @ExcelProperty("名称")
+    private String name;
+
+    @ExcelProperty("编码")
+    private String code;
+
+    @ColumnWidth(20)
+    @ExcelProperty(value = "状态", converter = StatusConverter.class)
+    private Integer status;
+
+    @ExcelProperty("备注")
+    private String remark;
+
+    @DateTimeFormat("yyyy-MM-dd HH:mm:ss")
+    @ExcelProperty("注册时间")
+    private Date registerDate;
+
+
+}

+ 30 - 0
logic/excel-logic/src/main/java/com/iohao/mmo/excel/dto/converter/StatusConverter.java

@@ -0,0 +1,30 @@
+package com.iohao.mmo.excel.dto.converter;
+
+import com.alibaba.excel.converters.Converter;
+import com.alibaba.excel.enums.CellDataTypeEnum;
+import com.alibaba.excel.metadata.GlobalConfiguration;
+import com.alibaba.excel.metadata.data.ReadCellData;
+import com.alibaba.excel.metadata.data.WriteCellData;
+import com.alibaba.excel.metadata.property.ExcelContentProperty;
+
+public class StatusConverter implements Converter<Integer> {
+    @Override
+    public Class<Integer> supportJavaTypeKey() {
+        return Integer.class;
+    }
+
+    @Override
+    public CellDataTypeEnum supportExcelTypeKey() {
+        return CellDataTypeEnum.STRING;
+    }
+
+    @Override
+    public Integer convertToJavaData(ReadCellData<?> cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) {
+        return cellData.getStringValue().equals("正常") ? 1 : 0;
+    }
+
+    @Override
+    public WriteCellData<?> convertToExcelData(Integer value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) {
+        return new WriteCellData<>(value == 1 ? "正常" : "停用");
+    }
+}

+ 32 - 0
logic/excel-logic/src/main/java/com/iohao/mmo/excel/entity/DemoExcel.java

@@ -0,0 +1,32 @@
+package com.iohao.mmo.excel.entity;
+
+import lombok.AccessLevel;
+import lombok.Data;
+import lombok.experimental.FieldDefaults;
+import org.springframework.data.annotation.Id;
+import org.springframework.data.mongodb.core.mapping.Document;
+import java.util.Date;
+
+/**
+ * Excel示例类
+ *
+ * @author 唐斌
+ * @date 2023-07-26
+ */
+@Data
+@Document
+@FieldDefaults(level = AccessLevel.PRIVATE)
+public class DemoExcel {
+    @Id
+    String id;
+    /** 名称 */
+    String name;
+    /** 编码 */
+    String code;
+    /** 状态 */
+    int status;
+    /** 备注 */
+    String remark;
+    /** 注册时间 */
+    Date registerDate;
+}

+ 51 - 0
logic/excel-logic/src/main/java/com/iohao/mmo/excel/kit/ConvertKit.java

@@ -0,0 +1,51 @@
+package com.iohao.mmo.excel.kit;
+
+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;
+
+/**
+ * 转换工具类
+ *
+ * @author toby javatangbin@163.com
+ */
+public class ConvertKit {
+    private static Logger logger = LoggerFactory.getLogger(ConvertKit.class);
+
+    public static <T> T sourceToTarget(Object source, Class<T> 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 <T> List<T> sourceToTarget(Collection<?> sourceList, Class<T> 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;
+    }
+}

+ 67 - 0
logic/excel-logic/src/main/java/com/iohao/mmo/excel/kit/ExcelKit.java

@@ -0,0 +1,67 @@
+package com.iohao.mmo.excel.kit;
+
+import com.alibaba.excel.EasyExcel;
+import com.alibaba.excel.converters.longconverter.LongStringConverter;
+import com.alibaba.excel.util.DateUtils;
+import jakarta.servlet.http.HttpServletResponse;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.BeanUtils;
+import java.io.IOException;
+import java.net.URLEncoder;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * excel工具类
+ *
+ * @author Toby javatangbin@163.com
+ */
+public class ExcelKit {
+
+    /**
+     * Excel导出
+     *
+     * @param response      response
+     * @param fileName      文件名
+     * @param sheetName     sheetName
+     * @param list          数据List
+     * @param pojoClass     对象Class
+     */
+    public static void exportExcel(HttpServletResponse response, String fileName, String sheetName, List<?> list,
+                                   Class<?> pojoClass) throws IOException {
+        if (StringUtils.isBlank(fileName)) {
+            //当前日期
+            fileName = DateUtils.format(new Date());
+        }
+
+        response.setContentType("application/vnd.ms-excel");
+        response.setCharacterEncoding("UTF-8");
+        fileName = URLEncoder.encode(fileName, StandardCharsets.UTF_8);
+        response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
+        EasyExcel.write(response.getOutputStream(), pojoClass).registerConverter(new LongStringConverter()).sheet(sheetName).doWrite(list);
+    }
+
+    /**
+     * Excel导出,先sourceList转换成List<targetClass>,再导出
+     *
+     * @param response      response
+     * @param fileName      文件名
+     * @param sheetName     sheetName
+     * @param sourceList    原数据List
+     * @param targetClass   目标对象Class
+     */
+    public static void exportExcelToTarget(HttpServletResponse response, String fileName, String sheetName, List<?> sourceList,
+                                           Class<?> targetClass) throws Exception {
+        List targetList = new ArrayList<>(sourceList.size());
+        for (Object source : sourceList) {
+            Object target = targetClass.newInstance();
+            BeanUtils.copyProperties(source, target);
+            targetList.add(target);
+        }
+
+        exportExcel(response, fileName, sheetName, targetList, targetClass);
+    }
+
+}

+ 53 - 0
logic/excel-logic/src/main/java/com/iohao/mmo/excel/kit/GenericsKit.java

@@ -0,0 +1,53 @@
+package com.iohao.mmo.excel.kit;
+
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+
+@SuppressWarnings("unchecked")
+public class GenericsKit {
+
+    /**
+     * 通过反射,获得定义Class时声明的父类的泛型参数的类型
+     * @param clazz
+     * @return
+     */
+    public static Class getSuperClassGenericType(Class clazz) {
+
+        return getSuperClassGenricType(clazz, 0);
+
+    }
+
+    /**
+     * 通过反射,获得定义Class声明的父类的泛型参数的类型
+     * @param clazz
+     * @param index
+     * @return
+     */
+    public static Class getSuperClassGenricType(Class clazz, int index) {
+
+        Type genType = clazz.getGenericSuperclass();
+
+        if (!(genType instanceof ParameterizedType)) {
+
+            return Object.class;
+
+        }
+
+        Type[] params = ((ParameterizedType) genType).getActualTypeArguments();
+
+        if (index >= params.length || index < 0) {
+
+            return Object.class;
+
+        }
+
+        if (!(params[index] instanceof Class)) {
+
+            return Object.class;
+
+        }
+
+        return (Class) params[index];
+
+    }
+}

+ 87 - 0
logic/excel-logic/src/main/java/com/iohao/mmo/excel/listener/ExcelDataCustomListener.java

@@ -0,0 +1,87 @@
+package com.iohao.mmo.excel.listener;
+
+import com.alibaba.excel.context.AnalysisContext;
+import com.alibaba.excel.event.AnalysisEventListener;
+import com.alibaba.fastjson2.JSONObject;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.iohao.mmo.excel.dto.DemoExcelDTO;
+import com.iohao.mmo.excel.entity.DemoExcel;
+import com.iohao.mmo.excel.kit.ConvertKit;
+import com.iohao.mmo.excel.service.DemoExcelService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Excel模板读取类(自定义读取类)
+ *
+ * @author Toby javatangbin@163.com
+ */
+public class ExcelDataCustomListener<E, T> extends AnalysisEventListener<T> {
+    private static final Logger LOGGER = LoggerFactory.getLogger(ExcelDataCustomListener.class);
+    /**
+     * 每隔2000条存储数据库,然后清理list,方便内存回收
+     */
+    private static final int BATCH_COUNT = 2000;
+    private final List<DemoExcel> list = new ArrayList<>();
+
+    /**
+     * 通过构造器注入Service
+     */
+    private final DemoExcelService demoExcelService;
+
+    /**
+     * 构造方法
+     *
+     * @param demoExcelService Service对象
+     */
+    public ExcelDataCustomListener(DemoExcelService demoExcelService) {
+        this.demoExcelService = demoExcelService;
+    }
+
+    /**
+     * 每条数据解析完,都会调用此方法
+     */
+    @Override
+    public void invoke(T data, AnalysisContext context) {
+        LOGGER.info("解析到一条数据:{}", JSONObject.toJSONString(data));
+        DemoExcelDTO excel = ConvertKit.sourceToTarget(data, DemoExcelDTO.class);
+
+        // 这里对数据做自定义设置
+        DemoExcel entity = ConvertKit.sourceToTarget(excel, DemoExcel.class);
+        if(entity.getStatus()==0){
+            entity.setRemark(entity.getRemark()+"-----我这里对状态为停用的数据做了自定义修改"); //转化为时间戳
+        }
+        list.add(entity);
+
+        // 达到BATCH_COUNT了,需要去存储一次数据库,防止数据几万条数据在内存,容易OOM
+        if (list.size() >= BATCH_COUNT) {
+            saveData();
+            // 存储完成清理 list
+            list.clear();
+        }
+    }
+    /**
+     * 所有数据解析完成了 都会来调用
+     */
+    @Override
+    public void doAfterAllAnalysed(AnalysisContext context) {
+        // 这里也要保存数据,确保最后遗留的数据也存储到数据库
+        saveData();
+        LOGGER.info("所有数据解析完成!");
+    }
+    /**
+     * 加上存储数据库
+     */
+    private void saveData() {
+        LOGGER.info("{}条数据,开始存储数据库!", list.size());
+        try {
+            //根据code批量更新或者插入
+            demoExcelService.updateBatch(list);
+        } catch (JsonProcessingException e) {
+            throw new RuntimeException(e);
+        }
+        LOGGER.info("存储数据库成功!");
+    }
+}

+ 77 - 0
logic/excel-logic/src/main/java/com/iohao/mmo/excel/listener/ExcelDataListener.java

@@ -0,0 +1,77 @@
+package com.iohao.mmo.excel.listener;
+
+import com.alibaba.excel.context.AnalysisContext;
+import com.alibaba.excel.event.AnalysisEventListener;
+import com.iohao.mmo.excel.kit.ConvertKit;
+import com.iohao.mmo.excel.service.BaseService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import java.util.ArrayList;
+import java.util.List;
+import com.alibaba.fastjson2.JSONObject;
+
+
+/**
+ * Excel模板读取类(通用读取类)
+ *
+ * @author Toby javatangbin@163.com
+ */
+public class ExcelDataListener<E, T> extends AnalysisEventListener<T> {
+    private static final Logger LOGGER = LoggerFactory.getLogger(ExcelDataListener.class);
+    /**
+     * 每隔2000条存储数据库,然后清理list,方便内存回收
+     */
+    private static final int BATCH_COUNT = 2000;
+    private final List<E> list = new ArrayList<>();
+
+    /**
+     * 通过构造器注入Service
+     */
+    private final BaseService<E> baseService;
+
+    /**
+     * 构造方法
+     *
+     * @param baseService Service对象
+     */
+    public ExcelDataListener(BaseService<E> baseService) {
+        this.baseService = baseService;
+    }
+
+    /**
+     * 每条数据解析完,都会调用此方法
+     */
+    @Override
+    public void invoke(T data, AnalysisContext context) {
+        LOGGER.info("解析到一条数据:{}", JSONObject.toJSONString(data));
+
+        E entity = ConvertKit.sourceToTarget(data, baseService.currentModelClass());
+        list.add(entity);
+
+        // 达到BATCH_COUNT了,需要去存储一次数据库,防止数据几万条数据在内存,容易OOM
+        if (list.size() >= BATCH_COUNT) {
+            saveData();
+            // 存储完成清理 list
+            list.clear();
+        }
+    }
+    /**
+     * 所有数据解析完成了 都会来调用
+     */
+    @Override
+    public void doAfterAllAnalysed(AnalysisContext context) {
+        // 这里也要保存数据,确保最后遗留的数据也存储到数据库
+        saveData();
+        LOGGER.info("所有数据解析完成!");
+    }
+
+    /**
+     * 加上存储数据库
+     */
+    private void saveData() {
+        LOGGER.info("{}条数据,开始存储数据库!", list.size());
+        //直接新增,不做重复判断
+        baseService.insertBatch(list);
+        LOGGER.info("存储数据库成功!");
+    }
+}

+ 68 - 0
logic/excel-logic/src/main/java/com/iohao/mmo/excel/service/BaseService.java

@@ -0,0 +1,68 @@
+package com.iohao.mmo.excel.service;
+
+import java.io.Serializable;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 基础服务接口
+ *
+ * @author Toby javatangbin@163.com
+ */
+public interface BaseService<T> {
+    Class<T> currentModelClass();
+    /**
+     * <p>
+     * 根据 参数 查询列表
+     * </p>
+     *
+     * @param param 参数集合
+     */
+    List<T> list(Map<String,Object> param, Class<T> entityClass);
+
+    /**
+     * <p>
+     * 根据 ID 查询
+     * </p>
+     *
+     * @param id 主键ID
+     */
+    T selectById(Serializable id,Class<T> entityClass);
+
+    /**
+     * <p>
+     * 插入一条记录(选择字段,策略插入)
+     * </p>
+     *
+     * @param entity 实体对象
+     */
+    void insert(T entity);
+
+    /**
+     * <p>
+     * 插入(批量)
+     * </p>
+     *
+     * @param entityList 实体对象集合
+     */
+    void insertBatch(Collection<T> entityList);
+
+    /**
+     * <p>
+     * 根据 ID 选择修改
+     * </p>
+     *
+     * @param entity 实体对象
+     */
+    void update(T entity);
+
+    /**
+     * <p>
+     * 根据 ID 批量删除
+     * </p>
+     *
+     * @param idList 主键ID
+     */
+    void deleteBatch(List<Serializable> idList,Class<T> entityClass);
+}

+ 21 - 0
logic/excel-logic/src/main/java/com/iohao/mmo/excel/service/DemoExcelService.java

@@ -0,0 +1,21 @@
+package com.iohao.mmo.excel.service;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.iohao.mmo.excel.entity.DemoExcel;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.List;
+
+
+/**
+ * Excel示例
+ *
+ * @author 唐斌
+ * @date 2023-08-30
+ * @description: Excel示例
+ */
+public interface DemoExcelService extends BaseService<DemoExcel>{
+
+    @Transactional(rollbackFor = Exception.class)
+    void updateBatch(List<DemoExcel> entityList) throws JsonProcessingException;
+}

+ 60 - 0
logic/excel-logic/src/main/java/com/iohao/mmo/excel/service/impl/BaseServiceImpl.java

@@ -0,0 +1,60 @@
+package com.iohao.mmo.excel.service.impl;
+
+import com.iohao.mmo.excel.kit.GenericsKit;
+import com.iohao.mmo.excel.service.BaseService;
+import lombok.AllArgsConstructor;
+import org.springframework.data.mongodb.core.MongoTemplate;
+import org.springframework.data.mongodb.core.query.Criteria;
+import org.springframework.data.mongodb.core.query.Query;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import java.io.Serializable;
+import java.util.*;
+
+/**
+ * 基础服务类
+ *
+ * @author Toby javatangbin@163.com
+ */
+@Service
+@AllArgsConstructor
+public abstract class BaseServiceImpl<T> implements BaseService<T> {
+    final MongoTemplate mongoTemplate;
+    @Override
+    public Class<T> currentModelClass() {
+        return (Class<T>) GenericsKit.getSuperClassGenricType(getClass(), 0);
+    }
+    @Override
+    public List<T> list(Map<String,Object> param,Class<T> entityClass) {
+        Query query = new Query();
+        return mongoTemplate.find(query, entityClass);
+    }
+
+    @Override
+    public T selectById(Serializable id,Class<T> entityClass) {
+        return mongoTemplate.findById(id, entityClass);
+    }
+
+    @Override
+    public void insert(T entity) {
+        mongoTemplate.insert(entity);
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void insertBatch(Collection<T> entityList) {
+        mongoTemplate.insertAll(entityList);
+    }
+
+    @Override
+    public void update(T entity) {
+        mongoTemplate.save(entity);
+    }
+
+    @Override
+    public void deleteBatch(List<Serializable> idList,Class<T> entityClass) {
+        Query query = new Query(new Criteria("id").in(idList));
+        mongoTemplate.remove(query, entityClass);
+    }
+
+}

+ 60 - 0
logic/excel-logic/src/main/java/com/iohao/mmo/excel/service/impl/DemoExcelServiceImpl.java

@@ -0,0 +1,60 @@
+package com.iohao.mmo.excel.service.impl;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.iohao.mmo.excel.entity.DemoExcel;
+import com.iohao.mmo.excel.service.DemoExcelService;
+import com.mongodb.bulk.BulkWriteResult;
+import org.apache.commons.collections4.CollectionUtils;
+import org.springframework.data.mongodb.core.BulkOperations;
+import org.springframework.data.mongodb.core.MongoTemplate;
+import org.springframework.data.mongodb.core.query.Criteria;
+import org.springframework.data.mongodb.core.query.Query;
+import org.springframework.data.mongodb.core.query.Update;
+import org.springframework.data.util.Pair;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Excel示例
+ *
+ * @author 唐斌
+ * @date 2023-08-30
+ * @description: Excel示例
+ */
+@Service
+public class DemoExcelServiceImpl extends BaseServiceImpl<DemoExcel> implements DemoExcelService {
+    final MongoTemplate mongoTemplate;
+
+    public DemoExcelServiceImpl(MongoTemplate mongoTemplate) {
+        super(mongoTemplate);
+        this.mongoTemplate = mongoTemplate;
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void updateBatch(List<DemoExcel> entityList) throws JsonProcessingException {
+        if (CollectionUtils.isEmpty(entityList)) {
+            return;
+        }
+        List<Pair<Query, Update>> updateList = new ArrayList<>(entityList.size());
+        BulkOperations operations = mongoTemplate.bulkOps(BulkOperations.BulkMode.UNORDERED, "demoExcel");
+        entityList.forEach(data -> {
+            //以code为标识判断新增或者修改
+            Query query = new Query(new Criteria("code").is(data.getCode()));
+            Update update = new Update();
+            //如果userId是主键,必须使用setOnInsert()
+            update.set("name",data.getName());
+            update.set("remark",data.getRemark());
+            update.set("status",data.getStatus());
+            update.set("registerDate",data.getRegisterDate());
+
+            Pair<Query, Update> updatePair = Pair.of(query, update);
+            updateList.add(updatePair);
+        });
+        operations.upsert(updateList);
+        BulkWriteResult result = operations.execute();
+        System.out.println(result.getUpserts());
+    }
+}

+ 0 - 5
one-application/src/main/java/com/iohao/mmo/OneApplication.java

@@ -18,20 +18,15 @@
  */
 package com.iohao.mmo;
 
-import com.iohao.game.action.skeleton.core.IoGameGlobalSetting;
-import com.iohao.game.action.skeleton.core.codec.JsonDataCodec;
 import com.iohao.game.action.skeleton.ext.spring.ActionFactoryBeanForSpring;
 import com.iohao.game.bolt.broker.client.AbstractBrokerClientStartup;
-import com.iohao.game.bolt.broker.core.common.IoGameGlobalConfig;
 import com.iohao.game.bolt.broker.server.BrokerServer;
-import com.iohao.game.common.kit.system.OsInfo;
 import com.iohao.game.external.core.ExternalServer;
 import com.iohao.game.external.core.config.ExternalGlobalConfig;
 import com.iohao.game.external.core.netty.simple.NettyRunOne;
 import com.iohao.mmo.bag.BagLogicServer;
 import com.iohao.mmo.broker.MyBrokerServer;
 import com.iohao.mmo.common.config.MyGlobalSetting;
-import com.iohao.mmo.common.logic.server.MyUserProcessorExecutorStrategy;
 import com.iohao.mmo.equip.EquipLogicServer;
 import com.iohao.mmo.external.MyExternalServer;
 import com.iohao.mmo.level.LevelLogicServer;

+ 5 - 0
pom.xml

@@ -45,6 +45,7 @@
         <module>provide/mail-provide</module>
         <module>logic/equip-logic</module>
         <module>provide/equip-provide</module>
+        <module>logic/excel-logic</module>
 
     </modules>
 
@@ -81,6 +82,10 @@
         <javafaker.version>1.0.2</javafaker.version>
         <!-- https://mvnrepository.com/artifact/com.alibaba.fastjson2/fastjson2 -->
         <fastjson2.version>2.0.39</fastjson2.version>
+        <!-- easyexcel -->
+        <easyexcel.version>3.3.2</easyexcel.version>
+        <!-- springdoc -->
+        <springdoc.version>2.1.0</springdoc.version>
     </properties>
 
     <dependencies>