Browse Source

提交代码

tianboguang 3 năm trước cách đây
commit
478ef0584b
34 tập tin đã thay đổi với 25518 bổ sung0 xóa
  1. 60 0
      4dkankan-common-utils/pom.xml
  2. 240 0
      4dkankan-common-utils/src/main/java/com/fdkankan/common/utils/FileUtil.java
  3. 39 0
      4dkankan-common-utils/src/main/java/com/fdkankan/utils/constant/ConstantFileName.java
  4. 49 0
      4dkankan-common-utils/src/main/java/com/fdkankan/utils/constant/ConstantFilePath.java
  5. 28 0
      4dkankan-common-utils/src/main/java/com/fdkankan/utils/constant/ConstantUrl.java
  6. 7340 0
      4dkankan-common-utils/src/main/java/com/fdkankan/utils/proto/BigSceneProto.java
  7. 4654 0
      4dkankan-common-utils/src/main/java/com/fdkankan/utils/proto/Common.java
  8. 4345 0
      4dkankan-common-utils/src/main/java/com/fdkankan/utils/proto/Visionmodeldata.java
  9. 156 0
      4dkankan-common-utils/src/main/java/com/fdkankan/utils/proto/format/CouchDBFormat.java
  10. 703 0
      4dkankan-common-utils/src/main/java/com/fdkankan/utils/proto/format/HtmlFormat.java
  11. 1338 0
      4dkankan-common-utils/src/main/java/com/fdkankan/utils/proto/format/JavaPropsFormat.java
  12. 1603 0
      4dkankan-common-utils/src/main/java/com/fdkankan/utils/proto/format/JsonFormat.java
  13. 1333 0
      4dkankan-common-utils/src/main/java/com/fdkankan/utils/proto/format/XmlFormat.java
  14. 65 0
      4dkankan-common-utils/src/main/java/com/fdkankan/utils/utils/Base64Converter.java
  15. 55 0
      4dkankan-common-utils/src/main/java/com/fdkankan/utils/utils/ConstantCmd.java
  16. 602 0
      4dkankan-common-utils/src/main/java/com/fdkankan/utils/utils/CreateObjUtil.java
  17. 240 0
      4dkankan-common-utils/src/main/java/com/fdkankan/utils/utils/FileUtil.java
  18. 1084 0
      4dkankan-common-utils/src/main/java/com/fdkankan/utils/utils/FileUtils.java
  19. 61 0
      4dkankan-common-utils/src/main/java/com/fdkankan/utils/utils/StreamGobbler.java
  20. 24 0
      4dkankan-utils-db/pom.xml
  21. 61 0
      4dkankan-utils-db/src/main/java/com/fdkankan/common/utils/StreamGobbler.java
  22. 42 0
      4dkankan-utils-mq/pom.xml
  23. 64 0
      4dkankan-utils-mq/src/main/java/com/fdkankan/mq/message/BaseBuildSceneMessage.java
  24. 145 0
      4dkankan-utils-mq/src/main/java/com/fdkankan/mq/message/BuildSceneMqMessage.java
  25. 30 0
      4dkankan-utils-mq/src/main/java/com/fdkankan/mq/message/BuildSceneResultMqMessage.java
  26. 24 0
      4dkankan-utils-mq/src/main/java/com/fdkankan/mq/message/MQBodyBean.java
  27. 173 0
      4dkankan-utils-mq/src/main/java/com/fdkankan/mq/util/RocketMQProducer.java
  28. 45 0
      4dkankan-utils-oss/pom.xml
  29. 90 0
      4dkankan-utils-oss/src/main/java/com/fdkankan/oss/UploadUtils.java
  30. 24 0
      4dkankan-utils-redis/pom.xml
  31. 45 0
      4dkankan-utils-redis/src/main/java/com/fdkankan/redis/config/RedisConfig.java
  32. 92 0
      4dkankan-utils-redis/src/main/java/com/fdkankan/redis/util/RedisLockUtil.java
  33. 546 0
      4dkankan-utils-redis/src/main/java/com/fdkankan/redis/util/RedisUtil.java
  34. 118 0
      pom.xml

+ 60 - 0
4dkankan-common-utils/pom.xml

