Jelajahi Sumber

批量上传

wangqifan 3 tahun lalu
induk
melakukan
3e0ea57e88

+ 11 - 0
src/main/java/com/izouma/nineth/dto/excel/AirDropExcelDTO.java

@@ -0,0 +1,11 @@
+package com.izouma.nineth.dto.excel;
+
+import com.alibaba.excel.annotation.ExcelProperty;
+import com.alibaba.excel.metadata.BaseRowModel;
+import lombok.Data;
+
+@Data
+public class AirDropExcelDTO extends BaseRowModel {
+    @ExcelProperty(value = "用户id", index = 0)
+    private Long userId;
+}

+ 2 - 0
src/main/java/com/izouma/nineth/repo/AssetRepo.java

@@ -80,4 +80,6 @@ public interface AssetRepo extends JpaRepository<Asset, Long>, JpaSpecificationE
     List<Asset> findByFromAssetId(Long id);
     List<Asset> findByFromAssetId(Long id);
 
 
     List<Asset> findAllByCollectionIdAndUserIdAndStatus(Long collectionId, Long userId, AssetStatus status);
     List<Asset> findAllByCollectionIdAndUserIdAndStatus(Long collectionId, Long userId, AssetStatus status);
+    List<Long> findAllByUserIdInAndCollectionId(List<Long> ids, Long collectionId);
+
 }
 }

+ 75 - 3
src/main/java/com/izouma/nineth/service/AirDropService.java

@@ -2,11 +2,13 @@ package com.izouma.nineth.service;
 
 
 import com.izouma.nineth.domain.*;
 import com.izouma.nineth.domain.*;
 import com.izouma.nineth.dto.PageQuery;
 import com.izouma.nineth.dto.PageQuery;
+import com.izouma.nineth.dto.excel.AirDropExcelDTO;
 import com.izouma.nineth.enums.AirDropType;
 import com.izouma.nineth.enums.AirDropType;
 import com.izouma.nineth.enums.CollectionType;
 import com.izouma.nineth.enums.CollectionType;
 import com.izouma.nineth.exception.BusinessException;
 import com.izouma.nineth.exception.BusinessException;
 import com.izouma.nineth.repo.*;
 import com.izouma.nineth.repo.*;
 import com.izouma.nineth.utils.JpaUtils;
 import com.izouma.nineth.utils.JpaUtils;
+import com.izouma.nineth.utils.excel2.excel.ExcelUtils;
 import lombok.AllArgsConstructor;
 import lombok.AllArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.BeanUtils;
@@ -14,7 +16,13 @@ import org.springframework.data.domain.Page;
 import org.springframework.stereotype.Service;
 import org.springframework.stereotype.Service;
 
 
 import javax.transaction.Transactional;
 import javax.transaction.Transactional;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
 import java.util.List;
 import java.util.List;
+import java.util.stream.Collector;
+import java.util.stream.Collectors;
 
 
 @Service
 @Service
 @AllArgsConstructor
 @AllArgsConstructor
