上传控件

1. 上传控件后台

上传控件使用了FastDfs作为文件存储服务器来进行存储,在使用上传控件时需对上传空间进行配置。
以下介绍几个概念

下面是FastDfs简单配置流程说明。

1.1 FastDFS配置

FastDFS的分组信息与服务端信息可在数据库中进行配置维护,或直接使用代码将配置信息写入,下面介绍使用数据库配置方式来进行配置。

现有以下二张表:
FAST_DFS_GROUPTRACKER_SERVER
内容如下:

FAST_DFS_GROUP:

列名 字段说明
id 主键
group_name 分组名称
connect_timeout 连接超时时间
network_timout 网络超时时间
charset 编码
tracker_http_address 通过nginx访问的IP地址
anti_streal_token 暂时不需要配置
tracker_http_port 通过nginx访问的端口号
secret_key 密钥

TRACKER_SERVER

列名 字段说明
id 主键
group_id 分组id,一个分组里可能会有多个tracker
tracker_server FastDFS服务器地址

文件服务器的信息应在服务器启动时,自动载入。以下给出一个简单载入实例:

1.在Spring中注入文件组容器

    <bean name="clientGroupContainer" class="com.gillion.fdfs.group.ClientGroupContainer"></bean

2.编写初始化类FastDfsGroupServiceFastDfsGroupServiceImpl

FastDfsGroupService:

package com.gillion.sebusiness.demo.service.upload;

import com.gfa4j.mybatis.service.BaseService;

/**
 * Created by wengms on 2015/7/30.
 */
public interface  FastDfsGroupService extends BaseService{
}

FastDfsGroupServiceImpl

package com.gillion.sebusiness.demo.service.upload.impl;

import com.gfa4j.mybatis.mapper.BaseMapper;
import com.gfa4j.mybatis.service.impl.BaseServiceImpl;
import com.gillion.fdfs.client.GroupFastDFSClient;
import com.gillion.fdfs.group.ClientGroup;
import com.gillion.fdfs.group.ClientGroupContainer;
import com.gillion.sebusiness.demo.service.upload.FastDfsGroupService;

import com.gillion.sebusiness.upload.mapper.FastDfsGroupMapper;
import com.gillion.sebusiness.upload.mapper.TrackerServerMapper;
import com.gillion.sebusiness.upload.model.FastDfsGroup;
import com.gillion.sebusiness.upload.model.TrackerServer;
import com.gillion.sebusiness.upload.model.TrackerServerExample;
import com.google.common.base.Function;
import com.google.common.collect.Lists;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Nullable;
import java.awt.*;
import java.util.List;
import java.util.stream.Collector;
import java.util.stream.Collectors;

/**
 * Created by wengms on 2015/7/30.
 */
@Service
public class FastDfsGroupServiceImpl extends BaseServiceImpl implements FastDfsGroupService,InitializingBean{

    @Autowired
    private FastDfsGroupMapper fastDfsGroupMapper;

    @Autowired
    private TrackerServerMapper trackerServerMapper;

    @Autowired
    private ClientGroupContainer clientGroupContainer;

    @Override
    public BaseMapper getMapper() {
        return fastDfsGroupMapper;
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        List<FastDfsGroup> groups = this.selectByExample(null);
        groups.stream().forEach(input -> {
            ClientGroup clientGroup = new ClientGroup();
            clientGroup.setAntiStrealToken(input.getAntiStrealToken());
            clientGroup.setCharset(input.getCharset());
            clientGroup.setConnectTimeout(input.getConnectTimeout());
            clientGroup.setGroupName(input.getGroupName());
            clientGroup.setNetworkTimeout(input.getNetworkTimeout());
            clientGroup.setSecretKey(input.getSecretKey());
            clientGroup.setTrackerHttpAddress(input.getTrackerHttpAddress());
            clientGroup.setTrackerHttpPort(input.getTrackerHttpPort());
            TrackerServerExample trackerServerExample = new TrackerServerExample();
            trackerServerExample.createCriteria().andGroupIdEqualTo(input.getId());
            List<TrackerServer> trackerServers = trackerServerMapper.selectByExample(trackerServerExample);
            List<String> trackerAddress = trackerServers.stream().map(trackerServer->trackerServer.getTrackerServer()).collect(Collectors.toList());
            clientGroup.setTrackerServerAddresses(trackerAddress);
            GroupFastDFSClient client = new GroupFastDFSClient();
            client.initGroup(clientGroup);
            clientGroupContainer.addGroup(clientGroup);
        });
    }
}