@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<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">
+    <packaging>jar</packaging>
+    <parent>
+        <groupId>com.fdkankan</groupId>
+        <artifactId>4dkankan-utils</artifactId>
+        <version>2.0.0</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>4dkankan-common-utils</artifactId>
+
+    <properties>
+        <ant-version>1.8.2</ant-version>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>com.google.protobuf</groupId>
+            <artifactId>protobuf-java</artifactId>
+            <version>3.2.0</version>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-api</artifactId>
+            <version>1.7.30</version>
+        </dependency>
+        <dependency>
+            <groupId>org.bytedeco</groupId>
+            <artifactId>javacpp</artifactId>
+            <version>1.4.3</version>
+        </dependency>
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>fastjson</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.ant</groupId>
+            <artifactId>ant</artifactId>
+            <version>${ant-version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.bytedeco</groupId>
+            <artifactId>javacv</artifactId>
+            <version>1.4.3</version>
+            <scope>compile</scope>
+        </dependency>
+        <dependency>
+            <groupId>joinery</groupId>
+            <artifactId>jave</artifactId>
+            <version>1.0.2.2</version>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-core</artifactId>
+        </dependency>
+    </dependencies>
+</project>

+ 240 - 0
4dkankan-common-utils/src/main/java/com/fdkankan/common/utils/FileUtil.java

@@ -0,0 +1,240 @@
+package com.fdkankan.common.utils;
+
+import java.io.*;
+import java.nio.ByteBuffer;
+import java.nio.MappedByteBuffer;
+import java.nio.channels.FileChannel;
+import java.nio.channels.FileChannel.MapMode;
+
+/**
+ * @author MeepoGuan
+ *
+ * <p>Description: file_util</p>
+ *
+ * 2017年4月30日
+ *
+ */
+public class FileUtil {
+
+/*	public static void main(String[] args) {
+		String dirName = "d:/FH/topic/";// 创建目录
+		FileUtil.createDir(dirName);
+	}*/
+
+	/**
+	 * 创建目录
+	 * 
+	 * @param destDirName
+	 *            目标目录名
+	 * @return 目录创建成功返回true,否则返回false
+	 */
+	public static boolean createDir(String destDirName) {
+		File dir = new File(destDirName);
+		if (dir.exists()) {
+			return false;
+		}
+		if (!destDirName.endsWith(File.separator)) {
+			destDirName = destDirName + File.separator;
+		}
+		// 创建单个目录
+		if (dir.mkdirs()) {
+			return true;
+		} else {
+			return false;
+		}
+	}
+
+	/**
+	 * 删除文件
+	 * 
+	 * @param filePathAndName
+	 *            String 文件路径及名称 如c:/fqf.txt
+	 * @return boolean
+	 */
+	public static void delFile(String filePathAndName) {
+		try {
+			String filePath = filePathAndName;
+			filePath = filePath.toString();
+			File myDelFile = new File(filePath);
+			myDelFile.delete();
+
+		} catch (Exception e) {
+			System.out.println("删除文件操作出错");
+			e.printStackTrace();
+
+		}
+
+	}
+
+	/**
+	 * 读取到字节数组0
+	 * 
+	 * @param filePath //路径
+	 * @throws IOException
+	 */
+	public static byte[] getContent(String filePath) throws IOException {
+		File file = new File(filePath);
+		long fileSize = file.length();
+		if (fileSize > Integer.MAX_VALUE) {
+			System.out.println("file too big...");
+			return null;
+		}
+		FileInputStream fi = new FileInputStream(file);
+		byte[] buffer = new byte[(int) fileSize];
+		int offset = 0;
+		int numRead = 0;
+		while (offset < buffer.length
+				&& (numRead = fi.read(buffer, offset, buffer.length - offset)) >= 0) {
+			offset += numRead;
+		}
+		// 确保所有数据均被读取
+		if (offset != buffer.length) {
+			throw new IOException("Could not completely read file "
+					+ file.getName());
+		}
+		fi.close();
+		return buffer;
+	}
+
+	/**
+	 * 读取到字节数组1
+	 * 
+	 * @param filePath
+	 * @return
+	 * @throws IOException
+	 */
+	public static byte[] toByteArray(String filePath) throws IOException {
+
+		File f = new File(filePath);
+		if (!f.exists()) {
+			throw new FileNotFoundException(filePath);
+		}
+		ByteArrayOutputStream bos = new ByteArrayOutputStream((int) f.length());
+		BufferedInputStream in = null;
+		try {
+			in = new BufferedInputStream(new FileInputStream(f));
+			int buf_size = 1024;
+			byte[] buffer = new byte[buf_size];
+			int len = 0;
+			while (-1 != (len = in.read(buffer, 0, buf_size))) {
+				bos.write(buffer, 0, len);
+			}
+			return bos.toByteArray();
+		} catch (IOException e) {
+			e.printStackTrace();
+			throw e;
+		} finally {
+			try {
+				in.close();
+			} catch (IOException e) {
+				e.printStackTrace();
+			}
+			bos.close();
+		}
+	}
+
+	/**
+	 * 读取到字节数组2
+	 * 
+	 * @param filePath
+	 * @return
+	 * @throws IOException
+	 */
+	public static byte[] toByteArray2(String filePath) throws IOException {
+
+		File f = new File(filePath);
+		if (!f.exists()) {
+			throw new FileNotFoundException(filePath);
+		}
+
+		FileChannel channel = null;
+		FileInputStream fs = null;
+		try {
+			fs = new FileInputStream(f);
+			channel = fs.getChannel();
+			ByteBuffer byteBuffer = ByteBuffer.allocate((int) channel.size());
+			while ((channel.read(byteBuffer)) > 0) {
+				// do nothing
+				// System.out.println("reading");
+			}
+			return byteBuffer.array();
+		} catch (IOException e) {
+			e.printStackTrace();
+			throw e;
+		} finally {
+			try {
+				channel.close();
+			} catch (IOException e) {
+				e.printStackTrace();
+			}
+			try {
+				fs.close();
+			} catch (IOException e) {
+				e.printStackTrace();
+			}
+		}
+	}
+
+	/**
+	 * Mapped File way MappedByteBuffer 可以在处理大文件时,提升性能
+	 * 
+	 * @param filePath
+	 * @return
+	 * @throws IOException
+	 */
+	public static byte[] toByteArray3(String filePath) throws IOException {
+
+		FileChannel fc = null;
+		RandomAccessFile rf = null;
+		try {
+			rf = new RandomAccessFile(filePath, "r");
+			fc = rf.getChannel();
+			MappedByteBuffer byteBuffer = fc.map(MapMode.READ_ONLY, 0,
+					fc.size()).load();
+			//System.out.println(byteBuffer.isLoaded());
+			byte[] result = new byte[(int) fc.size()];
+			if (byteBuffer.remaining() > 0) {
+				// System.out.println("remain");
+				byteBuffer.get(result, 0, byteBuffer.remaining());
+			}
+			return result;
+		} catch (IOException e) {
+			e.printStackTrace();
+			throw e;
+		} finally {
+			try {
+				rf.close();
+				fc.close();
+			} catch (IOException e) {
+				e.printStackTrace();
+			}
+		}
+	}
+
+    public static File[] sort(File[] s) {
+        //中间值
+        File temp = null;
+        //外循环:我认为最小的数,从0~长度-1
+        for (int j = 0; j < s.length - 1; j++) {
+            //最小值:假设第一个数就是最小的
+            String min = s[j].getName();
+            //记录最小数的下标的
+            int minIndex = j;
+            //内循环:拿我认为的最小的数和后面的数一个个进行比较
+            for (int k = j + 1; k < s.length; k++) {
+                //找到最小值
+                if (Integer.parseInt(min.substring(0, min.indexOf("."))) > Integer.parseInt(s[k].getName().substring(0, s[k].getName().indexOf(".")))) {
+                    //修改最小
+                    min = s[k].getName();
+                    minIndex = k;
+                }
+            }
+            //当退出内层循环就找到这次的最小值
+            //交换位置
+            temp = s[j];
+            s[j] = s[minIndex];
+            s[minIndex] = temp;
+        }
+        return s;
+    }
+}

+ 39 - 0
4dkankan-common-utils/src/main/java/com/fdkankan/utils/constant/ConstantFileName.java

@@ -0,0 +1,39 @@
+package com.fdkankan.utils.constant;
+
+public class ConstantFileName {
+    //背景音乐
+    public static final String BACKGROUND_MUSIC = "bg.mp3";
+    //编辑页面,第二代
+    public static final String MODEL_DATAFILE = "modeldata.json";
+    public static final String HOT_DATAFILE = "hot.json";
+    public static final String MEDIA_DATAFILE = "mediaInfo.json";
+    public static final String SCREEN_CRP_DATAFILE = "screenCap";
+    //导览(一代)
+    public static final String GUIDE_DATAFILE = "tour.json";
+
+    //文件夹名称
+    public static final String GUIDE_MEDIA_FOLDER = "guide";
+    public static final String HOT_MEDIA_FOLDER = "hot";
+    public static final String OTHER_MEDIA_FOLDER = "other";
+
+    //论坛过滤文档
+    public static final String BBS_SENSITIVE = "SensitiveWord.txt";
+    public static final String LOGO_NAME = "logo.jpg";
+
+    //app部分
+    public static final String APP_FOLDER = "appupload";
+
+    public static final String FLOOR_LOGO_PIC_NAME = "floorLogoImg.png";
+
+    public static final String TOUR_LIST = "tourList.json";
+    public static final String VOICE_NAME = "201810";
+    public static final String WECHAT_VOICE_NAME = "wechat";
+    public static final String APP_VOICE_NAME = "app";
+
+    public static final String TOURLIST_FOLDER = "tour";
+    //public static final String TEMPFILES = "tempFiles";
+
+    public static final String modelUUID = "dacf7dfa24ae47fab8fcebfe4dc41ab9";
+
+    public static final String BUCKET_NAME = "4dkankan";
+}

+ 49 - 0
4dkankan-common-utils/src/main/java/com/fdkankan/utils/constant/ConstantFilePath.java

@@ -0,0 +1,49 @@
+package com.fdkankan.utils.constant;
+
+public class ConstantFilePath {
+    public static final String BASE_PATH = "/mnt/4Dkankan";
+    //论坛上传图片后,服务器存放的地址
+    public static final String BBS_IMAGES_PATH = "/mnt/4Dkankan/bbs/upload/image/";
+    // 用户上传图片
+    public static final String USER_IMAGES_PATH = "/mnt/4Dkankan/user/";
+    // 图片暂存地址(创建二维码等)
+    public static final String TEMP_IMAGES_PATH = "/mnt/4Dkankan/temp/upload/image/";
+    // 场景
+    public static final String SCENE_PATH = "/mnt/4Dkankan/scene/";
+    // 代理商
+    public static final String AGENT_PATH = "/mnt/4Dkankan/agent/";
+    //电子发票
+    public static final String INVOICE_PATH = "/mnt/4Dkankan/invoice/";
+    // 场景二维码
+    public static final String SCENE_QR_CODE_PATH = "/mnt/4Dkankan/sceneQRcode/";
+    // excel
+    public static final String EXCEL_PATH = "/mnt/4Dkankan/excel/";
+    //    public static final String EXCEL_PATH = "F:\\excel\\";
+    // medias
+    public static final String MEDIAS_PATH = "/mnt/4Dkankan/medias/";
+    // logo
+    public static final String LOGO_PATH = "/mnt/4Dkankan/logo/";
+    // login qr code
+    public static final String LOGIN_QR_CODE_PATH = "/mnt/4Dkankan/login/qrcode/";
+
+    public static final String WEIXIN_CERT = "/mnt/home/ubuntu/user/apiclient_cert.p12";
+
+    public static final String PREFIX = "/home/user";
+    public static final String CREATE_MODEL_PATH = PREFIX + "/photo_data/model/";
+    //大场景
+    public static final String CREATE_BIG_SCENE_PATH = PREFIX + "/photo_data/bigscene/";
+    //生成模型的路径
+    public static final String BUILD_MODEL_PATH = "/mnt/data/";
+    //生成模型的路径
+    public static String BUILD_MODEL_LASER_PATH ="/mnt-laser/data/";
+
+    //支付二维码图片存放路径
+    public static final String ALI_QRCODE_FOLDER = "/mnt/4Dkankan/alicode/";
+    public static final String WEIXIN_QRCODE_FOLDER = "/mnt/4Dkankan/weixincode/";
+
+    public static final String OSS_PREFIX = "home/";
+
+    public void setHardDiskLaser(String value){
+        ConstantFilePath.BUILD_MODEL_LASER_PATH = value;
+    }
+}

+ 28 - 0
4dkankan-common-utils/src/main/java/com/fdkankan/utils/constant/ConstantUrl.java

@@ -0,0 +1,28 @@
+package com.fdkankan.utils.constant;
+
+public class ConstantUrl {
+
+    //	public static final String MAIN_URL = "https://www.4dkankan.com/";
+//	public static final String MAIN_URL = "http://120.79.15.136:8086/";
+//	public static final String MAIN_URL2 = "https://www.4dkankan.com/";
+//	public static final String DEFAULT_USER_HEAD = "https://scene3d.4dage.com/head.png";
+    public static final String DEFAULT_USER_HEAD = "https://4dkk.4dage.com/newHead.png";
+    public static final String BBS_TOUPLOAD = "https://scene3d.4dage.com/model/upload/image/";
+    public static final String DEFAULT_PREFIX_QINIU_PIC = "http://orw69myb5.bkt.clouddn.com/";
+    public static final String DEFAULT_SCENE_PIC="https://4dkk.4dage.com/loading/thumb.jpg";
+//	public static final String SCENE_URL = MAIN_URL + "show.html?m=";
+//	public static final String SCENE_URL2 = MAIN_URL + "showV2.html?m=";
+
+    //	public static final String PRO_SCENE_URL = MAIN_URL + "showProMobile.html?m=";
+    public static final String PREFIX_ALI = "https://4dkk.4dage.com/";
+    //亚马逊S3
+    public static final String PREFIX_AWS = "https://testeurs3.4dkankan.com/";
+    public static final String PREFIX_QINIU = "https://scene3d.4dage.com/";
+    public static final String PREFIX_QINIU2 = "https://creator.4dkankan.com/";
+    public static final String WEIXIN_PAYURL = "https://www.4dkankan.com/weixinmobilepay/weixinInfo?orderId=";
+    public static final String WEIXIN_TOKEN_URL1 = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=";
+    public static final String WEIXIN_TOKEN_URL2 = "https://api.weixin.qq.com/sns/userinfo?access_token=";
+    public static final String WEIXIN_MOBILE_PAY_URL = "mobile.html#/pay?timeStamp=";
+    public static final String WEIXIN_NOTIFY_URL = "https://www.4dkankan.com/weixinpay/Notify";
+    public static final String WEIXIN_ORDER_URL="https://api.mch.weixin.qq.com/pay/unifiedorder";
+}

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 7340 - 0
4dkankan-common-utils/src/main/java/com/fdkankan/utils/proto/BigSceneProto.java


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 4654 - 0
4dkankan-common-utils/src/main/java/com/fdkankan/utils/proto/Common.java


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 4345 - 0
4dkankan-common-utils/src/main/java/com/fdkankan/utils/proto/Visionmodeldata.java


+ 156 - 0
4dkankan-common-utils/src/main/java/com/fdkankan/utils/proto/format/CouchDBFormat.java

@@ -0,0 +1,156 @@
+package com.fdkankan.utils.proto.format;
+
+
+import com.google.protobuf.ExtensionRegistry;
+import com.google.protobuf.Message;
+import com.google.protobuf.UnknownFieldSet;
+
+import java.io.IOException;
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: aantonov
+ * Date: Mar 16, 2010
+ * Time: 4:06:05 PM
+ * To change this template use File | Settings | File Templates.
+ */
+public class CouchDBFormat extends JsonFormat {
+
+    /**
+     * Outputs a textual representation of the Protocol Message supplied into the parameter output.
+     * (This representation is the new version of the classic "ProtocolPrinter" output from the
+     * original Protocol Buffer system)
+     */
+    public static void print(Message message, Appendable output) throws IOException {
+        CouchDBGenerator generator = new CouchDBGenerator(output);
+        generator.print("{");
+        print(message, generator);
+        generator.print("}");
+    }
+
+    /**
+     * Outputs a textual representation of {@code fields} to {@code output}.
+     */
+    public static void print(UnknownFieldSet fields, Appendable output) throws IOException {
+        CouchDBGenerator generator = new CouchDBGenerator(output);
+        generator.print("{");
+        printUnknownFields(fields, generator);
+        generator.print("}");
+    }
+
+    /**
+     * Like {@code print()}, but writes directly to a {@code String} and returns it.
+     */
+    public static String printToString(Message message) {
+        try {
+            StringBuilder text = new StringBuilder();
+            print(message, text);
+            return text.toString();
+        } catch (IOException e) {
+            throw new RuntimeException("Writing to a StringBuilder threw an IOException (should never happen).",
+                                       e);
+        }
+    }
+
+    /**
+     * Like {@code print()}, but writes directly to a {@code String} and returns it.
+     */
+    public static String printToString(UnknownFieldSet fields) {
+        try {
+            StringBuilder text = new StringBuilder();
+            print(fields, text);
+            return text.toString();
+        } catch (IOException e) {
+            throw new RuntimeException("Writing to a StringBuilder threw an IOException (should never happen).",
+                                       e);
+        }
+    }
+
+    /**
+     * Parse a text-format message from {@code input} and merge the contents into {@code builder}.
+     */
+    public static void merge(Readable input, Message.Builder builder) throws IOException {
+        merge(input, ExtensionRegistry.getEmptyRegistry(), builder);
+    }
+
+    /**
+     * Parse a text-format message from {@code input} and merge the contents into {@code builder}.
+     */
+    public static void merge(CharSequence input, Message.Builder builder) throws ParseException {
+        merge(input, ExtensionRegistry.getEmptyRegistry(), builder);
+    }
+
+    /**
+     * Parse a text-format message from {@code input} and merge the contents into {@code builder}.
+     * Extensions will be recognized if they are registered in {@code extensionRegistry}.
+     */
+    public static void merge(Readable input,
+                             ExtensionRegistry extensionRegistry,
+                             Message.Builder builder) throws IOException {
+        // Read the entire input to a String then parse that.
+
+        // If StreamTokenizer were not quite so crippled, or if there were a kind
+        // of Reader that could read in chunks that match some particular regex,
+        // or if we wanted to write a custom Reader to tokenize our stream, then
+        // we would not have to read to one big String. Alas, none of these is
+        // the case. Oh well.
+
+        merge(toStringBuilder(input), extensionRegistry, builder);
+    }
+
+    /**
+     * Parse a text-format message from {@code input} and merge the contents into {@code builder}.
+     * Extensions will be recognized if they are registered in {@code extensionRegistry}.
+     */
+    public static void merge(CharSequence input,
+                             ExtensionRegistry extensionRegistry,
+                             Message.Builder builder) throws ParseException {
+        Tokenizer tokenizer = new Tokenizer(input);
+
+        // Based on the state machine @ http://json.org/
+
+        tokenizer.consume("{"); // Needs to happen when the object starts.
+        while (!tokenizer.tryConsume("}")) { // Continue till the object is done
+            mergeField(tokenizer, extensionRegistry, builder);
+        }
+    }
+
+    protected static class Tokenizer extends JsonFormat.Tokenizer {
+
+        /**
+         * Construct a tokenizer that parses tokens from the given text.
+         */
+        public Tokenizer(CharSequence text) {
+            super(text);
+        }
+
+        @Override
+        public String consumeIdentifier() throws ParseException {
+            String id = super.consumeIdentifier();
+            if ("_id".equals(id)) {
+                return "id";
+            } else if ("_rev".equals(id)) {
+                return "rev";
+            }
+            return id;
+        }
+    }
+
+    protected static class CouchDBGenerator extends JsonGenerator {
+
+        public CouchDBGenerator(Appendable output) {
+            super(output);
+        }
+
+        @Override
+        public void print(CharSequence text) throws IOException {
+            if ("id".equals(text)) {
+                super.print("_id");
+            } else if ("rev".equals(text)) {
+                super.print("_rev");
+            } else {
+                super.print(text);
+            }
+        }
+    }
+}

+ 703 - 0
4dkankan-common-utils/src/main/java/com/fdkankan/utils/proto/format/HtmlFormat.java

@@ -0,0 +1,703 @@
+package com.fdkankan.utils.proto.format;
+/* 
+    Copyright (c) 2009, Orbitz World Wide
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without modification, 
+    are permitted provided that the following conditions are met:
+
+        * Redistributions of source code must retain the above copyright notice, 
+          this list of conditions and the following disclaimer.
+        * Redistributions in binary form must reproduce the above copyright notice, 
+          this list of conditions and the following disclaimer in the documentation 
+          and/or other materials provided with the distribution.
+        * Neither the name of the Orbitz World Wide nor the names of its contributors 
+          may be used to endorse or promote products derived from this software 
+          without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+    A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+    OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+    SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+    LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+    DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+    THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+
+import com.google.protobuf.ByteString;
+import com.google.protobuf.Descriptors.EnumValueDescriptor;
+import com.google.protobuf.Descriptors.FieldDescriptor;
+import com.google.protobuf.Message;
+import com.google.protobuf.UnknownFieldSet;
+
+import java.io.IOException;
+import java.math.BigInteger;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+
+/**
+ * Provide ascii html formatting support for proto2 instances.
+ * <p>
+ * (c) 2009-10 Orbitz World Wide. All Rights Reserved.
+ * 
+ * @author eliran.bivas@gmail.com Eliran Bivas
+ * @version $HtmlFormat.java Mar 12, 2009 4:00:33 PM$
+ */
+public final class HtmlFormat {
+
+    private static final String META_CONTENT = "<meta http-equiv=\"content-type\" content=\"text/html; charset=UTF-8\" />";
+    private static final String MAIN_DIV_STYLE = "color: black; font-size: 14px; font-family: sans-serif; font-weight: bolder; margin-bottom: 10px;";
+    private static final String FIELD_NAME_STYLE = "font-weight: bold; color: #669966;font-size: 14px; font-family: sans-serif;";
+    private static final String FIELD_VALUE_STYLE = "color: #3300FF;font-size: 13px; font-family: sans-serif;";
+
+    /**
+     * Outputs a textual representation of the Protocol Message supplied into the parameter output.
+     * (This representation is the new version of the classic "ProtocolPrinter" output from the
+     * original Protocol Buffer system)
+     */
+    public static void print(Message message, Appendable output) throws IOException {
+        HtmlGenerator generator = new HtmlGenerator(output);
+        printTitle(message, generator);
+        print(message, generator);
+        generator.print("</body></html>");
+    }
+
+    private static void printTitle(final Message message, final HtmlGenerator generator) throws IOException {
+        generator.print("<html><head>");
+        generator.print(META_CONTENT);
+        generator.print("<title>");
+        generator.print(message.getDescriptorForType().getFullName());
+        generator.print("</title></head><body>");
+        generator.print("<div style=\"");
+        generator.print(MAIN_DIV_STYLE);
+        generator.print("\">message : ");
+        generator.print(message.getDescriptorForType().getFullName());
+        generator.print("</div>");
+    }
+
+    /**
+     * Outputs a textual representation of {@code fields} to {@code output}.
+     */
+    public static void print(UnknownFieldSet fields, Appendable output) throws IOException {
+        HtmlGenerator generator = new HtmlGenerator(output);
+        generator.print("<html>");
+        generator.print(META_CONTENT);
+        generator.print("</head><body>");
+        printUnknownFields(fields, generator);
+        generator.print("</body></html>");
+    }
+
+    /**
+     * Like {@code print()}, but writes directly to a {@code String} and returns it.
+     */
+    public static String printToString(Message message) {
+        try {
+            StringBuilder text = new StringBuilder();
+            print(message, text);
+            return text.toString();
+        } catch (IOException e) {
+            throw new RuntimeException("Writing to a StringBuilder threw an IOException (should never happen).",
+                                       e);
+        }
+    }
+
+    /**
+     * Like {@code print()}, but writes directly to a {@code String} and returns it.
+     */
+    public static String printToString(UnknownFieldSet fields) {
+        try {
+            StringBuilder text = new StringBuilder();
+            print(fields, text);
+            return text.toString();
+        } catch (IOException e) {
+            throw new RuntimeException("Writing to a StringBuilder threw an IOException (should never happen).",
+                                       e);
+        }
+    }
+
+    private static void print(Message message, HtmlGenerator generator) throws IOException {
+
+        for (Map.Entry<FieldDescriptor, Object> field : message.getAllFields().entrySet()) {
+            printField(field.getKey(), field.getValue(), generator);
+        }
+        printUnknownFields(message.getUnknownFields(), generator);
+    }
+
+    public static void printField(FieldDescriptor field, Object value, HtmlGenerator generator) throws IOException {
+
+        if (field.isRepeated()) {
+            // Repeated field. Print each element.
+            for (Object element : (List<?>) value) {
+                printSingleField(field, element, generator);
+            }
+        } else {
+            printSingleField(field, value, generator);
+        }
+    }
+
+    private static void printSingleField(FieldDescriptor field,
+                                         Object value,
+                                         HtmlGenerator generator) throws IOException {
+        if (field.isExtension()) {
+            generator.print("[<span style=\"");
+            generator.print(FIELD_NAME_STYLE);
+            generator.print("\">");
+            // We special-case MessageSet elements for compatibility with proto1.
+            if (field.getContainingType().getOptions().getMessageSetWireFormat()
+                            && (field.getType() == FieldDescriptor.Type.MESSAGE) && (field.isOptional())
+                            // object equality
+                            && (field.getExtensionScope() == field.getMessageType())) {
+                generator.print(field.getMessageType().getFullName());
+            } else {
+                generator.print(field.getFullName());
+            }
+            generator.print("</span>]");
+        } else {
+            generator.print("<span style=\"");
+            generator.print(FIELD_NAME_STYLE);
+            generator.print("\">");
+            if (field.getType() == FieldDescriptor.Type.GROUP) {
+                // Groups must be serialized with their original capitalization.
+                generator.print(field.getMessageType().getName());
+            } else {
+                generator.print(field.getName());
+            }
+            generator.print("</span>");
+        }
+
+        if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) {
+            generator.print(" <span style=\"color: red;\">{</span><br/>");
+            generator.indent();
+        } else {
+            generator.print(": ");
+        }
+
+        printFieldValue(field, value, generator);
+
+        if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) {
+            generator.outdent();
+            generator.print("<span style=\"color: red;\">}</span>");
+        }
+        generator.print("<br/>");
+    }
+
+    private static void printFieldValue(FieldDescriptor field, Object value, HtmlGenerator generator) throws IOException {
+        generator.print("<span style=\"");
+        generator.print(FIELD_VALUE_STYLE);
+        generator.print("\">");
+        switch (field.getType()) {
+            case INT32:
+            case INT64:
+            case SINT32:
+            case SINT64:
+            case SFIXED32:
+            case SFIXED64:
+            case FLOAT:
+            case DOUBLE:
+            case BOOL:
+                // Good old toString() does what we want for these types.
+                generator.print(value.toString());
+                break;
+
+            case UINT32:
+            case FIXED32:
+                generator.print(unsignedToString((Integer) value));
+                break;
+
+            case UINT64:
+            case FIXED64:
+                generator.print(unsignedToString((Long) value));
+                break;
+
+            case STRING:
+                generator.print("\"");
+                generator.print(value.toString());
+                generator.print("\"");
+                break;
+
+            case BYTES: {
+                generator.print("\"");
+                generator.print(escapeBytes((ByteString) value));
+                generator.print("\"");
+                break;
+            }
+
+            case ENUM: {
+                generator.print(((EnumValueDescriptor) value).getName());
+                break;
+            }
+
+            case MESSAGE:
+            case GROUP:
+                print((Message) value, generator);
+                break;
+        }
+        generator.print("</span>");
+    }
+
+    private static void printUnknownFields(UnknownFieldSet unknownFields, HtmlGenerator generator) throws IOException {
+        for (Map.Entry<Integer, UnknownFieldSet.Field> entry : unknownFields.asMap().entrySet()) {
+            UnknownFieldSet.Field field = entry.getValue();
+
+            for (long value : field.getVarintList()) {
+                generator.print(entry.getKey().toString());
+                generator.print(": ");
+                generator.print(unsignedToString(value));
+                generator.print("<br/>");
+            }
+            for (int value : field.getFixed32List()) {
+                generator.print(entry.getKey().toString());
+                generator.print(": ");
+                generator.print(String.format((Locale) null, "0x%08x", value));
+                generator.print("<br/>");
+            }
+            for (long value : field.getFixed64List()) {
+                generator.print(entry.getKey().toString());
+                generator.print(": ");
+                generator.print(String.format((Locale) null, "0x%016x", value));
+                generator.print("<br/>");
+            }
+            for (ByteString value : field.getLengthDelimitedList()) {
+                generator.print(entry.getKey().toString());
+                generator.print(": \"");
+                generator.print(escapeBytes(value));
+                generator.print("\"<br/>");
+            }
+            for (UnknownFieldSet value : field.getGroupList()) {
+                generator.print(entry.getKey().toString());
+                generator.print(" <span style=\"color: red;\">{</span><br/>");
+                generator.indent();
+                printUnknownFields(value, generator);
+                generator.outdent();
+                generator.print("<span style=\"color: red;\">}</span><br/>");
+            }
+        }
+    }
+
+    /**
+     * Convert an unsigned 32-bit integer to a string.
+     */
+    private static String unsignedToString(int value) {
+        if (value >= 0) {
+            return Integer.toString(value);
+        } else {
+            return Long.toString((value) & 0x00000000FFFFFFFFL);
+        }
+    }
+
+    /**
+     * Convert an unsigned 64-bit integer to a string.
+     */
+    private static String unsignedToString(long value) {
+        if (value >= 0) {
+            return Long.toString(value);
+        } else {
+            // Pull off the most-significant bit so that BigInteger doesn't think
+            // the number is negative, then set it again using setBit().
+            return BigInteger.valueOf(value & 0x7FFFFFFFFFFFFFFFL).setBit(63).toString();
+        }
+    }
+
+    /**
+     * An inner class for writing text to the output stream.
+     */
+    static private final class HtmlGenerator {
+
+        Appendable output;
+        boolean atStartOfLine = true;
+
+        public HtmlGenerator(Appendable output) {
+            this.output = output;
+        }
+
+        /**
+         * Indent text by two spaces. After calling Indent(), two spaces will be inserted at the
+         * beginning of each line of text. Indent() may be called multiple times to produce deeper
+         * indents.
+         * 
+         * @throws IOException
+         */
+        public void indent() throws IOException {
+            print("<div style=\"margin-left: 25px\">");
+        }
+
+        /**
+         * Reduces the current indent level by two spaces, or crashes if the indent level is zero.
+         * 
+         * @throws IOException
+         */
+        public void outdent() throws IOException {
+            print("</div>");
+        }
+
+        /**
+         * Print text to the output stream.
+         */
+        public void print(CharSequence text) throws IOException {
+            int size = text.length();
+            int pos = 0;
+
+            for (int i = 0; i < size; i++) {
+                if (text.charAt(i) == '\n') {
+                    write("<br/>", i - pos + 1);
+                    pos = i + 1;
+                    atStartOfLine = true;
+                }
+            }
+            write(text.subSequence(pos, size), size - pos);
+        }
+
+        private void write(CharSequence data, int size) throws IOException {
+            if (size == 0) {
+                return;
+            }
+            if (atStartOfLine) {
+                atStartOfLine = false;
+            }
+            output.append(data);
+        }
+    }
+
+    // =================================================================
+    // Utility functions
+    //
+    // Some of these methods are package-private because Descriptors.java uses
+    // them.
+
+    /**
+     * Escapes bytes in the format used in protocol buffer text format, which is the same as the
+     * format used for C string literals. All bytes that are not printable 7-bit ASCII characters
+     * are escaped, as well as backslash, single-quote, and double-quote characters. Characters for
+     * which no defined short-hand escape sequence is defined will be escaped using 3-digit octal
+     * sequences.
+     */
+    static String escapeBytes(ByteString input) {
+        StringBuilder builder = new StringBuilder(input.size());
+        for (int i = 0; i < input.size(); i++) {
+            byte b = input.byteAt(i);
+            switch (b) {
+                // Java does not recognize \a or \v, apparently.
+                case 0x07:
+                    builder.append("\\a");
+                    break;
+                case '\b':
+                    builder.append("\\b");
+                    break;
+                case '\f':
+                    builder.append("\\f");
+                    break;
+                case '\n':
+                    builder.append("\\n");
+                    break;
+                case '\r':
+                    builder.append("\\r");
+                    break;
+                case '\t':
+                    builder.append("\\t");
+                    break;
+                case 0x0b:
+                    builder.append("\\v");
+                    break;
+                case '\\':
+                    builder.append("\\\\");
+                    break;
+                case '\'':
+                    builder.append("\\\'");
+                    break;
+                case '"':
+                    builder.append("\\\"");
+                    break;
+                default:
+                    if (b >= 0x20) {
+                        builder.append((char) b);
+                    } else {
+                        builder.append('\\');
+                        builder.append((char) ('0' + ((b >>> 6) & 3)));
+                        builder.append((char) ('0' + ((b >>> 3) & 7)));
+                        builder.append((char) ('0' + (b & 7)));
+                    }
+                    break;
+            }
+        }
+        return builder.toString();
+    }
+
+    /**
+     * Un-escape a byte sequence as escaped using
+     * {@link #escapeBytes(com.googlecode.protobuf.format.ByteString)}. Two-digit hex escapes (starting with
+     * "\x") are also recognized.
+     */
+    static ByteString unescapeBytes(CharSequence input) throws InvalidEscapeSequence {
+        byte[] result = new byte[input.length()];
+        int pos = 0;
+        for (int i = 0; i < input.length(); i++) {
+            char c = input.charAt(i);
+            if (c == '\\') {
+                if (i + 1 < input.length()) {
+                    ++i;
+                    c = input.charAt(i);
+                    if (isOctal(c)) {
+                        // Octal escape.
+                        int code = digitValue(c);
+                        if ((i + 1 < input.length()) && isOctal(input.charAt(i + 1))) {
+                            ++i;
+                            code = code * 8 + digitValue(input.charAt(i));
+                        }
+                        if ((i + 1 < input.length()) && isOctal(input.charAt(i + 1))) {
+                            ++i;
+                            code = code * 8 + digitValue(input.charAt(i));
+                        }
+                        result[pos++] = (byte) code;
+                    } else {
+                        switch (c) {
+                            case 'a':
+                                result[pos++] = 0x07;
+                                break;
+                            case 'b':
+                                result[pos++] = '\b';
+                                break;
+                            case 'f':
+                                result[pos++] = '\f';
+                                break;
+                            case 'n':
+                                result[pos++] = '\n';
+                                break;
+                            case 'r':
+                                result[pos++] = '\r';
+                                break;
+                            case 't':
+                                result[pos++] = '\t';
+                                break;
+                            case 'v':
+                                result[pos++] = 0x0b;
+                                break;
+                            case '\\':
+                                result[pos++] = '\\';
+                                break;
+                            case '\'':
+                                result[pos++] = '\'';
+                                break;
+                            case '"':
+                                result[pos++] = '\"';
+                                break;
+
+                            case 'x':
+                                // hex escape
+                                int code = 0;
+                                if ((i + 1 < input.length()) && isHex(input.charAt(i + 1))) {
+                                    ++i;
+                                    code = digitValue(input.charAt(i));
+                                } else {
+                                    throw new InvalidEscapeSequence("Invalid escape sequence: '\\x' with no digits");
+                                }
+                                if ((i + 1 < input.length()) && isHex(input.charAt(i + 1))) {
+                                    ++i;
+                                    code = code * 16 + digitValue(input.charAt(i));
+                                }
+                                result[pos++] = (byte) code;
+                                break;
+
+                            default:
+                                throw new InvalidEscapeSequence("Invalid escape sequence: '\\" + c
+                                                                + "'");
+                        }
+                    }
+                } else {
+                    throw new InvalidEscapeSequence("Invalid escape sequence: '\\' at end of string.");
+                }
+            } else {
+                result[pos++] = (byte) c;
+            }
+        }
+
+        return ByteString.copyFrom(result, 0, pos);
+    }
+
+    /**
+     * Thrown by {@link JsonFormat#unescapeBytes} and {@link JsonFormat#unescapeText} when an
+     * invalid escape sequence is seen.
+     */
+    static class InvalidEscapeSequence extends IOException {
+
+        private static final long serialVersionUID = 1L;
+
+        public InvalidEscapeSequence(String description) {
+            super(description);
+        }
+    }
+
+    /**
+     * Like {@link #escapeBytes(com.googlecode.protobuf.format.ByteString)}, but escapes a text string.
+     * Non-ASCII characters are first encoded as UTF-8, then each byte is escaped individually as a
+     * 3-digit octal escape. Yes, it's weird.
+     */
+    static String escapeText(String input) {
+        return escapeBytes(ByteString.copyFromUtf8(input));
+    }
+
+    /**
+     * Un-escape a text string as escaped using {@link #escapeText(String)}. Two-digit hex escapes
+     * (starting with "\x") are also recognized.
+     */
+    static String unescapeText(String input) throws InvalidEscapeSequence {
+        return unescapeBytes(input).toStringUtf8();
+    }
+
+    /**
+     * Is this an octal digit?
+     */
+    private static boolean isOctal(char c) {
+        return ('0' <= c) && (c <= '7');
+    }
+
+    /**
+     * Is this a hex digit?
+     */
+    private static boolean isHex(char c) {
+        return (('0' <= c) && (c <= '9')) || (('a' <= c) && (c <= 'f'))
+        || (('A' <= c) && (c <= 'F'));
+    }
+
+    /**
+     * Interpret a character as a digit (in any base up to 36) and return the numeric value. This is
+     * like {@code Character.digit()} but we don't accept non-ASCII digits.
+     */
+    private static int digitValue(char c) {
+        if (('0' <= c) && (c <= '9')) {
+            return c - '0';
+        } else if (('a' <= c) && (c <= 'z')) {
+            return c - 'a' + 10;
+        } else {
+            return c - 'A' + 10;
+        }
+    }
+
+    /**
+     * Parse a 32-bit signed integer from the text. Unlike the Java standard {@code
+     * Integer.parseInt()}, this function recognizes the prefixes "0x" and "0" to signify
+     * hexidecimal and octal numbers, respectively.
+     */
+    static int parseInt32(String text) throws NumberFormatException {
+        return (int) parseInteger(text, true, false);
+    }
+
+    /**
+     * Parse a 32-bit unsigned integer from the text. Unlike the Java standard {@code
+     * Integer.parseInt()}, this function recognizes the prefixes "0x" and "0" to signify
+     * hexidecimal and octal numbers, respectively. The result is coerced to a (signed) {@code int}
+     * when returned since Java has no unsigned integer type.
+     */
+    static int parseUInt32(String text) throws NumberFormatException {
+        return (int) parseInteger(text, false, false);
+    }
+
+    /**
+     * Parse a 64-bit signed integer from the text. Unlike the Java standard {@code
+     * Integer.parseInt()}, this function recognizes the prefixes "0x" and "0" to signify
+     * hexidecimal and octal numbers, respectively.
+     */
+    static long parseInt64(String text) throws NumberFormatException {
+        return parseInteger(text, true, true);
+    }
+
+    /**
+     * Parse a 64-bit unsigned integer from the text. Unlike the Java standard {@code
+     * Integer.parseInt()}, this function recognizes the prefixes "0x" and "0" to signify
+     * hexidecimal and octal numbers, respectively. The result is coerced to a (signed) {@code long}
+     * when returned since Java has no unsigned long type.
+     */
+    static long parseUInt64(String text) throws NumberFormatException {
+        return parseInteger(text, false, true);
+    }
+
+    private static long parseInteger(String text, boolean isSigned, boolean isLong) throws NumberFormatException {
+        int pos = 0;
+
+        boolean negative = false;
+        if (text.startsWith("-", pos)) {
+            if (!isSigned) {
+                throw new NumberFormatException("Number must be positive: " + text);
+            }
+            ++pos;
+            negative = true;
+        }
+
+        int radix = 10;
+        if (text.startsWith("0x", pos)) {
+            pos += 2;
+            radix = 16;
+        } else if (text.startsWith("0", pos)) {
+            radix = 8;
+        }
+
+        String numberText = text.substring(pos);
+
+        long result = 0;
+        if (numberText.length() < 16) {
+            // Can safely assume no overflow.
+            result = Long.parseLong(numberText, radix);
+            if (negative) {
+                result = -result;
+            }
+
+            // Check bounds.
+            // No need to check for 64-bit numbers since they'd have to be 16 chars
+            // or longer to overflow.
+            if (!isLong) {
+                if (isSigned) {
+                    if ((result > Integer.MAX_VALUE) || (result < Integer.MIN_VALUE)) {
+                        throw new NumberFormatException("Number out of range for 32-bit signed integer: "
+                                                        + text);
+                    }
+                } else {
+                    if ((result >= (1L << 32)) || (result < 0)) {
+                        throw new NumberFormatException("Number out of range for 32-bit unsigned integer: "
+                                                        + text);
+                    }
+                }
+            }
+        } else {
+            BigInteger bigValue = new BigInteger(numberText, radix);
+            if (negative) {
+                bigValue = bigValue.negate();
+            }
+
+            // Check bounds.
+            if (!isLong) {
+                if (isSigned) {
+                    if (bigValue.bitLength() > 31) {
+                        throw new NumberFormatException("Number out of range for 32-bit signed integer: "
+                                                        + text);
+                    }
+                } else {
+                    if (bigValue.bitLength() > 32) {
+                        throw new NumberFormatException("Number out of range for 32-bit unsigned integer: "
+                                                        + text);
+                    }
+                }
+            } else {
+                if (isSigned) {
+                    if (bigValue.bitLength() > 63) {
+                        throw new NumberFormatException("Number out of range for 64-bit signed integer: "
+                                                        + text);
+                    }
+                } else {
+                    if (bigValue.bitLength() > 64) {
+                        throw new NumberFormatException("Number out of range for 64-bit unsigned integer: "
+                                                        + text);
+                    }
+                }
+            }
+
+            result = bigValue.longValue();
+        }
+
+        return result;
+    }
+}

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 1338 - 0
4dkankan-common-utils/src/main/java/com/fdkankan/utils/proto/format/JavaPropsFormat.java


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 1603 - 0
4dkankan-common-utils/src/main/java/com/fdkankan/utils/proto/format/JsonFormat.java


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 1333 - 0
4dkankan-common-utils/src/main/java/com/fdkankan/utils/proto/format/XmlFormat.java