@@ -28,9 +36,11 @@ public class AirDropService {
     private UserRepo          userRepo;
     private UserRepo          userRepo;
     private AssetService      assetService;
     private AssetService      assetService;
     private CollectionService collectionService;
     private CollectionService collectionService;
+    private AssetRepo         assetRepo;
 
 
     public Page<AirDrop> all(PageQuery pageQuery) {
     public Page<AirDrop> all(PageQuery pageQuery) {
-        return airDropRepo.findAll(JpaUtils.toSpecification(pageQuery, AirDrop.class), JpaUtils.toPageRequest(pageQuery));
+        return airDropRepo
+                .findAll(JpaUtils.toSpecification(pageQuery, AirDrop.class), JpaUtils.toPageRequest(pageQuery));
     }
     }
 
 
     @Transactional
     @Transactional
@@ -56,9 +66,11 @@ public class AirDropService {
                 try {
                 try {
                     if (collection.getType() == CollectionType.BLIND_BOX) {
                     if (collection.getType() == CollectionType.BLIND_BOX) {
                         BlindBoxItem winItem = collectionService.draw(collection.getId());
                         BlindBoxItem winItem = collectionService.draw(collection.getId());
-                        assetService.createAsset(winItem, user, null, null, "空投", collectionService.getNextNumber(winItem.getCollectionId()));
+                        assetService.createAsset(winItem, user, null, null, "空投", collectionService
+                                .getNextNumber(winItem.getCollectionId()));
                     } else {
                     } else {
-                        assetService.createAsset(collection, user, null, null, "空投", collectionService.getNextNumber(collection));
+                        assetService.createAsset(collection, user, null, null, "空投", collectionService
+                                .getNextNumber(collection));
                     }
                     }
                     collection.setStock(collection.getStock() - 1);
                     collection.setStock(collection.getStock() - 1);
                     collection.setSale(collection.getSale() + 1);
                     collection.setSale(collection.getSale() + 1);
@@ -70,4 +82,64 @@ public class AirDropService {
         }
         }
         return airDropRepo.save(record);
         return airDropRepo.save(record);
     }
     }
+
+    @Transactional
+    public void upload(InputStream is) throws IOException {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+
+        byte[] buffer = new byte[1024];
+        int len;
+        while ((len = is.read(buffer)) > -1) {
+            baos.write(buffer, 0, len);
+        }
+        baos.flush();
+
+        InputStream customerInfoStream = new ByteArrayInputStream(baos.toByteArray());
+        List<AirDropExcelDTO> userIds =
+                ExcelUtils.readExcel(customerInfoStream, AirDropExcelDTO.class, 1, 1);
+        List<Long> result = userIds.stream().map(AirDropExcelDTO::getUserId).collect(Collectors.toList());
+        System.out.println(result);
+        create2(result);
+    }
+
+    public AirDrop create2(List<Long> userIds) {
+        AirDrop record = new AirDrop();
+        record.setType(AirDropType.asset);
+        record.setCollectionId(1917664L);
+        record.setName("批量空投");
+        record.setProjectId(0);
+        record.setRemark("批量空投");
+        record.setUserIds(userIds);
+
+        Collection collection = collectionRepo.findById(record.getCollectionId())
+                .orElseThrow(new BusinessException("藏品不存在"));
+        if (collection.getStock() < record.getUserIds().size()) {
+            throw new BusinessException("藏品库存不足");
+        }
+        List<User> users = userRepo.findByIdInAndDelFalse(record.getUserIds());
+        for (User user : users) {
+            try {
+                if (collection.getType() == CollectionType.BLIND_BOX) {
+                    BlindBoxItem winItem = collectionService.draw(collection.getId());
+                    assetService.createAsset(winItem, user, null, null, "空投", collectionService
+                            .getNextNumber(winItem.getCollectionId()));
+                } else {
+                    assetService.createAsset(collection, user, null, null, "空投", collectionService
+                            .getNextNumber(collection));
+                }
+                collection.setStock(collection.getStock() - 1);
+                collection.setSale(collection.getSale() + 1);
+                collectionRepo.save(collection);
+            } catch (Exception e) {
+                log.error("空投出错", e);
+            }
+        }
+
+        return airDropRepo.save(record);
+    }
+
+    public void checkAirDrop(List<Long> userIds) {
+        List<Long> airDropUserIds = assetRepo.findAllByUserIdInAndCollectionId(userIds, 1917664L);
+
+    }
 }
 }

+ 2 - 1
src/main/java/com/izouma/nineth/service/IdentityAuthService.java