按照以上的配置,就完成了FastDFS组的初始化。

1.2 上传配置信息配置

上传控件的使用流程是通过发送一个key到服务器端获取上传控件的类型限制,大小限制等配置信息等,主要包括以下功能配置:

  1. 上传类型:文件或图片
  2. 限制类型:以文件后缀名作区分,多个类型之间以逗号分隔
  3. 限制数量:一次上传的限制数量
  4. 限制大小:对上传文件的大小进行限制
  5. FastDFS分组信息:指定文件在上次时,使用哪个文件服务器分组进行保存
  6. 压缩策略:如果是图片,需要进行怎样的压缩,目前分为大缩略图和小缩略图,大小自己在配置中指定
  7. 删除策略:物理删除或逻辑删除,物理删除会去文件服务器上将文件擦出,逻辑删除不删除物理文件,只删除数据库里保存的文件路径信息
  8. 删除引用表达式:使用SpringEL表达式,直接指定某个bean的某个方法进行调用

下面给个示例表:
UPLOAD_INFO

字段名 说明
id 主键,也作为key,在前端配置时使用
upload_type 上传类型
limit_type 限制类型
limit_count 限制数量
limit_size 限制大小
dfs_group 文件服务器分组名
compress_strategy 压缩策略
delete_strategy 删除策略
delete_sexpression 删除引用表达式

现在给出示例配置信息如下所示:

{
    "id":"1",
    "upload_type":"1",
    "limit_type":"jpg,gif,jpef,png,xls,xlsx",
    "limit_count":"3",
    "limit_size":"1000",
    "dfs_group":"word",
    "compress_strategy":{
        "largeThumbnail":{
            "width":"500",
            "height":"500"
        },
        "smallThumbnail":{
            "width":"150",
            "height":"150"
        }
    },
    "delete_strategy":"",
    "delete_expression":"@testBusinessService.delete([fileInfo][id],[id])"
}

除配置表外,还需要两张表配置文件的上传信息以及文件的FastDFS路径信息,示例表如下:

DFS_FILE:(此处命名有问题,请酌情根据自己需求命名)
用于保存文件的基本信息,如文件名,文件在nginx上的直接访问路径等

字段名 说明
id 主键
file_name 上传文件名
orginal_path 源文件在FastDFS上的直接访问路径
large_thumb_path 大缩略图在FastDFS上的访问路径
small_thumb_path 小缩略图在FastDFS上的访问路径

FAST_DFS_FILE
用于保存文件在FastDFS上的实际路径信息

字段名 说明
id 主键
group_server_name 文件服务器组名
file_name 文件名称
file_id 文件ID,对应DFS_FILE的主键,如果是图片,一个file_id可能对于多个Fast_DFS_FILE记录
group_name 文件服务器分配的组名称
path 文件存储路径,下载文件时,需与group_name结合获取文件内容

1.3 上传后台配置

文件控件后台提供一个访问接口,以供前台进行获取文件上传配置信息,文件上传操作,删除操作等。
其中需要在Spring里将UploadController注入
同时注入删除器Deleter

<bean name="deleter" class="com.gillion.upload.strategy.delete.Deleter"/>

在dispatcher-servlet.xml中引入上传文件配置

<import resource="classpath*:spring-upload.xml"/>

1.4 编写上传控件必须服务类

各个业务系统需根据自己的需求,实现UploadService接口,接口内容主要包括:

  1. getUploadBaseInfo(String key)通过配置的key,获取配置信息
  2. saveUploadFile(UploadedFile uploadedFile,DFSFileInfo dfsFileInfo) 在文件上传到文件服务器后,传入文件的上传信息与在文件服务器中的保存信息,在这里主要操作将数据存入数据库,以便后续进行维护
  3. saveUploadImage(UploadedImageFile uploadedImageFile,ImageDFSFileInfo imageDFSFileInfos) 与第二个方法类似,此处是处理图片上传的信息,图片上传的信息包括三个文件信息:原图,大缩略图,小缩略图
  4. getUploadInfo(String key)获取文件的详细配置信息,与getUploadBaseInfo不同的是,此处返回所有配置包括服务器分组配置等,这些信息不应暴露给前端,所以此处分为两个方法调用。
  5. deleteById(String fileId) 根据文件ID,删除数据库中存储的文件信息
  6. getDfsFileInfo(String fileId) 获取文件在文件服务器中的信息,如分组,获取路径等

