xushengqiang hace 6 años
padre
commit
d2fee5072b

+ 1 - 9
src/main/java/cn/efunbox/audio/config/Config.java

@@ -4,16 +4,8 @@ import cn.efunbox.audio.aop.AdminInterceptor;
 import cn.efunbox.audio.aop.AllowOriginIntercepter;
 import cn.efunbox.audio.aop.AuthInterceptor;
 import cn.efunbox.audio.aop.IgnoreOptionsInterceptor;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.context.EnvironmentAware;
 import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.ComponentScan;
 import org.springframework.context.annotation.Configuration;
-import org.springframework.core.env.Environment;
-import org.springframework.web.cors.CorsConfiguration;
-import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
-import org.springframework.web.filter.CorsFilter;
-import org.springframework.web.servlet.config.annotation.CorsRegistry;
 import org.springframework.web.servlet.config.annotation.EnableWebMvc;
 import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
 import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
@@ -58,7 +50,7 @@ public class Config extends WebMvcConfigurerAdapter{
 
         registry.addInterceptor(adminInterceptor())
                 .addPathPatterns("/**", "/device/update", "/device/delete")
-                .excludePathPatterns("/device/**", "/error", "/admin/login", "/audio/search");
+                .excludePathPatterns("/device/**", "/error", "/admin/login", "/audio/search","/file/**");
 
         registry.addInterceptor(ignoreOptionsInterceptor())
                 .addPathPatterns("/**");

+ 87 - 0
src/main/java/cn/efunbox/audio/controller/AlbumController.java

@@ -0,0 +1,87 @@
+package cn.efunbox.audio.controller;
+
+import cn.efunbox.audio.entity.Album;
+import cn.efunbox.audio.service.AdminService;
+import cn.efunbox.audio.service.AlbumService;
+import cn.efunbox.audio.service.TrailService;
+import cn.efunbox.audio.utils.ApiCode;
+import cn.efunbox.audio.utils.Common;
+import cn.efunbox.audio.utils.HttpUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.domain.Page;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * AlbumController
+ * Created by xusq on 2018/5/8.
+ */
+@RestController
+@Slf4j
+@RequestMapping(value = "/album")
+public class AlbumController {
+
+    @Autowired
+    private AlbumService albumService;
+    @Autowired
+    private TrailService trailService;
+    @Autowired
+    private AdminService adminService;
+
+
+    @RequestMapping(method = RequestMethod.POST)
+    public void Insert(HttpServletRequest request, HttpServletResponse response, @RequestBody Album album){
+        List<Album> list = albumService.searchByName(album.getName());
+        if(list!=null && list.size()>0){
+            HttpUtil.responseApiCode(request, response, ApiCode.RECORD_EXIST);
+            return;
+        }
+
+        album = albumService.Insert(album);
+
+        TrailController.Insert(adminService, trailService, request, "album", album.getId(), " 新建专辑:" + album.getName());
+
+        HttpUtil.responseOkData(request, response, album);
+        return;
+    }
+
+    @RequestMapping(value = "/update", method = RequestMethod.PUT)
+    public void Update(HttpServletRequest request, HttpServletResponse response, @RequestBody Album album){
+        Album albumOld = albumService.GetOne(album.getId());
+        if(albumOld==null){
+            HttpUtil.responseApiCode(request, response, ApiCode.PARAMETER_ERROR);
+            return;
+        }
+        album = (Album) Common.CopyValue(album, albumOld);
+        album = albumService.Insert(album);
+
+        TrailController.Insert(adminService, trailService, request, "album", album.getId(), " 更新专辑:" + album.getName());
+
+        HttpUtil.responseOkData(request, response, album);
+        return;
+    }
+
+    @RequestMapping(method = RequestMethod.GET)
+    public void list(HttpServletRequest request, HttpServletResponse response,Integer pageNo,Integer pageSize){
+
+        if (Objects.isNull(pageNo)) {
+            pageNo = 1;
+        }
+        if (Objects.isNull(pageSize)) {
+            pageSize = 10;
+        }
+
+        Page<Album> albumPage = albumService.SearchAll(pageNo,pageSize);
+
+        HttpUtil.responseOkData(request, response, albumPage);
+        return;
+    }
+}

+ 193 - 0
src/main/java/cn/efunbox/audio/controller/FileUploadController.java

@@ -0,0 +1,193 @@
+package cn.efunbox.audio.controller;
+
+import cn.efunbox.audio.utils.ApiCode;
+import cn.efunbox.audio.utils.HttpUtil;
+import cn.efunbox.audio.utils.SnowflakeIdUtil;
+import com.alibaba.fastjson.JSON;
+import com.aliyun.oss.OSSClient;
+import com.aliyun.oss.model.ObjectMetadata;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+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.RestController;
+import org.springframework.web.multipart.MultipartFile;
+import org.springframework.web.multipart.MultipartHttpServletRequest;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.io.InputStream;
+import java.text.SimpleDateFormat;
+import java.util.*;
+
+/**
+ * FileUploadController
+ * Created by xusq on 2018/3/12.
+ */
+@Slf4j
+@RestController
+@RequestMapping("/file")
+public class FileUploadController {
+
+
+
+    /**
+     * ossbuckt名
+     */
+    public static String BUCKETNAME = "efunimgs";
+
+    // 阿里云API的内或外网域名
+    @Value("${ali.oss.endpoint}")
+    private String endpoint;
+    // 阿里云API的密钥Access Key ID
+    @Value("${ali.oss.accessKeyId}")
+    private String accessKeyId;
+    // 阿里云API的密钥Access Key Secret
+    @Value("${ali.oss.accessKeySecret}")
+    private String accessKeySecret;
+
+    @Value("${aliyun.oss.file.prefix}")
+    private String ossPrefix;
+
+    @Value("${efunbox.oss.img.url}")
+    private String imgURL;
+
+    private static final String DOT = ".";
+
+
+
+    @RequestMapping(value="/uploads", method = RequestMethod.POST)
+    public void uploadFiles(HttpServletRequest request, HttpServletResponse response) {
+        MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
+        Map<String, MultipartFile> fileMap = multipartRequest.getFileMap();
+        Set<String> fileNames = fileMap.keySet() ;
+        try {
+            // key-图片名称 value 地址
+            Map<String, String> map = new HashMap<String, String>();
+            for (Map.Entry<String, MultipartFile> entity : fileMap.entrySet()) {
+                MultipartFile mf = entity.getValue();
+                String fileName = mf.getOriginalFilename();
+                fileName = new String(fileName.getBytes("ISO-8859-1"),"UTF-8");
+                long size = mf.getSize() ;
+                if( size > MAX_LENGTH ){
+                    HttpUtil.responseApiCode(request, response, ApiCode.FILE_TO_BIG);
+                    return ;
+                }
+
+                String suffix =  fileName.lastIndexOf(DOT) != -1 ? fileName.substring(fileName.lastIndexOf(DOT)) : ".jpg";
+                String ossName = upload(mf,suffix, size);
+                if (ossName == null) {// 上传失败
+                    HttpUtil.responseApiCode(request, response, ApiCode.FILE_UPLOAD_ERROR);
+                    return ;
+                }
+                map.put(fileName, ossName);
+            }
+            HttpUtil.responseOkData(request, response,map);
+            return;
+
+        } catch (Exception e) {
+            log.error("uploadFiles failed!  files={}", JSON.toJSONString(fileNames), e);
+        }
+    }
+
+    @RequestMapping(value = "/upload", method = RequestMethod.POST)
+    public void uploadFile(HttpServletRequest request, HttpServletResponse response,String code) throws Exception {
+        if (request.getCharacterEncoding() == null) {
+            request.setCharacterEncoding("UTF-8");
+        }
+        MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
+        Iterator<String> iterator = multipartRequest.getFileNames();
+        MultipartFile multipartFile = multipartRequest.getFile(iterator.next());
+        String fileName=multipartFile.getOriginalFilename();
+        String suffix = null;
+        if(!StringUtils.isEmpty(fileName)){
+            //解决中文乱码
+             suffix =  fileName.lastIndexOf(DOT) != -1 ? fileName.substring(fileName.lastIndexOf(DOT)) : ".jpg";
+        }
+        long size = multipartFile.getSize() ;
+        if( size > MAX_LENGTH ){
+            HttpUtil.responseApiCode(request, response, ApiCode.FILE_TO_BIG);
+            return;
+        }
+//        if(StringUtils.isNotBlank(code)){
+//            //截取后缀名 根据code从新命名
+
+//            fileName = code+suffix;
+//        }
+
+//        String ossName = upload(fileName, multipartFile, size);
+        String ossName = upload(multipartFile,suffix, size);
+        if (ossName == null) {// 上传失败
+            HttpUtil.responseApiCode(request, response, ApiCode.FILE_UPLOAD_ERROR);
+        }
+        HttpUtil.responseOkData(request, response,"/"+ossName);
+    }
+
+
+    private static final int MAX_LENGTH = 10 * 1024 * 1024 ;
+
+    private String upload(MultipartFile multipartFile,String suffix, long size){
+        log.info("UUID= {}  filename={}  size= {}",UUID.randomUUID(),size);
+        String pathName = null;
+        try {
+            if (size > MAX_LENGTH) {
+                return null;
+            } else {
+                pathName = save2Oss(multipartFile,suffix);
+            }
+
+        } catch (Exception e) {
+            log.error("upload  filename={}  size={}", size, e);
+        }
+        if (pathName == null) {// 上传失败
+            return null;
+        }
+
+        log.info("UUID= {}  filename={}  size= {} 上传 result= {} ",UUID.randomUUID(),size,pathName);
+        return pathName;
+    }
+
+
+    private String save2Oss(MultipartFile file,String suffix) throws IOException {
+
+        String code = SnowflakeIdUtil.getSnowflakeIdUtil().nextCode();
+        String savePath = ossPrefix + getDateStr() + "/"+ code + suffix;
+        InputStream is = file.getInputStream();
+        Long fileSize = file.getSize();
+        ObjectMetadata metadata = new ObjectMetadata();
+        metadata.setContentLength(is.available());
+        metadata.setCacheControl("no-cache");
+        metadata.setHeader("Pragma", "no-cache");
+        metadata.setContentEncoding("utf-8");
+//		metadata.setContentType(getContentType(fileName));
+        metadata.setContentDisposition("filename/filesize=" + savePath + "/" + fileSize + "Byte.");
+        OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
+        ossClient.putObject(BUCKETNAME, savePath, is, metadata);
+        return savePath;
+    }
+
+    /**
+     * 生成随机文件名:当前年月日时分秒+五位随机数
+     *
+     * @return
+     */
+    public static String getDateStr() {
+
+        SimpleDateFormat simpleDateFormat;
+
+        simpleDateFormat = new SimpleDateFormat("yyyyMMdd");
+
+        Date date = new Date();
+
+        String str = simpleDateFormat.format(date);
+
+      /*  Random random = new Random();
+
+        int rannum = (int) (random.nextDouble() * (99999 - 10000 + 1)) + 10000;// 获取5位随机数*/
+
+        return str;// 当前时间
+    }
+
+}

+ 35 - 0
src/main/java/cn/efunbox/audio/entity/Album.java

@@ -0,0 +1,35 @@
+package cn.efunbox.audio.entity;
+
+import lombok.Data;
+import lombok.ToString;
+import org.hibernate.annotations.DynamicInsert;
+import org.hibernate.annotations.DynamicUpdate;
+
+import javax.persistence.*;
+import java.io.Serializable;
+import java.sql.Timestamp;
+
+/**
+ * Album
+ * Created by xusq on 2018/5/8.
+ */
+@Data
+@ToString
+@Entity
+@Table(name = "album")
+@DynamicInsert
+@DynamicUpdate
+public class Album implements Serializable {
+
+    @Id
+    @GeneratedValue
+    private Long id;
+
+    private String name;
+
+    private String image;
+
+    private Timestamp created;
+
+    private Timestamp modified;
+}

+ 55 - 0
src/main/java/cn/efunbox/audio/impl/AlbumServiceImpl.java

@@ -0,0 +1,55 @@
+package cn.efunbox.audio.impl;
+
+import cn.efunbox.audio.entity.Album;
+import cn.efunbox.audio.repository.AlbumRepo;
+import cn.efunbox.audio.service.AlbumService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.PageRequest;
+import org.springframework.data.domain.Pageable;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ * AlbumServiceImpl
+ * Created by xusq on 2018/5/8.
+ */
+@Service
+public class AlbumServiceImpl implements AlbumService {
+
+    @Autowired
+    private AlbumRepo albumRepo;
+
+    @Override
+    public Album GetOne(Long id) {
+        return albumRepo.findOne(id);
+    }
+
+    @Override
+    public Page<Album> SearchAll(int page, int size) {
+        Pageable pageable = new PageRequest(page, size);
+        Page<Album> list = albumRepo.findAll(pageable);
+        return list;
+    }
+
+    @Override
+    public Album Insert(Album album) {
+        return albumRepo.save(album);
+    }
+
+    @Override
+    public Album Update(Album album) {
+        return albumRepo.save(album);
+    }
+
+    @Override
+    public List<Album> searchByName(String name) {
+        return albumRepo.findByNameLike(name);
+    }
+
+    public List<Long> findLikeName(String name) {
+        return albumRepo.findIdsByNameLike(name);
+    }
+
+}

+ 13 - 15
src/main/java/cn/efunbox/audio/impl/AudioServiceImpl.java

@@ -2,21 +2,17 @@ package cn.efunbox.audio.impl;
 
 import cn.efunbox.audio.consts.MediaType;
 import cn.efunbox.audio.entity.Audio;
-import cn.efunbox.audio.entity.Device;
+import cn.efunbox.audio.repository.AlbumRepo;
 import cn.efunbox.audio.repository.AudioRepo;
-import cn.efunbox.audio.repository.DeviceRepo;
 import cn.efunbox.audio.service.AudioService;
-import cn.efunbox.audio.service.DeviceService;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.data.domain.Page;
 import org.springframework.data.domain.PageRequest;
 import org.springframework.data.domain.Pageable;
 import org.springframework.stereotype.Service;
+import org.springframework.util.CollectionUtils;
 
-import java.util.ArrayList;
-import java.util.Date;
 import java.util.List;
-import java.util.UUID;
 
 /**
  * Created by yao on 17-9-26.
@@ -26,6 +22,8 @@ public class AudioServiceImpl implements AudioService {
 
     @Autowired
     AudioRepo audioRepo;
+    @Autowired
+    AlbumRepo albumRepo;
 
     @Override
     public Audio GetOne(Long id){
@@ -70,7 +68,7 @@ public class AudioServiceImpl implements AudioService {
             list = audioRepo.findByName(name);
 //        System.out.println("list1:"+list.toString());
 
-        if(list==null){
+        if(CollectionUtils.isEmpty(list)){
             list = audioRepo.findByNameLike(name);
             System.out.println("list:"+list.toString());
         }
@@ -82,13 +80,12 @@ public class AudioServiceImpl implements AudioService {
     public List<Audio> SearchByAlbum(int mediaType, String album){
         if(album==null || album.isEmpty())
             return null;
+        List<Long> albumIds = albumRepo.findIdsByNameLike(album);
         List<Audio> list = null;
         if(mediaType== MediaType.AUDIO.getCode() || mediaType==MediaType.VIDEO.getCode())
-            list = audioRepo.findByMediaTypeAndAlbum(mediaType, album);
+            list = audioRepo.findByMediaTypeAndAlbumIn(mediaType, albumIds);
         else
-            list = audioRepo.findByAlbum(album);
-        if(list==null)
-            list = audioRepo.findByAlbumLike(album);
+            list = audioRepo.findByAlbumIn(albumIds);
         return list;
     }
 
@@ -97,13 +94,14 @@ public class AudioServiceImpl implements AudioService {
         if(name==null || name.isEmpty()
                 || album==null || album.isEmpty())
             return null;
+        List<Long> albumIds = albumRepo.findIdsByNameLike(album);
         List<Audio> list = null;
         if(mediaType== MediaType.AUDIO.getCode() || mediaType==MediaType.VIDEO.getCode())
-            list = audioRepo.findByMediaTypeAndNameAndAlbum(mediaType, name, album);
+            list = audioRepo.findByMediaTypeAndNameAndAlbumIn(mediaType, name, albumIds);
         else
-            list = audioRepo.findByNameAndAlbum(name, album);
-        if(list==null)
-            list = audioRepo.searchByNameAndAlbum(name, album);
+            list = audioRepo.findByNameAndAlbumIn(name, albumIds);
+        if(CollectionUtils.isEmpty(list))
+            list = audioRepo.findByNameLikeAndAlbumIn(name, albumIds);
 
         return list;
     }

+ 23 - 0
src/main/java/cn/efunbox/audio/repository/AlbumRepo.java

@@ -0,0 +1,23 @@
+package cn.efunbox.audio.repository;
+
+import cn.efunbox.audio.entity.Album;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+
+/**
+ * Created by yao on 17-9-26.
+ */
+@Repository
+public interface AlbumRepo extends JpaRepository<Album, Long> {
+
+    @Query(value = "select a.id From album a where a.name like concat('%',?1,'%')", nativeQuery = true)
+    List<Long> findIdsByNameLike(String name);
+
+    @Query(value = "select * From album a where a.name like concat('%',?1,'%')", nativeQuery = true)
+    List<Album> findByNameLike(String name);
+
+
+}

+ 18 - 5
src/main/java/cn/efunbox/audio/repository/AudioRepo.java

@@ -1,7 +1,6 @@
 package cn.efunbox.audio.repository;
 
 import cn.efunbox.audio.entity.Audio;
-import cn.efunbox.audio.entity.Device;
 import org.springframework.data.domain.Page;
 import org.springframework.data.domain.Pageable;
 import org.springframework.data.jpa.repository.JpaRepository;
@@ -28,8 +27,8 @@ public interface AudioRepo extends JpaRepository<Audio, Long> {
     List<Audio> findByMediaTypeAndName(Integer mediaType, String name);
 
 //    @Query("from Audio a where a.name LIKE CONCAT('%',:name,'%')")
-    @Query(value = "select * From audio a where a.name like '%?1%'", nativeQuery = true)
-    List<Audio> findByNameLike(String name);
+//    @Query(value = "select * From audio a where a.name like '%?1%'", nativeQuery = true)
+//    List<Audio> findByNameLike(String name);
 
 //    @Query("from Audio a where a.media_type=:mediaType and a.name LIKE :name")
 //    List<Audio> findByMediaTypeAndNameLike(Integer mediaType, String name);
@@ -50,6 +49,20 @@ public interface AudioRepo extends JpaRepository<Audio, Long> {
 
     List<Audio> findByMediaTypeAndNameAndAlbum(Integer mediaType, String name, String Album);
 
-    @Query("from Audio a where a.name like CONCAT('%',:name,'%') and a.album like CONCAT('%',:album,'%') ")
-    List<Audio> searchByNameAndAlbum(@Param("name") String name, @Param("album") String album);
+//    @Query("from Audio a where a.name like CONCAT('%',:name,'%') and a.album like CONCAT('%',:album,'%') ")
+//    List<Audio> searchByNameAndAlbum(@Param("name") String name, @Param("album") String album);
+
+    List<Audio> findByMediaTypeAndAlbumIn(int mediaType, List<Long> albumIds);
+
+    List<Audio> findByAlbumIn(List<Long> albumIds);
+
+    List<Audio> findByMediaTypeAndNameAndAlbumIn(int mediaType, String name, List<Long> albumIds);
+
+    List<Audio> findByNameAndAlbumIn(String name, List<Long> albumIds);
+
+    @Query("from Audio a where a.name like CONCAT('%',:name,'%') and a.album in :albumIds")
+    List<Audio> findByNameLikeAndAlbumIn(@Param("name") String name, @Param("albumIds") List<Long> albumIds);
+
+    @Query("from Audio a where a.name LIKE CONCAT('%',:name,'%')")
+    List<Audio> findByNameLike(@Param("name") String name);
 }

+ 24 - 0
src/main/java/cn/efunbox/audio/service/AlbumService.java

@@ -0,0 +1,24 @@
+package cn.efunbox.audio.service;
+
+import cn.efunbox.audio.entity.Album;
+import org.springframework.data.domain.Page;
+
+import java.util.List;
+
+/**
+ * AlbumService
+ * Created by xusq on 2018/5/8.
+ */
+public interface AlbumService {
+
+    public Album GetOne(Long id);
+
+    public Page<Album> SearchAll(int page, int size);
+
+    public Album Insert(Album album);
+
+    public Album Update(Album album);
+
+    List<Album> searchByName(String name);
+
+}

+ 6 - 0
src/main/java/cn/efunbox/audio/utils/ApiCode.java

@@ -34,6 +34,12 @@ public class ApiCode extends AbstractApiCode {
     public static final int _C_OPERATION_FAIL = 550;
     public static final ApiCode OPERATION_FAIL = new ApiCode("操作失败", 550);
 
+    public final static int     _C_FILE_TO_BIG = 405;
+    public final static ApiCode FILE_TO_BIG    = new ApiCode("文件过大", _C_FILE_TO_BIG);
+
+    public final static int     _C_FILE_UPLOAD_ERROR= 407;
+    public final static ApiCode FILE_UPLOAD_ERROR    = new ApiCode("上传文件失败", _C_FILE_UPLOAD_ERROR);
+
     protected ApiCode(String message, int code) {
         super(code, message);
     }

+ 198 - 0
src/main/java/cn/efunbox/audio/utils/SnowflakeIdUtil.java

@@ -0,0 +1,198 @@
+package cn.efunbox.audio.utils;
+
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * Twitter_Snowflake<br>
+ * SnowFlake的结构如下(每部分用-分开):<br>
+ * 0 - 0000000000 0000000000 0000000000 0000000000 0 - 00000 - 00000 - 000000000000 <br>
+ * 1位标识,由于long基本类型在Java中是带符号的,最高位是符号位,正数是0,负数是1,所以id一般是正数,最高位是0<br>
+ * 41位时间截(毫秒级),注意,41位时间截不是存储当前时间的时间截,而是存储时间截的差值(当前时间截 - 开始时间截)
+ * 得到的值),这里的的开始时间截,一般是我们的id生成器开始使用的时间,由我们程序来指定的(如下下面程序IdWorker类的startTime属性)。41位的时间截,可以使用69年,年T = (1L << 41) / (1000L * 60 * 60 * 24 * 365) = 69<br>
+ * 10位的数据机器位,可以部署在1024个节点,包括5位datacenterId和5位workerId<br>
+ * 12位序列,毫秒内的计数,12位的计数顺序号支持每个节点每毫秒(同一机器,同一时间截)产生4096个ID序号<br>
+ * 加起来刚好64位,为一个Long型。<br>
+ * SnowFlake的优点是,整体上按照时间自增排序,并且整个分布式系统内不会产生ID碰撞(由数据中心ID和机器ID作区分),并且效率较高,经测试,SnowFlake每秒能够产生26万ID左右。
+ */
+public class SnowflakeIdUtil {
+
+    private static volatile SnowflakeIdUtil singleton = null;
+    // ==============================Fields===========================================
+    /** 开始时间截 (2015-01-01) */
+    private final long twepoch = 1420041600000L;
+
+    /** 机器id所占的位数 */
+    private final long workerIdBits = 5L;
+
+    /** 数据标识id所占的位数 */
+    private final long datacenterIdBits = 5L;
+
+    /** 支持的最大机器id,结果是31 (这个移位算法可以很快的计算出几位二进制数所能表示的最大十进制数) */
+    private final long maxWorkerId = -1L ^ (-1L << workerIdBits);
+
+    /** 支持的最大数据标识id,结果是31 */
+    private final long maxDatacenterId = -1L ^ (-1L << datacenterIdBits);
+
+    /** 序列在id中占的位数 */
+    private final long sequenceBits = 12L;
+
+    /** 机器ID向左移12位 */
+    private final long workerIdShift = sequenceBits;
+
+    /** 数据标识id向左移17位(12+5) */
+    private final long datacenterIdShift = sequenceBits + workerIdBits;
+
+    /** 时间截向左移22位(5+5+12) */
+    private final long timestampLeftShift = sequenceBits + workerIdBits + datacenterIdBits;
+
+    /** 生成序列的掩码,这里为4095 (0b111111111111=0xfff=4095) */
+    private final long sequenceMask = -1L ^ (-1L << sequenceBits);
+
+    /** 工作机器ID(0~31) */
+    private long workerId=1L;
+
+    /** 数据中心ID(0~31) */
+    private long datacenterId=1L;
+
+    /** 毫秒内序列(0~4095) */
+    private long sequence = 0L;
+
+    /** 上次生成ID的时间截 */
+    private long lastTimestamp = -1L;
+
+
+
+    //==============================Constructors=====================================
+    private SnowflakeIdUtil(){}
+    /**
+     * 构造函数
+     */
+    public static SnowflakeIdUtil getSnowflakeIdUtil(){
+        if(singleton == null){
+            synchronized (SnowflakeIdUtil.class){
+                if(singleton == null){
+                    singleton = new SnowflakeIdUtil(0,0);
+                }
+            }
+        }
+        return singleton;
+    }
+    public static SnowflakeIdUtil getSnowflakeIdUtil(long workerId, long datacenterId){
+        if(singleton == null){
+            synchronized (SnowflakeIdUtil.class){
+                if(singleton == null){
+                    singleton = new SnowflakeIdUtil(workerId,datacenterId);
+                }
+            }
+        }
+        return singleton;
+    }
+    /**
+     * 构造函数
+     * @param workerId 工作ID (0~31)
+     * @param datacenterId 数据中心ID (0~31)
+     */
+    public SnowflakeIdUtil(long workerId, long datacenterId) {
+        if (workerId > maxWorkerId || workerId < 0) {
+            throw new IllegalArgumentException(String.format("worker Id can't be greater than %d or less than 0", maxWorkerId));
+        }
+        if (datacenterId > maxDatacenterId || datacenterId < 0) {
+            throw new IllegalArgumentException(String.format("datacenter Id can't be greater than %d or less than 0", maxDatacenterId));
+        }
+        this.workerId = workerId;
+        this.datacenterId = datacenterId;
+    }
+
+    // ==============================Methods==========================================
+    /**
+     * 获得下一个ID (该方法是线程安全的)
+     * @return SnowflakeId
+     */
+    public synchronized long nextId() {
+        long timestamp = timeGen();
+
+        //如果当前时间小于上一次ID生成的时间戳,说明系统时钟回退过这个时候应当抛出异常
+        if (timestamp < lastTimestamp) {
+            throw new RuntimeException(
+                    String.format("Clock moved backwards.  Refusing to generate id for %d milliseconds", lastTimestamp - timestamp));
+        }
+
+        //如果是同一时间生成的,则进行毫秒内序列
+        if (lastTimestamp == timestamp) {
+            sequence = (sequence + 1) & sequenceMask;
+            //毫秒内序列溢出
+            if (sequence == 0) {
+                //阻塞到下一个毫秒,获得新的时间戳
+                timestamp = tilNextMillis(lastTimestamp);
+            }
+        }
+        //时间戳改变,毫秒内序列重置
+        else {
+            sequence = 0L;
+        }
+        //上次生成ID的时间截
+        lastTimestamp = timestamp;
+
+       /* //移位并通过或运算拼到一起组成64位的ID
+        return ((timestamp - twepoch) << timestampLeftShift) //
+                | (datacenterId << datacenterIdShift) //
+                | (workerId << workerIdShift) //
+                | sequence;*/
+
+        // modify by tomas 2017-08-28
+        try {
+            Thread.sleep(1);
+        } catch (InterruptedException e) {
+            e.printStackTrace();
+        }
+        return  Long.parseLong(timestamp+ getNewAppend() );
+    }
+
+    protected String getNewAppend() {
+        StringBuilder stringBuilder=new StringBuilder((System.nanoTime() + "").substring(7, 10));
+        return  stringBuilder.toString();
+
+    }
+    /**
+     * 阻塞到下一个毫秒,直到获得新的时间戳
+     * @param lastTimestamp 上次生成ID的时间截
+     * @return 当前时间戳
+     */
+    protected long tilNextMillis(long lastTimestamp) {
+        long timestamp = timeGen();
+        while (timestamp <= lastTimestamp) {
+            timestamp = timeGen();
+        }
+        return timestamp;
+    }
+
+    /**
+     * 返回字符串类型 code
+     * @return
+     */
+    public String nextCode() {
+        return  String.valueOf(nextId());
+    }
+    /**
+     * 返回以毫秒为单位的当前时间
+     * @return 当前时间(毫秒)
+     */
+    protected long timeGen() {
+        return System.currentTimeMillis();
+    }
+
+
+    public static void main(String[] args) throws Exception{
+
+        Set<Long> ids= new HashSet<>();
+        long start=System.currentTimeMillis();
+        for (int j=0 ;j<1000;j++){
+            long id = SnowflakeIdUtil.getSnowflakeIdUtil().nextId();
+            ids.add(id);
+            //System.out.println(id);
+        }
+        System.out.println(ids.size()+"---time="+ (System.currentTimeMillis()-start));
+
+    }
+}

+ 8 - 2
src/main/resources/application-dev.properties

@@ -33,8 +33,8 @@ spring.datasource.password=Efunbox^^2015$
 spring.datasource.driver-class-name=com.mysql.jdbc.Driver
 
 spring.jpa.properties.hibernate.hbm2ddl.auto=update
-
-#spring.jpa.show-sql=true
+spring.jpa.properties.hibernate.format_sql=true
+spring.jpa.show-sql=true
 
 ########################################################
 ### REDIS (RedisProperties) redis基本配置;
@@ -59,3 +59,9 @@ spring.redis.pool.min-idle=0
 # 连接超时时间(毫秒)
 spring.redis.timeout=0
 
+#oss
+ali.oss.endpoint=oss-cn-beijing.aliyuncs.com
+ali.oss.accessKeyId=LTAIUFvd17IXLBQ4
+ali.oss.accessKeySecret=YEm1VebbntRIGmV8s8N33LQfOoC2sA
+aliyun.oss.file.prefix=audio/album/
+efunbox.oss.img.url=http://efunimgs.ai160.com

+ 6 - 0
src/main/resources/application-prd.properties

@@ -59,3 +59,9 @@ spring.redis.pool.min-idle=0
 # 连接超时时间(毫秒)
 spring.redis.timeout=0
 
+#oss
+ali.oss.endpoint=oss-cn-beijing.aliyuncs.com
+ali.oss.accessKeyId=LTAIUFvd17IXLBQ4
+ali.oss.accessKeySecret=YEm1VebbntRIGmV8s8N33LQfOoC2sA
+aliyun.oss.file.prefix=audio/album/
+efunbox.oss.img.url=http://efunimgs.ai160.com