---
source: "https://weapp.eteams.cn/build/techdoc/wdoc/index.html#/public/doc/dc807691-8a6d-4ac6-94ef-d9a62240b5a5"
publicId: "dc807691-8a6d-4ac6-94ef-d9a62240b5a5"
---

# 前端存储配置页面二开

### **快速上手**

***1.开发流程介绍***

> - 集成模式的相关介绍请看[二开手册简介-相关术语介绍](https://weapp.eteams.cn/build/techdoc/wdoc/index.html#/public/doc/6ebe70ee-ae5b-435b-904b-41c0a40ad04e)
> - 前端存储配置页面二开和后端底层存储二开放在同一个二开项目中，生成一个二开jar包

1. 使用集成模式二开
2. 创建本地ecode二开项目weaver-file-storage-secondev
3. 继承抽象类新增实现类
4. 实现抽象类中的各个方法
5. ecode二开项目打包成二开jar包
6. 集成到weaver-file-service
7. 二开结束

***2.存储配置页面展示***  
![](https://showdoc.alphaxx.cn:19993/server/index.php?s=/api/attachment/visitFile&sign=762210a6456e1ce513dd5ee6c9c5ff9d)

### **二开准备**

1. 文件服务存储二开是基于 ecode [IDEA-本地项目二开 ](https://weapp.eteams.cn/ecode/playground/doc/share/view/974701716410515473#IDEA-%E6%9C%AC%E5%9C%B0%E9%A1%B9%E7%9B%AE%E4%BA%8C%E5%BC%80%E8%AF%B4%E6%98%8E%20%22IDEA-%E6%9C%AC%E5%9C%B0%E9%A1%B9%E7%9B%AE%E4%BA%8C%E5%BC%80)，请务必熟练掌握相关功能操作。
2. 创建code本地二开项目：weaver-file-storage-secondev 二开项目

### **实现方法说明**

***1. 继承抽象类构建实现类（必要）***

> 抽象基础类：[com.weaver.eteams.file.client.file.storage](http://com.weaver.eteams.file.client.file.storage).front.secondev.SecondBaseStoInstanceFrontStrategy

```
// 示例代码
public class DemoStoInstanceFrontStrategy extends SecondBaseStoInstanceFrontStrategy{}
```

***2. 定义自定义存储的标识（必要）***

> FileStorage说明：[存储标识类介绍](https://weapp.eteams.cn/build/techdoc/wdoc/index.html#/public/doc/8a2cc328-491e-4575-99ec-215b0232c285)

```
FileStorage getStorageType();
```

```
// 示例代码
public class DemoStoInstanceFrontStrategy extends SecondBaseStoInstanceFrontStrategy {
    public final static String CUSTOM_STORAGE_KEY = "xxxxxxxxx";
    public final static FileStorage CUSTOM_STORE = FileStorage.of("b60***e7", CUSTOM_STORAGE_KEY);
    @Override
    public FileStorage getStorageType() {
        return CUSTOM_STORE;
    }
}
```

***3. 实现自定义存储连通性（必要）***

> - 基于从页面接收到的存储相关配置的值，测试当前存储是否可以连通
> - 如果实在不想实现，切记一定要返回true，但是页面上测试连通性的按钮功能就没有了意义
> - StorageConfigInfo说明请看：[存储相关配置统一封装类介绍](https://weapp.eteams.cn/build/techdoc/wdoc/index.html#/public/doc/40ee76f1-df16-47fd-bf02-2dbf4eaec3ac)

```
public boolean testConnectivity(StorageConfigInfo configInfo) {}
```

```
// 示例代码
public class DemoStoInstanceFrontStrategy extends SecondBaseStoInstanceFrontStrategy{

    @Override
    public boolean testConnectivity(StorageConfigInfo configInfo) {
        COSClient cosClient = null;
        try {
            String secretId = configInfo.getAccessId();
            String secretKey = configInfo.getAccessKey();
            COSCredentials cred = new BasicCOSCredentials(secretId, secretKey);
            Region region = new Region(configInfo.getRegion());
            ClientConfig clientConfig = new ClientConfig(region);
            clientConfig.setHttpProtocol(HttpProtocol.https);
            cosClient = new COSClient(cred, clientConfig);
            String bucketName = configInfo.getBucket();
            boolean isExist = cosClient.doesBucketExist(bucketName);
            ValidatedUtils.state(isExist, "bucket is not exist");
        } catch (Exception e) {
            throw new GlobalException("test tencent connect failed", e);
        } finally {
            Optional.ofNullable(cosClient).ifPresent(COSClient::shutdown);
        }

        return true;
    }

}
```

***4. 定义使用系统默认可用的存储配置字段（必要）***

> - StorageInstanceFieldEnum说明请看：[系统默认存储配置枚举类介绍](https://weapp.eteams.cn/build/techdoc/wdoc/index.html#/public/doc/7160df94-0513-43ed-ada0-65377e45c04a)
> - 此方法定义的字段，在后端接口中会被StorageConfigInfo映射接收
> - StorageConfigInfo说明请看：[存储相关配置统一封装类介绍](https://weapp.eteams.cn/build/techdoc/wdoc/index.html#/public/doc/40ee76f1-df16-47fd-bf02-2dbf4eaec3ac)
> - StorageConfigInfo 会传递到存储底层weaver-storage中各个方法的统一入参StorageParam
> - StorageParam说明：[存储底层统一入参封装类介绍](https://weapp.eteams.cn/build/techdoc/wdoc/index.html#/public/doc/821dba42-8362-4d02-8916-fbbde713d27d)
> - weaver-storage项目说明：[二开手册简介-相关术语介绍](https://weapp.eteams.cn/build/techdoc/wdoc/index.html#/public/doc/6ebe70ee-ae5b-435b-904b-41c0a40ad04e)

```
LinkedList<StorageInstanceFieldEnum> defaultField();
```

```
//示例代码
@Override
public LinkedList<StorageInstanceFieldEnum> defaultField() {
    LinkedList<StorageInstanceFieldEnum> fieldEnumList = Lists.newLinkedList();
    fieldEnumList.add(StorageInstanceFieldEnum.STORAGE_STATE);
    fieldEnumList.add(StorageInstanceFieldEnum.MANUFACTURER);
    fieldEnumList.add(StorageInstanceFieldEnum.INSTANCE_NAME);
    fieldEnumList.add(StorageInstanceFieldEnum.LINK_STATUS);
    return fieldEnumList;
}
```

页面展示  
![](https://showdoc.alphaxx.cn:19993/server/index.php?s=/api/attachment/visitFile&sign=eb9066bc432d7557200e81cd8cc0aea1)

***5. 定义自定义存储配置字段（可选）***

> - 当StorageInstanceFieldEnum中不存在的字段时，通过实现此方法可以自定义配置字段
> - StorageInstanceFieldEnum说明请看：[系统默认存储配置枚举类介绍](https://weapp.eteams.cn/build/techdoc/wdoc/index.html#/public/doc/7160df94-0513-43ed-ada0-65377e45c04a)
> - 当实现此方法后，initExtFieldItem()、initExtFieldLayout()必须实现
> - 此方法定义的字段，在后端接口中会被StorageConfigInfo.extMap字段映射接收
> - StorageConfigInfo.extMap 传递到 weaver-storage中的StorageParam.extAttributes
> - StorageConfigInfo说明请看：[存储相关配置统一封装类介绍](https://weapp.eteams.cn/build/techdoc/wdoc/index.html#/public/doc/40ee76f1-df16-47fd-bf02-2dbf4eaec3ac)

```
LinkedList<String> extField();
```

```
//示例代码
@Override
public LinkedList<String> extField() {
    LinkedList<String> extFieldList = Lists.newLinkedList();
    extFieldList.add("appName");
    extFieldList.add("serverAddress");
    return extFieldList;
}
```

页面展示  
![](https://showdoc.alphaxx.cn:19993/server/index.php?s=/api/attachment/visitFile&sign=f412212378191651c7f6fcc09455ddaa)

***6. 构造自定义存储配置字段的表单组件（有条件必要）***

> - extField()方法实现后，此方法一定要实现

```
Map<String, WeaFormItem> initExtFieldItem();
```

```
// 示例代码
@Override
public Map<String, WeaFormItem> initExtFieldItem() {
    WeaFormItem appNameWeaFormItem = new WeaFormItem(WeaFormItemType.INPUT);
    appNameWeaFormItem.setVisible(true);
    appNameWeaFormItem.setRequired(true);

    WeaFormItem serverAddressWeaFormItem = new WeaFormItem(WeaFormItemType.INPUT);
    serverAddressWeaFormItem.setVisible(true);
    serverAddressWeaFormItem.setRequired(true);

    Map<String, WeaFormItem> itemMap = Maps.newHashMapWithExpectedSize(2);
    itemMap.put("appName", appNameWeaFormItem);
    itemMap.put("serverAddress", serverAddressWeaFormItem);
    return itemMap;
}
```

***7. 构造自定义存储配置字段的表单布局（有条件必要）***

> - extField()方法实现后，此方法一定要实现
> - 通过设置WeaFormLayout.OtherParams中order属性，double类型，控制页面该字段展示顺序，从小到大排序
> - StorageInstanceFieldEnum系统默认配置字段的order是固定的，请先观察使用的系统默认配置字段中的order后，再为自定义字段设置合理的order
> - StorageInstanceFieldEnum说明请看：[系统默认存储配置枚举类介绍](https://weapp.eteams.cn/build/techdoc/wdoc/index.html#/public/doc/7160df94-0513-43ed-ada0-65377e45c04a)

```
LinkedList<WeaFormLayout> initExtFieldLayout();
```

```
// 示例代码
@Override
public LinkedList<WeaFormLayout> initExtFieldLayout() {
    WeaFormLayout appNameLayout = new WeaFormLayout("appName", "应用名称", new String[]{"appName"});
    Map<String, Object> appNameOrderMap = Maps.newHashMapWithExpectedSize(1);
    // 设置展示顺序
    appNameOrderMap.put("order", 18.1);
    appNameLayout.setOtherParams(appNameOrderMap);
    WeaFormLayout serverAddressLayout = new WeaFormLayout("serverAddress", "服务器地址", new String[]{"serverAddress"});
    Map<String, Object> addOrderMap = Maps.newHashMapWithExpectedSize(1);
    // 设置展示顺序
    addOrderMap.put("order", 18.2);
    serverAddressLayout.setOtherParams(addOrderMap);

    LinkedList<WeaFormLayout> extFieldLayoutList = Lists.newLinkedList();
    extFieldLayoutList.add(appNameLayout);
    extFieldLayoutList.add(serverAddressLayout);
    return extFieldLayoutList;
}
```

***8. 定义自定义存储配置字段默认展示值（可选）***

```
Map<String, Object> extFieldDefaultValue(){};
```

```
// 示例代码
@Override
Map<String,Object> extDefualtValueMap= Maps.newHashMapWithExpectedSize(2);
extDefualtValueMap.put("appName","yzw");
extDefualtValueMap.put("serverAddress","http://127.0.0.1");
return extDefualtValueMap;
```

***9. 设置自定义存储类型显示的中文名（可选）***

> - 默认展示的是FileStorage.storageKey (英文名)
> - 存储标识FIleStorage类的介绍：[FileStorage存储标识类介绍](https://weapp.eteams.cn/build/techdoc/wdoc/index.html#/public/doc/8a2cc328-491e-4575-99ec-215b0232c285)

```
String customStorageTypeShowName();
```

```
// 示例代码
@Override
public String customStorageTypeShowName() {
    return "中建存储";
}
```

页面展示效果  
![](https://showdoc.alphaxx.cn:19993/server/index.php?s=/api/attachment/visitFile&sign=ef1ceac7f2a6ce5249d310eeddc4e262)

***10. 自定义存储配置的值保存到数据库前的校验（可选）***

```
void validateRequiredField(StorageConfigInfo configInfo);
```

```
// 示例代码
@Override
public void validateRequiredField(StorageConfigInfo configInfo) {
    // 如果是通过extField()定义自定义配置字段，那么它的值是通过StorageConfigInfo.extMap接收的
    Map<String, String> extFieldMap = Optional.ofNullable(configInfo.getExtMap()).orElse(Maps.newHashMapWithExpectedSize(0));
    String appName = extFieldMap.get("appName");
    String serverAddress = extFieldMap.get("serverAddress");
    // 假设对appName不能为空字符串的限制
    Validate.validState(StringUtils.isNotBlank(appName), "appName is required");
    // 假设对serverAddress必须要要有协议头
    Validate.validState(serverAddress.startsWith("http"), "http/https is required");
}
```

***11. 定义系统默认配置字段默认展示值（可选）***

```
Map<StorageInstanceFieldEnum, Object> defaultFieldDefaultValue();
```

```
// 示例代码
@Override
public Map<StorageInstanceFieldEnum, Object> defaultFieldDefaultValue() {
    Map<StorageInstanceFieldEnum, Object> maps = Maps.newHashMapWithExpectedSize(1);
    maps.put(StorageInstanceFieldEnum.INSTANCE_NAME, "自定义存储");
    return maps;
}
```
