feat(core): 新增飞书文件服务和表格构建器功能
- 新增 CustomFileService 类,用于获取根目录元数据等文件操作 - 新增 RootFolderMetaResponse 类,用于解析根目录元数据响应 - 新增 SheetBuilder 类,提供链式调用方式创建飞书表格 - 在 FeishuClient 中添加 customFiles 方法,返回 CustomFileService 实例 - 在 FsApiUtil 中添加创建文件夹和表格的方法 - 在 FsHelper 中添加创建表格构建器方法
This commit is contained in:
		
							parent
							
								
									a34df121bc
								
							
						
					
					
						commit
						3e25a91aed
					
				@ -5,6 +5,7 @@ import cn.isliu.core.FileData;
 | 
				
			|||||||
import cn.isliu.core.FsTableData;
 | 
					import cn.isliu.core.FsTableData;
 | 
				
			||||||
import cn.isliu.core.Sheet;
 | 
					import cn.isliu.core.Sheet;
 | 
				
			||||||
import cn.isliu.core.annotation.TableConf;
 | 
					import cn.isliu.core.annotation.TableConf;
 | 
				
			||||||
 | 
					import cn.isliu.core.builder.SheetBuilder;
 | 
				
			||||||
import cn.isliu.core.client.FeishuClient;
 | 
					import cn.isliu.core.client.FeishuClient;
 | 
				
			||||||
import cn.isliu.core.client.FsClient;
 | 
					import cn.isliu.core.client.FsClient;
 | 
				
			||||||
import cn.isliu.core.enums.ErrorCode;
 | 
					import cn.isliu.core.enums.ErrorCode;
 | 
				
			||||||