@@ -34,7 +34,8 @@ public class IdentityAuthService {
     private CollectionRepo   collectionRepo;
     private CollectionRepo   collectionRepo;
 
 
     public Page<IdentityAuth> all(PageQuery pageQuery) {
     public Page<IdentityAuth> all(PageQuery pageQuery) {
-        return identityAuthRepo.findAll(JpaUtils.toSpecification(pageQuery, IdentityAuth.class), JpaUtils.toPageRequest(pageQuery));
+        return identityAuthRepo
+                .findAll(JpaUtils.toSpecification(pageQuery, IdentityAuth.class), JpaUtils.toPageRequest(pageQuery));
     }
     }
 
 
     public void apply(IdentityAuth identityAuth) {
     public void apply(IdentityAuth identityAuth) {

+ 33 - 0
src/main/java/com/izouma/nineth/utils/excel2/excel/BooleanConverter.java

@@ -0,0 +1,33 @@
+package com.izouma.nineth.utils.excel2.excel;
+
+import com.alibaba.excel.converters.Converter;
+import com.alibaba.excel.enums.CellDataTypeEnum;
+import com.alibaba.excel.metadata.CellData;
+import com.alibaba.excel.metadata.GlobalConfiguration;
+import com.alibaba.excel.metadata.property.ExcelContentProperty;
+
+public class BooleanConverter implements Converter<Boolean> {
+    @Override
+    public Class<?> supportJavaTypeKey() {
+        return Boolean.class;
+    }
+
+    @Override
+    public CellDataTypeEnum supportExcelTypeKey() {
+        return CellDataTypeEnum.STRING;
+    }
+
+    @Override
+    public Boolean convertToJavaData(CellData cellData, ExcelContentProperty excelContentProperty, GlobalConfiguration globalConfiguration) throws Exception {
+        return Boolean.valueOf(cellData.getStringValue());
+    }
+
+    @Override
+    public CellData<?> convertToExcelData(Boolean booleanValue, ExcelContentProperty excelContentProperty, GlobalConfiguration globalConfiguration) throws Exception {
+        String str = "";
+        if (booleanValue != null) {
+            str = booleanValue ? "是" : "否";
+        }
+        return new CellData<>(str);
+    }
+}

+ 28 - 0
src/main/java/com/izouma/nineth/utils/excel2/excel/ExcelListener.java

@@ -0,0 +1,28 @@
+package com.izouma.nineth.utils.excel2.excel;
+
+import com.alibaba.excel.context.AnalysisContext;
+import com.alibaba.excel.event.AnalysisEventListener;
+import com.alibaba.excel.metadata.BaseRowModel;
+import lombok.extern.slf4j.Slf4j;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@Slf4j
+public class ExcelListener<T extends BaseRowModel> extends AnalysisEventListener<T> {
+    private final List<T> rows = new ArrayList<>();
+
+    @Override
+    public void invoke(T object, AnalysisContext context) {
+        rows.add(object);
+    }
+
+    @Override
+    public void doAfterAllAnalysed(AnalysisContext context) {
+        log.info("read {} rows %n", rows.size());
+    }
+
+    public List<T> getRows() {
+        return rows;
+    }
+}

+ 212 - 0
src/main/java/com/izouma/nineth/utils/excel2/excel/ExcelUtils.java

@@ -0,0 +1,212 @@
+package com.izouma.nineth.utils.excel2.excel;
+
+import com.alibaba.excel.EasyExcel;
+import com.alibaba.excel.ExcelReader;
+import com.alibaba.excel.ExcelWriter;
+import com.alibaba.excel.metadata.BaseRowModel;
+import com.alibaba.excel.metadata.Sheet;
+import com.alibaba.excel.support.ExcelTypeEnum;
+import com.alibaba.excel.write.metadata.style.WriteCellStyle;
+import com.alibaba.excel.write.metadata.style.WriteFont;
+import com.alibaba.excel.write.style.HorizontalCellStyleStrategy;
+import com.alibaba.excel.write.style.row.SimpleRowHeightStyleStrategy;
+import io.swagger.annotations.ApiModel;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.poi.poifs.filesystem.FileMagic;
+import org.apache.poi.ss.usermodel.*;
+
+import javax.servlet.http.HttpServletResponse;
+import java.io.*;
+import java.net.URLEncoder;
+import java.nio.charset.StandardCharsets;
+import java.util.List;
+
+@Slf4j
+public class ExcelUtils<T> {
+    public static <T> void export(HttpServletResponse response, List<T> data) throws IOException {
+        String fileName = "data.xlsx";
+        if (data != null && !data.isEmpty()) {
+            fileName = data.get(0).getClass().getSimpleName() + ".xlsx";
+            ApiModel apiModel = data.get(0).getClass().getAnnotation(ApiModel.class);
+            if (apiModel != null) {
+                if (StringUtils.isNotEmpty(apiModel.value())) {
+                    fileName = apiModel.value() + ".xlsx";
+                }
+            }
+        }
+        response.setContentType("application/vnd.ms-excel");
+        response.setCharacterEncoding("utf-8");
+        response.setHeader("Content-Disposition",
+                "attachment;filename=" + URLEncoder.encode(fileName, StandardCharsets.UTF_8.name()));
+        response.setHeader("File-Name", URLEncoder.encode(fileName, StandardCharsets.UTF_8.name()));
+
+        EasyExcel.write(response.getOutputStream(), data.get(0).getClass()).sheet("sheet")
+                .registerWriteHandler(customStyle())
+                .registerWriteHandler(new SimpleRowHeightStyleStrategy((short) 20, (short) 20))
+                .registerConverter(new LocalDateConverter())
+                .registerConverter(new LocalDateTimeConverter())
+                .registerConverter(new YearMonthConverter())
+                .registerConverter(new BooleanConverter())
+                .doWrite(data);
+    }
+
+    public static <T> void export(HttpServletResponse response, List<T> data, Class<?> head) throws IOException {
+        String fileName = "data.xlsx";
+        if (head != null) {
+            fileName = head.getSimpleName() + ".xlsx";
+
+            ApiModel apiModel = head.getAnnotation(ApiModel.class);
+            if (apiModel != null) {
+                if (StringUtils.isNotEmpty(apiModel.value())) {
+                    fileName = apiModel.value() + ".xlsx";
+                }
+            }
+
+        }
+        response.setContentType("application/vnd.ms-excel");
+        response.setCharacterEncoding("utf-8");
+        response.setHeader("Content-Disposition",
+                "attachment;filename=" + URLEncoder.encode(fileName, StandardCharsets.UTF_8.name()));
+        response.setHeader("File-Name", URLEncoder.encode(fileName, StandardCharsets.UTF_8.name()));
+        EasyExcel.write(response.getOutputStream(), head).sheet("sheet")
+                .registerWriteHandler(customStyle())
+                .registerWriteHandler(new SimpleRowHeightStyleStrategy((short) 20, (short) 20))
+                .registerConverter(new LocalDateConverter())
+                .registerConverter(new LocalDateTimeConverter())
+                .registerConverter(new YearMonthConverter())
+                .registerConverter(new BooleanConverter())
+                .doWrite(data);
+    }
+
+
+    /**
+     * 从Excel中读取文件,读取的文件是一个DTO类,该类必须继承BaseRowModel
+     * 具体实例参考 : MemberMarketDto.java
+     * 参考:https://github.com/alibaba/easyexcel
+     * 字符流必须支持标记,FileInputStream 不支持标记,可以使用BufferedInputStream 代替
+     * BufferedInputStream bis = new BufferedInputStream(new FileInputStream(...));
+     */
+    public static <T extends BaseRowModel> List<T> readExcel(final InputStream inputStream, final Class<? extends BaseRowModel> clazz, int sheetNo, int headLineMun) {
+        if (null == inputStream) {
+            throw new NullPointerException("the inputStream is null!");
+        }
+        ExcelListener<T> listener = new ExcelListener<>();
+        // 这里因为EasyExcel-1.1.1版本的bug,所以需要选用下面这个标记已经过期的版本
+        ExcelReader reader = new ExcelReader(inputStream, valueOf(inputStream), null, listener);
+        reader.read(new Sheet(sheetNo, headLineMun, clazz));
+
+        return listener.getRows();
+    }
+
+
+    public static void writeExcel(final File file, List<? extends BaseRowModel> list) {
+        try (OutputStream out = new FileOutputStream(file)) {
+            ExcelWriter writer = new ExcelWriter(out, ExcelTypeEnum.XLSX);
+            //写第一个sheet,  有模型映射关系
+            Class<? extends BaseRowModel> t = list.get(0).getClass();
+            Sheet sheet = new Sheet(1, 0, t);
+            writer.write(list, sheet);
+            writer.finish();
+        } catch (IOException e) {
+            log.warn("fail to write to excel file: file[{}]", file.getName(), e);
+        }
+    }
+
+
+    /**
+     * 根据输入流,判断为xls还是xlsx,该方法原本存在于easyexcel 1.1.0 的ExcelTypeEnum中。
+     */
+    public static ExcelTypeEnum valueOf(InputStream inputStream) {
+        try {
+            FileMagic fileMagic = FileMagic.valueOf(inputStream);
+            if (FileMagic.OLE2.equals(fileMagic)) {
+                return ExcelTypeEnum.XLS;
+            }
+            if (FileMagic.OOXML.equals(fileMagic)) {
+                return ExcelTypeEnum.XLSX;
+            }
+            throw new IllegalArgumentException("excelTypeEnum can not null");
+
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    public static HorizontalCellStyleStrategy customStyle() {
+        // 头的策略
+        WriteCellStyle headWriteCellStyle = new WriteCellStyle();
+        WriteFont headWriteFont = new WriteFont();
+        headWriteFont.setFontName("微软雅黑");
+        headWriteFont.setBold(false);
+        headWriteFont.setFontHeightInPoints((short) 12);
+        headWriteCellStyle.setWriteFont(headWriteFont);
+        // 内容的策略
+        WriteCellStyle contentWriteCellStyle = new WriteCellStyle();
+        WriteFont contentWriteFont = new WriteFont();
+        contentWriteFont.setFontName("微软雅黑");
+        // 字体大小
+        contentWriteFont.setFontHeightInPoints((short) 12);
+        contentWriteCellStyle.setWriteFont(contentWriteFont);
+        // 这个策略是 头是头的样式 内容是内容的样式 其他的策略可以自己实现
+        return new HorizontalCellStyleStrategy(headWriteCellStyle, contentWriteCellStyle);
+    }
+
+    public static CellStyle contentCellStyle(Workbook workbook) {
+        // 正文样式
+        Font cellStyleFont = workbook.createFont();
+        cellStyleFont.setFontHeightInPoints((short) 12);
+        cellStyleFont.setColor(IndexedColors.BLACK.getIndex());
+        cellStyleFont.setFontName("微软雅黑");
+
+        CellStyle cellStyle = workbook.createCellStyle();
+        cellStyle.setAlignment(HorizontalAlignment.CENTER); // 居中设置
+        cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
+        cellStyle.setWrapText(true);
+        cellStyle.setBorderRight(BorderStyle.THIN);
+        cellStyle.setBorderLeft(BorderStyle.THIN);
+        cellStyle.setBorderTop(BorderStyle.THIN);
+        cellStyle.setBorderBottom(BorderStyle.THIN);
+        cellStyle.setFont(cellStyleFont);
+        return cellStyle;
+    }
+
+    public static CellStyle headerCellStyle(Workbook workbook) {
+        // 文件头样式
+        CellStyle headerStyle = workbook.createCellStyle();
+        headerStyle.setAlignment(HorizontalAlignment.CENTER);
+        headerStyle.setVerticalAlignment(VerticalAlignment.CENTER);
+        headerStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex()); // 前景色
+        headerStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND); // 颜色填充方式
+        headerStyle.setWrapText(true);
+        headerStyle.setBorderRight(BorderStyle.THIN); // 设置边界
+        headerStyle.setRightBorderColor(IndexedColors.BLACK.getIndex());
+        headerStyle.setBorderLeft(BorderStyle.THIN);
+        headerStyle.setLeftBorderColor(IndexedColors.BLACK.getIndex());
+        headerStyle.setBorderTop(BorderStyle.THIN);
+        headerStyle.setTopBorderColor(IndexedColors.BLACK.getIndex());
+        headerStyle.setBorderBottom(BorderStyle.THIN);
+        headerStyle.setBottomBorderColor(IndexedColors.BLACK.getIndex());
+        Font headerFont = workbook.createFont();
+        headerFont.setFontHeightInPoints((short) 12);
+        headerFont.setColor(IndexedColors.BLACK.getIndex());
+        headerFont.setFontName("微软雅黑");
+        headerStyle.setFont(headerFont);
+        return headerStyle;
+    }
+
+    public static CellStyle titleCellStyle(Workbook workbook) {
+        // 文件头样式
+        CellStyle titleStyle = workbook.createCellStyle();
+        titleStyle.setAlignment(HorizontalAlignment.CENTER); // 水平对齐
+        titleStyle.setVerticalAlignment(VerticalAlignment.CENTER); // 垂直对齐
+        titleStyle.setLocked(true); // 样式锁定
+        titleStyle.setFillForegroundColor(IndexedColors.LIGHT_YELLOW.getIndex());
+        Font titleFont = workbook.createFont();
+        titleFont.setFontHeightInPoints((short) 16);
+        titleFont.setBold(true);
+        titleFont.setFontName("微软雅黑");
+        titleStyle.setFont(titleFont);
+        return titleStyle;
+    }
+}

+ 32 - 0
src/main/java/com/izouma/nineth/utils/excel2/excel/LocalDateConverter.java

@@ -0,0 +1,32 @@
+package com.izouma.nineth.utils.excel2.excel;
+
+import com.alibaba.excel.converters.Converter;
+import com.alibaba.excel.enums.CellDataTypeEnum;
+import com.alibaba.excel.metadata.CellData;
+import com.alibaba.excel.metadata.GlobalConfiguration;
+import com.alibaba.excel.metadata.property.ExcelContentProperty;
+
+import java.time.LocalDate;
+import java.time.format.DateTimeFormatter;
+
+public class LocalDateConverter implements Converter<LocalDate> {
+    @Override
+    public Class<?> supportJavaTypeKey() {
+        return LocalDate.class;
+    }
+
+    @Override
+    public CellDataTypeEnum supportExcelTypeKey() {
+        return CellDataTypeEnum.STRING;
+    }
+
+    @Override
+    public LocalDate convertToJavaData(CellData cellData, ExcelContentProperty excelContentProperty, GlobalConfiguration globalConfiguration) throws Exception {
+        return LocalDate.parse(cellData.getStringValue(), DateTimeFormatter.ofPattern("yyyy-MM-dd"));
+    }
+
+    @Override
+    public CellData<?> convertToExcelData(LocalDate localDate, ExcelContentProperty excelContentProperty, GlobalConfiguration globalConfiguration) throws Exception {
+        return new CellData<>(DateTimeFormatter.ofPattern("yyyy-MM-dd").format(localDate));
+    }
+}

+ 32 - 0
src/main/java/com/izouma/nineth/utils/excel2/excel/LocalDateTimeConverter.java

@@ -0,0 +1,32 @@
+package com.izouma.nineth.utils.excel2.excel;
+
+import com.alibaba.excel.converters.Converter;
+import com.alibaba.excel.enums.CellDataTypeEnum;
+import com.alibaba.excel.metadata.CellData;
+import com.alibaba.excel.metadata.GlobalConfiguration;
+import com.alibaba.excel.metadata.property.ExcelContentProperty;
+
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+
+public class LocalDateTimeConverter implements Converter<LocalDateTime> {
+    @Override
+    public Class<?> supportJavaTypeKey() {
+        return LocalDateTime.class;
+    }
+
+    @Override
+    public CellDataTypeEnum supportExcelTypeKey() {
+        return CellDataTypeEnum.STRING;
+    }
+
+    @Override
+    public LocalDateTime convertToJavaData(CellData cellData, ExcelContentProperty excelContentProperty, GlobalConfiguration globalConfiguration) throws Exception {
+        return LocalDateTime.parse(cellData.getStringValue(), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
+    }
+
+    @Override
+    public CellData<?> convertToExcelData(LocalDateTime localDateTime, ExcelContentProperty excelContentProperty, GlobalConfiguration globalConfiguration) throws Exception {
+        return new CellData<>(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").format(localDateTime));
+    }
+}

+ 32 - 0
src/main/java/com/izouma/nineth/utils/excel2/excel/YearMonthConverter.java

@@ -0,0 +1,32 @@
+package com.izouma.nineth.utils.excel2.excel;
+
+import com.alibaba.excel.converters.Converter;
+import com.alibaba.excel.enums.CellDataTypeEnum;
+import com.alibaba.excel.metadata.CellData;
+import com.alibaba.excel.metadata.GlobalConfiguration;
+import com.alibaba.excel.metadata.property.ExcelContentProperty;
+
+import java.time.YearMonth;
+import java.time.format.DateTimeFormatter;
+
+public class YearMonthConverter implements Converter<YearMonth> {
+    @Override
+    public Class<?> supportJavaTypeKey() {
+        return YearMonth.class;
+    }
+
+    @Override
+    public CellDataTypeEnum supportExcelTypeKey() {
+        return CellDataTypeEnum.STRING;
+    }
+
+    @Override
+    public YearMonth convertToJavaData(CellData cellData, ExcelContentProperty excelContentProperty, GlobalConfiguration globalConfiguration) {
+        return YearMonth.parse(cellData.getStringValue(), DateTimeFormatter.ofPattern("yyyy-MM"));
+    }
+
+    @Override
+    public CellData<?> convertToExcelData(YearMonth yearMonth, ExcelContentProperty excelContentProperty, GlobalConfiguration globalConfiguration) {
+        return new CellData<>(DateTimeFormatter.ofPattern("yyyy-MM").format(yearMonth));
+    }
+}

+ 50 - 0
src/main/java/com/izouma/nineth/utils/excel2/excel/handler/CustomCellWriteHandler.java

@@ -0,0 +1,50 @@
+package com.izouma.nineth.utils.excel2.excel.handler;
+
+import com.alibaba.excel.metadata.CellData;
+import com.alibaba.excel.metadata.Head;
+import com.alibaba.excel.write.handler.CellWriteHandler;
+import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
+import com.alibaba.excel.write.metadata.holder.WriteTableHolder;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.poi.common.usermodel.HyperlinkType;
+import org.apache.poi.ss.usermodel.Cell;
+import org.apache.poi.ss.usermodel.CreationHelper;
+import org.apache.poi.ss.usermodel.Hyperlink;
+import org.apache.poi.ss.usermodel.Row;
+
+import java.util.List;
+
+@Slf4j
+public class CustomCellWriteHandler implements CellWriteHandler {
+
+    @Override
+    public void beforeCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row,
+                                 Head head, Integer columnIndex, Integer relativeRowIndex, Boolean isHead) {
+
+    }
+
+    @Override
+    public void afterCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Cell cell,
+                                Head head, Integer relativeRowIndex, Boolean isHead) {
+
+    }
+
+    @Override
+    public void afterCellDataConverted(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder,
+                                       CellData cellData, Cell cell, Head head, Integer integer, Boolean aBoolean) {
+
+    }
+
+    @Override
+    public void afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder,
+                                 List<CellData> cellDataList, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) {
+        // 这里可以对cell进行任何操作
+        log.info("第{}行,第{}列写入完成。", cell.getRowIndex(), cell.getColumnIndex());
+        if (isHead && cell.getColumnIndex() == 0) {
+            CreationHelper createHelper = writeSheetHolder.getSheet().getWorkbook().getCreationHelper();
+            Hyperlink hyperlink = createHelper.createHyperlink(HyperlinkType.URL);
+            hyperlink.setAddress("https://github.com/alibaba/easyexcel");
+            cell.setHyperlink(hyperlink);
+        }
+    }
+}

+ 26 - 0
src/main/java/com/izouma/nineth/utils/excel2/excel/handler/CustomSheetWriteHandler.java

@@ -0,0 +1,26 @@
+package com.izouma.nineth.utils.excel2.excel.handler;
+
+import com.alibaba.excel.write.handler.SheetWriteHandler;
+import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
+import com.alibaba.excel.write.metadata.holder.WriteWorkbookHolder;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.poi.ss.usermodel.Cell;
+import org.apache.poi.ss.usermodel.Row;
+
+@Slf4j
+public class CustomSheetWriteHandler implements SheetWriteHandler {
+
+    @Override
+    public void beforeSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) {
+
+    }
+
+    @Override
+    public void afterSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) {
+        log.info("{} Sheet写入成功。", writeSheetHolder.getSheetName());
+
+        Row row = writeSheetHolder.getSheet().createRow(16);
+        Cell cell = row.createCell(1);
+        cell.setCellValue("123321");
+    }
+}