以下给个示例实现,请根据各自不同的表设计进行修改:

package com.gillion.sebusiness.demo.service.upload.impl;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.gfa4j.mybatis.mapper.BaseMapper;
import com.gfa4j.mybatis.service.impl.BaseServiceImpl;
import com.gillion.fdfs.entity.DFSFileInfo;
import com.gillion.sebusiness.demo.service.upload.DfsFileService;

import com.gillion.sebusiness.upload.mapper.DfsFileMapper;
import com.gillion.sebusiness.upload.mapper.FastDfsFileMapper;
import com.gillion.sebusiness.upload.model.DfsFile;
import com.gillion.sebusiness.upload.model.FastDfsFile;
import com.gillion.sebusiness.upload.model.FastDfsFileExample;
import com.gillion.upload.entity.*;
import com.gillion.upload.service.UploadService;
import com.gillion.upload.strategy.compress.CompressStrategy;
import com.gillion.upload.strategy.delete.DeleteStrategy;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Service;

import javax.sql.DataSource;
import java.io.IOException;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.stream.Collectors;

/**
 * Created by wengms on 2015/7/29.
 */
@Service
public class UploadServiceImpl extends BaseServiceImpl implements UploadService, DfsFileService, InitializingBean {

    @Autowired
    private DataSource dataSource;

    private JdbcTemplate jdbcTemplate;

    @Autowired
    private DfsFileMapper dfsFileMapper;

    @Autowired
    private FastDfsFileMapper fastDfsFileMapper;

    @Override
    public UploadBaseInfo getUploadBaseInfo(String key) {
        return jdbcTemplate.queryForObject("SELECT DFS_GROUP,UPLOAD_TYPE,LIMIT_TYPE,LIMIT_COUNT,LIMIT_SIZE FROM UPLOAD_INFO WHERE ID = ?", new RowMapper<UploadBaseInfo>() {
            @Override
            public UploadBaseInfo mapRow(ResultSet rs, int rowNum) throws SQLException {
                UploadBaseInfo uploadBaseInfo = new UploadBaseInfo();
                uploadBaseInfo.setDfsGroup(rs.getString(1));
                uploadBaseInfo.setUploadType(rs.getInt(2));
                String limitTypeStr = rs.getString(3);
                if (!StringUtils.isEmpty(limitTypeStr)) {
                    uploadBaseInfo.setLimitType(Arrays.asList(limitTypeStr.split(",")));
                }
                uploadBaseInfo.setLimitCount(rs.getInt(4));
                uploadBaseInfo.setLimitSize(rs.getBigDecimal(5));
                return uploadBaseInfo;
            }
        }, key);
    }

    @Override
    public BaseMapper getMapper() {
        return dfsFileMapper;
    }

    @Override
    public Object saveUploadFile(UploadedFile uploadedFile,DFSFileInfo dfsFileInfo) {
        DfsFile dfsFile = new DfsFile();
        dfsFile.setFileName(uploadedFile.getFileName());
        dfsFile.setOrginalPath(uploadedFile.getOriginalPath());
        dfsFile = this.save(dfsFile);
        saveFile(dfsFile.getId(),dfsFileInfo);
        return dfsFile;
    }

    @Override
    public Object saveUploadImage(UploadedImageFile uploadedImageFile,ImageDFSFileInfo imageDFSFileInfos) {
        DfsFile dfsFile = new DfsFile();
        dfsFile.setFileName(uploadedImageFile.getFileName());
        dfsFile.setLargeThumbPath(uploadedImageFile.getLargeThumbnailPath());
        dfsFile.setOrginalPath(uploadedImageFile.getOriginalPath());
        dfsFile.setSmallThumbPath(uploadedImageFile.getSmallThumbnailPath());
        dfsFile = this.save(dfsFile);
        /*对FastDFS信息进行存储*/
        //1.存储原图
        saveFile(dfsFile.getId(), imageDFSFileInfos.getOriginalImageFileInfo());
        //2.存储大缩略图
        saveFile(dfsFile.getId(), imageDFSFileInfos.getLargeThumbnailFileInfo());
        //3.存储小缩略图
        saveFile(dfsFile.getId(), imageDFSFileInfos.getSmallThumbnailFileInfo());
        return dfsFile;
    }