+ 65 - 0
4dkankan-common-utils/src/main/java/com/fdkankan/utils/utils/Base64Converter.java

@@ -0,0 +1,65 @@
+package com.fdkankan.utils.utils;
+
+import java.io.UnsupportedEncodingException;
+import java.util.Base64;
+
+public class Base64Converter {
+
+    public final static Base64.Encoder encoder = Base64.getEncoder();
+    final static Base64.Decoder decoder = Base64.getDecoder();
+
+    /**
+     * 给字符串加密
+     * @param text
+     * @return
+     */
+    public static String encode(String text) {
+        byte[] textByte = new byte[0];
+        try {
+            textByte = text.getBytes("UTF-8");
+        } catch (UnsupportedEncodingException e) {
+            e.printStackTrace();
+        }
+        String encodedText = encoder.encodeToString(textByte);
+        return encodedText;
+    }
+
+    /**
+     * 给字符串加密
+     * @param textByte
+     * @return
+     */
+    public static String encode(byte[] textByte) {
+        return encoder.encodeToString(textByte);
+    }
+
+    /**
+     * 将加密后的字符串进行解密
+     * @param encodedText
+     * @return
+     */
+    public static String decode(String encodedText) {
+        String text = null;
+        try {
+            text = new String(decoder.decode(encodedText), "UTF-8");
+        } catch (UnsupportedEncodingException e) {
+            e.printStackTrace();
+        }
+        return text;
+    }
+
+    /**
+     * 根据逻辑截取加密后的密码
+     * @param text
+     * @return
+     */
+    public static String subText(String text){
+        //去掉前8位字符串
+        text = text.substring(8);
+        //去掉后8位字符串
+        text = text.substring(0, text.length() - 8);
+        //最后两个字符串换到前面,并且去掉剩下的后8位字符串
+        String result = text.substring(text.length() - 2) + text.substring(0, text.length() - 10);
+        return result;
+    }
+}

