提交 4bde5096 authored 作者: zhouzhigang's avatar zhouzhigang

--no commit message

上级 f2383551
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.zrqx</groupId>
<artifactId>com.zrqx.pom</artifactId>
<version>1.0.0</version>
<relativePath>../com.zrqx.pom</relativePath>
</parent>
<groupId>com.zrqx.file</groupId>
<artifactId>com.zrqx.file</artifactId>
<dependencies>
<!--视频时长 -->
<dependency>
<groupId>it.sauronsoftware.jave</groupId>
<artifactId>jave</artifactId>
<version>1.0.2</version>
</dependency>
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.11.3</version>
</dependency>
<!-- <dependency> <groupId>com.positiondev.epublib</groupId> <artifactId>epublib-core</artifactId>
<version>3.1</version> </dependency> -->
<dependency>
<groupId>com.github.junrar</groupId>
<artifactId>junrar</artifactId>
<version>0.7</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.2</version>
</dependency>
<dependency>
<groupId>com.zrqx</groupId>
<artifactId>com.zrqx.core</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
</dependency>
<!--熔断器 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix-dashboard</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zipkin</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<!--表示为web工程 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Springsecurity给服务端提供安全访问 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<!-- 用于健康监控 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!-- <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId>
</dependency> -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- 李禚新添加jar用于ftp上传和文件互转 -->
<dependency>
<groupId>commons-net</groupId>
<artifactId>commons-net</artifactId>
<version>3.6</version>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
<!--分布式事务 -->
<!-- <dependency> <groupId>com.codingapi</groupId> <artifactId>transaction-springcloud</artifactId>
<exclusions> <exclusion> <groupId>org.slf4j</groupId> <artifactId>*</artifactId>
</exclusion> </exclusions> </dependency> <dependency> <groupId>com.codingapi</groupId>
<artifactId>tx-plugins-db</artifactId> <exclusions> <exclusion> <groupId>org.slf4j</groupId>
<artifactId>*</artifactId> </exclusion> </exclusions> </dependency> -->
<!--swagger2 -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
</dependency>
<!-- 引入epublib -->
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.8.3</version>
</dependency>
<dependency>
<groupId>com.positiondev.epublib</groupId>
<artifactId>epublib-core</artifactId>
<version>3.1</version>
</dependency>
<!--用于测试的 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- 热部署工具 -->
<!-- <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId>
</dependency> -->
</dependencies>
</project>
\ No newline at end of file
package com.zrqx.file;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.feign.EnableFeignClients;
import org.springframework.cloud.netflix.hystrix.EnableHystrix;
import org.springframework.cloud.netflix.hystrix.dashboard.EnableHystrixDashboard;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Import;
import org.springframework.transaction.PlatformTransactionManager;
import com.zrqx.file.util.SpringUtil;
import tk.mybatis.spring.annotation.MapperScan;
@SpringBootApplication
@Import(SpringUtil.class)
@EnableEurekaClient
@EnableFeignClients
@EnableHystrix
@EnableHystrixDashboard
@MapperScan(basePackages = { "com.zrqx.file.mapper" })
public class AppStart {
private final static Logger logger = LoggerFactory.getLogger(AppStart.class);
public static void main(String[] args) throws InterruptedException {
SpringApplication.run(AppStart.class, args);
logger.info("File服务已启动.....");
}
@Bean
public Object testBean(PlatformTransactionManager platformTransactionManager) {
System.out.println(">>>>>>>>>>" + platformTransactionManager.getClass().getName());
return new Object();
}
}
package com.zrqx.file.client;
import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import com.zrqx.core.util.CallBack;
import com.zrqx.file.util.JSONResult;
@FeignClient(name="pdf", fallback = PdfClientHystric.class)
public interface PdfClient {
@GetMapping("/file/dividePDFByPage")
public CallBack<JSONResult> dividePDFByPage (@RequestParam("pdfFilename") String pdfFilename,@RequestParam("pdfSlice") Integer pdfSlice);
}
\ No newline at end of file
package com.zrqx.file.client;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;
import com.zrqx.core.util.CallBack;
import com.zrqx.file.util.JSONResult;
@Component
public class PdfClientHystric implements PdfClient {
private static final Logger log = Logger.getLogger(PdfClientHystric.class);
@Override
public CallBack<JSONResult> dividePDFByPage(String pdfFilename, Integer pdfSlice) {
// TODO Auto-generated method stub
return CallBack.fail();
}
}
package com.zrqx.file.client;
import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import com.zrqx.core.constant.resource.ResourceRequestPath;
import com.zrqx.core.model.resource.ebook.Book;
import com.zrqx.core.util.CallBack;
@FeignClient(name="resource", fallback = ResourceClientHystric.class)
public interface ResourceClient {
/** 查找用户,用户所属部门,用户角色*/
@GetMapping(ResourceRequestPath.BG + ResourceRequestPath.EBOOK + ResourceRequestPath.ISBNONE)
CallBack<Book> getOneByIsbn(@RequestParam("isbn") String isbn);
}
\ No newline at end of file
package com.zrqx.file.client;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;
import com.zrqx.core.model.resource.ebook.Book;
import com.zrqx.core.util.CallBack;
import com.zrqx.core.vo.sysuser.bg.user.UserVO;
/**
* @author Tujide.lv
*
*/
@Component
public class ResourceClientHystric implements ResourceClient {
private static final Logger log = Logger.getLogger(ResourceClientHystric.class);
@Override
public CallBack<Book> getOneByIsbn(String isbn) {
return CallBack.fail();
}
}
package com.zrqx.file.commons;
import java.io.IOException;
import java.util.Enumeration;
import java.util.concurrent.TimeUnit;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import com.zrqx.core.enums.ResponseCodeEnum;
import com.zrqx.core.exception.BaseException;
import com.zrqx.core.model.sysuser.user.User;
import com.zrqx.core.util.JsonUtil.JsonUtil;
/**
* redis消息调用
* @author Administrator
*
*/
@Component
public class Redis {
private static final String FG_TOKEN = "y-token";
private static final String BG_TOKEN = "x-token";
@Autowired
StringRedisTemplate stringRedisTemplate;
public void updateDatebase(int num) {
JedisConnectionFactory jedisConnectionFactory = (JedisConnectionFactory) stringRedisTemplate.getConnectionFactory();
jedisConnectionFactory.setDatabase(num);
stringRedisTemplate.setConnectionFactory(jedisConnectionFactory);
}
/**
* 获取后台登录用户信息
*
* @return
*/
public User getUser() {
return getInfoObjectRedis(getToken(BG_TOKEN), User.class);
}
public String fmtObj(Object obj) throws IOException {
return obj instanceof String ? obj.toString():JsonUtil.bean2Json(obj);
}
/**
* 添加到redis
* @param token
* Key
* @param obj
* Value
* @param timeout
* 过期时间
* @param unit
* TimeUnitEnum 时间格式
* @throws IOException
*/
public void set(String token, Object obj, long timeout,TimeUnit unit) throws IOException {
stringRedisTemplate.opsForValue().set(token,fmtObj(obj),timeout,unit);
}
public void set(String token, Object obj, long timeout) throws IOException {
stringRedisTemplate.opsForValue().set(token,fmtObj(obj),timeout,TimeUnit.SECONDS);
}
/**
* 添加到redis
* @param token Key
* @param obj Value
* @throws IOException
*/
public void set(String token,Object obj) throws IOException{
stringRedisTemplate.opsForValue().set(token,fmtObj(obj));
}
/**
* 根据key删除redis中的数据
* @param key
* @throws IOException
*/
public void delete(String key) throws IOException{
stringRedisTemplate.delete(key);
}
/**
* 根据key查询redis中的数据
*
* @param token
* @return
*/
public String get(String token) {
return stringRedisTemplate.opsForValue().get(token);
}
public <T> T getInfoObjectRedis(String key,Class<T> objClass){
try {
String userInfo = get(key);
if(StringUtils.isEmpty(userInfo)) {
throw new BaseException(ResponseCodeEnum.NO_LOGIN);
}
return JsonUtil.json2Bean(userInfo, objClass);
} catch (Exception e) {
throw new BaseException("获取用户信息错误!"+e.getMessage());
}
}
public static String getToken(String tokenName){
HttpServletRequest request = ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest();
Enumeration<String> headerNames = request.getHeaderNames();
String token = null;
while (headerNames.hasMoreElements()) {
String key = (String) headerNames.nextElement();
//TODO--前台获取token
if(key.toLowerCase().equals(tokenName)){
token=request.getHeader(key);
}
}
if (token == null) {
throw new BaseException(ResponseCodeEnum.NO_LOGIN);
}
return token;
}
public static String getBgToken(){
return getToken(BG_TOKEN);
}
public static String getFgToken(){
return getToken(FG_TOKEN);
}
}
package com.zrqx.file.commons.interceptor;
import java.util.Date;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.log4j.Logger;
import org.springframework.http.HttpStatus;
import org.springframework.validation.BindException;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import com.zrqx.core.exception.BaseException;
import com.zrqx.core.util.CallBack;
/**
*controller 异常处理
* @ClassName: CustomExceptionHandler
* @Description: TODO(这里用一句话描述这个类的作用)
* @author 杨振广
* @date 2016-7-14 上午9:45:40
*
*/
@ControllerAdvice
public class CustomExceptionHandler {
private static Logger logger = Logger.getLogger(CustomExceptionHandler.class);
@ExceptionHandler(Exception.class)
@ResponseStatus(HttpStatus.OK)
@ResponseBody
public Object handlerException(HttpServletRequest request,HttpServletResponse response,Exception e){
e.printStackTrace();
StackTraceElement[] s = e.getStackTrace();
StringBuffer stes = new StringBuffer(s.length*2);
for (StackTraceElement stackTraceElement : s) {
stes.append(stackTraceElement.toString());
stes.append("<br/>");
}
String info = "异常时间:"+new Date().toLocaleString()+"\n请求地址:"+request.getRequestURI()+"\n参数:"+request.getQueryString()+"\n"+e.getMessage();
logger.error(info+"\n"+stes.toString());
request.setAttribute("error",info);
request.setAttribute("errorInfo",e.getStackTrace());
return CallBack.exception(e.getMessage());
}
/**
* 参数验证异常处理
* @Title: handlerException
* @Description:
* @param request
* @param response
* @param e BindException
* @return
* @author lpf
* @date: 2018年5月9日 下午5:01:58
*/
@ExceptionHandler(BindException.class)
@ResponseStatus(HttpStatus.OK)
@ResponseBody
public Object handlerException(HttpServletRequest request,HttpServletResponse response,BindException e) {
List<ObjectError> errors = e.getAllErrors();
StringBuffer msg = new StringBuffer();
for (ObjectError objectError : errors) {
msg.append(objectError.getDefaultMessage());
msg.append(",");
}
msg.deleteCharAt(msg.length()-1);
return CallBack.validate(msg.toString());
}
/**
* 执行异常处理
* @Description:
* @param e BaseException
* @return
* @date: 2018年5月9日 下午5:01:58
*
*/
@ExceptionHandler(BaseException.class)
@ResponseStatus(HttpStatus.OK)
@ResponseBody
public Object myException(BaseException e) {
return CallBack.exception(e.getCode(),null,e.getMessage());
}
}
\ No newline at end of file
package com.zrqx.file.config;
public class FTPConfig {
public static String ip = "192.168.2.234";
//public static String ip = "192.168.0.208";
public static Integer port = 21;
public static String username = "lizhuo";
//public static String username = "hxcbs";
public static String password = "111111";
//public static String password = "11111111";
}
package com.zrqx.file.config;
import java.lang.reflect.Method;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
@Configuration
@EnableCaching
public class RedisConfig extends CachingConfigurerSupport{
@Bean
public KeyGenerator keyGenerator() {
return new KeyGenerator() {
@Override
public Object generate(Object target, Method method, Object... params) {
StringBuilder sb = new StringBuilder();
sb.append(target.getClass().getName());
sb.append(method.getName());
for (Object obj : params) {
sb.append(obj.toString());
}
return sb.toString();
}
};
}
@SuppressWarnings("rawtypes")
@Bean
public CacheManager cacheManager(RedisTemplate redisTemplate) {
RedisCacheManager rcm = new RedisCacheManager(redisTemplate);
//设置缓存过期时间
//rcm.setDefaultExpiration(60);//秒
return rcm;
}
@Bean
public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory factory) {
StringRedisTemplate template = new StringRedisTemplate(factory);
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
template.setValueSerializer(jackson2JsonRedisSerializer);
template.afterPropertiesSet();
return template;
}
}
\ No newline at end of file
package com.zrqx.file.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
/**
* 访问地址 http://ip:port/swagger-ui.html
*
* 最常用的5个注解
*
* @Api:修饰整个类,描述Controller的作用
* @ApiOperation:描述一个类的一个方法,或者说一个接口
* @ApiParam:单个参数描述
* @ApiModel:用对象来接收参数
* @ApiModelProperty:用对象接收参数时,描述对象的一个字段
*
* 其它若干
*
* @ApiResponse:HTTP响应其中1个描述
* @ApiResponses:HTTP响应整体描述
* @ApiIgnore:使用该注解忽略这个API
*
* @ApiClass
* @ApiError
* @ApiErrors
*
* @ApiParamImplicit
* @ApiParamsImplicit
*/
@EnableSwagger2
@Configuration
public class Swagger2Config {
@Bean
public Docket createRestApi() {
return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo()).select()
// 为当前包路径
.apis(RequestHandlerSelectors.basePackage("com.zrqx.file.controller")).paths(PathSelectors.any())
.build();
}
// 构建 api文档的详细信息函数
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
// 页面标题
.title("file 测试使用 Swagger2 构建RESTful API")
// 描述
.description("file服务 API 描述")
// 创建人
.contact(new Contact("陈新昌", "www.baidu.com", "cxinchang@126.com"))
// 版本号
.version("1.0")
.build();
}
}
\ No newline at end of file
package com.zrqx.file.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
@Configuration
public class WebAppConfig extends WebMvcConfigurerAdapter {
/**
* 跨域支持
*/
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**").allowedOrigins("*").allowedMethods("*").allowCredentials(false).maxAge(3600);
}
}
\ No newline at end of file
package com.zrqx.file.controller;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import javax.servlet.http.HttpServletRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import com.zrqx.core.exception.BaseException;
import com.zrqx.core.vo.resource.ebook.EpubVo;
import com.zrqx.file.commons.Redis;
import com.zrqx.file.util.BookUtil;
@RestController
@RequestMapping(value = "/epub")
@Api(description = "单本epub解析(弃用)")
public class EpubController {
private final static Logger logger = LoggerFactory.getLogger(EpubController.class);
@Value("${file-root-path}")
private String rootPath;
@Autowired
private Redis redis;
private EpubVo ev = new EpubVo();
@ApiOperation(value = "epub上传 返回token")
@RequestMapping(value = "/upload", method = RequestMethod.POST)
public String upload(@RequestParam("file") MultipartFile file,HttpServletRequest request) throws Exception {
request.setCharacterEncoding("UTF-8");
BookUtil bu = new BookUtil();
String token = "";
try {
EpubVo ev = bu.getBaseInformation(rootPath, file);
token = ev.getEbook().getFileName();
redis.set(token, ev);
} catch (Exception e) {
throw new BaseException("epub上传失败");
}
return token;
}
}
package com.zrqx.file.mapper;
import java.util.List;
import org.apache.ibatis.annotations.Select;
import com.zrqx.core.mapper.BaseMapper;
import com.zrqx.core.model.file.FileInfo;
public interface FileMapper extends BaseMapper<FileInfo>{
@Select("<script>"
+ "SELECT * from fileinfo where suffixName='.epub'"
+ "</script>")
List<FileInfo> queryByIsbn();
}
package com.zrqx.file.model;
import java.util.Date;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
public class FileInfo {
@Id
@GeneratedValue(generator="JDBC")
@ApiModelProperty(value="文件ID")
private Integer id;
@ApiModelProperty(value="文件名")
private String fileName;
@ApiModelProperty(value="内容类型")
private String contentType;
@ApiModelProperty(value="后缀名")
private String suffixName;
@ApiModelProperty(value="原文件名")
private String originalFileName;
@ApiModelProperty(value="存储路径")
private String path;
@ApiModelProperty(value="文件大小")
private Long size;
@ApiModelProperty(value="文件时长")
private Long time;
@ApiModelProperty(value="创建时间")
private Date createTime;
}
package com.zrqx.file.service;
import java.util.List;
import org.springframework.web.multipart.MultipartFile;
import com.zrqx.core.form.file.CreatreQRCodeForm;
import com.zrqx.core.model.file.FileInfo;
import com.zrqx.core.model.pdf.PdfInfo;
import com.zrqx.core.service.BaseService;
public interface FileService extends BaseService<FileInfo, Integer>{
public FileInfo uploadFile(MultipartFile file);
public FileInfo createFile(CreatreQRCodeForm form);
public PdfInfo uploadFilePdf(MultipartFile file);
List<FileInfo> queryByIsbn();
}
package com.zrqx.file.service.impl;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import com.zrqx.core.exception.BaseException;
import com.zrqx.core.form.file.CreatreQRCodeForm;
import com.zrqx.core.mapper.BaseMapper;
import com.zrqx.core.model.file.FileInfo;
import com.zrqx.core.model.pdf.PdfInfo;
import com.zrqx.core.model.pdf.PdfInfoMapper;
import com.zrqx.core.service.BaseServiceImpl;
import com.zrqx.core.util.QrCodeCreateUtil;
import com.zrqx.core.util.UUIDUtil;
import com.zrqx.file.mapper.FileMapper;
import com.zrqx.file.service.FileService;
@Service
public class FileServiceImpl extends BaseServiceImpl<FileInfo, Integer> implements FileService {
private final static Logger logger = LoggerFactory.getLogger(FileServiceImpl.class);
@Autowired
private FileMapper mapper;
@Override
public BaseMapper<FileInfo> getMapper() {
return mapper;
}
@Value("${file-root-path}")
private String rootPath;
@Override
public FileInfo uploadFile(MultipartFile file) {
String contentType = file.getContentType();
// 获取文件名
String fileName = file.getOriginalFilename();
// 获取文件的后缀名
String suffixName = fileName.substring(fileName.lastIndexOf("."));
// 解决中文问题,liunx下中文路径,图片显示问题
String uuid = UUIDUtil.getUUID();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
String path = sdf.format(new Date());
String filePath = rootPath + path + "/";
File targetFile = new File(filePath);
if (!targetFile.exists()) {
targetFile.mkdirs();
}
filePath = filePath + uuid + suffixName;
FileOutputStream fos = null;
BufferedOutputStream bos = null;
FileInfo entity = new FileInfo();
try {
fos = new FileOutputStream(filePath);
bos = new BufferedOutputStream(fos);
bos.write(file.getBytes());
entity.setFileName(uuid);
entity.setOriginalFileName(fileName);
entity.setSuffixName(suffixName);
entity.setPath(path);
entity.setContentType(contentType);
entity.setSize(file.getSize());
entity.setCreateTime(new Date());
} catch (Exception e) {
logger.error("上传异常:" + e);
e.printStackTrace();
} finally {
try {
if (null != fos)
fos.close();
if (null != bos)
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return entity;
}
@Override
public FileInfo createFile(CreatreQRCodeForm form) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
String path = sdf.format(new Date());
String filePath = rootPath + path + "/";
File targetFile = new File(filePath);
if (!targetFile.exists()) {
targetFile.mkdirs();
}
// 获取文件名
String fileName = form.getFileName();
// 获取文件的后缀名
String suffixName = ".jpg";
// 解决中文问题,liunx下中文路径,图片显示问题
String uuid = UUIDUtil.getUUID();
filePath = filePath + uuid + suffixName;
FileOutputStream fos = null;
BufferedOutputStream bos = null;
FileInfo entity = new FileInfo();
try {
File file = new File(filePath);
fos = new FileOutputStream(file);
bos = new BufferedOutputStream(fos);
if (!QrCodeCreateUtil.createQrCode(fos, form.getContent())) {
throw new BaseException(fileName + ": 二维码生成失败!" + form.getContent());
}
entity.setFileName(uuid);
entity.setOriginalFileName(fileName+suffixName);
entity.setSuffixName(suffixName);
entity.setPath(path);
entity.setContentType(form.getContent());
entity.setSize(file.length());
entity.setCreateTime(new Date());
} catch (Exception e) {
logger.error("上传异常:" + e);
e.printStackTrace();
} finally {
try {
if (null != fos)
fos.flush();
if (null != bos)
bos.close();
} catch (IOException e) {
}
}
return entity;
}
@Override
public PdfInfo uploadFilePdf(MultipartFile file) {
String contentType = file.getContentType();
// 获取文件名
String fileName = file.getOriginalFilename();
// 获取文件的后缀名
String suffixName = fileName.substring(fileName.lastIndexOf("."));
// 解决中文问题,liunx下中文路径,图片显示问题
String uuid = UUIDUtil.getUUID();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
String path = sdf.format(new Date());
String filePath = rootPath + path + "/";
File targetFile = new File(filePath);
if (!targetFile.exists()) {
targetFile.mkdirs();
}
filePath = filePath + uuid + suffixName;
FileOutputStream fos = null;
BufferedOutputStream bos = null;
PdfInfo entity = new PdfInfo();
try {
fos = new FileOutputStream(filePath);
bos = new BufferedOutputStream(fos);
bos.write(file.getBytes());
entity.setFilename(fileName);
entity.setFileNameId(uuid);
entity.setPath(path);
entity.setUploadtime(new Date());
} catch (Exception e) {
logger.error("上传异常:" + e);
e.printStackTrace();
} finally {
try {
if (null != fos)
fos.close();
if (null != bos)
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return entity;
}
@Override
public List<FileInfo> queryByIsbn() {
// TODO Auto-generated method stub
return mapper.queryByIsbn();
}
}
package com.zrqx.file.util;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.springframework.context.ApplicationContext;
import org.springframework.web.multipart.MultipartFile;
import com.zrqx.core.exception.BaseException;
import com.zrqx.core.model.file.FileInfo;
import com.zrqx.core.model.resource.articlelibrary.ArticleLibrary;
import com.zrqx.core.model.resource.articlelibrary.ChapterLibrary;
import com.zrqx.core.model.resource.ebook.Book;
import com.zrqx.core.model.resource.ebook.BookGoods;
import com.zrqx.core.model.resource.ebook.BookIssued;
import com.zrqx.core.model.resource.ebook.Ebook;
import com.zrqx.core.model.resource.imagelibrary.ImageLibrary;
import com.zrqx.core.util.UUIDUtil;
import com.zrqx.core.vo.resource.ebook.EpubVo;
import com.zrqx.file.service.FileService;
import nl.siegmann.epublib.domain.TOCReference;
public class BookUtil {
ApplicationContext appCtx = SpringUtil.getApplicationContext();
public FileService service = appCtx.getBean(FileService.class);
private EpubVo ev = new EpubVo();
public EpubVo getBaseInformation(String rootPath, MultipartFile file) throws Exception {
// 获取原文件的全名称
String originalFilename = file.getOriginalFilename();
System.out.println(file.getContentType());
// 源文件的名称,不带后缀
String fileName = originalFilename.substring(0, originalFilename.lastIndexOf("."));
FileInfo fileInfo = new FileInfo();
fileInfo.setOriginalFileName(originalFilename);
/* int count = service.selectCount(fileInfo);
if (count > 0) {
throw new BaseException("epub已存在");
}*/
Ebook ebook = new Ebook();
Book book = new Book();
BookGoods bookgoods =new BookGoods();
BookIssued bookissued = new BookIssued();
// epub工具类
EpubUtil epubUtil = new EpubUtil();
// epub解析方法类
EpubResolve er = new EpubResolve();
FileInfo entity = er.uploadFile(file, rootPath , fileName);
if (!service.insert(entity)) {
throw new BaseException("上传失败!");
} else {
String path = entity.getPath();
// 载入电子书资源
epubUtil.setEpubFile(file.getInputStream());
ev.setBook(book);
ev.setEbook(ebook);
ev.setBookgoods(bookgoods);
ev.setBookissued(bookissued);
ev = er.setBookInfo(epubUtil, ev);
/**
* 保存元数据相关内容
*/
// 名称
book.setName(epubUtil.getBookTitle());
// 作者
book.setAuthor(epubUtil.getAuthor());
// 出版时间
book.setPublishTime(epubUtil.getPublishDate());
book.setIsbn(epubUtil.getISBN());
// 关键字(图书的名字)20
book.setKeywords(epubUtil.getBookTitle());
// 保存封面
if(epubUtil.getCover() != null){
String imgName = epubUtil.getCover().getHref().substring(epubUtil.getCover().getHref().lastIndexOf("/") + 1);
MultipartFile multipartFile = new MockMultipartFile(imgName, imgName, "image/jpeg", epubUtil.getCover().getInputStream());
FileInfo cover = er.uploadFile(multipartFile, rootPath , fileName);
book.setCover(cover.getFileName());
service.insert(cover);
}
book.setUploadTime(new Date());
book.setStatus(0);
book.setId(UUIDUtil.getUUID());
ev.setBook(book);
/**
* 保存电子书相关内容
*/
ebook.setBookId(book.getId());
ebook.setUploadTime(new Date());
// 修改时间4
ebook.setUpdateTime(new Date());// 设置为上传时间
ebook.setEpubFile(path);
ebook.setFileName(entity.getFileName());
// css路径
FileInfo cssentity = er.getCss(epubUtil, rootPath , fileName);
if (!service.insert(cssentity)) {
throw new BaseException("css文件上传失败!");
}
ebook.setCssPath(cssentity.getFileName());
// 完善图书信息(13-17)
ev.setEbook(ebook);
// ---------获取图书所有内容------------
List<TOCReference> listReferences = epubUtil.getTocReferences();
// 当前目录
TOCReference tocRef = new TOCReference();
// 初始化顶级目录id 为 "0"
tocRef.setFragmentId("0");
// 初始化顶级目录层级为 0
int level = 0;
// *******************解析章节信息*************
Set<ChapterLibrary> chapterSet = new HashSet<>();
chapterSet = er.setChapter(listReferences, tocRef, level, ebook, chapterSet);
ev.setChapterSet(chapterSet);
// ******************解析内容信息**************
Set<ArticleLibrary> contentSet = new HashSet<>();
Map<String, String> imgtzMap = new HashMap<>();// 图片图注信息
Object[] data = new Object[2];
ebook.setAuthor(book.getAuthor());
data = er.setContent(listReferences, contentSet, ebook, imgtzMap, data);
ev.setArticleSet(contentSet);
// ************导入图书中的图片资源************
if (data[1] instanceof Map && data[1] != null) {
imgtzMap = (Map<String, String>) data[1];
// 图片info
List<FileInfo> imageInfoList = er.getImages(epubUtil, rootPath , fileName);
if (!service.insertList(imageInfoList)) {
throw new BaseException("图片上传失败!");
}
importBookImgs(imgtzMap, book, imageInfoList);
}
}
return ev;
}
/**
* (后台) 导入epub中的图片资源到resource
*
* @throws Exception
*/
public void importBookImgs(Map<String, String> imgtzMap, Book book,
List<FileInfo> imageInfoList) throws Exception {
Set<ImageLibrary> imageSet = new HashSet<ImageLibrary>();
try {
// 保存图书中的图片资源到资源表中
for (FileInfo file : imageInfoList) {
ImageLibrary il = new ImageLibrary();
String imgName = file.getOriginalFileName();
String showName = imgtzMap.get(file.getPath());
// 图片的页面显示名称(图注),没有默认为原文件名
showName = (showName != null && !showName.equals("")) ? showName : imgName;
il.setName(showName);
// il.setImage(relativeBookFolderPath + file.getPath());
il.setUploadTime(new Date());
il.setBookId(book.getId());
il.setBookName(book.getName());
il.setStatus(0);
il.setImage(file.getFileName());
imageSet.add(il);
}
ev.setImageSet(imageSet);
} catch (Exception e) {
// 保存操作日志
throw new Exception();
}
}
}
package com.zrqx.file.util;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.List;
import java.util.zip.ZipInputStream;
import nl.siegmann.epublib.domain.Author;
import nl.siegmann.epublib.domain.Book;
import nl.siegmann.epublib.domain.Date;
import nl.siegmann.epublib.domain.Identifier;
import nl.siegmann.epublib.domain.MediaType;
import nl.siegmann.epublib.domain.Metadata;
import nl.siegmann.epublib.domain.Resource;
import nl.siegmann.epublib.domain.Resources;
import nl.siegmann.epublib.domain.SpineReference;
import nl.siegmann.epublib.domain.TOCReference;
import nl.siegmann.epublib.epub.EpubReader;
/**
* epub 数字书籍格式 数据工具包
* @author Administrator
*
*/
public class EpubUtil {
private Book book=null;
private EpubReader epubReader=null;
/**
* 设置Book实例对象
* @return
*/
public EpubUtil setEpubFile(File file){
try {
return setEpubFile(new FileInputStream(file));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
return this;
}
/**
* 设置Book实例对象
* @return
*/
public EpubUtil setEpubFile(InputStream in){
try {
epubReader=getEpubReader();
book=epubReader.readEpub(in);
} catch (IOException e) {
e.printStackTrace();
}
return this;
}
/**
* 设置Book实例对象
* @return
*/
public EpubUtil setEpubFile(InputStream in, String encoding){
try {
epubReader=getEpubReader();
book=epubReader.readEpub(in,encoding);
} catch (IOException e) {
e.printStackTrace();
}
return this;
}
/**
* 设置Book实例对象
* @return
*/
public EpubUtil setEpubFile(ZipInputStream in){
try {
epubReader=getEpubReader();
book=epubReader.readEpub(in);
} catch (IOException e) {
e.printStackTrace();
}
return this;
}
/**
* 设置Book实例对象
* @return
*/
public EpubUtil setEpubFile(ZipInputStream in,String encoding){
try {
epubReader=getEpubReader();
book=epubReader.readEpub(in,encoding);
} catch (IOException e) {
e.printStackTrace();
}
return this;
}
/**
* 获取所有的资源对象
* @return
*/
public Resources getResources(){
return book.getResources();
}
/**
* 获取封面
*/
public Resource getCover(){
//epub格式的书籍中都没有将封面图片的信息放到<metadata>标签下的cover标签中。所以用第二种fangs
Resource res = book.getCoverImage();
if(res!=null){
return res;
}else{
Resources ress = book.getResources();
res = ress.getById("cover");
return res;
}
}
/**
* 获取制定的文件资源
* @param mediaTypes
* @return
*/
public List<Resource> getResources(MediaType ... mediaTypes){
return getResources().getResourcesByMediaTypes(mediaTypes);
}
/**
* 获取图书的css资源文件
* @return
*/
public Resource getCssResource(){
List<Resource> list=getResources(new MediaType("text/css","css"));
if(list!=null && list.size()>0){
return list.get(0);
}
return null;
}
/**
* 获取图书的图片资源
* @return
*/
public List<Resource> getImagesResources(){
return getResources(
new MediaType("image/jpeg","jpg"),
new MediaType("image/gif","gif"),
new MediaType("image/png","png")
);
}
/**
*获取根据阅读顺序获取图书的内容资源(html)文件资源
* @return
*/
public List<SpineReference> getSpineReferences(){
return book.getSpine().getSpineReferences();
}
/**
*获取图书的目录结构标题及对应的资源内容
* @return
*/
public List<TOCReference> getTocReferences(){
return book.getTableOfContents().getTocReferences();
}
/**
* 获取图书
* @return
* author:haopeng
*/
public Book getBook(){
return book;
}
/**
* 获取图书信息
* @return
* author:haopeng
* @throws Exception
*/
public Metadata getMetadata() throws Exception{
if(book==null){
throw new NullPointerException("图书Book属性为null");
}
return book.getMetadata();
}
/**
* 获取文件读取器
* @return
*/
private EpubReader getEpubReader(){
if(epubReader==null){
epubReader=new EpubReader();
}
return epubReader;
}
/**
* 获取图书ISBN号
* @throws Exception
*/
public String getISBN() throws Exception{
String isbn=null;
List<Identifier> identifiers=getMetadata().getIdentifiers();
for(Identifier identifier:identifiers){
String value=identifier.getValue();
// if(value.matches("^97[8|9]\\d{10}$") ){//新版isbn号格式
if(value.contains("-")){
value=value.replaceAll("-", "");
isbn=value;
break;
}
isbn=value;
}
return isbn;
}
/**
* 获取图书作者
*/
public String getAuthor(){
List<Author> authors = null;
try {
authors = getMetadata().getAuthors();
} catch (Exception e) {
e.printStackTrace();
}
String author = "";
if(authors.size()>0){
author = authors.get(0).getFirstname()+authors.get(0).getLastname();
author = author.replaceAll("[\\[\\],]"," ");
}
return author;
}
/**
* 获取出版日期
*/
public java.util.Date getPublishDate(){
List<Date> dates = null;
try {
dates = getMetadata().getDates();
} catch (Exception e) {
e.printStackTrace();
}
SimpleDateFormat sdf = new SimpleDateFormat("yyy");
String tempDate = "";
if(dates.size()>0){
if(dates.get(0).toString().contains(".")){
sdf= new SimpleDateFormat("yyy.MM");
}
if(dates.get(0).toString().contains("-")){
sdf= new SimpleDateFormat("yyy-MM");
}
tempDate= dates.get(0).toString();
}
java.util.Date publicDate = null;
try {
if(tempDate!=null && !tempDate.equals("")){
publicDate = sdf.parse(tempDate);
}
} catch (ParseException e) {
System.out.println("日期转换错误!");
e.printStackTrace();
}
return publicDate;
}
/**
* 获取图书的名字
*/
public String getBookTitle(){
String bookTitle = "";
//List<String> bookTitle2 = null;
try {
bookTitle = getMetadata().getFirstTitle();
//bookTitle2 = getMetadata().getTitles();
} catch (Exception e) {
e.printStackTrace();
}
return bookTitle;
}
}
package com.zrqx.file.util;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.FileOutputStream;
import java.util.List;
import javax.imageio.ImageIO;
import nl.siegmann.epublib.domain.Resource;
/**
* 图片处理工具类:<br>
* 功能:缩放图像、切割图像、图像类型转换、彩色转黑白、文字水印、图片水印等
*
* @author Administrator
*/
public class ImageUtil {
/**
* 多线程生成缩略图
*
* @param reslist
* @param dist
*/
public static void createThumbnailToThread(List<Resource> reslist, String dist) {
try {
float width = 165;
float height = 215;
BufferedImage image = null;
BufferedImage bfImage = null;
FileOutputStream os = null;
for (Resource res : reslist) {
/**
* 设置图片路径
*/
String newUrl = dist + res.getHref();
int index = newUrl.lastIndexOf("/");
String imgName = newUrl.substring(index + 1);
String newName = "sl_" + imgName;
String newPath = newUrl.substring(0, index + 1) + newName;
image = ImageIO.read(res.getInputStream());
// 获得缩放的比例
double ratio = 1.0;
// 判断如果高、宽都不大于设定值,则不处理
if (image.getHeight() > height || image.getWidth() > width) {
if (image.getHeight() > image.getWidth()) {
ratio = height / image.getHeight();
} else {
ratio = width / image.getWidth();
}
}
// 计算新的图面宽度和高度
int newWidth = (int) (image.getWidth() * ratio);
int newHeight = (int) (image.getHeight() * ratio);
bfImage = new BufferedImage(newWidth, newHeight, BufferedImage.TYPE_INT_RGB);
bfImage.getGraphics().drawImage(image.getScaledInstance(newWidth, newHeight, Image.SCALE_SMOOTH), 0, 0, null);
os = new FileOutputStream(newPath);
ImageIO.write(bfImage, "jpeg", os);
os.flush();
os.close();
}
} catch (Exception e) {
System.out.println("创建缩略图发生异常" + e.getMessage());
e.printStackTrace();
}
}
}
package com.zrqx.file.util;
import java.util.List;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
/**
*
* @Title: JSONResult.java
* @Package com.wyf.util
* @Description: 自定义响应数据结构
* 这个类是提供给门户,ios,安卓,微信商城用的
* 门户接受此类数据后需要使用本类的方法转换成对于的数据类型格式(类,或者list)
* 其他自行处理
* 200:表示成功
* 500:表示错误,错误信息在msg字段中
* 501:bean验证错误,不管多少个错误都以map形式返回
* 502:拦截器拦截到用户token出错
* 555:异常抛出信息
*
*
* @version V1.0
*/
public class JSONResult {
// 定义jackson对象
private static final ObjectMapper MAPPER = new ObjectMapper();
// 响应业务状态
private Integer status;
// 响应消息
private String msg;
// 响应中的数据
private Object data;
//private String ok; // 不使用
public static JSONResult build(Integer status, String msg, Object data) {
return new JSONResult(status, msg, data);
}
public static JSONResult ok(Object data) {
return new JSONResult(data);
}
public static JSONResult ok() {
return new JSONResult(null);
}
public static JSONResult errorMsg(String msg) {
return new JSONResult(500, msg, null);
}
public static JSONResult errorMap(Object data) {
return new JSONResult(501, "error", data);
}
public static JSONResult errorTokenMsg(String msg) {
return new JSONResult(502, msg, null);
}
public static JSONResult errorException(String msg) {
return new JSONResult(555, msg, null);
}
public JSONResult() {
}
// public static LeeJSONResult build(Integer status, String msg) {
// return new LeeJSONResult(status, msg, null);
// }
public JSONResult(Integer status, String msg, Object data) {
this.status = status;
this.msg = msg;
this.data = data;
}
public JSONResult(Object data) {
this.status = 200;
this.msg = "OK";
this.data = data;
}
public Boolean isOK() {
return this.status == 200;
}
public Integer getStatus() {
return status;
}
public void setStatus(Integer status) {
this.status = status;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
/**
*
* @Description: 将json结果集转化为LeeJSONResult对象
* 需要转换的对象是一个类
* @param jsonData
* @param clazz
* @return
*
* @date 2016年4月22日 下午8:34:58
*/
public static JSONResult formatToPojo(String jsonData, Class<?> clazz) {
try {
if (clazz == null) {
return MAPPER.readValue(jsonData, JSONResult.class);
}
JsonNode jsonNode = MAPPER.readTree(jsonData);
JsonNode data = jsonNode.get("data");
Object obj = null;
if (clazz != null) {
if (data.isObject()) {
obj = MAPPER.readValue(data.traverse(), clazz);
} else if (data.isTextual()) {
obj = MAPPER.readValue(data.asText(), clazz);
}
}
return build(jsonNode.get("status").intValue(), jsonNode.get("msg").asText(), obj);
} catch (Exception e) {
return null;
}
}
/**
*
* @Description: 没有object对象的转化
* @param json
* @return
*
*/
public static JSONResult format(String json) {
try {
return MAPPER.readValue(json, JSONResult.class);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
*
* @Description: Object是集合转化
* 需要转换的对象是一个list
* @param jsonData
* @param clazz
* @return
*
*/
public static JSONResult formatToList(String jsonData, Class<?> clazz) {
try {
JsonNode jsonNode = MAPPER.readTree(jsonData);
JsonNode data = jsonNode.get("data");
Object obj = null;
if (data.isArray() && data.size() > 0) {
obj = MAPPER.readValue(data.traverse(),
MAPPER.getTypeFactory().constructCollectionType(List.class, clazz));
}
return build(jsonNode.get("status").intValue(), jsonNode.get("msg").asText(), obj);
} catch (Exception e) {
return null;
}
}
/*public String getOk() {
return ok;
}*/
/*public void setOk(String ok) {
this.ok = ok;
}*/
}
package com.zrqx.file.util;
/*
* Copyright 2002-2012 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import org.springframework.util.Assert;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.multipart.MultipartFile;
/**
* Mock implementation of the {@link org.springframework.web.multipart.MultipartFile}
* interface.
*
* <p>Useful in conjunction with a {@link MockMultipartHttpServletRequest}
* for testing application controllers that access multipart uploads.
*
* @author Juergen Hoeller
* @author Eric Crampton
* @since 2.0
* @see MockMultipartHttpServletRequest
*/
public class MockMultipartFile implements MultipartFile {
private final String name;
private String originalFilename;
private String contentType;
private final byte[] content;
/**
* Create a new MockMultipartFile with the given content.
* @param name the name of the file
* @param content the content of the file
*/
public MockMultipartFile(String name, byte[] content) {
this(name, "", null, content);
}
/**
* Create a new MockMultipartFile with the given content.
* @param name the name of the file
* @param contentStream the content of the file as stream
* @throws IOException if reading from the stream failed
*/
public MockMultipartFile(String name, InputStream contentStream) throws IOException {
this(name, "", null, FileCopyUtils.copyToByteArray(contentStream));
}
/**
* Create a new MockMultipartFile with the given content.
* @param name the name of the file
* @param originalFilename the original filename (as on the client's machine)
* @param contentType the content type (if known)
* @param content the content of the file
*/
public MockMultipartFile(String name, String originalFilename, String contentType, byte[] content) {
Assert.hasLength(name, "Name must not be null");
this.name = name;
this.originalFilename = (originalFilename != null ? originalFilename : "");
this.contentType = contentType;
this.content = (content != null ? content : new byte[0]);
}
/**
* Create a new MockMultipartFile with the given content.
* @param name the name of the file
* @param originalFilename the original filename (as on the client's machine)
* @param contentType the content type (if known)
* @param contentStream the content of the file as stream
* @throws IOException if reading from the stream failed
*/
public MockMultipartFile(String name, String originalFilename, String contentType, InputStream contentStream)
throws IOException {
this(name, originalFilename, contentType, FileCopyUtils.copyToByteArray(contentStream));
}
@Override
public String getName() {
return this.name;
}
@Override
public String getOriginalFilename() {
return this.originalFilename;
}
@Override
public String getContentType() {
return this.contentType;
}
@Override
public boolean isEmpty() {
return (this.content.length == 0);
}
@Override
public long getSize() {
return this.content.length;
}
@Override
public byte[] getBytes() throws IOException {
return this.content;
}
@Override
public InputStream getInputStream() throws IOException {
return new ByteArrayInputStream(this.content);
}
@Override
public void transferTo(File dest) throws IOException, IllegalStateException {
FileCopyUtils.copy(this.content, dest);
}
}
package com.zrqx.file.util;
/*
* @desc:提供非SPRING管理类调用管理类的功能
* 注意在服务启动的时候进行import,apllication中引入
*/
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
public class SpringUtil implements ApplicationContextAware {
private static ApplicationContext applicationContext = null;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
if (SpringUtil.applicationContext == null) {
SpringUtil.applicationContext = applicationContext;
}
System.out.println("---------------------------------------------------------------------");
System.out.println(
"========ApplicationContext配置成功,在普通类可以通过调用SpringUtils.getAppContext()获取applicationContext对象,applicationContext="
+ SpringUtil.applicationContext + "========");
System.out.println("---------------------------------------------------------------------");
}
// 获取applicationContext
public static ApplicationContext getApplicationContext() {
return applicationContext;
}
// 通过name获取 Bean.
public static Object getBean(String name) {
return getApplicationContext().getBean(name);
}
// 通过class获取Bean.
public static <T> T getBean(Class<T> clazz) {
return getApplicationContext().getBean(clazz);
}
// 通过name,以及Clazz返回指定的Bean
public static <T> T getBean(String name, Class<T> clazz) {
return getApplicationContext().getBean(name, clazz);
}
}
package com.zrqx.file.util;
public class StringUtils {
/**
* 判断字符串中是否包含regex(用逗号隔开的字符串)中的全部或部分
* @param currStr
* @param regex
* @return
*/
public static boolean anyContains(String currStr,String regex){
boolean isContain = false;
String[] strArr = regex.split(",");
for (String s : strArr) {
if(currStr.contains(s)){
isContain = true;
break;
}
}
return isContain;
}
/**
* currStr中包含的"a,b,c"中的最后一个
* @param currStr
* @param regex
* @return
*/
public static Integer containsMaxIndex(String currStr,String regex){
Integer maxIndex = 0;
String[] strArr = regex.split(",");
for (String s : strArr) {
if(currStr.indexOf(s)>0 && currStr.indexOf(s)>maxIndex)
maxIndex = currStr.indexOf(s);
}
return maxIndex;
}
/**
* 判断是否有等于其中某一字符串
* @param currStr
* @param regex
* @return
*/
public static boolean anyEquals(String currStr,String regex){
boolean anyEquals = false;
String[] strArr = regex.split(",");
for (String s : strArr) {
if(currStr.equals(s)){
anyEquals = true;
break;
}
}
return anyEquals;
}
}
#################redis基础配置#################
#spring.redis.database=5
#spring.redis.host=192.168.2.230
#spring.redis.password=123456
#spring.redis.port=6379
# 连接超时时间 单位 ms(毫秒)
#spring.redis.timeout=3000
#################redis线程池设置#################
# 连接池中的最大空闲连接,默认值也是8。
#spring.redis.pool.max-idle=500
#连接池中的最小空闲连接,默认值也是0。
#spring.redis.pool.min-idle=50
# 如果赋值为-1,则表示不限制;如果pool已经分配了maxActive个jedis实例,则此时pool的状态为exhausted(耗尽)。
#spring.redis.pool.max-active=2000
# 等待可用连接的最大时间,单位毫秒,默认值为-1,表示永不超时。如果超过等待时间,则直接抛出JedisConnectionException
#spring.redis.pool.max-wait=1000
#################redis哨兵设置#################
# Redis服务器master的名字
#spring.redis.sentinel.master=master8026
# redis-sentinel的配置地址和端口
#spring.redis.sentinel.nodes=10.189.80.25:26379,10.189.80.26:26379,10.189.80.27:26378
file-root-path=/opt/upload/
#ftp-root-path =/home/lizhuo/
ftp-root-path =/home/hxcbs/
ftp-down-path =download/
feign:
hystrix:
enabled: true
ribbon:
connectionRequestTimeout: 60000000
ConnectTimeout: 60000000
ReadTimeout: 60000000
security:
sessions: always #always设置保存用户状态(内存可能会被占满) stateless设置不保存用户状态
basic:
enabled: false #开启认证
user:
name: user
password: 123456
spring:
resources:
static-locations: classpath:/static/,classpath:/META-INF/resources/,file:/home/hxcbs/,file:/opt/upload/
#
#static-locations: classpath:/static/,classpath:/META-INF/resources/,file:/home/lizhuo/
http:
multipart:
maxFileSize: 2000Mb
maxRequestSize: 2000Mb
redis:
#host: 192.168.0.210
host: 192.168.2.234
port: 6379
password: 123456
timeout: 300000 # 连接超时时间 单位 ms(毫秒)
database: 5
pool:
max-idle: 5000 # 连接池中的最大空闲连接,默认值也是8。
min-idle: 500 #连接池中的最小空闲连接,默认值也是0。
max-active: 200000 # 如果赋值为-1,则表示不限制;如果pool已经分配了maxActive个jedis实例,则此时pool的状态为exhausted(耗尽)。
max-wait: 100000 # 等待可用连接的最大时间,单位毫秒,默认值为-1,表示永不超时。如果超过等待时间,则直接抛出JedisConnectionException
mybatis:
type-aliases-package: com.zrqx.file.model
mapper:
mappers:
- com.zrqx.core.mapper.BaseMapper
not-empty: false
i-d-e-n-t-i-t-y: MYSQL
style: normal
b-e-f-o-r-e: true
pagehelper:
helperDialect: mysql
reasonable: true
supportMethodsArguments: true
params: count=countSql
hystrix:
command:
default:
execution:
isolation:
strategy: SEMAPHORE
thread:
timeoutInMilliseconds: 12000000
\ No newline at end of file
server:
port: 8397
spring:
cloud:
config:
#uri: http://192.168.0.209:8318 #配置中心地址
uri: http://192.168.2.234:8318 #配置中心地址
name: file
profile: prod
label: master
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<configuration
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://www.padual.com/java/logback.xsd"
debug="false" scan="true" scanPeriod="30 second">
<!--读取配置中心的属性-->
<springProperty scope="context" name="name" source="spring.application.name"/>
<property name="ROOT" value="/opt/logs/nrgl/${name}/" />
<property name="FILESIZE" value="50MB" />
<property name="MAXHISTORY" value="100" />
<property name="DATETIME" value="yyyy-MM-dd HH:mm:ss" />
<!-- 控制台打印 -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder charset="utf-8">
<pattern>[%-5level] %d{${DATETIME}} [%thread] %logger{36} - %m%n
</pattern>
</encoder>
</appender>
<!-- ERROR 输入到文件,按日期和文件大小 -->
<appender name="ERROR" class="ch.qos.logback.core.rolling.RollingFileAppender">
<encoder charset="utf-8">
<pattern>[%-5level] %d{${DATETIME}} [%thread] %logger{36} - %m%n
</pattern>
</encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>ERROR</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${ROOT}%d/error.%i.log</fileNamePattern>
<maxHistory>${MAXHISTORY}</maxHistory>
<timeBasedFileNamingAndTriggeringPolicy
class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>${FILESIZE}</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
</appender>
<!-- WARN 输入到文件,按日期和文件大小 -->
<appender name="WARN" class="ch.qos.logback.core.rolling.RollingFileAppender">
<encoder charset="utf-8">
<pattern>[%-5level] %d{${DATETIME}} [%thread] %logger{36} - %m%n
</pattern>
</encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>WARN</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${ROOT}%d/warn.%i.log</fileNamePattern>
<maxHistory>${MAXHISTORY}</maxHistory>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>${FILESIZE}</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
</appender>
<!-- INFO 输入到文件,按日期和文件大小 -->
<appender name="INFO" class="ch.qos.logback.core.rolling.RollingFileAppender">
<encoder charset="utf-8">
<pattern>[%-5level] %d{${DATETIME}} [%thread] %logger{36} - %m%n
</pattern>
</encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>INFO</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${ROOT}%d/info.%i.log</fileNamePattern>
<maxHistory>${MAXHISTORY}</maxHistory>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>${FILESIZE}</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
</appender>
<!-- DEBUG 输入到文件,按日期和文件大小 -->
<appender name="DEBUG" class="ch.qos.logback.core.rolling.RollingFileAppender">
<encoder charset="utf-8">
<pattern>[%-5level] %d{${DATETIME}} [%thread] %logger{36} - %m%n
</pattern>
</encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>DEBUG</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${ROOT}%d/debug.%i.log</fileNamePattern>
<maxHistory>${MAXHISTORY}</maxHistory>
<timeBasedFileNamingAndTriggeringPolicy
class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>${FILESIZE}</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
</appender>
<!-- TRACE 输入到文件,按日期和文件大小 -->
<appender name="TRACE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<encoder charset="utf-8">
<pattern>[%-5level] %d{${DATETIME}} [%thread] %logger{36} - %m%n
</pattern>
</encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>TRACE</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
<rollingPolicy
class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${ROOT}%d/trace.%i.log</fileNamePattern>
<maxHistory>${MAXHISTORY}</maxHistory>
<timeBasedFileNamingAndTriggeringPolicy
class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>${FILESIZE}</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
</appender>
<!-- SQL相关日志输出-->
<logger name="org.mybatis.spring" level="DEBUG" additivity="true" />
<logger name="com.zrqx.file" level="DEBUG" additivity="true" />
<!-- Logger 根目录 -->
<root level="INFO">
<appender-ref ref="STDOUT" />
<appender-ref ref="DEBUG" />
<appender-ref ref="ERROR" />
<appender-ref ref="WARN" />
<appender-ref ref="INFO" />
<appender-ref ref="TRACE" />
</root>
</configuration>
\ No newline at end of file
@CHARSET "UTF-8";
#container {
color: #838383;
font-size: 12px;
}
#uploader .queueList {
margin: 20px;
border: 3px dashed #e6e6e6;
}
#uploader .queueList.filled {
padding: 17px;
margin: 0;
border: 3px dashed transparent;
}
#uploader .queueList.webuploader-dnd-over {
border: 3px dashed #999999;
}
#uploader p {margin: 0;}
.element-invisible {
position: absolute !important;
clip: rect(1px 1px 1px 1px); /* IE6, IE7 */
clip: rect(1px,1px,1px,1px);
}
#uploader .placeholder {
min-height: 350px;
padding-top: 178px;
text-align: center;
background: url(../images/image.png) center 93px no-repeat;
color: #cccccc;
font-size: 18px;
position: relative;
}
#uploader .placeholder .webuploader-pick {
font-size: 18px;
background: #00b7ee;
border-radius: 3px;
line-height: 44px;
padding: 0 30px;
*width: 120px;
color: #fff;
display: inline-block;
margin: 0 auto 20px auto;
cursor: pointer;
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1);
}
#uploader .placeholder .webuploader-pick-hover {
background: #00a2d4;
}
#uploader .placeholder .flashTip {
color: #666666;
font-size: 12px;
position: absolute;
width: 100%;
text-align: center;
bottom: 20px;
}
#uploader .placeholder .flashTip a {
color: #0785d1;
text-decoration: none;
}
#uploader .placeholder .flashTip a:hover {
text-decoration: underline;
}
#uploader .filelist {
list-style: none;
margin: 0;
padding: 0;
}
#uploader .filelist:after {
content: '';
display: block;
width: 0;
height: 0;
overflow: hidden;
clear: both;
}
#uploader .filelist li {
width: 110px;
height: 110px;
background: url(../images/bg.png) no-repeat;
text-align: center;
margin: 0 8px 20px 0;
position: relative;
display: inline;
float: left;
overflow: hidden;
font-size: 12px;
}
#uploader .filelist li p.log {
position: relative;
top: -45px;
}
#uploader .filelist li p.title {
position: absolute;
top: 0;
left: 0;
width: 100%;
overflow: hidden;
white-space: nowrap;
text-overflow : ellipsis;
top: 5px;
text-indent: 5px;
text-align: left;
}
#uploader .filelist li p.progress {
position: absolute;
width: 100%;
bottom: 0;
left: 0;
height: 8px;
overflow: hidden;
z-index: 50;
margin: 0;
border-radius: 0;
background: none;
-webkit-box-shadow: 0 0 0;
}
#uploader .filelist li p.progress span {
display: none;
overflow: hidden;
width: 0;
height: 100%;
background: #1483d8 url(../images/progress.png) repeat-x;
-webit-transition: width 200ms linear;
-moz-transition: width 200ms linear;
-o-transition: width 200ms linear;
-ms-transition: width 200ms linear;
transition: width 200ms linear;
-webkit-animation: progressmove 2s linear infinite;
-moz-animation: progressmove 2s linear infinite;
-o-animation: progressmove 2s linear infinite;
-ms-animation: progressmove 2s linear infinite;
animation: progressmove 2s linear infinite;
-webkit-transform: translateZ(0);
}
@-webkit-keyframes progressmove {
0% {
background-position: 0 0;
}
100% {
background-position: 17px 0;
}
}
@-moz-keyframes progressmove {
0% {
background-position: 0 0;
}
100% {
background-position: 17px 0;
}
}
@keyframes progressmove {
0% {
background-position: 0 0;
}
100% {
background-position: 17px 0;
}
}
#uploader .filelist li p.imgWrap {
position: relative;
z-index: 2;
line-height: 110px;
vertical-align: middle;
overflow: hidden;
width: 110px;
height: 110px;
-webkit-transform-origin: 50% 50%;
-moz-transform-origin: 50% 50%;
-o-transform-origin: 50% 50%;
-ms-transform-origin: 50% 50%;
transform-origin: 50% 50%;
-webit-transition: 200ms ease-out;
-moz-transition: 200ms ease-out;
-o-transition: 200ms ease-out;
-ms-transition: 200ms ease-out;
transition: 200ms ease-out;
}
#uploader .filelist li img {
width: 100%;
}
#uploader .filelist li p.error {
background: #f43838;
color: #fff;
position: absolute;
bottom: 0;
left: 0;
height: 28px;
line-height: 28px;
width: 100%;
z-index: 100;
}
#uploader .filelist li .success {
display: block;
position: absolute;
left: 0;
bottom: 0;
height: 40px;
width: 100%;
z-index: 200;
background: url(../images/success.png) no-repeat right bottom;
}
#uploader .filelist div.file-panel {
position: absolute;
height: 0;
filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0,startColorstr='#80000000', endColorstr='#80000000')\0;
background: rgba( 0, 0, 0, 0.5 );
width: 100%;
top: 0;
left: 0;
overflow: hidden;
z-index: 300;
}
#uploader .filelist div.file-panel span {
width: 24px;
height: 24px;
display: inline;
float: right;
text-indent: -9999px;
overflow: hidden;
background: url(../images/icons.png) no-repeat;
margin: 5px 1px 1px;
cursor: pointer;
}
#uploader .filelist div.file-panel span.rotateLeft {
background-position: 0 -24px;
}
#uploader .filelist div.file-panel span.rotateLeft:hover {
background-position: 0 0;
}
#uploader .filelist div.file-panel span.rotateRight {
background-position: -24px -24px;
}
#uploader .filelist div.file-panel span.rotateRight:hover {
background-position: -24px 0;
}
#uploader .filelist div.file-panel span.cancel {
background-position: -48px -24px;
}
#uploader .filelist div.file-panel span.cancel:hover {
background-position: -48px 0;
}
#uploader .statusBar {
height: 63px;
border-top: 1px solid #dadada;
padding: 0 20px;
line-height: 63px;
vertical-align: middle;
position: relative;
}
#uploader .statusBar .progress {
border: 1px solid #1483d8;
width: 198px;
background: #fff;
height: 18px;
position: relative;
display: inline-block;
text-align: center;
line-height: 20px;
color: #6dbfff;
position: relative;
margin: 0 10px 0 0;
}
#uploader .statusBar .progress span.percentage {
width: 0;
height: 100%;
left: 0;
top: 0;
background: #1483d8;
position: absolute;
}
#uploader .statusBar .progress span.text {
position: relative;
z-index: 10;
}
#uploader .statusBar .info {
display: inline-block;
font-size: 14px;
color: #666666;
}
#uploader .statusBar .btns {
position: absolute;
top: 10px;
right: 20px;
line-height: 40px;
}
#filePicker2 {
display: inline-block;
float: left;
}
#uploader .statusBar .btns .webuploader-pick,
#uploader .statusBar .btns .uploadBtn,
#uploader .statusBar .btns .uploadBtn.state-uploading,
#uploader .statusBar .btns .uploadBtn.state-paused {
background: #ffffff;
border: 1px solid #cfcfcf;
color: #565656;
padding: 0 18px;
display: inline-block;
border-radius: 3px;
margin-left: 10px;
cursor: pointer;
font-size: 14px;
float: left;
}
#uploader .statusBar .btns .webuploader-pick-hover,
#uploader .statusBar .btns .uploadBtn:hover,
#uploader .statusBar .btns .uploadBtn.state-uploading:hover,
#uploader .statusBar .btns .uploadBtn.state-paused:hover {
background: #f0f0f0;
}
#uploader .statusBar .btns .uploadBtn {
background: #00b7ee;
color: #fff;
border-color: transparent;
}
#uploader .statusBar .btns .uploadBtn:hover {
background: #00a2d4;
}
#uploader .statusBar .btns .uploadBtn.disabled {
pointer-events: none;
opacity: 0.6;
}
\ No newline at end of file
<!DOCTYPE html>
<html>
<head>
<title>file.html</title>
<meta charset="UTF-8">
<!--引入CSS-->
<link rel="stylesheet" type="text/css" href="webuploader/webuploader.css">
<style>
.progress{
height: 22px;
width: 100px;
border: 1px solid #000;
}
.progress-bar{
height: 22px;
background-color: red;
}
</style>
</head>
<body>
<input id = "jindutiao" type = "hidden" />
<div id="uploader" class="wu-example">
<!--用来存放文件信息-->
<div id="thelist" class="uploader-list"></div>
<div class="btns">
<div id="picker">选择文件</div>
<button id="ctlBtn" class="btn btn-default">开始上传</button>
</div>
</div>
</body>
<script type="text/javascript">
// 添加全局站点信息
var BASE_URL = '/webuploader';
</script>
<!--引入JS-->
<script type="text/javascript" src="js/jquery-1.9.1.js"></script>
<script type="text/javascript" src="webuploader/webuploader.js"></script>
<script type="text/javascript" src="js/file.js"></script>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>文件夹上传</title>
</head>
<body>
<form action="/ftp/upload/folder" method="post" enctype="multipart/form-data">
<!-- html5支持选择文件夹上传 -->
<input type="file" name="folder" multiple webkitdirectory>
<button type="submit">上传</button>
<input type ="hidden" name="basePath" value="basePath/"/>
</form>
</body>
<!DOCTYPE html>
<html>
<head>
<title>index.html</title>
<meta charset="UTF-8">
<!--引入CSS-->
<link rel="stylesheet" type="text/css" href="webuploader/webuploader.css">
<link rel="stylesheet" type="text/css" href="css/index.css">
<body>
<h1 id="demo">Demo</h1>
<p>您可以尝试文件拖拽,使用QQ截屏工具,然后激活窗口后粘贴,或者点击添加图片按钮,来体验此demo.</p>
<div id="uploader" class="wu-example">
<div class="queueList">
<div id="dndArea" class="placeholder">
<div id="filePicker"></div>
<p>或将照片拖到这里,单次最多可选300张</p>
</div>
</div>
<div class="statusBar" style="display:none;">
<div class="progress">
<span class="text">0%</span> <span class="percentage"></span>
</div>
<div class="info"></div>
<div class="btns">
<div id="filePicker2"></div>
<div class="uploadBtn">开始上传</div>
</div>
</div>
</div>
</body>
<script type="text/javascript">
// 添加全局站点信息
var BASE_URL = '/webuploader';
</script>
<!--引入JS-->
<script type="text/javascript" src="js/jquery-1.9.1.js"></script>
<script type="text/javascript" src="webuploader/webuploader.js"></script>
<script type="text/javascript" src="js/index.js"></script>
</head>
</html>
This source diff could not be displayed because it is too large. You can view the blob instead.
目录说明
========================
```bash
├── Uploader.swf # SWF文件,当使用Flash运行时需要引入。
├── webuploader.js # 完全版本。
├── webuploader.min.js # min版本
├── webuploader.flashonly.js # 只有Flash实现的版本。
├── webuploader.flashonly.min.js # min版本
├── webuploader.html5only.js # 只有Html5实现的版本。
├── webuploader.html5only.min.js # min版本
├── webuploader.noimage.js # 去除图片处理的版本,包括HTML5和FLASH.
├── webuploader.noimage.min.js # min版本
├── webuploader.custom.js # 自定义打包方案,请查看 Gruntfile.js,满足移动端使用。
└── webuploader.custom.min.js # min版本
```
## 示例
请把整个 Git 包下载下来放在 php 服务器下,因为默认提供的文件接受是用 php 编写的,打开 examples 页面便能查看示例效果。
\ No newline at end of file
.webuploader-container {
position: relative;
}
.webuploader-element-invisible {
position: absolute !important;
clip: rect(1px 1px 1px 1px); /* IE6, IE7 */
clip: rect(1px,1px,1px,1px);
}
.webuploader-pick {
position: relative;
display: inline-block;
cursor: pointer;
background: #00b7ee;
padding: 10px 15px;
color: #fff;
text-align: center;
border-radius: 3px;
overflow: hidden;
}
.webuploader-pick-hover {
background: #00a2d4;
}
.webuploader-pick-disable {
opacity: 0.6;
pointer-events:none;
}
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论