    private void saveFile(String fileId,DFSFileInfo dfsFileInfo){
        if (dfsFileInfo != null){
            FastDfsFile file = new FastDfsFile();
            file.setFileid(fileId);
            file.setGroupName(dfsFileInfo.getGroup());
            file.setPath(dfsFileInfo.getPath());
            file.setGroupServerName(dfsFileInfo.getGroupServer());
            file.setFileName(dfsFileInfo.getFileName());
            file.setId(UUID.randomUUID().toString());
            fastDfsFileMapper.insert(file);
        }
    }

    @Override
    public UploadInfo getUploadInfo(String key) {
        return jdbcTemplate.queryForObject("SELECT ID,DFS_GROUP,UPLOAD_TYPE,LIMIT_TYPE,LIMIT_COUNT,LIMIT_SIZE,DELETE_STRATEGY,DELETE_EXPRESSION,COMPRESS_STRATEGY FROM UPLOAD_INFO WHERE ID = ?", new RowMapper<UploadInfo>() {
            @Override
            public UploadInfo mapRow(ResultSet rs, int rowNum) throws SQLException {
                UploadInfo uploadInfo = null;
                if (StringUtils.equals("0",rs.getString(3))){
                    uploadInfo = new UploadInfo();
                }else{
                    uploadInfo = new ImageUploadInfo();
                }


                uploadInfo.setKey(rs.getString(1));
                uploadInfo.setDfsGroup(rs.getString(2));
                uploadInfo.setUploadType(rs.getInt(3));
                String limitTypeStr = rs.getString(4);
                if (!StringUtils.isEmpty(limitTypeStr)) {
                    uploadInfo.setLimitType(Arrays.asList(limitTypeStr.split(",")));
                }
                uploadInfo.setLimitCount(rs.getInt(5));
                uploadInfo.setLimitSize(rs.getBigDecimal(6));
                String deleteStrategy = rs.getString(7);
                if (StringUtils.equals("1",deleteStrategy)){
                    uploadInfo.setDeleteStrategy(DeleteStrategy.PHYSIC_DELETE);
                }else{
                    uploadInfo.setDeleteStrategy(DeleteStrategy.LOGIC_DELETE);
                }
                uploadInfo.setDeleteExpression(rs.getString(8));
                if (StringUtils.equals("0",rs.getString(3))){
                    return uploadInfo;
                }else{
                    ImageUploadInfo imageUploadInfo = (ImageUploadInfo) uploadInfo;
                    //解析压缩策略
                    ObjectMapper objectMapper = new ObjectMapper();
                    CompressStrategy compressStrategy =null;
                    try {
                        compressStrategy = objectMapper.readValue(rs.getString(9),objectMapper.constructType(CompressStrategy.class));
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    imageUploadInfo.setCompressStrategy(compressStrategy);

                    return imageUploadInfo;
                }
            }
        }, key);
    }

    @Override
    public boolean deleteById(String fileId) {
        //删除文件ID下所有相关文件数据
        FastDfsFileExample example = new FastDfsFileExample();
        example.createCriteria().andFileidEqualTo(fileId);
        fastDfsFileMapper.deleteByExample(example);

        //删除文件数据
        dfsFileMapper.deleteByPrimaryKey(fileId);
        return true;
    }

    @Override
    public List<DFSFileInfo> getDfsFileInfo(String fileId) {
        FastDfsFileExample example = new FastDfsFileExample();
        example.createCriteria().andFileidEqualTo(fileId);
        List<FastDfsFile> fastDfsFiles = fastDfsFileMapper.selectByExample(example);

        return fastDfsFiles.stream().map(fastDfsFile->{
            DFSFileInfo dfsFileInfo = new DFSFileInfo();
            dfsFileInfo.setGroup(fastDfsFile.getGroupName());
            dfsFileInfo.setPath(fastDfsFile.getPath());
            dfsFileInfo.setFileName(fastDfsFile.getFileName());
            dfsFileInfo.setGroupServer(fastDfsFile.getGroupServerName());
            return dfsFileInfo;
        }).collect(Collectors.toList());
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        this.jdbcTemplate = new JdbcTemplate(this.dataSource);
    }
}

1.5 编写示例业务配置

现有示例业务表如下:
TEST_BUSINESS:

列名 含义
id 主键
business_name 业务名称

TEST_BUSINESS_FILE (业务与文件关系表):

列名 含义
id 主键
BUSINESS_ID 业务ID
FILE_ID 文件存储ID,对应DFS_FILE表的主键

编写业务操作Service与Controller,此处略去接口编写,自己根据业务需要添加

TestBusinessServiceImpl.java

package com.gillion.sebusiness.demo.service.upload.impl;

import com.gfa4j.mybatis.mapper.BaseMapper;
import com.gfa4j.mybatis.service.impl.BaseServiceImpl;
import com.gfa4j.utils.ResultUtils;
import com.gillion.fdfs.group.ClientGroupContainer;
import com.gillion.sebusiness.demo.service.upload.TestBusinessService;
import com.gillion.sebusiness.demo.vo.upload.TestBusinessVO;
import com.gillion.sebusiness.upload.mapper.*;
import com.gillion.sebusiness.upload.model.DfsFile;
import com.gillion.sebusiness.upload.model.TestBusiness;
import com.gillion.sebusiness.upload.model.TestBusinessFile;
import com.gillion.sebusiness.upload.model.TestBusinessFileExample;
import com.gillion.upload.service.UploadService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;

/**
 * Created by wengms on 2015/8/6.
 */
@Service("testBusinessService")
public class TestBusinessServiceImpl extends BaseServiceImpl implements TestBusinessService {