+ 55 - 0
4dkankan-common-utils/src/main/java/com/fdkankan/utils/utils/ConstantCmd.java

@@ -0,0 +1,55 @@
+package com.fdkankan.utils.utils;
+
+public class ConstantCmd {
+
+	//生成模型的命令
+	public static final String BUILD_MODEL_COMMAND = "bash /home/ubuntu/bin/Launcher.sh ";
+
+	//生成模型的命令
+	public static final String BUILD_MODEL_COMMAND2 = "bash /opt/ossutil/sshoss.sh ";
+
+	public static final String BUILD_MODEL_OLD_COMMAND = "bash /home/ubuntu/bin_old/Launcher.sh ";
+	public static final String BUILD_MODEL_SFM_COMMAND = "bash /home/ubuntu/run_sfm.sh ";
+
+	public static final String OBJ_TO_TXT = "bash /home/ubuntu/bin_old/obj2txt.sh ";
+
+	public static final String REBUILD_MODEL_FLLOR = "bash /home/ubuntu/bin/Panoramix_Floorplan.sh ";
+	//切图命令
+	public static final String CUT_IMG_COMMAND = "bash /home/ubuntu/OpenSfM/bin/run_cube.sh ";
+	//调整图片的命令
+	public static final String ADJUST_IMG_COMMAND = "/home/ubuntu/OpenSfM/bin/run_skybox ";
+	  
+	  
+	  
+	//转台拼图命令
+	public static final String BUILD_PANORAMA = "AutopanoGiga /home/ubuntu/data/";
+	//六目,拼图,计算,切图(二代)
+	public static final String BUILD_FOR_SIX = "bash /home/ubuntu/run_all_m6.sh ";
+
+	//合并音频
+	public static final String MERGE_VIDEO = "bash /monchickey/ffmpeg/bin/ff_synthesis.sh ";
+
+	//生成一段静音音频
+	public static final String CREATE_MUTE_VIDEO = "bash /monchickey/ffmpeg/bin/ff_mtue.sh ";
+
+	//将mp4文件转换成flv
+	public static final String MP4_TO_FLV = "bash /monchickey/ffmpeg/bin/ff_mp4TOflv.sh ";
+
+	//删除/mnt/data/下的数据脚本
+	public static final String DELETE_FILE = "bash /monchickey/ffmpeg/bin/delete.sh ";
+
+	public static final String OSS_UTIL_CP ="bash /opt/ossutil/oss.sh ";
+
+	public static final String OSS_FILE_CP = "bash /opt/ossutil/file.sh ";
+
+	public static final String MATTERPRO_CUT_IMG = "node /opt/4dkankan_scene/index.js ";
+
+	//激光相机 extra迁移
+	public static final String CP_JG_EXTRA = "bash /opt/ossutil/laser-copy.sh ";
+
+	public static final String CP_JG_ALL = "bash /opt/ossutil/laser-cp-r.sh ";
+
+	// 修改户型图json文件
+	public static final String TRANSLATE_HOUST_FLOOR = "/opt/Robin/JsonRead.out ";
+
+}

+ 602 - 0
4dkankan-common-utils/src/main/java/com/fdkankan/utils/utils/CreateObjUtil.java