@ -74,6 +75,22 @@ public class FsHelper {
 | 
				
			|||||||
        return sheetId;
 | 
					        return sheetId;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 创建飞书表格构建器
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * 返回一个表格构建器实例,支持链式调用和高级配置选项,
 | 
				
			||||||
 | 
					     * 如字段过滤等功能。
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param sheetName 工作表名称
 | 
				
			||||||
 | 
					     * @param spreadsheetToken 电子表格Token
 | 
				
			||||||
 | 
					     * @param clazz 实体类Class对象,用于解析表头和字段属性
 | 
				
			||||||
 | 
					     * @param <T> 实体类泛型
 | 
				
			||||||
 | 
					     * @return SheetBuilder实例,支持链式调用
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public static <T> SheetBuilder<T> createBuilder(String sheetName, String spreadsheetToken, Class<T> clazz) {
 | 
				
			||||||
 | 
					        return new SheetBuilder<>(sheetName, spreadsheetToken, clazz);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * 从飞书表格中读取数据
 | 
					     * 从飞书表格中读取数据
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										122
									
								
								src/main/java/cn/isliu/core/builder/SheetBuilder.java
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										122
									
								
								src/main/java/cn/isliu/core/builder/SheetBuilder.java
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,122 @@
 | 
				
			|||||||
 | 
					package cn.isliu.core.builder;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import cn.isliu.core.annotation.TableConf;
 | 
				
			||||||
 | 
					import cn.isliu.core.client.FeishuClient;
 | 
				
			||||||
 | 
					import cn.isliu.core.client.FsClient;
 | 
				
			||||||
 | 
					import cn.isliu.core.pojo.FieldProperty;
 | 
				
			||||||
 | 
					import cn.isliu.core.service.CustomCellService;
 | 
				
			||||||
 | 
					import cn.isliu.core.utils.FsApiUtil;
 | 
				
			||||||
 | 
					import cn.isliu.core.utils.FsTableUtil;
 | 
				
			||||||
 | 
					import cn.isliu.core.utils.PropertyUtil;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import java.util.ArrayList;
 | 
				
			||||||
 | 
					import java.util.List;
 | 
				
			||||||
 | 
					import java.util.Map;
 | 
				
			||||||
 | 
					import java.util.stream.Collectors;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * 表格构建器
 | 
				
			||||||
 | 
					 * 
 | 
				
			||||||
 | 
					 * 提供链式调用方式创建飞书表格,支持字段过滤等高级功能。
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					public class SheetBuilder<T> {
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    private final String sheetName;
 | 
				
			||||||
 | 
					    private final String spreadsheetToken;
 | 
				
			||||||
 | 
					    private final Class<T> clazz;
 | 
				
			||||||
 | 
					    private List<String> includeFields;
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 构造函数
 | 
				
			||||||
 | 
					     * 
 | 
				
			||||||
 | 
					     * @param sheetName 工作表名称
 | 
				
			||||||
 | 
					     * @param spreadsheetToken 电子表格Token
 | 
				
			||||||
 | 
					     * @param clazz 实体类Class对象
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public SheetBuilder(String sheetName, String spreadsheetToken, Class<T> clazz) {
 | 
				
			||||||
 | 
					        this.sheetName = sheetName;
 | 
				
			||||||
 | 
					        this.spreadsheetToken = spreadsheetToken;
 | 
				
			||||||
 | 
					        this.clazz = clazz;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 设置包含的字段列表
 | 
				
			||||||
 | 
					     * 
 | 
				
			||||||
 | 
					     * 指定要包含在表格中的字段名称列表。如果不设置,则包含所有带有@TableProperty注解的字段。
 | 
				
			||||||
 | 
					     * 
 | 
				
			||||||
 | 
					     * @param fields 要包含的字段名称列表
 | 
				
			||||||
 | 
					     * @return SheetBuilder实例,支持链式调用
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public SheetBuilder<T> includeColumnField(List<String> fields) {
 | 
				
			||||||
 | 
					        this.includeFields = new ArrayList<>(fields);
 | 
				
			||||||
 | 
					        return this;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 构建表格并返回工作表ID
 | 
				
			||||||
 | 
					     * 
 | 
				
			||||||
 | 
					     * 根据配置的参数创建飞书表格,包括表头、样式、单元格格式和下拉选项等。
 | 
				
			||||||
 | 
					     * 
 | 
				
			||||||
 | 
					     * @return 创建成功返回工作表ID
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public String build() {
 | 
				
			||||||
 | 
					        // 获取所有字段映射
 | 
				
			||||||
 | 
					        Map<String, FieldProperty> allFieldsMap = PropertyUtil.getTablePropertyFieldsMap(clazz);
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        // 根据includeFields过滤字段映射
 | 
				
			||||||
 | 
					        Map<String, FieldProperty> fieldsMap = filterFieldsMap(allFieldsMap);
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        // 生成表头
 | 
				
			||||||
 | 
					        List<String> headers = PropertyUtil.getHeaders(fieldsMap);
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        // 获取表格配置
 | 
				
			||||||
 | 
					        TableConf tableConf = PropertyUtil.getTableConf(clazz);
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        // 创建飞书客户端
 | 
				
			||||||
 | 
					        FeishuClient client = FsClient.getInstance().getClient();
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        // 1、创建sheet
 | 
				
			||||||
 | 
					        String sheetId = FsApiUtil.createSheet(sheetName, client, spreadsheetToken);
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        // 2、添加表头数据
 | 
				
			||||||
 | 
					        FsApiUtil.putValues(spreadsheetToken, FsTableUtil.getHeadTemplateBuilder(sheetId, headers, fieldsMap, tableConf), client);
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        // 3、设置表格样式
 | 
				
			||||||
 | 
					        FsApiUtil.setTableStyle(FsTableUtil.getDefaultTableStyle(sheetId, fieldsMap, tableConf), client, spreadsheetToken);
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        // 4、合并单元格
 | 
				
			||||||
 | 
					        List<CustomCellService.CellRequest> mergeCell = FsTableUtil.getMergeCell(sheetId, fieldsMap);
 | 
				
			||||||
 | 
					        if (!mergeCell.isEmpty()) {
 | 
				
			||||||
 | 
					            mergeCell.forEach(cell -> FsApiUtil.mergeCells(cell, client, spreadsheetToken));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        // 5、设置单元格为文本格式
 | 
				
			||||||
 | 
					        if (tableConf.isText()) {
 | 
				
			||||||
 | 
					            String column = FsTableUtil.getColumnNameByNuNumber(headers.size());
 | 
				
			||||||
 | 
					            FsApiUtil.setCellType(sheetId, "@", "A1", column + 200, client, spreadsheetToken);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        // 6、设置表格下拉
 | 
				
			||||||
 | 
					        FsTableUtil.setTableOptions(spreadsheetToken, headers, fieldsMap, sheetId, tableConf.enableDesc());
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        return sheetId;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 根据包含字段列表过滤字段映射
 | 
				
			||||||
 | 
					     * 
 | 
				
			||||||
 | 
					     * @param allFieldsMap 所有字段映射
 | 
				
			||||||
 | 
					     * @return 过滤后的字段映射
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    private Map<String, FieldProperty> filterFieldsMap(Map<String, FieldProperty> allFieldsMap) {
 | 
				
			||||||
 | 
					        // 如果没有指定包含字段,返回所有字段
 | 
				
			||||||
 | 
					        if (includeFields == null || includeFields.isEmpty()) {
 | 
				
			||||||
 | 
					            return allFieldsMap;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        // 根据字段名过滤,保留指定的字段
 | 
				
			||||||
 | 
					        return allFieldsMap.entrySet().stream()
 | 
				
			||||||
 | 
					                .filter(entry -> includeFields.contains(entry.getValue().getField()))
 | 
				
			||||||
 | 
					                .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -116,6 +116,16 @@ public class FeishuClient {
 | 
				
			|||||||
        return serviceManager.getService(CustomProtectedDimensionService.class, () -> new CustomProtectedDimensionService(this));
 | 
					        return serviceManager.getService(CustomProtectedDimensionService.class, () -> new CustomProtectedDimensionService(this));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 获取扩展文件服务
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return 扩展文件服务
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public CustomFileService customFiles() {
 | 
				
			||||||
 | 
					        return serviceManager.getService(CustomFileService.class, () -> new CustomFileService(this));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * 获取官方客户端
 | 
					     * 获取官方客户端
 | 
				
			||||||
     *
 | 
					     *
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										280
									
								
								src/main/java/cn/isliu/core/pojo/RootFolderMetaResponse.java
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										280
									
								
								src/main/java/cn/isliu/core/pojo/RootFolderMetaResponse.java
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,280 @@
 | 
				
			|||||||
 | 
					package cn.isliu.core.pojo;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import com.google.gson.annotations.SerializedName;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * 飞书API获取根目录元数据的响应模型类
 | 
				
			||||||
 | 
					 * 
 | 
				
			||||||
 | 
					 * 对应飞书API返回的JSON格式:
 | 
				
			||||||
 | 
					 * {
 | 
				
			||||||
 | 
					 *   "code": 0,
 | 
				
			||||||
 | 
					 *   "msg": "success",
 | 
				
			||||||
 | 
					 *   "data": {
 | 
				
			||||||
 | 
					 *     "token": "fldbc0k5Zws8AQBpfzlFMKCpN4z",
 | 
				
			||||||
 | 
					 *     "id": "fldbc0k5Zws8AQBpfzlFMKCpN4z",
 | 
				
			||||||
 | 
					 *     "user_id": "ou_xxxxx",
 | 
				
			||||||
 | 
					 *     "name": "我的空间"
 | 
				
			||||||
 | 
					 *   }
 | 
				
			||||||
 | 
					 * }
 | 
				
			||||||
 | 
					 * 
 | 
				
			||||||
 | 
					 * @author FsHelper
 | 
				
			||||||
 | 
					 * @since 1.0
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					public class RootFolderMetaResponse {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 响应状态码
 | 
				
			||||||
 | 
					     * 0表示成功,非0表示失败
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    @SerializedName("code")
 | 
				
			||||||
 | 
					    private int code;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 响应消息
 | 
				
			||||||
 | 
					     * 通常成功时为"success",失败时包含错误描述
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    @SerializedName("msg")
 | 
				
			||||||
 | 
					    private String msg;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 根目录元数据
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    @SerializedName("data")
 | 
				
			||||||
 | 
					    private RootFolderMeta data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 默认构造函数
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public RootFolderMetaResponse() {
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 完整构造函数
 | 
				
			||||||
 | 
					     * 
 | 
				
			||||||
 | 
					     * @param code 响应状态码
 | 
				
			||||||
 | 
					     * @param msg 响应消息
 | 
				
			||||||
 | 
					     * @param data 根目录元数据
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public RootFolderMetaResponse(int code, String msg, RootFolderMeta data) {
 | 
				
			||||||
 | 
					        this.code = code;
 | 
				
			||||||
 | 
					        this.msg = msg;
 | 
				
			||||||
 | 
					        this.data = data;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 获取响应状态码
 | 
				
			||||||
 | 
					     * 
 | 
				
			||||||
 | 
					     * @return 响应状态码,0表示成功
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public int getCode() {
 | 
				
			||||||
 | 
					        return code;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 设置响应状态码
 | 
				
			||||||
 | 
					     * 
 | 
				
			||||||
 | 
					     * @param code 响应状态码
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public void setCode(int code) {
 | 
				
			||||||
 | 
					        this.code = code;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 获取响应消息
 | 
				
			||||||
 | 
					     * 
 | 
				
			||||||
 | 
					     * @return 响应消息
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public String getMsg() {
 | 
				
			||||||
 | 
					        return msg;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 设置响应消息
 | 
				
			||||||
 | 
					     * 
 | 
				
			||||||
 | 
					     * @param msg 响应消息
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public void setMsg(String msg) {
 | 
				
			||||||
 | 
					        this.msg = msg;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 获取根目录元数据
 | 
				
			||||||
 | 
					     * 
 | 
				
			||||||
 | 
					     * @return 根目录元数据
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public RootFolderMeta getData() {
 | 
				
			||||||
 | 
					        return data;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 设置根目录元数据
 | 
				
			||||||
 | 
					     * 
 | 
				
			||||||
 | 
					     * @param data 根目录元数据
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public void setData(RootFolderMeta data) {
 | 
				
			||||||
 | 
					        this.data = data;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 检查响应是否成功
 | 
				
			||||||
 | 
					     * 
 | 
				
			||||||
 | 
					     * @return true表示API调用成功,false表示失败
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public boolean isSuccess() {
 | 
				
			||||||
 | 
					        return code == 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 检查是否包含有效的根目录数据
 | 
				
			||||||
 | 
					     * 
 | 
				
			||||||
 | 
					     * @return true表示包含有效的根目录数据
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public boolean hasValidData() {
 | 
				
			||||||
 | 
					        return isSuccess() && 
 | 
				
			||||||
 | 
					               data != null && 
 | 
				
			||||||
 | 
					               data.getToken() != null && 
 | 
				
			||||||
 | 
					               !data.getToken().trim().isEmpty();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 根目录元数据内部类
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public static class RootFolderMeta {
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        /**
 | 
				
			||||||
 | 
					         * 文件夹token
 | 
				
			||||||
 | 
					         */
 | 
				
			||||||
 | 
					        @SerializedName("token")
 | 
				
			||||||
 | 
					        private String token;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /**
 | 
				
			||||||
 | 
					         * 文件夹ID
 | 
				
			||||||
 | 
					         */
 | 
				
			||||||
 | 
					        @SerializedName("id")
 | 
				
			||||||
 | 
					        private String id;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /**
 | 
				
			||||||
 | 
					         * 用户ID
 | 
				
			||||||
 | 
					         */
 | 
				
			||||||
 | 
					        @SerializedName("user_id")
 | 
				
			||||||
 | 
					        private String userId;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /**
 | 
				
			||||||
 | 
					         * 文件夹名称
 | 
				
			||||||
 | 
					         */
 | 
				
			||||||
 | 
					        @SerializedName("name")
 | 
				
			||||||
 | 
					        private String name;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /**
 | 
				
			||||||
 | 
					         * 默认构造函数
 | 
				
			||||||
 | 
					         */
 | 
				
			||||||
 | 
					        public RootFolderMeta() {
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /**
 | 
				
			||||||
 | 
					         * 完整构造函数
 | 
				
			||||||
 | 
					         * 
 | 
				
			||||||
 | 
					         * @param token 文件夹token
 | 
				
			||||||
 | 
					         * @param id 文件夹ID
 | 
				
			||||||
 | 
					         * @param userId 用户ID
 | 
				
			||||||
 | 
					         * @param name 文件夹名称
 | 
				
			||||||
 | 
					         */
 | 
				
			||||||
 | 
					        public RootFolderMeta(String token, String id, String userId, String name) {
 | 
				
			||||||
 | 
					            this.token = token;
 | 
				
			||||||
 | 
					            this.id = id;
 | 
				
			||||||
 | 
					            this.userId = userId;
 | 
				
			||||||
 | 
					            this.name = name;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /**
 | 
				
			||||||
 | 
					         * 获取文件夹token
 | 
				
			||||||
 | 
					         * 
 | 
				
			||||||
 | 
					         * @return 文件夹token
 | 
				
			||||||
 | 
					         */
 | 
				
			||||||
 | 
					        public String getToken() {
 | 
				
			||||||
 | 
					            return token;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /**
 | 
				
			||||||
 | 
					         * 设置文件夹token
 | 
				
			||||||
 | 
					         * 
 | 
				
			||||||
 | 
					         * @param token 文件夹token
 | 
				
			||||||
 | 
					         */
 | 
				
			||||||
 | 
					        public void setToken(String token) {
 | 
				
			||||||
 | 
					            this.token = token;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /**
 | 
				
			||||||
 | 
					         * 获取文件夹ID
 | 
				
			||||||
 | 
					         * 
 | 
				
			||||||
 | 
					         * @return 文件夹ID
 | 
				
			||||||
 | 
					         */
 | 
				
			||||||
 | 
					        public String getId() {
 | 
				
			||||||
 | 
					            return id;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /**
 | 
				
			||||||
 | 
					         * 设置文件夹ID
 | 
				
			||||||
 | 
					         * 
 | 
				
			||||||
 | 
					         * @param id 文件夹ID
 | 
				
			||||||
 | 
					         */
 | 
				
			||||||
 | 
					        public void setId(String id) {
 | 
				
			||||||
 | 
					            this.id = id;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /**
 | 
				
			||||||
 | 
					         * 获取用户ID
 | 
				
			||||||
 | 
					         * 
 | 
				
			||||||
 | 
					         * @return 用户ID
 | 
				
			||||||
 | 
					         */
 | 
				
			||||||
 | 
					        public String getUserId() {
 | 
				
			||||||
 | 
					            return userId;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /**
 | 
				
			||||||
 | 
					         * 设置用户ID
 | 
				
			||||||
 | 
					         * 
 | 
				
			||||||
 | 
					         * @param userId 用户ID
 | 
				
			||||||
 | 
					         */
 | 
				
			||||||
 | 
					        public void setUserId(String userId) {
 | 
				
			||||||
 | 
					            this.userId = userId;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /**
 | 
				
			||||||
 | 
					         * 获取文件夹名称
 | 
				
			||||||
 | 
					         * 
 | 
				
			||||||
 | 
					         * @return 文件夹名称
 | 
				
			||||||
 | 
					         */
 | 
				
			||||||
 | 
					        public String getName() {
 | 
				
			||||||
 | 
					            return name;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /**
 | 
				
			||||||
 | 
					         * 设置文件夹名称
 | 
				
			||||||
 | 
					         * 
 | 
				
			||||||
 | 
					         * @param name 文件夹名称
 | 
				
			||||||
 | 
					         */
 | 
				
			||||||
 | 
					        public void setName(String name) {
 | 
				
			||||||
 | 
					            this.name = name;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        @Override
 | 
				
			||||||
 | 
					        public String toString() {
 | 
				
			||||||
 | 
					            return "RootFolderMeta{" +
 | 
				
			||||||
 | 
					                    "token='" + token + '\'' +
 | 
				
			||||||
 | 
					                    ", id='" + id + '\'' +
 | 
				
			||||||
 | 
					                    ", userId='" + userId + '\'' +
 | 
				
			||||||
 | 
					                    ", name='" + name + '\'' +
 | 
				
			||||||
 | 
					                    '}';
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Override
 | 
				
			||||||
 | 
					    public String toString() {
 | 
				
			||||||
 | 
					        return "RootFolderMetaResponse{" +
 | 
				
			||||||
 | 
					                "code=" + code +
 | 
				
			||||||
 | 
					                ", msg='" + msg + '\'' +
 | 
				
			||||||
 | 
					                ", data=" + data +
 | 
				
			||||||
 | 
					                '}';
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										44
									
								
								src/main/java/cn/isliu/core/service/CustomFileService.java
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										44
									
								
								src/main/java/cn/isliu/core/service/CustomFileService.java
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,44 @@
 | 
				
			|||||||
 | 
					package cn.isliu.core.service;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import cn.isliu.core.client.FeishuClient;
 | 
				
			||||||
 | 
					import cn.isliu.core.pojo.RootFolderMetaResponse;
 | 
				
			||||||
 | 
					import okhttp3.Request;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import java.io.IOException;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * 飞书文件服务
 | 
				
			||||||
 | 
					 * 
 | 
				
			||||||
 | 
					 * 处理飞书云盘相关的API调用,包括获取根目录元数据等功能
 | 
				
			||||||
 | 
					 * 
 | 
				
			||||||
 | 
					 * @author FsHelper
 | 
				
			||||||
 | 
					 * @since 1.0
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					public class CustomFileService extends AbstractFeishuApiService {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 构造函数
 | 
				
			||||||
 | 
					     * 
 | 
				
			||||||
 | 
					     * @param feishuClient 飞书客户端
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public CustomFileService(FeishuClient feishuClient) {
 | 
				
			||||||
 | 
					        super(feishuClient);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 获取根目录元数据
 | 
				
			||||||
 | 
					     * 
 | 
				
			||||||
 | 
					     * 调用飞书开放平台API获取当前租户的根目录token和相关信息
 | 
				
			||||||
 | 
					     * API接口: GET https://open.feishu.cn/open-apis/drive/explorer/v2/root_folder/meta
 | 
				
			||||||
 | 
					     * 
 | 
				
			||||||
 | 
					     * @return 根目录元数据响应
 | 
				
			||||||
 | 
					     * @throws IOException 网络请求异常
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public RootFolderMetaResponse getRootFolderMeta() throws IOException {
 | 
				
			||||||
 | 
					        String url = BASE_URL + "/drive/explorer/v2/root_folder/meta";
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        Request request = createAuthenticatedRequest(url, "GET", null).build();
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        return executeRequest(request, RootFolderMetaResponse.class);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -9,18 +9,13 @@ import cn.isliu.core.client.FeishuClient;
 | 
				
			|||||||
import cn.isliu.core.exception.FsHelperException;
 | 
					import cn.isliu.core.exception.FsHelperException;
 | 
				
			||||||
import cn.isliu.core.logging.FsLogger;
 | 
					import cn.isliu.core.logging.FsLogger;
 | 
				
			||||||
import cn.isliu.core.pojo.ApiResponse;
 | 
					import cn.isliu.core.pojo.ApiResponse;
 | 
				
			||||||
 | 
					import cn.isliu.core.pojo.RootFolderMetaResponse;
 | 
				
			||||||
import cn.isliu.core.service.*;
 | 
					import cn.isliu.core.service.*;
 | 
				
			||||||
import com.google.gson.Gson;
 | 
					import com.google.gson.Gson;
 | 
				
			||||||
import com.google.gson.JsonArray;
 | 
					import com.google.gson.JsonArray;
 | 
				
			||||||
import com.google.gson.JsonObject;
 | 
					import com.google.gson.JsonObject;
 | 
				
			||||||
import com.lark.oapi.service.drive.v1.model.BatchGetTmpDownloadUrlMediaReq;
 | 
					import com.lark.oapi.service.drive.v1.model.*;
 | 
				
			||||||
import com.lark.oapi.service.drive.v1.model.BatchGetTmpDownloadUrlMediaResp;
 | 
					import com.lark.oapi.service.sheets.v3.model.*;
 | 
				
			||||||
import com.lark.oapi.service.drive.v1.model.DownloadMediaReq;
 | 
					 | 
				
			||||||
import com.lark.oapi.service.drive.v1.model.DownloadMediaResp;
 | 
					 | 
				
			||||||
import com.lark.oapi.service.sheets.v3.model.GetSpreadsheetReq;
 | 
					 | 
				
			||||||
import com.lark.oapi.service.sheets.v3.model.GetSpreadsheetResp;
 | 
					 | 
				
			||||||
import com.lark.oapi.service.sheets.v3.model.QuerySpreadsheetSheetReq;
 | 
					 | 
				
			||||||
import com.lark.oapi.service.sheets.v3.model.QuerySpreadsheetSheetResp;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
import java.io.IOException;
 | 
					import java.io.IOException;
 | 
				
			||||||
import java.util.List;
 | 
					import java.util.List;
 | 
				
			||||||
@ -160,6 +155,83 @@ public class FsApiUtil {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 获取根目录Token
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * 调用飞书开放平台API获取当前租户的根目录token,用于后续的文件夹和文件操作
 | 
				
			||||||
 | 
					     * API接口: GET https://open.feishu.cn/open-apis/drive/v1/files/root_folder/meta
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param client 飞书客户端
 | 
				
			||||||
 | 
					     * @return 根目录token,获取失败时抛出异常
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public static String getRootFolderToken(FeishuClient client) {
 | 
				
			||||||
 | 
					        try {
 | 
				
			||||||
 | 
					            // 使用自定义文件服务获取根目录元数据
 | 
				
			||||||
 | 
					            RootFolderMetaResponse response = client.customFiles().getRootFolderMeta();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (response.isSuccess() && response.hasValidData()) {
 | 
				
			||||||
 | 
					                String rootFolderToken = response.getData().getToken();
 | 
				
			||||||
 | 
					                FsLogger.info("【飞书表格】 获取根目录Token成功!Token: {}", rootFolderToken);
 | 
				
			||||||
 | 
					                return rootFolderToken;
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                FsLogger.warn("【飞书表格】 获取根目录Token失败!错误码:{},错误信息:{}",
 | 
				
			||||||
 | 
					                        response.getCode(), response.getMsg());
 | 
				
			||||||
 | 
					                throw new FsHelperException("【飞书表格】 获取根目录Token失败!错误信息:" + response.getMsg());
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        } catch (Exception e) {
 | 
				
			||||||
 | 
					            FsLogger.warn("【飞书表格】 获取根目录Token异常!错误信息:{}", e.getMessage(), e);
 | 
				
			||||||
 | 
					            throw new FsHelperException("【飞书表格】 获取根目录Token异常!");
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public static CreateFolderFileRespBody createFolder(String folderName, String folderToken, FeishuClient client) {
 | 
				
			||||||
 | 
					        try {
 | 
				
			||||||
 | 
					            // 创建请求对象
 | 
				
			||||||
 | 
					            CreateFolderFileReq req = CreateFolderFileReq.newBuilder()
 | 
				
			||||||
 | 
					                    .createFolderFileReqBody(CreateFolderFileReqBody.newBuilder()
 | 
				
			||||||
 | 
					                            .name(folderName)
 | 
				
			||||||
 | 
					                            .folderToken(folderToken)
 | 
				
			||||||
 | 
					                            .build())
 | 
				
			||||||
 | 
					                    .build();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // 发起请求
 | 
				
			||||||
 | 
					            CreateFolderFileResp resp = client.drive().v1().file().createFolder(req);
 | 
				
			||||||
 | 
					            if (resp.success()) {
 | 
				
			||||||
 | 
					                FsLogger.info("【飞书表格】 创建文件夹成功! {}", gson.toJson(resp));
 | 
				
			||||||
 | 
					                return resp.getData();
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                FsLogger.warn("【飞书表格】 创建文件夹失败!参数:{},错误信息:{}", String.format("folderName: %s, folderToken: %s", folderName, folderToken), resp.getMsg());
 | 
				
			||||||
 | 
					                throw new FsHelperException("【飞书表格】 创建文件夹失败!");
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        } catch (Exception e) {
 | 
				
			||||||
 | 
					            FsLogger.warn("【飞书表格】 创建文件夹异常!参数:{},错误信息:{}", String.format("folderName: %s, folderToken: %s", folderName, folderToken), e.getMessage(), e);
 | 
				
			||||||
 | 
					            throw new FsHelperException("【飞书表格】 创建文件夹异常!");
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public static CreateSpreadsheetRespBody createTable(String tableName, String folderToken, FeishuClient client) {
 | 
				
			||||||
 | 
					        try {
 | 
				
			||||||
 | 
					            CreateSpreadsheetReq req = CreateSpreadsheetReq.newBuilder()
 | 
				
			||||||
 | 
					                    .spreadsheet(Spreadsheet.newBuilder()
 | 
				
			||||||
 | 
					                            .title(tableName)
 | 
				
			||||||
 | 
					                            .folderToken(folderToken)
 | 
				
			||||||
 | 
					                            .build())
 | 
				
			||||||
 | 
					                    .build();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            CreateSpreadsheetResp resp = client.sheets().v3().spreadsheet().create(req);
 | 
				
			||||||
 | 
					            if (resp.success()) {
 | 
				
			||||||
 | 
					                FsLogger.info("【飞书表格】 创建表格成功! {}", gson.toJson(resp));
 | 
				
			||||||
 | 
					                return resp.getData();
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                FsLogger.warn("【飞书表格】 创建表格失败!错误信息:{}", gson.toJson(resp));
 | 
				
			||||||
 | 
					                throw new FsHelperException("【飞书表格】 创建表格异常!");
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        } catch (Exception e) {
 | 
				
			||||||
 | 
					            FsLogger.warn("【飞书表格】 创建表格异常!参数:{},错误信息:{}", String.format("tableName:%s, folderToken:%s", tableName, folderToken), e.getMessage(), e);
 | 
				
			||||||
 | 
					            throw new FsHelperException("【飞书表格】 创建表格异常!");
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public static String createSheet(String title, FeishuClient client, String spreadsheetToken) {
 | 
					    public static String createSheet(String title, FeishuClient client, String spreadsheetToken) {
 | 
				
			||||||
        String sheetId = null;
 | 
					        String sheetId = null;
 | 
				
			||||||
        try {
 | 
					        try {
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user