    @Autowired
    private TestBusinessMapper testBusinessMapper;

    @Autowired
    private TestBusinessFileMapper testBusinessFileMapper;

    @Autowired
    private DfsFileMapper dfsFileMapper;

    @Autowired
    private UploadService uploadService;

    @Autowired
    private UploadInfoMapper uploadInfoMapper;

    @Autowired
    private FastDfsFileMapper fastDfsFileMapper;

    @Autowired
    private ClientGroupContainer clientGroupContainer;


    @Override
    public BaseMapper getMapper() {
        return testBusinessMapper;
    }


    @Override
    public TestBusinessVO save(TestBusinessVO testBusinessVO) {
        TestBusiness testBusiness = new TestBusiness();
        BeanUtils.copyProperties(testBusinessVO, testBusiness);
        List<DfsFile> dfsFiles = testBusinessVO.getDfsFiles();
        List<String> fileIds = dfsFiles.stream().map((dfsFile) -> dfsFile.getId()).collect(Collectors.toList());

        testBusiness = this.save(testBusiness);
        final String businessId = testBusiness.getId();
        fileIds.forEach(fileId -> {
            TestBusinessFile testBusinessFile = new TestBusinessFile();
            testBusinessFile.setFileId(fileId);
            testBusinessFile.setBusinessId(businessId);
            testBusinessFile.setId(UUID.randomUUID().toString());
            this.testBusinessFileMapper.insert(testBusinessFile);
        });
        return testBusinessVO;
    }

    @Override
    public TestBusinessVO selectById(String id) {
        TestBusiness testBusiness = this.selectByPrimaryKey(id);
        TestBusinessFileExample example = new TestBusinessFileExample();
        example.createCriteria().andBusinessIdEqualTo(id);
        List<TestBusinessFile> testBusinessFiles = this.testBusinessFileMapper.selectByExample(example);
        List<DfsFile> dfsFiles = testBusinessFiles.stream().map((file) -> dfsFileMapper.selectByPrimaryKey(file.getFileId())).collect(Collectors.toList());

        TestBusinessVO testBusinessVO = new TestBusinessVO();
        BeanUtils.copyProperties(testBusiness, testBusinessVO);
        testBusinessVO.setDfsFiles(dfsFiles);

        return testBusinessVO;
    }