@@ -0,0 +1,602 @@
+package com.fdkankan.utils.utils;
+
+import com.fdkankan.utils.constant.ConstantFileName;
+import com.fdkankan.utils.constant.ConstantFilePath;
+import com.fdkankan.utils.proto.BigSceneProto;
+import com.fdkankan.utils.proto.Common;
+import com.fdkankan.utils.proto.Visionmodeldata;
+import com.fdkankan.utils.proto.format.JsonFormat;
+import com.google.protobuf.TextFormat;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.util.StopWatch;
+
+import java.io.*;
+import java.util.HashMap;
+import java.util.Map;
+
+public class CreateObjUtil {
+
+	private static Logger log = LoggerFactory.getLogger(CreateObjUtil.class);
+
+	public void saveuploadImgs(String folderName) throws IOException, Exception
+	{
+		log.info("开始计算");
+		String command = "bash /home/ubuntu/photoscan-pro/build_model.sh "+folderName;
+		callshell(command);
+		boolean flag = false;
+		String sPath =  ConstantFilePath.CREATE_MODEL_PATH+folderName+File.separator+"mesh"+File.separator+"mesh.obj";
+		while(!flag)
+		{
+			flag = isModel(sPath,folderName);
+		}
+		log.info("计算完毕");
+	}
+	
+	public void saveuploadImgs2(String folderName) throws IOException, Exception
+	{
+		log.info("开始计算");
+		String command = "bash /home/ubuntu/photoscan-pro/build_bigscene.sh "+folderName;
+		callshell(command);
+		boolean flag = false;
+		String sPath = ConstantFilePath.CREATE_BIG_SCENE_PATH+folderName+File.separator+"mesh"+File.separator+"mesh.obj";
+		while(!flag)
+		{
+			flag = isModel(sPath,folderName);
+		}
+		log.info("计算完毕");
+		log.info("obj和camera转换成大场景要的格式");
+		convertobjTotxt( folderName);
+		
+	}
+
+	//开始建模
+	public static void unRar(String rarPath,String dataPath) throws Exception{
+		log.info("解压rar开始");
+		String command = "unrar e " + rarPath + " " + dataPath;
+		callshell(command);
+		log.info("解压rar完毕:" + command);
+	}
+
+	public static void unZip(String zipPath,String dataPath) throws Exception{
+		log.info("解压zip开始");
+		String command = "unzip -O GBK/GB18030CP936 " + zipPath + " -d " + dataPath;
+		callshell(command);
+		log.info("解压zip完毕:" + command);
+	}
+
+	//开始建模
+	public static void build3dModel(String folderName,String isModel) throws Exception{
+		log.info("开始建模");
+		String command = ConstantCmd.BUILD_MODEL_COMMAND+folderName;
+		callshell(command);
+		log.info("计算完毕:" + command);
+	}
+
+	//开始建模
+	public static void build3dModel2(String folderName,String isModel) throws Exception{
+		log.info("开始建模");
+		String command = ConstantCmd.BUILD_MODEL_COMMAND2+folderName;
+		callshell(command);
+		log.info("计算完毕:" + command);
+	}
+
+	//开始建模
+	public static void build3dModelOld(String folderName,String isModel) throws Exception{
+		log.info("开始v2建模");
+		String command = ConstantCmd.BUILD_MODEL_OLD_COMMAND+folderName;
+		callshell(command);
+		log.info("计算v2完毕:" + command);
+	}
+
+	//开始建模
+	public static void translateHoustfloorJSONFile(String filePath,String outputPath) throws Exception{
+		log.info("开始转换houst_floor.json");
+		String command = ConstantCmd.TRANSLATE_HOUST_FLOOR + filePath + " " + outputPath;
+		callshell(command);
+		log.info("转换houst_floor.json 结束");
+	}
+
+	//激光相机复制资源
+	public static void cpfile(String filepathOld,String filepathNew) throws Exception{
+		log.info("开始复制");
+		String command = ConstantCmd.CP_JG_EXTRA+ " " + filepathOld + " " + filepathNew;
+		callshell(command);
+		log.info("复制完毕:" + command);
+	}
+
+
+	//激光相机复制资源laser下的全部资源
+	public static void cplaserfile(String filepathOld,String filepathNew) throws Exception{
+		log.info("开始复制");
+		String command = ConstantCmd.CP_JG_ALL+ " " + filepathOld + " " + filepathNew;
+		callshell(command);
+		log.info("复制完毕:" + command);
+	}
+	
+	//开始建模
+	public void build3dModelSFM(String folderName,String isModel) throws Exception{
+		log.info("开始建模");
+		String command = ConstantCmd.BUILD_MODEL_SFM_COMMAND+folderName+" "+isModel;
+		callshell(command);
+		log.info("计算完毕");
+	}
+
+	//obj文件转换问txt
+	public static void objToTxt(String folderName,String isModel) throws Exception{
+		log.info("obj2txt开始转换");
+		String command = ConstantCmd.OBJ_TO_TXT+folderName;
+		callshell(command);
+		log.info("转换完毕:" + command);
+	}
+
+	public void rebuildModelFllor(String folderName, String isModel) {
+		try{
+			log.info("开始建模");
+			String command = ConstantCmd.REBUILD_MODEL_FLLOR+folderName+" "+isModel;
+			callshell(command);
+			log.info("计算完毕");
+		}
+		catch(Exception e)
+		{
+			e.printStackTrace();
+		}
+	}
+
+	//切图
+	public void cutImgs(String[] imgNames ,String folderName)
+	{
+		try{
+			log.info("开始切图");
+			for(int i=0;i<imgNames.length;++i)
+			{
+				String imgName=imgNames[i].replace(".jpg", "");
+				String command = ConstantCmd.CUT_IMG_COMMAND+folderName+" "+imgName;
+				callshell(command);
+			}
+			log.info("切图完毕");
+		}
+		catch(Exception e)
+		{
+			e.printStackTrace();
+		}
+	}
+	
+	//调整切图
+	public void adjustImgs(String folderName)
+	{
+		try{
+			String command = ConstantCmd.ADJUST_IMG_COMMAND + folderName;
+			log.info("开始调整图片");
+			callshell(command);
+			log.info("调整图片完毕");
+		}
+		catch(Exception e)
+		{
+			e.printStackTrace();
+		}
+	}
+	
+	//obj和camera转换成大场景要的格式
+	public void convertobjTotxt(String folderName) throws Exception
+	{
+		//obj
+		String command = "/home/ubuntu/photoscan-pro/main/mesh/mesh "+folderName;
+		callshell(command);
+		//camera
+		command = "/home/ubuntu/photoscan-pro/main/read_camera/read_camera "+folderName;
+		callshell(command);
+		
+		String prefix = ConstantFilePath.CREATE_BIG_SCENE_PATH+folderName+File.separator+"data"+File.separator;
+		String srcpath = prefix +"mesh.txt";
+		String despath = prefix +"dacf7dfa24ae47fab8fcebfe4dc41ab9_50k.dam";
+				
+		convertTxtToDam( srcpath, despath);
+		//dam转换成lzma
+		command = "lzma /home/ubuntu/photo_data/bigscene/"+folderName+"/data/dacf7dfa24ae47fab8fcebfe4dc41ab9_50k.dam";
+		callshell(command);
+		
+		srcpath = prefix +"vision.txt";
+		despath = prefix +"vision.modeldata";
+		convertTxtToVisionmodeldata( srcpath, despath);
+	}
+
+	public static void convertDamToLzma(String folderName)throws Exception
+	{
+		try
+		{
+			String command = "lzma "+ folderName+File.separator+ ConstantFileName.modelUUID+"_50k.dam";
+			log.info("开始转换lzma");
+			callshell(command);
+			log.info("转换lzma完毕");
+		}
+		catch(Exception e)
+		{
+			StringWriter trace=new StringWriter();
+			e.printStackTrace(new PrintWriter(trace));
+			log.error(trace.toString());
+		}
+
+	}
+
+	public static void convertDamToLzma2(String folderName)throws Exception
+	{
+		try
+		{
+			String command = "lzma "+ folderName+File.separator+ ConstantFileName.modelUUID+"_50k2.dam";
+			log.info("开始转换lzma");
+			callshell(command);
+			log.info("转换lzma完毕");
+		}
+		catch(Exception e)
+		{
+			StringWriter trace=new StringWriter();
+			e.printStackTrace(new PrintWriter(trace));
+			log.error(trace.toString());
+		}
+
+	}
+	
+	public static void convertTxtToDam(String srcpath,String despath)throws Exception
+	{
+			BigSceneProto.binary_mesh.Builder builder= BigSceneProto.binary_mesh.newBuilder();
+			InputStream inputStream = new FileInputStream(srcpath);
+			InputStreamReader reader = new InputStreamReader(inputStream, "ASCII");
+			TextFormat.merge(reader, builder);
+			byte[] buf= builder.build().toByteArray();
+			
+			 //把序列化后的数据写入本地磁盘  
+	        ByteArrayInputStream stream = new ByteArrayInputStream(buf);  
+	        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(despath));//设置输出路径  
+	        BufferedInputStream bis = new BufferedInputStream(stream);  
+	        int b = -1;  
+	        while ((b = bis.read()) != -1) {  
+	            bos.write(b);  
+	        }  
+	        bis.close();  
+	        bos.close();
+	}
+	
+	public static void convertVisionmodeldataToTxt(String srcpath,String despath)throws Exception
+	{
+		try
+		{
+			File file = new File(srcpath); 
+			FileInputStream fis=new FileInputStream(file);
+
+			Visionmodeldata.NavigationInfo data_NavigationInfo = Visionmodeldata.NavigationInfo.parseFrom(fis);
+	
+			//PrintStream out = new PrintStream(despath); 
+			String jsonFormat1 = JsonFormat.printToString(data_NavigationInfo);
+			ByteArrayInputStream stream = new ByteArrayInputStream(jsonFormat1.getBytes());  
+	        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(despath));//设置输出路径  
+	        BufferedInputStream bis = new BufferedInputStream(stream);  
+	        int b = -1;  
+	        while ((b = bis.read()) != -1) {  
+	           bos.write(b);  
+	        }  
+			//out.close();
+	        bis.close();  
+	        bos.close(); 
+		}
+		catch(Exception e)
+		{
+			StringWriter trace=new StringWriter();
+	        e.printStackTrace(new PrintWriter(trace));
+	        log.error(trace.toString());
+		}
+	}
+	
+	public static void convertTxtToVisionmodeldata(String srcpath,String despath)throws Exception
+	{
+		try
+		{
+			Visionmodeldata.NavigationInfo.Builder builder = Visionmodeldata.NavigationInfo.newBuilder();
+			String jsonFormat = readTxtFileToJson(srcpath);
+			JsonFormat.merge(jsonFormat, builder);
+			byte[] buf= builder.build().toByteArray();
+			
+			 //把序列化后的数据写入本地磁盘  
+	        ByteArrayInputStream stream = new ByteArrayInputStream(buf);  
+	        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(despath));//设置输出路径  
+	        BufferedInputStream bis = new BufferedInputStream(stream);  
+	        int b = -1;  
+	        while ((b = bis.read()) != -1) {  
+	           bos.write(b);  
+	        }  
+	        bis.close();  
+	        bos.close(); 
+		}
+		catch(Exception e)
+		{
+			StringWriter trace=new StringWriter();
+	        e.printStackTrace(new PrintWriter(trace));
+	        log.error(trace.toString());
+		}
+	}
+
+	public static void convertVisionmodeldataToTxtCommon(String srcpath,String despath)throws Exception
+	{
+		try
+		{
+			File file = new File(srcpath);
+			FileInputStream fis=new FileInputStream(file);
+
+			Common.NavigationInfo data_NavigationInfo = Common.NavigationInfo.parseFrom(fis);
+
+			//PrintStream out = new PrintStream(despath);
+			String jsonFormat1 = JsonFormat.printToString(data_NavigationInfo);
+			ByteArrayInputStream stream = new ByteArrayInputStream(jsonFormat1.getBytes());
+			BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(despath));//设置输出路径
+			BufferedInputStream bis = new BufferedInputStream(stream);
+			int b = -1;
+			while ((b = bis.read()) != -1) {
+				bos.write(b);
+			}
+			//out.close();
+			bis.close();
+			bos.close();
+		}
+		catch(Exception e)
+		{
+			StringWriter trace=new StringWriter();
+			e.printStackTrace(new PrintWriter(trace));
+			log.error(trace.toString());
+		}
+	}
+
+	public static void convertTxtToVisionmodeldataCommon(String srcpath,String despath)throws Exception
+	{
+		try
+		{
+			Common.NavigationInfo.Builder builder = Common.NavigationInfo.newBuilder();
+			String jsonFormat = readTxtFileToJson(srcpath);
+			JsonFormat.merge(jsonFormat, builder);
+			byte[] buf= builder.build().toByteArray();
+
+			//把序列化后的数据写入本地磁盘
+			ByteArrayInputStream stream = new ByteArrayInputStream(buf);
+			BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(despath));//设置输出路径
+			BufferedInputStream bis = new BufferedInputStream(stream);
+			int b = -1;
+			while ((b = bis.read()) != -1) {
+				bos.write(b);
+			}
+			bis.close();
+			bos.close();
+		}
+		catch(Exception e)
+		{
+			StringWriter trace=new StringWriter();
+			e.printStackTrace(new PrintWriter(trace));
+			log.error(trace.toString());
+		}
+	}
+	
+	public static void callshell(String command)
+	{ 
+        try {
+			 StopWatch stopWatch = new StopWatch();
+			 stopWatch.start();
+			 Process process = Runtime.getRuntime().exec(command);
+        	 StreamGobbler errorGobbler = new StreamGobbler(process.getErrorStream(), "ERROR");
+             errorGobbler.start();  
+             StreamGobbler outGobbler = new StreamGobbler(process.getInputStream(), "STDOUT");  
+             outGobbler.start();  
+             process.waitFor();
+			log.info("脚本{}执行完毕,用时:{}",command,stopWatch.toString());
+        } catch (Exception e) {  
+            e.printStackTrace();  
+        }  
+	}
+	
+	public static int doWaitFor(Process process) {
+		  InputStream in = null;
+		  InputStream err = null;
+		  int exitValue = -1; // returned to caller when p is finished
+		  try {
+		    in = process.getInputStream();
+		    err = process.getErrorStream();
+		    boolean finished = false; // Set to true when p is finished
+		    while (!finished) {
+		      try {
+		        while (in.available() > 0) {
+		          // Print the output of our system call
+		          Character c = new Character((char) in.read());
+		          System.out.print(c);
+		        }
+		        while (err.available() > 0) {
+		          // Print the output of our system call
+		          Character c = new Character((char) err.read());
+		          System.out.print(c);
+		        }
+		        // Ask the process for its exitValue. If the process
+		        // is not finished, an IllegalThreadStateException
+		        // is thrown. If it is finished, we fall through and
+		        // the variable finished is set to true.
+		        exitValue = process.exitValue();
+		        finished = true;
+		      } catch (IllegalThreadStateException e) {
+		        // Process is not finished yet;
+		        // Sleep a little to save on CPU cycles
+		        Thread.currentThread().sleep(500);
+		      }
+		    }
+		  } catch (Exception e) {
+		    e.printStackTrace();
+		  } finally {
+		    try {
+		      if (in != null) {
+		        in.close();
+		      }
+		    } catch (IOException e) {
+		      e.printStackTrace();
+		    }
+		    if (err != null) {
+		      try {
+		        err.close();
+		      } catch (IOException e) {
+		        e.printStackTrace();
+		      }
+		    }
+		  }
+		  return exitValue;
+		}
+
+	
+	private boolean isModel(String sPath,String folderName)
+	{
+		boolean flag = false;  
+		File file = new File(sPath);  
+	    if (file.isFile() && file.exists()) {  
+	        flag = true;  
+	    }  
+	    log.info("等待...");
+	    return flag;  
+	}
+	
+	public static String readTxtFileToJson(String filePath){
+        try { 
+                String encoding="UTF-8"; 
+                File file=new File(filePath); 
+                if(file.isFile() && file.exists()){ 
+                    InputStreamReader read = new InputStreamReader( 
+                    new FileInputStream(file),encoding);
+                    BufferedReader bufferedReader = new BufferedReader(read); 
+                    String lineTxt = null; 
+                    String result="";
+                    while((lineTxt = bufferedReader.readLine()) != null){ 
+                    	result+=lineTxt;
+                        //log.info(lineTxt); 
+                    } 
+                    read.close(); 
+                    return result;
+        }else{ 
+            return null;
+        } 
+        } catch (Exception e) { 
+            e.printStackTrace(); 
+            return null;
+        } 
+      
+    }
+	
+	public Map<String,String> getAllFile(String dPath,String prefix)
+	{
+		File dirFile = new File(dPath);
+	    if (!dirFile.isDirectory()) {
+        }
+	    Map<String,String> map = new HashMap<String,String>();
+	    File[] files = dirFile.listFiles();
+	    for (int i = 0; i < files.length; i++) {
+            if (files[i].isFile()) {
+            	String path = files[i].getPath();
+            	map.put(path, prefix+path.substring(path.lastIndexOf("/")+1));
+            }
+        }
+	    return map;
+	}
+	
+	public Map<String,String> getchildFile(String dPath,String prefix,String childname)
+	{
+		File dirFile = new File(dPath+File.separator+childname);
+	    if (!dirFile.isDirectory()) {
+	    	return null;
+        }
+	    Map<String,String> map = new HashMap<String,String>();
+	    File[] files = dirFile.listFiles();
+	    for (int i = 0; i < files.length; i++) {
+            if (files[i].isFile()) {
+            	String path = files[i].getPath();
+            	map.put(path, prefix+childname+path.substring(path.lastIndexOf("/")));
+            }
+        }
+	    return map;
+	}
+	
+	//转台拼图
+	public void buildPanoramicImgs(String folderName)throws Exception
+	{
+		String command = ConstantCmd.BUILD_PANORAMA + folderName;
+		log.info("开始拼全景图");
+		callshell(command);
+		log.info("全景图拼接完毕");
+	}
+	
+	//六目拼图、切图,计算
+	public void buildForSix(String folderName)throws Exception
+	{
+		String command = ConstantCmd.BUILD_FOR_SIX + folderName;
+		log.info("开始处理数据(六目)");
+		callshell(command);
+		log.info("数据处理完毕(六目)");
+	}
+
+	public static void createSoftConnection(String source, String target) {
+		String command = "ln -s " + source + " " + target;
+		log.info("开始创建文件夹软连接");
+		callshell(command);
+		log.info("数据处理完毕(六目):" + command);
+	}
+
+	//合并音频
+	public static void mergeVideo(String oldVideo , String newVideo, String targetVideo) throws Exception{
+		String command = ConstantCmd.MERGE_VIDEO + " " + oldVideo + " " + newVideo + " " + targetVideo + " -y";
+		log.info("开始合并视频");
+		callshell(command);
+		log.info("合并视频完毕:" + command);
+	}
+
+	//生成一段静音音频
+	public static void createMuteViode(double time , String targetVideo) throws Exception{
+		String command = ConstantCmd.CREATE_MUTE_VIDEO + " " + time + " " + targetVideo + " -y";
+		log.info("开始生成一段静音音频");
+		callshell(command);
+		log.info("生成一段静音音频完毕:" + command);
+	}
+
+	//mp4文件转换成flv文件
+	public static void mp4ToFlv(String oldVideo, String newVideo) throws Exception{
+		String command = ConstantCmd.MP4_TO_FLV + " " + oldVideo + " " + newVideo;
+		log.info("mp4文件转换成flv文件");
+		callshell(command);
+		log.info("mp4文件转换成flv文件完毕:" + command);
+	}
+
+	//删除/mnt/data/下的数据
+	public static void deleteFile(String filePath) throws Exception{
+		String command = ConstantCmd.DELETE_FILE + " " + filePath;
+		log.info("删除/mnt/data/下的数据");
+		callshell(command);
+		log.info("删除/mnt/data/下的数据完毕:" + command);
+	}
+
+	public static void ossUtilCp(String fileUrl , String path) throws Exception{
+		String command = ConstantCmd.OSS_UTIL_CP + " " + fileUrl + " " + path;
+		Long start = System.currentTimeMillis();
+		log.info("开始oss下载文件:" + command);
+		callshell(command);
+		log.info("oss下载文件完成,时间为:" + (System.currentTimeMillis() - start));
+	}
+
+	public static void ossFileCp(String fileUrl , String path) throws Exception{
+		String command = ConstantCmd.OSS_FILE_CP + " " + fileUrl + " " + path;
+		Long start = System.currentTimeMillis();
+		log.info("开始s3文件下载文件:" + command);
+		callshell(command);
+		log.info("s3文件下载文件完成,时间为:" + (System.currentTimeMillis() - start));
+	}
+
+	/**
+	 * matterpro场景获取阿里云的切图数据
+	 * @param path
+	 * @throws Exception
+     */
+	public static void matterproCutImg(String num , String path) throws Exception{
+		String command = ConstantCmd.MATTERPRO_CUT_IMG + " -s " + num + " -d " + path;
+		Long start = System.currentTimeMillis();
+		log.info("开始matterpro获取阿里云图片方法:" + command);
+		callshell(command);
+		log.info("matterpro获取阿里云图片方法完成,时间为:" + (System.currentTimeMillis() - start));
+	}
+}

+ 240 - 0
4dkankan-common-utils/src/main/java/com/fdkankan/utils/utils/FileUtil.java