+ 17 - 1
src/main/java/com/izouma/nineth/web/AirDropController.java

@@ -7,20 +7,24 @@ import com.izouma.nineth.repo.AirDropRepo;
 import com.izouma.nineth.service.AirDropService;
 import com.izouma.nineth.service.AirDropService;
 import com.izouma.nineth.utils.excel.ExcelUtils;
 import com.izouma.nineth.utils.excel.ExcelUtils;
 import lombok.AllArgsConstructor;
 import lombok.AllArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
 import org.springframework.data.domain.Page;
 import org.springframework.data.domain.Page;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.web.bind.annotation.*;
 import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
 
 
 import javax.servlet.http.HttpServletResponse;
 import javax.servlet.http.HttpServletResponse;
 import java.io.IOException;
 import java.io.IOException;
+import java.io.InputStream;
 import java.util.List;
 import java.util.List;
 
 
+@Slf4j
 @RestController
 @RestController
 @RequestMapping("/airDrop")
 @RequestMapping("/airDrop")
 @AllArgsConstructor
 @AllArgsConstructor
 public class AirDropController extends BaseController {
 public class AirDropController extends BaseController {
     private AirDropService airDropService;
     private AirDropService airDropService;
-    private AirDropRepo airDropRepo;
+    private AirDropRepo    airDropRepo;
 
 
     @PreAuthorize("hasRole('ADMIN')")
     @PreAuthorize("hasRole('ADMIN')")
     @PostMapping("/save")
     @PostMapping("/save")
@@ -28,6 +32,18 @@ public class AirDropController extends BaseController {
         return airDropService.create(record);
         return airDropService.create(record);
     }
     }
 
 
+    @PostMapping("/upload")
+    public void uploadFile(@RequestParam("file") MultipartFile file) {
+        InputStream is;
+        try {
+            is = file.getInputStream();
+            airDropService.upload(is);
+        } catch (IOException e) {
+            log.error("上传失败", e);
+            throw new BusinessException("上传失败", e.getMessage());
+        }
+    }
+
 
 
     //@PreAuthorize("hasRole('ADMIN')")
     //@PreAuthorize("hasRole('ADMIN')")
     @PostMapping("/all")
     @PostMapping("/all")

+ 26 - 1
src/main/vue/src/views/AirDropList.vue

@@ -13,6 +13,16 @@
             <!-- <el-button @click="download" icon="el-icon-upload2" :loading="downloading" :disabled="fetchingData" class="filter-item">
             <!-- <el-button @click="download" icon="el-icon-upload2" :loading="downloading" :disabled="fetchingData" class="filter-item">
                 导出
                 导出
             </el-button> -->
             </el-button> -->
+            <el-upload
+                class="upload-button filter-item"
+                :action="uploadUrl"
+                :on-success="onSuccess"
+                :before-upload="beforeUpload"
+                :headers="{ Authorization: Authorization }"
+                style="margin-left:10px;"
+            >
+                <el-button size="small" :loading="uploadLoading" type="primary"> 上传文件</el-button>
+            </el-upload>
         </page-title>
         </page-title>
         <div class="filters-container">
         <div class="filters-container">
             <created-at-picker v-model="createdAt" name="创建" @input="getData"></created-at-picker>
             <created-at-picker v-model="createdAt" name="创建" @input="getData"></created-at-picker>
@@ -78,10 +88,14 @@
 <script>
 <script>
 import { mapState } from 'vuex';
 import { mapState } from 'vuex';
 import pageableTable from '@/mixins/pageableTable';
 import pageableTable from '@/mixins/pageableTable';
+import resolveUrl from 'resolve-url';
 
 
 export default {
 export default {
     name: 'AirDropList',
     name: 'AirDropList',
     mixins: [pageableTable],
     mixins: [pageableTable],
+    created() {
+        this.uploadUrl = resolveUrl(this.$baseUrl, 'airDrop/upload');
+    },
     data() {
     data() {
         return {
         return {
             multipleMode: false,
             multipleMode: false,
@@ -92,7 +106,10 @@ export default {
                 { label: '藏品', value: 'asset' },
                 { label: '藏品', value: 'asset' },
                 { label: '兑换券', value: 'coupon' }
                 { label: '兑换券', value: 'coupon' }
             ],
             ],
-            createdAt: ''
+            createdAt: '',
+            uploadUrl: '',
+            uploadLoading: false,
+            Authorization: 'Bearer ' + localStorage.getItem('token'),
         };
         };
     },
     },
     computed: {
     computed: {
@@ -133,6 +150,14 @@ export default {
                 }
                 }
             });
             });
         },
         },
+        beforeUpload(file) {
+            this.uploadLoading = true;
+            return true;
+        },
+        onSuccess(res, file) {
+            this.uploadLoading = false;
+            this.$message.success('上传成功');
+        },
         download() {
         download() {
             this.downloading = true;
             this.downloading = true;
             this.$axios
             this.$axios