    @Override
    public Object delete(String fileId, String bussinessId) {
        TestBusinessFileExample testBusinessFileExample = new TestBusinessFileExample();
        testBusinessFileExample.createCriteria().andBusinessIdEqualTo(bussinessId).andFileIdEqualTo(fileId);
        testBusinessFileMapper.deleteByExample(testBusinessFileExample);
        uploadInfoMapper.deleteByPrimaryKey(fileId);
        return ResultUtils.getSuccessResultData();
    }
}

在数据库表UPLOAD_INFO里配置删除引用表达式为:@testBusinessService.delete([fileInfo][id],[id]),即在删除文件时,调用此方法,删除业务表与文件表的引用关系

TestBusinessVO:

package com.gillion.sebusiness.demo.vo.upload;

import com.gillion.sebusiness.upload.model.DfsFile;

import java.util.List;

/**
 * Created by wengms on 2015/8/6.
 */
public class TestBusinessVO {
    private String id;
    private String businessName;

    private List<DfsFile> dfsFiles;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getBusinessName() {
        return businessName;
    }

    public void setBusinessName(String businessName) {
        this.businessName = businessName;
    }

    public List<DfsFile> getDfsFiles() {
        return dfsFiles;
    }

    public void setDfsFiles(List<DfsFile> dfsFiles) {
        this.dfsFiles = dfsFiles;
    }
}

TestBusinessController:

package com.gillion.sebusiness.demo.controller.upload;

import com.gillion.sebusiness.demo.service.datasource.StudentService;
import com.gillion.sebusiness.demo.service.upload.TestBusinessService;
import com.gillion.sebusiness.demo.vo.upload.TestBusinessVO;
import com.gillion.sebusiness.upload.model.DfsFile;
import com.gillion.sebusiness.upload.model.TestBusiness;
import com.gillion.sebusiness.upload.model.TestBusinessFile;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.stream.Collectors;

/**
 * Created by wengms on 2015/8/6.
 */
@RequestMapping("/upload/test")
@Controller
public class TestBusinessController {

    @Autowired
    private TestBusinessService testBusinessService;


    @ResponseBody
    @RequestMapping(method = RequestMethod.POST)
    public TestBusinessVO save(@RequestBody TestBusinessVO testBusinessVO){
        return this.testBusinessService.save(testBusinessVO);
    }

    @RequestMapping(method = RequestMethod.GET)
    @ResponseBody
    public TestBusinessVO get(@RequestParam String id){
        return this.testBusinessService.selectById(id);
    }
}

至此,后端配置已完成。

2. 上传控件前端配置

前端配置属性:

参数名 含义 是否必须 说明
key 用于前端获取前端配置的key Y
upload-info-url 获取配置信息的访问地址 Y
upload-url 文件上传地址 N 若没填写,默认与upload-info-url相同
delete-url 点击删除时,访问的接口地址 Y
delete-params 在删除时,需要携带的信息,如:业务ID等 N 为字面量配置:{“businessId”:”321321321”}
initial-show-count 初始化时显示的数量 N 默认为1
image-show-url-prop 如果控件显示是从已有的ngModel中取值进行显示,则ngModel必须提供一个控件访问地址,同时还需要配置此属性去接收那个地址,用于控件进行显示 N 默认为smallThumbnail
ng-model 双向绑定 N 若有设值,则为一个数组,默认每个文件信息里必须包含:id,url用于在页面中文件的显示与点击删除按钮时,文件信息的传递

示例配置:

    <g-upload-group 
    key="1" 
    upload-info-url="/sebusiness/upload"
    upload-url="/sebusiness/upload"
    delete-url="/sebusiness/upload/delete"
    delete-params="deleteParams"
    initial-show-count="1"
    image-show-url-prop="smallThumbPath"
    ng-model="business.dfsFiles"
    >
    </g-upload-group>

js示例代码:


define(["angular", "framework/upload/UploadGroupModule"], function(angular) {
    var TestUploadModule;
    TestUploadModule = angular.module("TestUploadModule", ["UploadGroupModule"]);
    TestUploadModule.controller("UploadController", function($scope, Resource) {
      var Business;
      Business = Resource("/sebusiness/upload/test");
      Business.get({
        id: "e782f3a3-1988-47b6-a768-1e1267dd78cc"
      }, function(result) {
        $scope.business = result;
        $scope.deleteParams = {
          id: "e782f3a3-1988-47b6-a768-1e1267dd78cc"
        };
      });

      /*保存订单 */
      $scope.save = function() {
        $scope.business.id = void 0;
        Business.save($scope.business, function(result) {
          console.info("保存成功!!");
        });
      };
    });
  });