@@ -0,0 +1,240 @@
+package com.fdkankan.utils.utils;
+
+import java.io.*;
+import java.nio.ByteBuffer;
+import java.nio.MappedByteBuffer;
+import java.nio.channels.FileChannel;
+import java.nio.channels.FileChannel.MapMode;
+
+/**
+ * @author MeepoGuan
+ *
+ * <p>Description: file_util</p>
+ *
+ * 2017年4月30日
+ *
+ */
+public class FileUtil {
+
+/*	public static void main(String[] args) {
+		String dirName = "d:/FH/topic/";// 创建目录
+		FileUtil.createDir(dirName);
+	}*/
+
+	/**
+	 * 创建目录
+	 * 
+	 * @param destDirName
+	 *            目标目录名
+	 * @return 目录创建成功返回true,否则返回false
+	 */
+	public static boolean createDir(String destDirName) {
+		File dir = new File(destDirName);
+		if (dir.exists()) {
+			return false;
+		}
+		if (!destDirName.endsWith(File.separator)) {
+			destDirName = destDirName + File.separator;
+		}
+		// 创建单个目录
+		if (dir.mkdirs()) {
+			return true;
+		} else {
+			return false;
+		}
+	}
+
+	/**
+	 * 删除文件
+	 * 
+	 * @param filePathAndName
+	 *            String 文件路径及名称 如c:/fqf.txt
+	 * @return boolean
+	 */
+	public static void delFile(String filePathAndName) {
+		try {
+			String filePath = filePathAndName;
+			filePath = filePath.toString();
+			File myDelFile = new File(filePath);
+			myDelFile.delete();
+
+		} catch (Exception e) {
+			System.out.println("删除文件操作出错");
+			e.printStackTrace();
+
+		}
+
+	}
+
+	/**
+	 * 读取到字节数组0
+	 * 
+	 * @param filePath //路径
+	 * @throws IOException
+	 */
+	public static byte[] getContent(String filePath) throws IOException {
+		File file = new File(filePath);
+		long fileSize = file.length();
+		if (fileSize > Integer.MAX_VALUE) {
+			System.out.println("file too big...");
+			return null;
+		}
+		FileInputStream fi = new FileInputStream(file);
+		byte[] buffer = new byte[(int) fileSize];
+		int offset = 0;
+		int numRead = 0;
+		while (offset < buffer.length
+				&& (numRead = fi.read(buffer, offset, buffer.length - offset)) >= 0) {
+			offset += numRead;
+		}
+		// 确保所有数据均被读取
+		if (offset != buffer.length) {
+			throw new IOException("Could not completely read file "
+					+ file.getName());
+		}
+		fi.close();
+		return buffer;
+	}
+
+	/**
+	 * 读取到字节数组1
+	 * 
+	 * @param filePath
+	 * @return
+	 * @throws IOException
+	 */
+	public static byte[] toByteArray(String filePath) throws IOException {
+
+		File f = new File(filePath);
+		if (!f.exists()) {
+			throw new FileNotFoundException(filePath);
+		}
+		ByteArrayOutputStream bos = new ByteArrayOutputStream((int) f.length());
+		BufferedInputStream in = null;
+		try {
+			in = new BufferedInputStream(new FileInputStream(f));
+			int buf_size = 1024;
+			byte[] buffer = new byte[buf_size];
+			int len = 0;
+			while (-1 != (len = in.read(buffer, 0, buf_size))) {
+				bos.write(buffer, 0, len);
+			}
+			return bos.toByteArray();
+		} catch (IOException e) {
+			e.printStackTrace();
+			throw e;
+		} finally {
+			try {
+				in.close();
+			} catch (IOException e) {
+				e.printStackTrace();
+			}
+			bos.close();
+		}
+	}
+
+	/**
+	 * 读取到字节数组2
+	 * 
+	 * @param filePath
+	 * @return
+	 * @throws IOException
+	 */
+	public static byte[] toByteArray2(String filePath) throws IOException {
+
+		File f = new File(filePath);
+		if (!f.exists()) {
+			throw new FileNotFoundException(filePath);
+		}
+
+		FileChannel channel = null;
+		FileInputStream fs = null;
+		try {
+			fs = new FileInputStream(f);
+			channel = fs.getChannel();
+			ByteBuffer byteBuffer = ByteBuffer.allocate((int) channel.size());
+			while ((channel.read(byteBuffer)) > 0) {
+				// do nothing
+				// System.out.println("reading");
+			}
+			return byteBuffer.array();
+		} catch (IOException e) {
+			e.printStackTrace();
+			throw e;
+		} finally {
+			try {
+				channel.close();
+			} catch (IOException e) {
+				e.printStackTrace();
+			}
+			try {
+				fs.close();
+			} catch (IOException e) {
+				e.printStackTrace();
+			}
+		}
+	}
+
+	/**
+	 * Mapped File way MappedByteBuffer 可以在处理大文件时,提升性能
+	 * 
+	 * @param filePath
+	 * @return
+	 * @throws IOException
+	 */
+	public static byte[] toByteArray3(String filePath) throws IOException {
+
+		FileChannel fc = null;
+		RandomAccessFile rf = null;
+		try {
+			rf = new RandomAccessFile(filePath, "r");
+			fc = rf.getChannel();
+			MappedByteBuffer byteBuffer = fc.map(MapMode.READ_ONLY, 0,
+					fc.size()).load();
+			//System.out.println(byteBuffer.isLoaded());
+			byte[] result = new byte[(int) fc.size()];
+			if (byteBuffer.remaining() > 0) {
+				// System.out.println("remain");
+				byteBuffer.get(result, 0, byteBuffer.remaining());
+			}
+			return result;
+		} catch (IOException e) {
+			e.printStackTrace();
+			throw e;
+		} finally {
+			try {
+				rf.close();
+				fc.close();
+			} catch (IOException e) {
+				e.printStackTrace();
+			}
+		}
+	}
+
+    public static File[] sort(File[] s) {
+        //中间值
+        File temp = null;
+        //外循环:我认为最小的数,从0~长度-1
+        for (int j = 0; j < s.length - 1; j++) {
+            //最小值:假设第一个数就是最小的
+            String min = s[j].getName();
+            //记录最小数的下标的
+            int minIndex = j;
+            //内循环:拿我认为的最小的数和后面的数一个个进行比较
+            for (int k = j + 1; k < s.length; k++) {
+                //找到最小值
+                if (Integer.parseInt(min.substring(0, min.indexOf("."))) > Integer.parseInt(s[k].getName().substring(0, s[k].getName().indexOf(".")))) {
+                    //修改最小
+                    min = s[k].getName();
+                    minIndex = k;
+                }
+            }
+            //当退出内层循环就找到这次的最小值
+            //交换位置
+            temp = s[j];
+            s[j] = s[minIndex];
+            s[minIndex] = temp;
+        }
+        return s;
+    }
+}

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 1084 - 0
4dkankan-common-utils/src/main/java/com/fdkankan/utils/utils/FileUtils.java


+ 61 - 0
4dkankan-common-utils/src/main/java/com/fdkankan/utils/utils/StreamGobbler.java

@@ -0,0 +1,61 @@
+package com.fdkankan.utils.utils;
+
+import java.io.*;
+
+public class StreamGobbler extends Thread {
+
+	InputStream is;  
+    String type;  
+    OutputStream os;  
+
+    public StreamGobbler(InputStream is, String type) {  
+        this(is, type, null);  
+    }  
+
+    StreamGobbler(InputStream is, String type, OutputStream redirect) {  
+        this.is = is;  
+        this.type = type;  
+        this.os = redirect;  
+    }  
+
+    public void run() {  
+        InputStreamReader isr = null;  
+        BufferedReader br = null;  
+        PrintWriter pw = null;  
+        try {  
+            if (os != null)  
+                pw = new PrintWriter(os);  
+
+            isr = new InputStreamReader(is);  
+            br = new BufferedReader(isr);  
+            String line=null;  
+            while ( (line = br.readLine()) != null) {  
+                if (pw != null)  
+                    pw.println(line);  
+                System.out.println(type + ">" + line);      
+            }  
+
+            if (pw != null)  
+                pw.flush();  
+        } catch (IOException ioe) {  
+            ioe.printStackTrace();    
+        } finally{  
+            try {  
+            	if(pw!=null)
+            	{
+            		 pw.close();  
+            	}
+            	if(br!=null)
+            	{
+            		br.close();  
+            	}
+            	if(isr!=null)
+            	{
+            		isr.close();  
+            	}
+            } catch (IOException e) {  
+                e.printStackTrace();  
+            }  
+        }  
+    }  
+}

+ 24 - 0
4dkankan-utils-db/pom.xml

@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<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">
+    <packaging>jar</packaging>
+    <parent>
+        <groupId>com.fdkankan</groupId>
+        <artifactId>4dkankan-utils</artifactId>
+        <version>2.0.0</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>4dkankan-utils-db</artifactId>
+
+    <dependencies>
+        <dependency>
+            <groupId>com.baomidou</groupId>
+            <artifactId>mybatis-plus-boot-starter</artifactId>
+            <version>3.4.3.4</version>
+        </dependency>
+
+    </dependencies>
+
+</project>

+ 61 - 0
4dkankan-utils-db/src/main/java/com/fdkankan/common/utils/StreamGobbler.java

@@ -0,0 +1,61 @@
+package com.fdkankan.common.utils;
+
+import java.io.*;
+
+public class StreamGobbler extends Thread {
+
+	InputStream is;  
+    String type;  
+    OutputStream os;  
+
+    public StreamGobbler(InputStream is, String type) {  
+        this(is, type, null);  
+    }  
+
+    StreamGobbler(InputStream is, String type, OutputStream redirect) {  
+        this.is = is;  
+        this.type = type;  
+        this.os = redirect;  
+    }  
+
+    public void run() {  
+        InputStreamReader isr = null;  
+        BufferedReader br = null;  
+        PrintWriter pw = null;  
+        try {  
+            if (os != null)  
+                pw = new PrintWriter(os);  
+
+            isr = new InputStreamReader(is);  
+            br = new BufferedReader(isr);  
+            String line=null;  
+            while ( (line = br.readLine()) != null) {  
+                if (pw != null)  
+                    pw.println(line);  
+                System.out.println(type + ">" + line);      
+            }  
+
+            if (pw != null)  
+                pw.flush();  
+        } catch (IOException ioe) {  
+            ioe.printStackTrace();    
+        } finally{  
+            try {  
+            	if(pw!=null)
+            	{
+            		 pw.close();  
+            	}
+            	if(br!=null)
+            	{
+            		br.close();  
+            	}
+            	if(isr!=null)
+            	{
+            		isr.close();  
+            	}
+            } catch (IOException e) {  
+                e.printStackTrace();  
+            }  
+        }  
+    }  
+}

+ 42 - 0
4dkankan-utils-mq/pom.xml

@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<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">
+    <packaging>jar</packaging>
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <configuration>
+                    <source>7</source>
+                    <target>7</target>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+    <parent>
+        <groupId>com.fdkankan</groupId>
+        <artifactId>4dkankan-utils</artifactId>
+        <version>2.0.0</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>4dkankan-utils-mq</artifactId>
+
+    <dependencies>
+        <dependency>
+            <groupId>com.google.protobuf</groupId>
+            <artifactId>protobuf-java</artifactId>
+            <version>3.2.0</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.rocketmq</groupId>
+            <artifactId>rocketmq-spring-boot-starter</artifactId>
+            <version>2.1.1</version>
+        </dependency>
+    </dependencies>
+
+
+</project>

+ 64 - 0
4dkankan-utils-mq/src/main/java/com/fdkankan/mq/message/BaseBuildSceneMessage.java

@@ -0,0 +1,64 @@
+package com.fdkankan.mq.message;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import org.apache.rocketmq.common.message.Message;
+
+import java.io.Serializable;
+
+@Data
+public class BaseBuildSceneMessage implements Serializable{
+    /**
+     * 0:第一次计算;1:重新构建
+     */
+    private String rebuild = "0";
+
+    /**
+     * 0:非标定计算;1:标定计算
+     */
+    private String isStandardization;
+
+    /**
+     * 创建时间
+     */
+    private String createTime;
+
+    /**
+     * 执行结果接收消息队列名称
+     */
+    private String resultReceiverMqName;
+
+    public String getRebuild() {
+        return rebuild;
+    }
+
+    public void setRebuild(String rebuild) {
+        this.rebuild = rebuild;
+    }
+
+    public String getIsStandardization() {
+        return isStandardization;
+    }
+
+    public void setIsStandardization(String isStandardization) {
+        this.isStandardization = isStandardization;
+    }
+
+    public String getCreateTime() {
+        return createTime;
+    }
+
+    public void setCreateTime(String createTime) {
+        this.createTime = createTime;
+    }
+
+    public String getResultReceiverMqName() {
+        return resultReceiverMqName;
+    }
+
+    public void setResultReceiverMqName(String resultReceiverMqName) {
+        this.resultReceiverMqName = resultReceiverMqName;
+    }
+}

+ 145 - 0
4dkankan-utils-mq/src/main/java/com/fdkankan/mq/message/BuildSceneMqMessage.java

@@ -0,0 +1,145 @@
+package com.fdkankan.mq.message;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.Date;
+
+@Data
+public class BuildSceneMqMessage extends BaseBuildSceneMessage {
+
+    private String unicode;
+    private String path;
+    private String prefix;
+    private String imgsName;
+    private String sceneNum;
+    private String isModel;
+    private String userName;
+    //不同的相机不同的方法
+    private String cameraType;
+    private String algorithm;
+    private String fileId;
+    private String cameraName;
+    //0表示有4k图,1表示没有
+    private String resolution;
+
+    //判断调用V2还是V3版本的算法
+    private String buildType;
+
+    private Long sceneProId;
+    private String sceneName;
+    private String webSite;
+    private Date sceneProCreateTime;
+    private Long userId;
+    private String dataSource;
+    private Integer sceneStatus;
+    private Integer PayStatus;
+    private String thumb;
+
+//    public String getUnicode() {
+//        return unicode;
+//    }
+//
+//    public void setUnicode(String unicode) {
+//        this.unicode = unicode;
+//    }
+//
+//    public String getPath() {
+//        return path;
+//    }
+//
+//    public void setPath(String path) {
+//        this.path = path;
+//    }
+//
+//    public String getPrefix() {
+//        return prefix;
+//    }
+//
+//    public void setPrefix(String prefix) {
+//        this.prefix = prefix;
+//    }
+//
+//    public String getImgsName() {
+//        return imgsName;
+//    }
+//
+//    public void setImgsName(String imgsName) {
+//        this.imgsName = imgsName;
+//    }
+//
+//    public String getSceneNum() {
+//        return sceneNum;
+//    }
+//
+//    public void setSceneNum(String sceneNum) {
+//        this.sceneNum = sceneNum;
+//    }
+//
+//    public String getIsModel() {
+//        return isModel;
+//    }
+//
+//    public void setIsModel(String isModel) {
+//        this.isModel = isModel;
+//    }
+//
+//    public String getUserName() {
+//        return userName;
+//    }
+//
+//    public void setUserName(String userName) {
+//        this.userName = userName;
+//    }
+//
+//    public String getCameraType() {
+//        return cameraType;
+//    }
+//
+//    public void setCameraType(String cameraType) {
+//        this.cameraType = cameraType;
+//    }
+//
+//    public String getAlgorithm() {
+//        return algorithm;
+//    }
+//
+//    public void setAlgorithm(String algorithm) {
+//        this.algorithm = algorithm;
+//    }
+//
+//    public String getFileId() {
+//        return fileId;
+//    }
+//
+//    public void setFileId(String fileId) {
+//        this.fileId = fileId;
+//    }
+//
+//    public String getCameraName() {
+//        return cameraName;
+//    }
+//
+//    public void setCameraName(String cameraName) {
+//        this.cameraName = cameraName;
+//    }
+//
+//    public String getResolution() {
+//        return resolution;
+//    }
+//
+//    public void setResolution(String resolution) {
+//        this.resolution = resolution;
+//    }
+//
+//    public String getBuildType() {
+//        return buildType;
+//    }
+//
+//    public void setBuildType(String buildType) {
+//        this.buildType = buildType;
+//    }
+
+}

+ 30 - 0
4dkankan-utils-mq/src/main/java/com/fdkankan/mq/message/BuildSceneResultMqMessage.java

@@ -0,0 +1,30 @@
+package com.fdkankan.mq.message;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class BuildSceneResultMqMessage {
+
+    private String cameraType;
+
+    private String scenenCode;
+
+    private Long space;
+
+    private Integer payStatus;
+
+    private String videosJson;
+
+    private Long computeTime;
+
+    private String fileId;
+
+    private Boolean buildSuccess;
+
+}

+ 24 - 0
4dkankan-utils-mq/src/main/java/com/fdkankan/mq/message/MQBodyBean.java

@@ -0,0 +1,24 @@
+package com.fdkankan.mq.message;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import org.apache.rocketmq.common.message.Message;
+import org.springframework.messaging.support.MessageBuilder;
+
+import java.io.Serializable;
+import java.util.Date;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@Builder
+public class MQBodyBean implements Serializable {
+
+    private String id;
+
+    private Object content;
+
+    private Date date;
+}

+ 173 - 0
4dkankan-utils-mq/src/main/java/com/fdkankan/mq/util/RocketMQProducer.java

@@ -0,0 +1,173 @@
+package com.fdkankan.mq.util;
+
+import cn.hutool.core.util.StrUtil;
+import org.apache.rocketmq.client.producer.SendCallback;
+import org.apache.rocketmq.client.producer.SendResult;
+import org.apache.rocketmq.spring.core.RocketMQTemplate;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.messaging.Message;
+import org.springframework.messaging.support.MessageBuilder;
+import org.springframework.stereotype.Component;
+
+import java.util.Objects;
+
+@Component
+public class RocketMQProducer {
+
+    @Autowired
+    RocketMQTemplate rocketMQTemplate;
+
+    /**
+     * 同步发送
+     * @param topic 主题名
+     * @param body 消息体
+     * @return
+     */
+    public SendResult syncSend(String topic, Object body){
+        return this.syncSend(topic, null, null, body, null);
+    }
+
+    /**
+     * 同步发送
+     * @param topic 主题名
+     * @param tag  tag
+     * @param body 消息体
+     * @return
+     */
+    public SendResult syncSend(String topic, String tag, Object body){
+        return this.syncSend(topic, tag, null, body, null);
+    }
+
+    /**
+     * 同步发送
+     * @param topic 主题名
+     * @param tag  tag
+     * @param key key
+     * @param body 消息体
+     * @return
+     */
+    public SendResult syncSend(String topic, String tag, String key, Object body){
+        return this.syncSend(topic, tag, key, body, null);
+    }
+
+    /**
+     * 同步发送
+     * @param topic 主题名
+     * @param tag  tag
+     * @param key key
+     * @param body 消息体
+     * @param sendMsgTimeOut 发送消息超时时间
+     * @return
+     */
+    public SendResult syncSend(String topic, String tag, String key, Object body, Long sendMsgTimeOut){
+        if(StrUtil.isNotEmpty(tag)){
+            topic = topic + ":" + tag;
+        }
+        MessageBuilder messageBuilder = MessageBuilder.withPayload(body);
+        if(StrUtil.isNotEmpty(key)){
+            messageBuilder.setHeader("KEYS", key);
+        }
+        Message message = messageBuilder.build();
+
+        sendMsgTimeOut = Objects.isNull(sendMsgTimeOut) ? rocketMQTemplate.getProducer().getSendMsgTimeout() : sendMsgTimeOut;
+
+        return rocketMQTemplate.syncSend(topic, message, sendMsgTimeOut);
+    }
+
+    /**
+     * 异步发送消息
+     * @param topic 主题名
+     * @param body 消息体
+     * @param sendCallback 回调函数
+     */
+    public void asyncSend(String topic, Object body, SendCallback sendCallback){
+        this.asyncSend(topic, null, null, body, sendCallback, null);
+    }
+
+    /**
+     * 异步发送消息
+     * @param topic 主题名
+     * @param tag tag
+     * @param body 消息体
+     * @param sendCallback 回调函数
+     */
+    public void asyncSend(String topic, String tag, Object body, SendCallback sendCallback){
+        this.asyncSend(topic, tag, null, body, sendCallback, null);
+    }
+
+    /**
+     * 异步发送消息
+     * @param topic 主题名
+     * @param tag tag
+     * @param key key
+     * @param body 消息体
+     * @param sendCallback 回调函数
+     */
+    public void asyncSend(String topic, String tag, String key, Object body, SendCallback sendCallback){
+        this.asyncSend(topic, tag, key, body, sendCallback, null);
+    }
+
+    /**
+     * 异步发送消息
+     * @param topic 主题名
+     * @param tag tag
+     * @param key key
+     * @param body 消息体
+     * @param sendCallback 回调函数
+     * @param sendMsgTimeOut 发送消息超时时间
+     */
+    public void asyncSend(String topic, String tag, String key, Object body, SendCallback sendCallback, Long sendMsgTimeOut){
+        if(StrUtil.isNotEmpty(tag)){
+            topic = topic + ":" + tag;
+        }
+        MessageBuilder messageBuilder = MessageBuilder.withPayload(body);
+        if(StrUtil.isNotEmpty(key)){
+            messageBuilder.setHeader("KEYS", key);
+        }
+        Message message = messageBuilder.build();
+
+        sendMsgTimeOut = Objects.isNull(sendMsgTimeOut) ? rocketMQTemplate.getProducer().getSendMsgTimeout() : sendMsgTimeOut;
+
+        rocketMQTemplate.asyncSend(topic, message, sendCallback, sendMsgTimeOut);
+    }
+
+    /**
+     * 反向发送消息,生产者只管发送,不管发送结果
+     * @param topic 主题名
+     * @param body 消息体
+     */
+    public void sendOneWay(String topic, Object body){
+        this.sendOneWay(topic, null, null, body);
+    }
+
+    /**
+     * 反向发送消息,生产者只管发送,不管发送结果
+     * @param topic 主题名
+     * @param tag tag
+     * @param body 消息体
+     */
+    public void sendOneWay(String topic, String tag, Object body){
+        this.sendOneWay(topic, tag, null, body);
+    }
+
+    /**
+     * 反向发送消息,生产者只管发送,不管发送结果
+     * @param topic 主题名
+     * @param tag tag
+     * @param key key
+     * @param body 消息体
+     */
+    public void sendOneWay(String topic, String tag, String key, Object body){
+        if(StrUtil.isNotEmpty(tag)){
+            topic = topic + ":" + tag;
+        }
+        MessageBuilder messageBuilder = MessageBuilder.withPayload(body);
+        if(StrUtil.isNotEmpty(key)){
+            messageBuilder.setHeader("KEYS", key);
+        }
+        Message message = messageBuilder.build();
+
+        rocketMQTemplate.sendOneWay(topic, message);
+    }
+
+}

+ 45 - 0
4dkankan-utils-oss/pom.xml

@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<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">
+
+    <parent>
+        <groupId>com.fdkankan</groupId>
+        <artifactId>4dkankan-utils</artifactId>
+        <version>2.0.0</version>
+    </parent>
+
+    <artifactId>4dkankan-utils-oss</artifactId>
+    <packaging>jar</packaging>
+    <modelVersion>4.0.0</modelVersion>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-context</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-beans</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.aliyun.oss</groupId>
+            <artifactId>aliyun-sdk-oss</artifactId>
+            <version>2.5.0</version>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-api</artifactId>
+            <version>1.7.30</version>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-autoconfigure</artifactId>
+            <version>2.3.12.RELEASE</version>
+        </dependency>
+
+
+    </dependencies>
+
+
+</project>

+ 90 - 0
4dkankan-utils-oss/src/main/java/com/fdkankan/oss/UploadUtils.java

@@ -0,0 +1,90 @@
+package com.fdkankan.oss;
+
+import com.aliyun.oss.OSSClient;
+import com.aliyun.oss.model.ObjectMetadata;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.stereotype.Component;
+
+import java.io.File;
+import java.util.Map;
+
+@Component
+@ComponentScan
+public class UploadUtils {
+    private static Logger log = LoggerFactory.getLogger(UploadUtils.class);
+
+    @Value("${oss.point}")
+    private String point;
+
+    @Value("${oss.key}")
+    private String key;
+
+    @Value("${oss.secrey}")
+    private String secrey;
+
+    @Value("${oss.bucket.bucket}")
+    private String bucket;
+
+    public void upload(String filePath, String key1) {
+        OSSClient ossClient = new OSSClient(point, key, secrey);
+        try {
+            File file = new File(filePath);
+            if (!file.exists()) {
+                log.error("要上传的文件不存在:" + filePath);
+            }
+
+            ObjectMetadata metadata = new ObjectMetadata();
+            if(filePath.contains(".jpg")){
+                metadata.setContentType("image/jpeg");
+            }
+            ossClient.putObject(bucket, key1, new File(filePath), metadata);
+
+        } catch (Exception e) {
+            log.error(e.toString() + filePath);
+        }
+    }
+
+    public void upload2(String filePath, String key1) {
+        OSSClient ossClient = new OSSClient(point, key, secrey);
+        try {
+            ObjectMetadata metadata = new ObjectMetadata();
+            if(filePath.contains(".jpg")){
+                metadata.setContentType("image/jpeg");
+            }
+            if(filePath.contains(".mp4")){
+                metadata.setContentType("video/mp4");
+            }
+            if(filePath.contains(".mp3")){
+                metadata.setContentType("audio/mp3");
+            }
+            ossClient.putObject(bucket, key1, new File(filePath), metadata);
+        } catch (Exception e) {
+            log.error(e.toString() + filePath);
+        }
+    }
+
+    //上传的数据是文件夹,参数是文件夹路径,key是上传后的文件名
+    public void uploadMulFiles(Map<String, String> filepaths) {
+        if (filepaths == null) {
+            return;
+        }
+        Long start = System.currentTimeMillis();
+        log.info("开始批量上传到阿里云:" + start);
+        if (filepaths.size() > 50) {
+            for (String filePath : filepaths.keySet()) {
+                // log.info("文件:"+key);
+                upload2(filePath, filepaths.get(filePath));
+            }
+        } else {
+            for (String filePath : filepaths.keySet()) {
+                log.info("文件:" + filePath + "到阿里云:" + filepaths.get(filePath));
+                upload(filePath, filepaths.get(filePath));
+            }
+        }
+        log.info("批量上传阿里云完毕:" + (System.currentTimeMillis() - start));
+    }
+
+}

+ 24 - 0
4dkankan-utils-redis/pom.xml

@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<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">
+    <packaging>jar</packaging>
+    <parent>
+        <groupId>com.fdkankan</groupId>
+        <artifactId>4dkankan-utils</artifactId>
+        <version>2.0.0</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>4dkankan-utils-redis</artifactId>
+
+    <dependencies>
+       <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-data-redis</artifactId>
+           <version>2.3.12.RELEASE</version>
+        </dependency>
+    </dependencies>
+
+
+</project>

+ 45 - 0
4dkankan-utils-redis/src/main/java/com/fdkankan/redis/config/RedisConfig.java

@@ -0,0 +1,45 @@
+package com.fdkankan.redis.config;
+
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.AutoConfigureAfter;
+import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.data.redis.serializer.StringRedisSerializer;
+
+@Configuration
+@AutoConfigureAfter(RedisAutoConfiguration.class)
+public class RedisConfig {
+
+    @Autowired
+    LettuceConnectionFactory lettuceConnectionFactory;
+
+    @Bean
+    public RedisTemplate<String, Object> redisTemplate(LettuceConnectionFactory redisConnectionFactory) {
+        RedisTemplate template = new RedisTemplate();
+        template.setConnectionFactory(redisConnectionFactory);
+//        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
+        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
+
+        /*
+         * Jackson对象映射器(Object Mapper)可以把JSON解析为用户自定义类对象, 或者解析为JSON内置的树模型的对象
+         * DefaultTyping.NON_FINAL,将会为(String、Boolean、Integer、Double)除外的其他类型及非final类型的数组添加反序列化所需要的类型。
+         * JsonTypeInfo.As.PROPERTY,它将包含@class属性,作为序列化的一个属性,值就是完全限定名类型。当前类及其属性都会添加这个名为@class的属性。
+         */
+//        ObjectMapper om = new ObjectMapper();
+//        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
+//        om.activateDefaultTyping(LaissezFaireSubTypeValidator.instance , ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);
+//        jackson2JsonRedisSerializer.setObjectMapper(om);
+        template.setKeySerializer(stringRedisSerializer);
+        template.setValueSerializer(stringRedisSerializer);
+        template.setHashKeySerializer(stringRedisSerializer);
+        template.setHashValueSerializer(stringRedisSerializer);
+
+        template.afterPropertiesSet();
+        template.setEnableTransactionSupport(true);
+        return template;
+    }
+}

+ 92 - 0
4dkankan-utils-redis/src/main/java/com/fdkankan/redis/util/RedisLockUtil.java

@@ -0,0 +1,92 @@
+package com.fdkankan.redis.util;
+
+import cn.hutool.core.util.StrUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.data.redis.core.script.DefaultRedisScript;
+import org.springframework.stereotype.Component;
+
+import java.util.Arrays;
+import java.util.Objects;
+import java.util.concurrent.TimeUnit;
+
+@Component
+@Slf4j
+public class RedisLockUtil {
+
+    @Autowired
+    private RedisTemplate redisTemplate;
+
+    private static final String UNLOCK_LUA =
+            "if redis.call('get',KEYS[1]) == ARGV[1] then\n" +
+            "    return redis.call('del',KEYS[1])\n" +
+            "else\n" +
+            "    return 0\n" +
+            "end";
+
+    /**
+     * 加锁,自旋重试三次
+     *
+     * @param lockKey 锁key
+     * @param expireTime 锁过期时间 单位 毫秒
+     * @return
+     */
+    public boolean lock(String lockKey, int expireTime) {
+        boolean locked = false;
+        int tryCount = 3;
+        String threadId = String.valueOf(Thread.currentThread().getId());
+        while (!locked && tryCount > 0) {
+            locked = redisTemplate.opsForValue().setIfAbsent(lockKey, threadId, expireTime, TimeUnit.MILLISECONDS);
+            tryCount--;
+            try {
+                Thread.sleep(300);
+            } catch (InterruptedException e) {
+                log.error("线程被中断[线程id:" + threadId + "]", e);
+            }
+        }
+        return locked;
+    }
+
+    /**
+     * 非原子解锁,可能解别人锁,不安全
+     *
+     * @param redisLockEntity
+     * @return
+     */
+    public boolean unlock(String lockKey) {
+        String threadId = String.valueOf(Thread.currentThread().getId());
+        if (StrUtil.isEmpty(lockKey) || Objects.isNull(threadId))
+            return false;
+        boolean releaseLock = false;
+        Long val = (Long) redisTemplate.opsForValue().get(lockKey);
+        if (threadId.equals(val)) {
+            releaseLock = redisTemplate.delete(lockKey);
+        }
+        return releaseLock;
+    }
+
+    /**
+     * 使用lua脚本解锁,不会解除别人锁
+     *
+     * @param
+     * @return
+     */
+    public boolean unlockLua(String lockKey) {
+        String threadId = String.valueOf(Thread.currentThread().getId());
+        if (StrUtil.isEmpty(lockKey) || Objects.isNull(threadId))
+            return false;
+        DefaultRedisScript<Long> redisScript = new DefaultRedisScript();
+//        redisScript.setLocation(new ClassPathResource("unlock.lua"));
+        redisScript.setScriptText(UNLOCK_LUA);
+        redisScript.setResultType(Long.class);
+
+        Object result = redisTemplate.execute(redisScript, Arrays.asList(lockKey), threadId);
+        return result.equals(Long.valueOf(1));
+    }
+
+
+
+
+
+}

+ 546 - 0
4dkankan-utils-redis/src/main/java/com/fdkankan/redis/util/RedisUtil.java

@@ -0,0 +1,546 @@
+package com.fdkankan.redis.util;
+
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.stereotype.Component;
+import org.springframework.util.CollectionUtils;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+
+@Component
+@Slf4j
+public class RedisUtil<K, V>{
+
+    @Autowired
+    private RedisTemplate redisTemplate;
+
+    /**
+     * 指定缓存失效时间
+     *
+     * @param key  键
+     * @param time 时间(秒)
+     * @return
+     */
+    public boolean expire(String key, long time) {
+        try {
+            if (time > 0) {
+                redisTemplate.expire(key, time, TimeUnit.SECONDS);
+            }
+            return true;
+        } catch (Exception e) {
+            e.printStackTrace();
+            return false;
+        }
+    }
+    /**
+     * 根据key 获取过期时间
+     *
+     * @param key 键 不能为null
+     * @return 时间(秒) 返回0代表为永久有效
+     */
+    public long getExpire(String key) {
+        redisTemplate.getExpire(key, TimeUnit.SECONDS);
+        return redisTemplate.getExpire(key, TimeUnit.SECONDS);
+    }
+    /**
+     * 判断key是否存在
+     *
+     * @param key 键
+     * @return true 存在 false不存在
+     */
+    public boolean hasKey(String key) {
+        try {
+            return redisTemplate.hasKey(key);
+        } catch (Exception e) {
+            e.printStackTrace();
+            return false;
+        }
+    }
+    /**
+     * 删除缓存
+     *
+     * @param key 可以传一个值 或多个
+     */
+    @SuppressWarnings("unchecked")
+    public void del(String... key) {
+        if (key != null && key.length > 0) {
+            if (key.length == 1) {
+                redisTemplate.delete(key[0]);
+            } else {
+                redisTemplate.delete(CollectionUtils.arrayToList(key));
+            }
+        }
+    }
+    // ============================String=============================
+    /**
+     * 普通缓存获取
+     *
+     * @param key 键
+     * @return 值
+     */
+    public String get(String key) {
+        return key == null ? null : (String) redisTemplate.opsForValue().get(key);
+    }
+    /**
+     * 普通缓存放入
+     *
+     * @param key   键
+     * @param value 值
+     * @return true成功 false失败
+     */
+    public boolean set(String key, String value) {
+        try {
+            redisTemplate.opsForValue().set(key, value);
+            return true;
+        } catch (Exception e) {
+            e.printStackTrace();
+            return false;
+        }
+    }
+    /**
+     * 普通缓存放入并设置时间
+     *
+     * @param key   键
+     * @param value 值
+     * @param time  时间(秒) time要大于0 如果time小于等于0 将设置无限期
+     * @return true成功 false 失败
+     */
+    public boolean set(String key, String value, long time) {
+        try {
+            if (time > 0) {
+                redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
+            } else {
+                set(key, value);
+            }
+            return true;
+        } catch (Exception e) {
+            e.printStackTrace();
+            return false;
+        }
+    }
+    /**
+     * 递增
+     *
+     * @param key   键
+     * @param delta 要增加几(大于0)
+     * @return
+     */
+    public long incr(String key, long delta) {
+        if (delta < 0) {
+            throw new RuntimeException("递增因子必须大于0");
+        }
+        return redisTemplate.opsForValue().increment(key, delta);
+    }
+    /**
+     * 递减
+     *
+     * @param key   键
+     * @param delta 要减少几(小于0)
+     * @return
+     */
+    public long decr(String key, long delta) {
+        if (delta < 0) {
+            throw new RuntimeException("递减因子必须大于0");
+        }
+        return redisTemplate.opsForValue().increment(key, -delta);
+    }
+    // ================================Map=================================
+    /**
+     * HashGet
+     *
+     * @param key  键 不能为null
+     * @param item 项 不能为null
+     * @return 值
+     */
+    public Object hget(String key, String item) {
+        return redisTemplate.opsForHash().get(key, item);
+    }
+    /**
+     * 获取hashKey对应的所有键值
+     *
+     * @param key 键
+     * @return 对应的多个键值
+     */
+    public Map<Object, Object> hmget(String key) {
+        return redisTemplate.opsForHash().entries(key);
+    }
+    /**
+     * HashSet
+     *
+     * @param key 键
+     * @param map 对应多个键值
+     * @return true 成功 false 失败
+     */
+    public boolean hmset(String key, Map<String, Object> map) {
+        try {
+            redisTemplate.opsForHash().putAll(key, map);
+            return true;
+        } catch (Exception e) {
+            e.printStackTrace();
+            return false;
+        }
+    }
+    /**
+     * HashSet 并设置时间
+     *
+     * @param key  键
+     * @param map  对应多个键值
+     * @param time 时间(秒)
+     * @return true成功 false失败
+     */
+    public boolean hmset(String key, Map<String, Object> map, long time) {
+        try {
+            redisTemplate.opsForHash().putAll(key, map);
+            if (time > 0) {
+                expire(key, time);
+            }
+            return true;
+        } catch (Exception e) {
+            e.printStackTrace();
+            return false;
+        }
+    }
+    /**
+     * 向一张hash表中放入数据,如果不存在将创建
+     *
+     * @param key   键
+     * @param item  项
+     * @param value 值
+     * @return true 成功 false失败
+     */
+    public boolean hset(String key, String item, Object value) {
+        try {
+            redisTemplate.opsForHash().put(key, item, value);
+            return true;
+        } catch (Exception e) {
+            e.printStackTrace();
+            return false;
+        }
+    }
+    /**
+     * 向一张hash表中放入数据,如果不存在将创建
+     *
+     * @param key   键
+     * @param item  项
+     * @param value 值
+     * @param time  时间(秒) 注意:如果已存在的hash表有时间,这里将会替换原有的时间
+     * @return true 成功 false失败
+     */
+    public boolean hset(String key, String item, Object value, long time) {
+        try {
+            redisTemplate.opsForHash().put(key, item, value);
+            if (time > 0) {
+                expire(key, time);
+            }
+            return true;
+        } catch (Exception e) {
+            e.printStackTrace();
+            return false;
+        }
+    }
+    /**
+     * 删除hash表中的值
+     *
+     * @param key  键 不能为null
+     * @param item 项 可以使多个 不能为null
+     */
+    public void hdel(String key, Object... item) {
+        redisTemplate.opsForHash().delete(key, item);
+    }
+    /**
+     * 判断hash表中是否有该项的值
+     *
+     * @param key  键 不能为null
+     * @param item 项 不能为null
+     * @return true 存在 false不存在
+     */
+    public boolean hHasKey(String key, String item) {
+        return redisTemplate.opsForHash().hasKey(key, item);
+    }
+    /**
+     * hash递增 如果不存在,就会创建一个 并把新增后的值返回
+     *
+     * @param key  键
+     * @param item 项
+     * @param by   要增加几(大于0)
+     * @return
+     */
+    public double hincr(String key, String item, double by) {
+        return redisTemplate.opsForHash().increment(key, item, by);
+    }
+    /**
+     * hash递减
+     *
+     * @param key  键
+     * @param item 项
+     * @param by   要减少记(小于0)
+     * @return
+     */
+    public double hdecr(String key, String item, double by) {
+        return redisTemplate.opsForHash().increment(key, item, -by);
+    }
+    // ============================set=============================
+    /**
+     * 根据key获取Set中的所有值
+     *
+     * @param key 键
+     * @return
+     */
+    public Set<Object> sGet(String key) {
+        try {
+            return redisTemplate.opsForSet().members(key);
+        } catch (Exception e) {
+            e.printStackTrace();
+            return null;
+        }
+    }
+    /**
+     * 根据value从一个set中查询,是否存在
+     *
+     * @param key   键
+     * @param value 值
+     * @return true 存在 false不存在
+     */
+    public boolean sHasKey(String key, Object value) {
+        try {
+            return redisTemplate.opsForSet().isMember(key, value);
+        } catch (Exception e) {
+            e.printStackTrace();
+            return false;
+        }
+    }
+    /**
+     * 将数据放入set缓存
+     *
+     * @param key    键
+     * @param values 值 可以是多个
+     * @return 成功个数
+     */
+    public long sSet(String key, Object... values) {
+        try {
+            return redisTemplate.opsForSet().add(key, values);
+        } catch (Exception e) {
+            e.printStackTrace();
+            return 0;
+        }
+    }
+    /**
+     * 将set数据放入缓存
+     *
+     * @param key    键
+     * @param time   时间(秒)
+     * @param values 值 可以是多个
+     * @return 成功个数
+     */
+    public long sSet(String key, long time, Object... values) {
+        try {
+            Long count = redisTemplate.opsForSet().add(key, values);
+            if (time > 0)
+                expire(key, time);
+            return count;
+        } catch (Exception e) {
+            e.printStackTrace();
+            return 0;
+        }
+    }
+    /**
+     * 获取set缓存的长度
+     *
+     * @param key 键
+     * @return
+     */
+    public long sGetSize(String key) {
+        try {
+            return redisTemplate.opsForSet().size(key);
+        } catch (Exception e) {
+            e.printStackTrace();
+            return 0;
+        }
+    }
+    /**
+     * 移除值为value的
+     *
+     * @param key    键
+     * @param values 值 可以是多个
+     * @return 移除的个数
+     */
+    public long setRemove(String key, Object... values) {
+        try {
+            Long count = redisTemplate.opsForSet().remove(key, values);
+            return count;
+        } catch (Exception e) {
+            e.printStackTrace();
+            return 0;
+        }
+    }
+    // ===============================list=================================
+    /**
+     * 获取list缓存的内容
+     *
+     * @param key   键
+     * @param start 开始
+     * @param end   结束 0 到 -1代表所有值
+     * @return
+     */
+    public List<Object> lGet(String key, long start, long end) {
+        try {
+            List<Object> range = redisTemplate.opsForList().range(key, start, end);
+            return range;
+        } catch (Exception e) {
+            e.printStackTrace();
+            return null;
+        }
+    }
+    /**
+     * 获取list缓存的长度
+     *
+     * @param key 键
+     * @return
+     */
+    public long lGetSize(String key) {
+        try {
+            return redisTemplate.opsForList().size(key);
+        } catch (Exception e) {
+            e.printStackTrace();
+            return 0;
+        }
+    }
+    /**
+     * 通过索引 获取list中的值
+     *
+     * @param key   键
+     * @param index 索引 index>=0时, 0 表头,1 第二个元素,依次类推;index<0时,-1,表尾,-2倒数第二个元素,依次类推
+     * @return
+     */
+    public Object lGetIndex(String key, long index) {
+        try {
+            return redisTemplate.opsForList().index(key, index);
+        } catch (Exception e) {
+            e.printStackTrace();
+            return null;
+        }
+    }
+    /**
+     * 将list放入缓存
+     * @param key   键
+     * @param value 值
+     * @return
+     */
+    public boolean lRightPush(String key, Object value) {
+        try {
+            redisTemplate.opsForList().rightPush(key, value);
+            return true;
+        } catch (Exception e) {
+            e.printStackTrace();
+            return false;
+        }
+    }
+    /**
+     * 将list放入缓存
+     *
+     * @param key   键
+     * @param value 值
+     * @param time  时间(秒)
+     * @return
+     */
+    public boolean lRightPush(String key, Object value, long time) {
+        try {
+            redisTemplate.opsForList().rightPush(key, value);
+            if (time > 0)
+                expire(key, time);
+            return true;
+        } catch (Exception e) {
+            e.printStackTrace();
+            return false;
+        }
+    }
+    /**
+     * 将list放入缓存
+     *
+     * @param key   键
+     * @param value 值
+     * @return
+     */
+    public boolean lRightPushAll(String key, List<Object> value) {
+        try {
+            redisTemplate.opsForList().rightPushAll(key, value);
+            return true;
+        } catch (Exception e) {
+            e.printStackTrace();
+            return false;
+        }
+    }
+
+    /**
+     * 将list放入缓存
+     *
+     * @param key   键
+     * @param value 值
+     * @param time  时间(秒)
+     * @return
+     */
+    public boolean lRightPushAll(String key, List<Object> value, long time) {
+        try {
+            redisTemplate.opsForList().rightPushAll(key, value);
+            if (time > 0)
+                expire(key, time);
+            return true;
+        } catch (Exception e) {
+            e.printStackTrace();
+            return false;
+        }
+    }
+
+    /**
+     *
+     * @param key   键
+     * @return
+     */
+    public Object lLeftPop(String key) {
+        try {
+            return redisTemplate.opsForList().leftPop(key);
+        } catch (Exception e) {
+            e.printStackTrace();
+            return null;
+        }
+    }
+
+    /**
+     * 根据索引修改list中的某条数据
+     *
+     * @param key   键
+     * @param index 索引
+     * @param value 值
+     * @return
+     */
+    public boolean lUpdateByIndex(String key, long index, Object value) {
+        try {
+            redisTemplate.opsForList().set(key, index, value);
+            return true;
+        } catch (Exception e) {
+            e.printStackTrace();
+            return false;
+        }
+    }
+    /**
+     * 移除N个值为value
+     *
+     * @param key   键
+     * @param count 移除多少个
+     * @param value 值
+     * @return 移除的个数
+     */
+    public long lRemove(String key, long count, Object value) {
+        try {
+            Long remove = redisTemplate.opsForList().remove(key, count, value);
+            return remove;
+        } catch (Exception e) {
+            e.printStackTrace();
+            return 0;
+        }
+    }
+}

+ 118 - 0
pom.xml

@@ -0,0 +1,118 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+    <modelVersion>4.0.0</modelVersion>
+    <modules>
+        <module>4dkankan-utils-mq</module>
+        <module>4dkankan-common-utils</module>
+        <module>4dkankan-utils-db</module>
+        <module>4dkankan-utils-redis</module>
+        <module>4dkankan-utils-oss</module>
+    </modules>
+
+    <groupId>com.fdkankan</groupId>
+    <artifactId>4dkankan-utils</artifactId>
+    <version>2.0.0</version>
+    <packaging>pom</packaging>
+
+    <repositories>
+        <repository>
+            <id>releases</id>
+            <url>http://192.168.0.115:8081/nexus-2.14.2-01/content/repositories/releases/</url>
+        </repository>
+        <repository>
+            <id>nexus-aliyun</id>
+            <url>http://maven.aliyun.com/nexus/content/groups/public</url>
+        </repository>
+    </repositories>
+
+    <properties>
+        <java.version>1.8</java.version>
+        <fastjson-version>1.2.79</fastjson-version>
+        <hutool-version>5.7.17</hutool-version>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>cn.hutool</groupId>
+            <artifactId>hutool-all</artifactId>
+            <version>${hutool-version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+            <version>1.18.20</version>
+            <scope>provided</scope>
+        </dependency>
+
+    </dependencies>
+
+    <dependencyManagement>
+        <dependencies>
+            <dependency>
+                <groupId>org.springframework</groupId>
+                <artifactId>spring-core</artifactId>
+                <version>5.2.15.RELEASE</version>
+            </dependency>
+            <dependency>
+                <groupId>org.springframework</groupId>
+                <artifactId>spring-context</artifactId>
+                <version>5.2.15.RELEASE</version>
+            </dependency>
+            <dependency>
+                <groupId>org.springframework</groupId>
+                <artifactId>spring-beans</artifactId>
+                <version>5.2.15.RELEASE</version>
+            </dependency>
+            <dependency>
+                <groupId>org.slf4j</groupId>
+                <artifactId>slf4j-api</artifactId>
+                <version>1.7.25</version>
+            </dependency>
+            <dependency>
+                <groupId>com.alibaba</groupId>
+                <artifactId>fastjson</artifactId>
+                <version>${fastjson-version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.apache.logging.log4j</groupId>
+                <artifactId>log4j-api</artifactId>
+                <version>2.17.0</version>
+            </dependency>
+            <dependency>
+                <groupId>org.apache.logging.log4j</groupId>
+                <artifactId>log4j-to-slf4j</artifactId>
+                <version>2.17.0</version>
+            </dependency>
+        </dependencies>
+    </dependencyManagement>
+
+
+
+    <build>
+        <pluginManagement>
+            <plugins>
+                <plugin>
+                    <groupId>org.apache.maven.plugins</groupId>
+                    <artifactId>maven-compiler-plugin</artifactId>
+                    <version>3.8.1</version>
+                </plugin>
+            </plugins>
+        </pluginManagement>
+    </build>
+
+    <distributionManagement>
+        <repository>
+            <!-- 这里的ID要和setting的id一致 -->
+            <id>releases</id>
+            <url>http://192.168.0.115:8081/nexus-2.14.2-01/content/repositories/releases/</url>
+        </repository>
+        <!--这是打成快照版本的配置 -->
+        <snapshotRepository>
+            <id>snapshots</id>
+            <url>http://192.168.0.115:8081/nexus-2.14.2-01/content/repositories/snapshots/</url>
+        </snapshotRepository>
+    </distributionManagement>
+
+</project>