verguenza 5 年之前
當前提交
ce3259e3b3
共有 66 個文件被更改,包括 3447 次插入0 次删除
  1. 31 0
      .gitignore
  2. 118 0
      .mvn/wrapper/MavenWrapperDownloader.java
  3. 二進制
      .mvn/wrapper/maven-wrapper.jar
  4. 2 0
      .mvn/wrapper/maven-wrapper.properties
  5. 二進制
      lib/taobao-sdk-java-auto_1479188381469-20200205-source.jar
  6. 二進制
      lib/taobao-sdk-java-auto_1479188381469-20200205.jar
  7. 310 0
      mvnw
  8. 182 0
      mvnw.cmd
  9. 92 0
      pom.xml
  10. 二進制
      src/main/.DS_Store
  11. 二進制
      src/main/java/.DS_Store
  12. 二進制
      src/main/java/com/.DS_Store
  13. 二進制
      src/main/java/com/galaxis/.DS_Store
  14. 二進制
      src/main/java/com/galaxis/manatee/.DS_Store
  15. 19 0
      src/main/java/com/galaxis/manatee/ManateeApplication.java
  16. 28 0
      src/main/java/com/galaxis/manatee/configuration/ChuanyunConfiguration.java
  17. 46 0
      src/main/java/com/galaxis/manatee/configuration/DingTalkConfiguration.java
  18. 23 0
      src/main/java/com/galaxis/manatee/configuration/JsonConfiguration.java
  19. 50 0
      src/main/java/com/galaxis/manatee/constant/ChuanYunConstant.java
  20. 58 0
      src/main/java/com/galaxis/manatee/constant/DingTalkConstant.java
  21. 24 0
      src/main/java/com/galaxis/manatee/constant/StringConstant.java
  22. 105 0
      src/main/java/com/galaxis/manatee/controller/ChuanyunTestController.java
  23. 36 0
      src/main/java/com/galaxis/manatee/controller/DataStructureTestController.java
  24. 63 0
      src/main/java/com/galaxis/manatee/controller/DingTalkTestController.java
  25. 25 0
      src/main/java/com/galaxis/manatee/controller/UtilsController.java
  26. 14 0
      src/main/java/com/galaxis/manatee/dao/DingTalkProcessInstanceDao.java
  27. 21 0
      src/main/java/com/galaxis/manatee/dao/DingTalkRobotDao.java
  28. 14 0
      src/main/java/com/galaxis/manatee/dao/ProjectDao.java
  29. 二進制
      src/main/java/com/galaxis/manatee/entity/.DS_Store
  30. 30 0
      src/main/java/com/galaxis/manatee/entity/chuanyun/BaseChuanyunResponse.java
  31. 22 0
      src/main/java/com/galaxis/manatee/entity/chuanyun/ChuanyunFindAllResponse.java
  32. 26 0
      src/main/java/com/galaxis/manatee/entity/chuanyun/ChuanyunFindAllReturnData.java
  33. 23 0
      src/main/java/com/galaxis/manatee/entity/chuanyun/ChuanyunFindResponse.java
  34. 19 0
      src/main/java/com/galaxis/manatee/entity/chuanyun/ChuanyunFindReturnData.java
  35. 21 0
      src/main/java/com/galaxis/manatee/entity/chuanyun/ChuanyunSaveAllResponse.java
  36. 21 0
      src/main/java/com/galaxis/manatee/entity/chuanyun/ChuanyunSaveAllReturnData.java
  37. 22 0
      src/main/java/com/galaxis/manatee/entity/chuanyun/ChuanyunSaveResponse.java
  38. 21 0
      src/main/java/com/galaxis/manatee/entity/chuanyun/ChuanyunSaveReturnData.java
  39. 86 0
      src/main/java/com/galaxis/manatee/entity/chuanyun/Filter.java
  40. 238 0
      src/main/java/com/galaxis/manatee/entity/chuanyun/bo/MaterialResendBO.java
  41. 83 0
      src/main/java/com/galaxis/manatee/entity/chuanyun/data/object/BasicDO.java
  42. 113 0
      src/main/java/com/galaxis/manatee/entity/chuanyun/data/object/ProjectDO.java
  43. 170 0
      src/main/java/com/galaxis/manatee/entity/chuanyun/data/object/ProjectLogDO.java
  44. 61 0
      src/main/java/com/galaxis/manatee/entity/ding/DingTalkProcessInstance.java
  45. 29 0
      src/main/java/com/galaxis/manatee/entity/ding/DingTalkResponse.java
  46. 57 0
      src/main/java/com/galaxis/manatee/entity/ding/DingTalkRobot.java
  47. 192 0
      src/main/java/com/galaxis/manatee/entity/ding/DingTalkRobotRequest.java
  48. 12 0
      src/main/java/com/galaxis/manatee/entity/ding/DingTalkRobotResponse.java
  49. 12 0
      src/main/java/com/galaxis/manatee/entity/ding/bo/MaterialResendBO.java
  50. 54 0
      src/main/java/com/galaxis/manatee/manager/ChuanYunManager.java
  51. 23 0
      src/main/java/com/galaxis/manatee/manager/DingTalkRobotWebHook.java
  52. 145 0
      src/main/java/com/galaxis/manatee/manager/impl/DefaultChuanyunManagerImpl.java
  53. 34 0
      src/main/java/com/galaxis/manatee/manager/impl/DingTalkRobotWebHookImpl.java
  54. 147 0
      src/main/java/com/galaxis/manatee/service/ChuanyunScheduledTask.java
  55. 61 0
      src/main/java/com/galaxis/manatee/service/DingTalkAuthorization.java
  56. 11 0
      src/main/java/com/galaxis/manatee/service/DingTalkRobotService.java
  57. 125 0
      src/main/java/com/galaxis/manatee/service/DingTalkScheduledTask.java
  58. 10 0
      src/main/java/com/galaxis/manatee/service/ProcessService.java
  59. 18 0
      src/main/java/com/galaxis/manatee/util/ChuanyunLocalDateTimeDeserializer.java
  60. 18 0
      src/main/java/com/galaxis/manatee/util/ChuanyunLocalDateTimeSerializer.java
  61. 36 0
      src/main/java/com/galaxis/manatee/util/DingTalkRobotUtils.java
  62. 15 0
      src/main/java/com/galaxis/manatee/util/IdGenerate.java
  63. 48 0
      src/main/java/com/galaxis/manatee/util/impl/GalaxisIdGenerator.java
  64. 127 0
      src/main/java/com/galaxis/manatee/util/impl/SnowflakeIdGenerator.java
  65. 43 0
      src/main/resources/application.yml
  66. 13 0
      src/test/java/com/galaxis/manatee/ManateeApplicationTests.java

+ 31 - 0
.gitignore

@@ -0,0 +1,31 @@
+HELP.md
+target/
+!.mvn/wrapper/maven-wrapper.jar
+!**/src/main/**
+!**/src/test/**
+
+### STS ###
+.apt_generated
+.classpath
+.factorypath
+.project
+.settings
+.springBeans
+.sts4-cache
+
+### IntelliJ IDEA ###
+.idea
+*.iws
+*.iml
+*.ipr
+
+### NetBeans ###
+/nbproject/private/
+/nbbuild/
+/dist/
+/nbdist/
+/.nb-gradle/
+build/
+
+### VS Code ###
+.vscode/

+ 118 - 0
.mvn/wrapper/MavenWrapperDownloader.java

@@ -0,0 +1,118 @@
+/*
+ * Copyright 2007-present the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.net.*;
+import java.io.*;
+import java.nio.channels.*;
+import java.util.Properties;
+
+public class MavenWrapperDownloader {
+
+    private static final String WRAPPER_VERSION = "0.5.6";
+    /**
+     * Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided.
+     */
+    private static final String DEFAULT_DOWNLOAD_URL = "https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/"
+            + WRAPPER_VERSION + "/maven-wrapper-" + WRAPPER_VERSION + ".jar";
+
+    /**
+     * Path to the maven-wrapper.properties file, which might contain a downloadUrl property to
+     * use instead of the default one.
+     */
+    private static final String MAVEN_WRAPPER_PROPERTIES_PATH =
+            ".mvn/wrapper/maven-wrapper.properties";
+
+    /**
+     * Path where the maven-wrapper.jar will be saved to.
+     */
+    private static final String MAVEN_WRAPPER_JAR_PATH =
+            ".mvn/wrapper/maven-wrapper.jar";
+
+    /**
+     * Name of the property which should be used to override the default download url for the wrapper.
+     */
+    private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl";
+
+    public static void main(String args[]) {
+        System.out.println("- Downloader started");
+        File baseDirectory = new File(args[0]);
+        System.out.println("- Using base directory: " + baseDirectory.getAbsolutePath());
+
+        // If the maven-wrapper.properties exists, read it and check if it contains a custom
+        // wrapperUrl parameter.
+        File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH);
+        String url = DEFAULT_DOWNLOAD_URL;
+        if (mavenWrapperPropertyFile.exists()) {
+            FileInputStream mavenWrapperPropertyFileInputStream = null;
+            try {
+                mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile);
+                Properties mavenWrapperProperties = new Properties();
+                mavenWrapperProperties.load(mavenWrapperPropertyFileInputStream);
+                url = mavenWrapperProperties.getProperty(PROPERTY_NAME_WRAPPER_URL, url);
+            } catch (IOException e) {
+                System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'");
+            } finally {
+                try {
+                    if (mavenWrapperPropertyFileInputStream != null) {
+                        mavenWrapperPropertyFileInputStream.close();
+                    }
+                } catch (IOException e) {
+                    // Ignore ...
+                }
+            }
+        }
+        System.out.println("- Downloading from: " + url);
+
+        File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH);
+        if (!outputFile.getParentFile().exists()) {
+            if (!outputFile.getParentFile().mkdirs()) {
+                System.out.println(
+                        "- ERROR creating output directory '" + outputFile.getParentFile().getAbsolutePath() + "'");
+            }
+        }
+        System.out.println("- Downloading to: " + outputFile.getAbsolutePath());
+        try {
+            downloadFileFromURL(url, outputFile);
+            System.out.println("Done");
+            System.exit(0);
+        } catch (Throwable e) {
+            System.out.println("- Error downloading");
+            e.printStackTrace();
+            System.exit(1);
+        }
+    }
+
+    private static void downloadFileFromURL(String urlString, File destination) throws Exception {
+        if (System.getenv("MVNW_USERNAME") != null && System.getenv("MVNW_PASSWORD") != null) {
+            String username = System.getenv("MVNW_USERNAME");
+            char[] password = System.getenv("MVNW_PASSWORD").toCharArray();
+            Authenticator.setDefault(new Authenticator() {
+                @Override
+                protected PasswordAuthentication getPasswordAuthentication() {
+                    return new PasswordAuthentication(username, password);
+                }
+            });
+        }
+        URL website = new URL(urlString);
+        ReadableByteChannel rbc;
+        rbc = Channels.newChannel(website.openStream());
+        FileOutputStream fos = new FileOutputStream(destination);
+        fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
+        fos.close();
+        rbc.close();
+    }
+
+}

二進制
.mvn/wrapper/maven-wrapper.jar


+ 2 - 0
.mvn/wrapper/maven-wrapper.properties

@@ -0,0 +1,2 @@
+distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.3/apache-maven-3.6.3-bin.zip
+wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar

二進制
lib/taobao-sdk-java-auto_1479188381469-20200205-source.jar


二進制
lib/taobao-sdk-java-auto_1479188381469-20200205.jar


+ 310 - 0
mvnw

@@ -0,0 +1,310 @@
+#!/bin/sh
+# ----------------------------------------------------------------------------
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#    https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+# ----------------------------------------------------------------------------
+
+# ----------------------------------------------------------------------------
+# Maven Start Up Batch script
+#
+# Required ENV vars:
+# ------------------
+#   JAVA_HOME - location of a JDK home dir
+#
+# Optional ENV vars
+# -----------------
+#   M2_HOME - location of maven2's installed home dir
+#   MAVEN_OPTS - parameters passed to the Java VM when running Maven
+#     e.g. to debug Maven itself, use
+#       set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
+#   MAVEN_SKIP_RC - flag to disable loading of mavenrc files
+# ----------------------------------------------------------------------------
+
+if [ -z "$MAVEN_SKIP_RC" ] ; then
+
+  if [ -f /etc/mavenrc ] ; then
+    . /etc/mavenrc
+  fi
+
+  if [ -f "$HOME/.mavenrc" ] ; then
+    . "$HOME/.mavenrc"
+  fi
+
+fi
+
+# OS specific support.  $var _must_ be set to either true or false.
+cygwin=false;
+darwin=false;
+mingw=false
+case "`uname`" in
+  CYGWIN*) cygwin=true ;;
+  MINGW*) mingw=true;;
+  Darwin*) darwin=true
+    # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home
+    # See https://developer.apple.com/library/mac/qa/qa1170/_index.html
+    if [ -z "$JAVA_HOME" ]; then
+      if [ -x "/usr/libexec/java_home" ]; then
+        export JAVA_HOME="`/usr/libexec/java_home`"
+      else
+        export JAVA_HOME="/Library/Java/Home"
+      fi
+    fi
+    ;;
+esac
+
+if [ -z "$JAVA_HOME" ] ; then
+  if [ -r /etc/gentoo-release ] ; then
+    JAVA_HOME=`java-config --jre-home`
+  fi
+fi
+
+if [ -z "$M2_HOME" ] ; then
+  ## resolve links - $0 may be a link to maven's home
+  PRG="$0"
+
+  # need this for relative symlinks
+  while [ -h "$PRG" ] ; do
+    ls=`ls -ld "$PRG"`
+    link=`expr "$ls" : '.*-> \(.*\)$'`
+    if expr "$link" : '/.*' > /dev/null; then
+      PRG="$link"
+    else
+      PRG="`dirname "$PRG"`/$link"
+    fi
+  done
+
+  saveddir=`pwd`
+
+  M2_HOME=`dirname "$PRG"`/..
+
+  # make it fully qualified
+  M2_HOME=`cd "$M2_HOME" && pwd`
+
+  cd "$saveddir"
+  # echo Using m2 at $M2_HOME
+fi
+
+# For Cygwin, ensure paths are in UNIX format before anything is touched
+if $cygwin ; then
+  [ -n "$M2_HOME" ] &&
+    M2_HOME=`cygpath --unix "$M2_HOME"`
+  [ -n "$JAVA_HOME" ] &&
+    JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
+  [ -n "$CLASSPATH" ] &&
+    CLASSPATH=`cygpath --path --unix "$CLASSPATH"`
+fi
+
+# For Mingw, ensure paths are in UNIX format before anything is touched
+if $mingw ; then
+  [ -n "$M2_HOME" ] &&
+    M2_HOME="`(cd "$M2_HOME"; pwd)`"
+  [ -n "$JAVA_HOME" ] &&
+    JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`"
+fi
+
+if [ -z "$JAVA_HOME" ]; then
+  javaExecutable="`which javac`"
+  if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then
+    # readlink(1) is not available as standard on Solaris 10.
+    readLink=`which readlink`
+    if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then
+      if $darwin ; then
+        javaHome="`dirname \"$javaExecutable\"`"
+        javaExecutable="`cd \"$javaHome\" && pwd -P`/javac"
+      else
+        javaExecutable="`readlink -f \"$javaExecutable\"`"
+      fi
+      javaHome="`dirname \"$javaExecutable\"`"
+      javaHome=`expr "$javaHome" : '\(.*\)/bin'`
+      JAVA_HOME="$javaHome"
+      export JAVA_HOME
+    fi
+  fi
+fi
+
+if [ -z "$JAVACMD" ] ; then
+  if [ -n "$JAVA_HOME"  ] ; then
+    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+      # IBM's JDK on AIX uses strange locations for the executables
+      JAVACMD="$JAVA_HOME/jre/sh/java"
+    else
+      JAVACMD="$JAVA_HOME/bin/java"
+    fi
+  else
+    JAVACMD="`which java`"
+  fi
+fi
+
+if [ ! -x "$JAVACMD" ] ; then
+  echo "Error: JAVA_HOME is not defined correctly." >&2
+  echo "  We cannot execute $JAVACMD" >&2
+  exit 1
+fi
+
+if [ -z "$JAVA_HOME" ] ; then
+  echo "Warning: JAVA_HOME environment variable is not set."
+fi
+
+CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher
+
+# traverses directory structure from process work directory to filesystem root
+# first directory with .mvn subdirectory is considered project base directory
+find_maven_basedir() {
+
+  if [ -z "$1" ]
+  then
+    echo "Path not specified to find_maven_basedir"
+    return 1
+  fi
+
+  basedir="$1"
+  wdir="$1"
+  while [ "$wdir" != '/' ] ; do
+    if [ -d "$wdir"/.mvn ] ; then
+      basedir=$wdir
+      break
+    fi
+    # workaround for JBEAP-8937 (on Solaris 10/Sparc)
+    if [ -d "${wdir}" ]; then
+      wdir=`cd "$wdir/.."; pwd`
+    fi
+    # end of workaround
+  done
+  echo "${basedir}"
+}
+
+# concatenates all lines of a file
+concat_lines() {
+  if [ -f "$1" ]; then
+    echo "$(tr -s '\n' ' ' < "$1")"
+  fi
+}
+
+BASE_DIR=`find_maven_basedir "$(pwd)"`
+if [ -z "$BASE_DIR" ]; then
+  exit 1;
+fi
+
+##########################################################################################
+# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
+# This allows using the maven wrapper in projects that prohibit checking in binary data.
+##########################################################################################
+if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then
+    if [ "$MVNW_VERBOSE" = true ]; then
+      echo "Found .mvn/wrapper/maven-wrapper.jar"
+    fi
+else
+    if [ "$MVNW_VERBOSE" = true ]; then
+      echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..."
+    fi
+    if [ -n "$MVNW_REPOURL" ]; then
+      jarUrl="$MVNW_REPOURL/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
+    else
+      jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
+    fi
+    while IFS="=" read key value; do
+      case "$key" in (wrapperUrl) jarUrl="$value"; break ;;
+      esac
+    done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties"
+    if [ "$MVNW_VERBOSE" = true ]; then
+      echo "Downloading from: $jarUrl"
+    fi
+    wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar"
+    if $cygwin; then
+      wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"`
+    fi
+
+    if command -v wget > /dev/null; then
+        if [ "$MVNW_VERBOSE" = true ]; then
+          echo "Found wget ... using wget"
+        fi
+        if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
+            wget "$jarUrl" -O "$wrapperJarPath"
+        else
+            wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath"
+        fi
+    elif command -v curl > /dev/null; then
+        if [ "$MVNW_VERBOSE" = true ]; then
+          echo "Found curl ... using curl"
+        fi
+        if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
+            curl -o "$wrapperJarPath" "$jarUrl" -f
+        else
+            curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f
+        fi
+
+    else
+        if [ "$MVNW_VERBOSE" = true ]; then
+          echo "Falling back to using Java to download"
+        fi
+        javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java"
+        # For Cygwin, switch paths to Windows format before running javac
+        if $cygwin; then
+          javaClass=`cygpath --path --windows "$javaClass"`
+        fi
+        if [ -e "$javaClass" ]; then
+            if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
+                if [ "$MVNW_VERBOSE" = true ]; then
+                  echo " - Compiling MavenWrapperDownloader.java ..."
+                fi
+                # Compiling the Java class
+                ("$JAVA_HOME/bin/javac" "$javaClass")
+            fi
+            if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
+                # Running the downloader
+                if [ "$MVNW_VERBOSE" = true ]; then
+                  echo " - Running MavenWrapperDownloader.java ..."
+                fi
+                ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR")
+            fi
+        fi
+    fi
+fi
+##########################################################################################
+# End of extension
+##########################################################################################
+
+export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}
+if [ "$MVNW_VERBOSE" = true ]; then
+  echo $MAVEN_PROJECTBASEDIR
+fi
+MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin; then
+  [ -n "$M2_HOME" ] &&
+    M2_HOME=`cygpath --path --windows "$M2_HOME"`
+  [ -n "$JAVA_HOME" ] &&
+    JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"`
+  [ -n "$CLASSPATH" ] &&
+    CLASSPATH=`cygpath --path --windows "$CLASSPATH"`
+  [ -n "$MAVEN_PROJECTBASEDIR" ] &&
+    MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"`
+fi
+
+# Provide a "standardized" way to retrieve the CLI args that will
+# work with both Windows and non-Windows executions.
+MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@"
+export MAVEN_CMD_LINE_ARGS
+
+WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
+
+exec "$JAVACMD" \
+  $MAVEN_OPTS \
+  -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
+  "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
+  ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@"

+ 182 - 0
mvnw.cmd

@@ -0,0 +1,182 @@
+@REM ----------------------------------------------------------------------------
+@REM Licensed to the Apache Software Foundation (ASF) under one
+@REM or more contributor license agreements.  See the NOTICE file
+@REM distributed with this work for additional information
+@REM regarding copyright ownership.  The ASF licenses this file
+@REM to you under the Apache License, Version 2.0 (the
+@REM "License"); you may not use this file except in compliance
+@REM with the License.  You may obtain a copy of the License at
+@REM
+@REM    https://www.apache.org/licenses/LICENSE-2.0
+@REM
+@REM Unless required by applicable law or agreed to in writing,
+@REM software distributed under the License is distributed on an
+@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+@REM KIND, either express or implied.  See the License for the
+@REM specific language governing permissions and limitations
+@REM under the License.
+@REM ----------------------------------------------------------------------------
+
+@REM ----------------------------------------------------------------------------
+@REM Maven Start Up Batch script
+@REM
+@REM Required ENV vars:
+@REM JAVA_HOME - location of a JDK home dir
+@REM
+@REM Optional ENV vars
+@REM M2_HOME - location of maven2's installed home dir
+@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
+@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending
+@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
+@REM     e.g. to debug Maven itself, use
+@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
+@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
+@REM ----------------------------------------------------------------------------
+
+@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
+@echo off
+@REM set title of command window
+title %0
+@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on'
+@if "%MAVEN_BATCH_ECHO%" == "on"  echo %MAVEN_BATCH_ECHO%
+
+@REM set %HOME% to equivalent of $HOME
+if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
+
+@REM Execute a user defined script before this one
+if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
+@REM check for pre script, once with legacy .bat ending and once with .cmd ending
+if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat"
+if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd"
+:skipRcPre
+
+@setlocal
+
+set ERROR_CODE=0
+
+@REM To isolate internal variables from possible post scripts, we use another setlocal
+@setlocal
+
+@REM ==== START VALIDATION ====
+if not "%JAVA_HOME%" == "" goto OkJHome
+
+echo.
+echo Error: JAVA_HOME not found in your environment. >&2
+echo Please set the JAVA_HOME variable in your environment to match the >&2
+echo location of your Java installation. >&2
+echo.
+goto error
+
+:OkJHome
+if exist "%JAVA_HOME%\bin\java.exe" goto init
+
+echo.
+echo Error: JAVA_HOME is set to an invalid directory. >&2
+echo JAVA_HOME = "%JAVA_HOME%" >&2
+echo Please set the JAVA_HOME variable in your environment to match the >&2
+echo location of your Java installation. >&2
+echo.
+goto error
+
+@REM ==== END VALIDATION ====
+
+:init
+
+@REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
+@REM Fallback to current working directory if not found.
+
+set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
+IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
+
+set EXEC_DIR=%CD%
+set WDIR=%EXEC_DIR%
+:findBaseDir
+IF EXIST "%WDIR%"\.mvn goto baseDirFound
+cd ..
+IF "%WDIR%"=="%CD%" goto baseDirNotFound
+set WDIR=%CD%
+goto findBaseDir
+
+:baseDirFound
+set MAVEN_PROJECTBASEDIR=%WDIR%
+cd "%EXEC_DIR%"
+goto endDetectBaseDir
+
+:baseDirNotFound
+set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
+cd "%EXEC_DIR%"
+
+:endDetectBaseDir
+
+IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
+
+@setlocal EnableExtensions EnableDelayedExpansion
+for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
+@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
+
+:endReadAdditionalConfig
+
+SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
+set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
+set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
+
+set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
+
+FOR /F "tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO (
+    IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B
+)
+
+@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
+@REM This allows using the maven wrapper in projects that prohibit checking in binary data.
+if exist %WRAPPER_JAR% (
+    if "%MVNW_VERBOSE%" == "true" (
+        echo Found %WRAPPER_JAR%
+    )
+) else (
+    if not "%MVNW_REPOURL%" == "" (
+        SET DOWNLOAD_URL="%MVNW_REPOURL%/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
+    )
+    if "%MVNW_VERBOSE%" == "true" (
+        echo Couldn't find %WRAPPER_JAR%, downloading it ...
+        echo Downloading from: %DOWNLOAD_URL%
+    )
+
+    powershell -Command "&{"^
+		"$webclient = new-object System.Net.WebClient;"^
+		"if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^
+		"$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^
+		"}"^
+		"[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^
+		"}"
+    if "%MVNW_VERBOSE%" == "true" (
+        echo Finished downloading %WRAPPER_JAR%
+    )
+)
+@REM End of extension
+
+@REM Provide a "standardized" way to retrieve the CLI args that will
+@REM work with both Windows and non-Windows executions.
+set MAVEN_CMD_LINE_ARGS=%*
+
+%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
+if ERRORLEVEL 1 goto error
+goto end
+
+:error
+set ERROR_CODE=1
+
+:end
+@endlocal & set ERROR_CODE=%ERROR_CODE%
+
+if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost
+@REM check for post script, once with legacy .bat ending and once with .cmd ending
+if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat"
+if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd"
+:skipRcPost
+
+@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
+if "%MAVEN_BATCH_PAUSE%" == "on" pause
+
+if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE%
+
+exit /B %ERROR_CODE%

+ 92 - 0
pom.xml

@@ -0,0 +1,92 @@
+<?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>
+    <parent>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-starter-parent</artifactId>
+        <version>2.2.2.RELEASE</version>
+        <relativePath/> <!-- lookup parent from repository -->
+    </parent>
+    <groupId>com.galaxis</groupId>
+    <artifactId>manatee</artifactId>
+    <version>0.1</version>
+    <name>manatee</name>
+    <description>galaxis first step into cloud</description>
+
+    <properties>
+        <java.version>13</java.version>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-data-jpa</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+            <optional>true</optional>
+        </dependency>
+
+        <dependency>
+            <groupId>mysql</groupId>
+            <artifactId>mysql-connector-java</artifactId>
+            <version>8.0.18</version>
+        </dependency>
+
+        <dependency>
+            <groupId>com.vladmihalcea</groupId>
+            <artifactId>hibernate-types-52</artifactId>
+            <version>2.9.1</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-test</artifactId>
+            <scope>test</scope>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.junit.vintage</groupId>
+                    <artifactId>junit-vintage-engine</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+
+        <dependency>
+            <groupId>com.dingtalk.open</groupId>
+            <artifactId>taobao-sdk-java</artifactId>
+            <scope>system</scope>
+            <version>1.0.0-SNAPSHOT</version>
+            <systemPath>${project.basedir}/lib/taobao-sdk-java-auto_1479188381469-20200205.jar</systemPath>
+        </dependency>
+
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+            </plugin>
+            <plugin>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <version>3.8.0</version>
+                <configuration>
+                    <release>13</release>
+                    <compilerArgs>
+                        <arg>--enable-preview</arg>
+                    </compilerArgs>
+                    <forceJavacCompilerUse>true</forceJavacCompilerUse>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>

二進制
src/main/.DS_Store


二進制
src/main/java/.DS_Store


二進制
src/main/java/com/.DS_Store


二進制
src/main/java/com/galaxis/.DS_Store


二進制
src/main/java/com/galaxis/manatee/.DS_Store


+ 19 - 0
src/main/java/com/galaxis/manatee/ManateeApplication.java

@@ -0,0 +1,19 @@
+package com.galaxis.manatee;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.scheduling.annotation.EnableScheduling;
+
+/**
+ * @author zcj
+ * @version 0.1
+ */
+@EnableScheduling
+@SpringBootApplication
+public class ManateeApplication {
+
+    public static void main(String[] args) {
+        SpringApplication.run(ManateeApplication.class, args);
+    }
+
+}

+ 28 - 0
src/main/java/com/galaxis/manatee/configuration/ChuanyunConfiguration.java

@@ -0,0 +1,28 @@
+package com.galaxis.manatee.configuration;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.SerializationFeature;
+import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * @author zcj
+ * @version 0.1
+ * @date 2020/2/5 3:30 下午
+ */
+@Configuration
+public class ChuanyunConfiguration {
+
+    /**
+     * 系统对象转氚云字符串类
+     * @return  转换类
+     */
+    @Bean
+    public ObjectMapper chuanyunSaveObjectMapper(){
+        ObjectMapper objectMapper=new ObjectMapper();
+        objectMapper.registerModule(new JavaTimeModule());
+        objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
+        return new ObjectMapper();
+    }
+}

+ 46 - 0
src/main/java/com/galaxis/manatee/configuration/DingTalkConfiguration.java

@@ -0,0 +1,46 @@
+package com.galaxis.manatee.configuration;
+
+import com.dingtalk.api.DefaultDingTalkClient;
+import com.dingtalk.api.DingTalkClient;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * @author zcj
+ * @version 0.1
+ * @date 2020/1/9 4:52 下午
+ */
+@Configuration
+public class DingTalkConfiguration {
+
+    /**
+     * 获取审批列表的URL
+     */
+    @Value("${dingTalk.processUrl.listIds}")
+    private String processUrlListId;
+
+    /**
+     * 获取审批实例
+     */
+    @Value(("${dingTalk.processUrl.instance}"))
+    private String processUrlInstance;
+
+    /**
+     * 获取审批列表Id的客户端
+     * @return  客户端
+     */
+    @Bean
+    public DingTalkClient processInstanceListIdsClient(){
+        return new DefaultDingTalkClient(processUrlListId);
+    }
+
+    /**
+     * 获取审批内容客户端
+     * @return  客户端
+     */
+    @Bean
+    public DingTalkClient processInstanceClient(){
+        return new DefaultDingTalkClient(processUrlInstance);
+    }
+}

+ 23 - 0
src/main/java/com/galaxis/manatee/configuration/JsonConfiguration.java

@@ -0,0 +1,23 @@
+package com.galaxis.manatee.configuration;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * @author zcj
+ * @version 0.1
+ * @date 2020/2/6 9:52 上午
+ */
+@Configuration
+public class JsonConfiguration {
+
+    /**
+     * 对象映射类
+     * @return  对象实例
+     */
+    @Bean
+    public ObjectMapper objectMapper(){
+        return new ObjectMapper();
+    }
+}

+ 50 - 0
src/main/java/com/galaxis/manatee/constant/ChuanYunConstant.java

@@ -0,0 +1,50 @@
+package com.galaxis.manatee.constant;
+
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @author zcj
+ * @version 0.1
+ * @date 2020/1/10 12:01 上午
+ */
+@Service
+public class ChuanYunConstant {
+
+    /**
+     * 保存项目号、项目ObjectId的映射关系
+     */
+    public static Map<String,String> PROJECT_CODE=new HashMap<>(2048);
+    /**
+     * 调用地址
+     */
+    public static String CHUAN_YUN_INVOKE_URL;
+
+    /**
+     * 账号
+     */
+    public static String ENGINE_CODE;
+
+    /**
+     * 密码
+     */
+    public static String ENGINE_SECRET;
+
+    @Value(value = "${chuanYun.engine.code}")
+    public void setEngineCode(String engineCode) {
+        ENGINE_CODE = engineCode;
+    }
+
+    @Value(value = "${chuanYun.engine.secret}")
+    public void setEngineSecret(String engineSecret) {
+        ENGINE_SECRET = engineSecret;
+    }
+
+    @Value(value = "${chuanYun.url.invoke}")
+    public void setChuanYunInvokeUrl(String chuanYunInvokeUrl) {
+        CHUAN_YUN_INVOKE_URL = chuanYunInvokeUrl;
+    }
+}

+ 58 - 0
src/main/java/com/galaxis/manatee/constant/DingTalkConstant.java

@@ -0,0 +1,58 @@
+package com.galaxis.manatee.constant;
+
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+
+/**
+ * @author zcj
+ * @version 0.1
+ * @date 2020/1/8 5:52 下午
+ */
+@Service
+public class DingTalkConstant {
+
+    /**
+     * 钉钉token
+     */
+    public static String DING_TALK_TOKEN = "";
+
+    /**
+     * 钉钉appKey
+     */
+    public static String DING_TALK_APP_KEY;
+
+    /**
+     * 钉钉appSecret
+     */
+    public static String DING_TALK_APP_SECRET;
+
+    /**
+     * 钉钉出差审批流编码
+     */
+    public static String PROCESS_CODE_BUSINESS_TRIP;
+
+    /**
+     * 物料补发
+     */
+    public static String PROCESS_CODE_MATERIAL_RESEND;
+
+    @Value(value = "${dingTalk.appKey}")
+    public void setDingTalkAppKey(String dingTalkAppKey) {
+        DingTalkConstant.DING_TALK_APP_KEY = dingTalkAppKey;
+    }
+
+    @Value(value = "${dingTalk.appSecret}")
+    public void setDingTalkAppSecret(String dingTalkAppSecret) {
+        DingTalkConstant.DING_TALK_APP_SECRET = dingTalkAppSecret;
+    }
+
+    @Value(value = "${dingTalk.processCode.businessTrip}")
+    public void setProcessCodeBusinessTrip(String processCodeBusinessTrip) {
+        DingTalkConstant.PROCESS_CODE_BUSINESS_TRIP = processCodeBusinessTrip;
+    }
+
+    @Value(value = "${dingTalk.processCode.materialResend}")
+    public void setMaterialResend(String materialResend) {
+        DingTalkConstant.PROCESS_CODE_MATERIAL_RESEND = materialResend;
+    }
+}

+ 24 - 0
src/main/java/com/galaxis/manatee/constant/StringConstant.java

@@ -0,0 +1,24 @@
+package com.galaxis.manatee.constant;
+
+/**
+ * @author zcj
+ * @version 0.1
+ * @date 2020/4/1 12:19 上午
+ */
+public class StringConstant {
+
+    /**
+     * tab字符串
+     */
+    public static final String TAB_STRING="/t";
+
+    /**
+     * 换行
+     */
+    public static final String RETURN_STRING="/n";
+
+    /**
+     * 空格字符串
+     */
+    public static final String SPACE_STRING=" ";
+}

+ 105 - 0
src/main/java/com/galaxis/manatee/controller/ChuanyunTestController.java

@@ -0,0 +1,105 @@
+package com.galaxis.manatee.controller;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.galaxis.manatee.entity.chuanyun.*;
+import com.galaxis.manatee.entity.chuanyun.bo.MaterialResendBO;
+import com.galaxis.manatee.entity.chuanyun.data.object.ProjectDO;
+import com.galaxis.manatee.entity.chuanyun.data.object.ProjectLogDO;
+import com.galaxis.manatee.manager.ChuanYunManager;
+import org.hibernate.Session;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.persistence.EntityManager;
+import java.time.LocalDate;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author zcj
+ * @version 0.1
+ * @date 2020/2/5 4:03 下午
+ */
+@RestController
+public class ChuanyunTestController {
+
+    private ChuanYunManager chuanYunManager;
+    private EntityManager entityManager;
+//    public ChuanyunTestController(ChuanYunManager chuanYunManager) {
+//        this.chuanYunManager = chuanYunManager;
+//    }
+
+
+    public ChuanyunTestController(ChuanYunManager chuanYunManager, EntityManager entityManager) {
+        this.chuanYunManager = chuanYunManager;
+        this.entityManager = entityManager;
+    }
+
+    /**
+     * 测试
+     */
+    @GetMapping("/testEntity")
+    public void test() throws JsonProcessingException {
+        Session session=entityManager.unwrap(Session.class);
+        List<Object> testList=session.createSQLQuery("select * from baba").list();
+        ObjectMapper objectMapper=new ObjectMapper();
+        System.out.println(objectMapper.writeValueAsString(testList));
+    }
+
+    /**
+     * 单条查询测试
+     * @return  测试结果
+     */
+    @GetMapping("/chuanyunTest/testFind")
+    public String testFind() throws JsonProcessingException {
+        ObjectMapper objectMapper=new ObjectMapper();
+        ChuanyunFindResponse<ProjectLogDO> logTemplateChuanYunFindResponse =chuanYunManager.find(ProjectLogDO.SCHEMA_CODE,"ae5f74e9-a8f8-4d20-9e94-b594e57c12bc");
+        return objectMapper.writeValueAsString(logTemplateChuanYunFindResponse);
+    }
+
+    /**
+     * 单条查询测试
+     * @return  测试结果
+     */
+    @GetMapping("/chuanyunTest/testFindList")
+    public String testFindList() throws JsonProcessingException {
+        ObjectMapper objectMapper=new ObjectMapper();
+        Filter testFilter=Filter.instance(0,20,true);
+        ChuanyunFindAllResponse<ProjectDO> logTemplateChuanYunFindAllResponse =chuanYunManager.findAll(ProjectDO.SCHEMA_CODE,testFilter);
+        return objectMapper.writeValueAsString(logTemplateChuanYunFindAllResponse);
+    }
+
+    /**
+     * 保存测试
+     * @return  保存结果
+     */
+    @GetMapping("/chuanyunTest/testSave")
+    public String testSave() throws JsonProcessingException {
+        MaterialResendBO resendVO=new MaterialResendBO();
+        resendVO.setRequestDate(LocalDate.now());
+        resendVO.setRequestType("test");
+        ObjectMapper objectMapper=new ObjectMapper();
+        ChuanyunSaveResponse chuanyunSaveResponse= chuanYunManager.save(MaterialResendBO.SCHEMA_CODE,objectMapper.writeValueAsString(resendVO),true);
+        return objectMapper.writeValueAsString(chuanyunSaveResponse);
+    }
+
+    /**
+     * 保存所有
+     * @return  保存结果
+     * @throws JsonProcessingException  json处理异常
+     */
+    @GetMapping("/chuanyunTest/testSaveAll")
+    public String testSaveAll() throws JsonProcessingException {
+        MaterialResendBO resend1=new MaterialResendBO();
+        MaterialResendBO resend2=new MaterialResendBO();
+        resend1.setRequestType("helloChuanyunSaveAll1");
+        resend2.setRequestType("helloChuanyunSaveAll2");
+        ObjectMapper objectMapper=new ObjectMapper();
+        List<String> strings=new ArrayList<>();
+        strings.add(objectMapper.writeValueAsString(resend1));
+        strings.add(objectMapper.writeValueAsString(resend2));
+        ChuanyunSaveAllResponse chuanyunSaveAllResponse= chuanYunManager.saveAll(MaterialResendBO.SCHEMA_CODE,strings,true);
+        return objectMapper.writeValueAsString(chuanyunSaveAllResponse);
+    }
+}

+ 36 - 0
src/main/java/com/galaxis/manatee/controller/DataStructureTestController.java

@@ -0,0 +1,36 @@
+package com.galaxis.manatee.controller;
+
+import com.dingtalk.api.response.OapiProcessinstanceGetResponse;
+import com.galaxis.manatee.dao.DingTalkProcessInstanceDao;
+import com.galaxis.manatee.entity.ding.DingTalkProcessInstance;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.List;
+
+/**
+ * @author zcj
+ * @version 0.1
+ * @date 2020/2/6 7:14 下午
+ */
+@Slf4j
+@RestController
+public class DataStructureTestController {
+
+    private DingTalkProcessInstanceDao dingTalkProcessInstanceDao;
+
+    public DataStructureTestController(DingTalkProcessInstanceDao dingTalkProcessInstanceDao) {
+        this.dingTalkProcessInstanceDao = dingTalkProcessInstanceDao;
+    }
+
+    @GetMapping("/testData")
+    public void testData(){
+        DingTalkProcessInstance dingTalkProcessInstance=dingTalkProcessInstanceDao.findById("774cd621-e754-4893-8d84-e1fc96fc5e2c").get();
+        OapiProcessinstanceGetResponse.ProcessInstanceTopVo processInstanceTopVo=dingTalkProcessInstance.getProcessInstance();
+        List<OapiProcessinstanceGetResponse.FormComponentValueVo> list= processInstanceTopVo.getFormComponentValues();
+        list.forEach(a->{
+            log.info(a.getName()+"///"+a.getValue());
+        });
+    }
+}

+ 63 - 0
src/main/java/com/galaxis/manatee/controller/DingTalkTestController.java

@@ -0,0 +1,63 @@
+package com.galaxis.manatee.controller;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.galaxis.manatee.dao.DingTalkRobotDao;
+import com.galaxis.manatee.entity.ding.DingTalkRobot;
+import com.galaxis.manatee.entity.ding.DingTalkRobotRequest;
+import com.galaxis.manatee.entity.ding.DingTalkRobotResponse;
+import com.galaxis.manatee.manager.DingTalkRobotWebHook;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @author zcj
+ * @version 0.1
+ * @date 2020/1/9 1:10 下午
+ */
+@Slf4j
+@RequestMapping("/dingTalkTest")
+@RestController
+public class DingTalkTestController {
+
+
+    private ObjectMapper objectMapper=new ObjectMapper();
+    private DingTalkRobotDao dingTalkRobotDao;
+    private DingTalkRobotWebHook dingTalkRobotWebHook;
+
+    public DingTalkTestController(ObjectMapper objectMapper, DingTalkRobotDao dingTalkRobotDao, DingTalkRobotWebHook dingTalkRobotWebHook) {
+        this.objectMapper = objectMapper;
+        this.dingTalkRobotDao = dingTalkRobotDao;
+        this.dingTalkRobotWebHook = dingTalkRobotWebHook;
+    }
+
+    /**
+     * 测试中兴机器人
+     * @throws Exception 机器人接口调用异常
+     */
+    @GetMapping("/dingTalkRobotWebHookTest")
+    public void dingTalkRobotWebHookTest() throws Exception {
+        Map<String,String> params=new HashMap<>(1);
+        params.put("content","考勤报告,这是测试");
+        DingTalkRobotRequest.At at=DingTalkRobotRequest.At.instance(new ArrayList<>(),false);
+        DingTalkRobot dingTalkRobot=dingTalkRobotDao.findByName("中兴关键词机器人");
+        DingTalkRobotResponse dingTalkRobotResponse=dingTalkRobotWebHook.invoke(DingTalkRobotRequest.instanceOf(params, DingTalkRobotRequest.MessageType.TEXT,at),dingTalkRobot);
+        log.info(objectMapper.writeValueAsString(dingTalkRobotResponse));
+    }
+
+    /**
+     * 测试保存
+     */
+    @GetMapping("/saveDingTalkRobot")
+    public void saveDingTalkRobot(){
+        DingTalkRobot dingTalkRobot=new DingTalkRobot();
+        dingTalkRobot.setName("测试创建");
+        dingTalkRobotDao.save(dingTalkRobot);
+    }
+
+}

+ 25 - 0
src/main/java/com/galaxis/manatee/controller/UtilsController.java

@@ -0,0 +1,25 @@
+package com.galaxis.manatee.controller;
+
+import com.galaxis.manatee.util.impl.SnowflakeIdGenerator;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * @author zcj
+ * @version 0.1
+ * @date 2020/1/8 11:59 下午
+ */
+@RequestMapping("/utils")
+@RestController
+public class UtilsController {
+
+    /**
+     * 获取一个Id
+     * @return  id
+     */
+    @GetMapping("/useGalaxisIdGenerator")
+    public String useGalaxisIdGenerator(){
+        return SnowflakeIdGenerator.getSnowflakeIdGenerator(1L).nextId().toString();
+    }
+}

+ 14 - 0
src/main/java/com/galaxis/manatee/dao/DingTalkProcessInstanceDao.java

@@ -0,0 +1,14 @@
+package com.galaxis.manatee.dao;
+
+import com.galaxis.manatee.entity.ding.DingTalkProcessInstance;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+
+/**
+ * @author zcj
+ * @version 0.1
+ * @date 2020/1/9 2:55 下午
+ */
+@Repository
+public interface DingTalkProcessInstanceDao extends JpaRepository<DingTalkProcessInstance,String> {
+}

+ 21 - 0
src/main/java/com/galaxis/manatee/dao/DingTalkRobotDao.java

@@ -0,0 +1,21 @@
+package com.galaxis.manatee.dao;
+
+import com.galaxis.manatee.entity.ding.DingTalkRobot;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+
+/**
+ * @author zcj
+ * @version 0.1
+ * @date 2020/1/9 1:11 下午
+ */
+@Repository
+public interface DingTalkRobotDao extends JpaRepository<DingTalkRobot,Long> {
+
+    /**
+     * 根据名称获取机器人实例
+     * @param name  机器人名称
+     * @return  机器人信息
+     */
+    DingTalkRobot findByName(String name);
+}

+ 14 - 0
src/main/java/com/galaxis/manatee/dao/ProjectDao.java

@@ -0,0 +1,14 @@
+package com.galaxis.manatee.dao;
+
+import com.galaxis.manatee.entity.chuanyun.data.object.ProjectDO;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+
+/**
+ * @author zcj
+ * @version 0.1
+ * @date 2020/2/13 4:39 下午
+ */
+@Repository
+public interface ProjectDao extends JpaRepository<ProjectDO,String> {
+}

二進制
src/main/java/com/galaxis/manatee/entity/.DS_Store


+ 30 - 0
src/main/java/com/galaxis/manatee/entity/chuanyun/BaseChuanyunResponse.java

@@ -0,0 +1,30 @@
+package com.galaxis.manatee.entity.chuanyun;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+
+/**
+ * @author zcj
+ * @version 0.1
+ * @date 2020/2/5 6:08 下午
+ */
+@Data
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class  BaseChuanyunResponse {
+    /**
+     * 是否获取成功
+     */
+    @JsonProperty("Successful")
+    protected boolean successful;
+    /**
+     * 错误信息
+     */
+    @JsonProperty("ErrorMessage")
+    protected String errorMessage;
+    /**
+     * 默认为0
+     */
+    @JsonProperty("DataType")
+    protected int dataType;
+}

+ 22 - 0
src/main/java/com/galaxis/manatee/entity/chuanyun/ChuanyunFindAllResponse.java

@@ -0,0 +1,22 @@
+package com.galaxis.manatee.entity.chuanyun;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * @author zcj
+ * @version 0.1
+ */
+@EqualsAndHashCode(callSuper = true)
+@Data
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class ChuanyunFindAllResponse<T> extends BaseChuanyunResponse{
+
+    /**
+     * 返回数据(重要)
+     */
+    @JsonProperty("ReturnData")
+    private ChuanyunFindAllReturnData<T> returnData;
+}

+ 26 - 0
src/main/java/com/galaxis/manatee/entity/chuanyun/ChuanyunFindAllReturnData.java

@@ -0,0 +1,26 @@
+package com.galaxis.manatee.entity.chuanyun;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * @author zcj
+ * @version 0.1
+ */
+@Data
+public class ChuanyunFindAllReturnData<T> {
+
+    /**
+     * 总行数
+     */
+    @JsonProperty(value = "TotalCount")
+    private Long totalCount;
+
+    /**
+     * 返回数据
+     */
+    @JsonProperty("BizObjectArray")
+    private List<T> bizObjectArray;
+}

+ 23 - 0
src/main/java/com/galaxis/manatee/entity/chuanyun/ChuanyunFindResponse.java

@@ -0,0 +1,23 @@
+package com.galaxis.manatee.entity.chuanyun;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * @author zcj
+ * @version 0.1
+ * @date 2020/2/5 6:16 下午
+ */
+@EqualsAndHashCode(callSuper = true)
+@Data
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class ChuanyunFindResponse<T> extends BaseChuanyunResponse {
+
+    /**
+     * 返回数据(重要)
+     */
+    @JsonProperty("ReturnData")
+    private ChuanyunFindReturnData<T> returnData;
+}

+ 19 - 0
src/main/java/com/galaxis/manatee/entity/chuanyun/ChuanyunFindReturnData.java

@@ -0,0 +1,19 @@
+package com.galaxis.manatee.entity.chuanyun;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+
+/**
+ * @author zcj
+ * @version 0.1
+ * @date 2020/2/5 6:12 下午
+ */
+@Data
+public class ChuanyunFindReturnData<T> {
+    /**
+     * 返回数据
+     */
+    @JsonProperty("BizObject")
+    private T bizObject;
+}
+

+ 21 - 0
src/main/java/com/galaxis/manatee/entity/chuanyun/ChuanyunSaveAllResponse.java

@@ -0,0 +1,21 @@
+package com.galaxis.manatee.entity.chuanyun;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * @author zcj
+ * @version 0.1
+ * @date 2020/2/5 10:18 下午
+ */
+@EqualsAndHashCode(callSuper = true)
+@Data
+public class ChuanyunSaveAllResponse extends BaseChuanyunResponse{
+
+    /**
+     * 返回数据
+     */
+    @JsonProperty(value = "ReturnData")
+    private ChuanyunSaveAllReturnData chuanyunSaveAllReturnData;
+}

+ 21 - 0
src/main/java/com/galaxis/manatee/entity/chuanyun/ChuanyunSaveAllReturnData.java

@@ -0,0 +1,21 @@
+package com.galaxis.manatee.entity.chuanyun;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+
+/**
+ * @author zcj
+ * @version 0.1
+ * @date 2020/2/5 10:16 下午
+ */
+@Data
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class ChuanyunSaveAllReturnData {
+
+    /**
+     * Id列表
+     */
+    @JsonProperty(value = "BizObjectIdArray")
+    private String[] bizObjectIdArray;
+}

+ 22 - 0
src/main/java/com/galaxis/manatee/entity/chuanyun/ChuanyunSaveResponse.java

@@ -0,0 +1,22 @@
+package com.galaxis.manatee.entity.chuanyun;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * @author zcj
+ * @version 0.1
+ * @date 2020/2/5 10:18 下午
+ */
+@EqualsAndHashCode(callSuper = true)
+@Data
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class ChuanyunSaveResponse extends BaseChuanyunResponse{
+    /**
+     * 返回数据(重要)
+     */
+    @JsonProperty("ReturnData")
+    private ChuanyunSaveReturnData returnData;
+}

+ 21 - 0
src/main/java/com/galaxis/manatee/entity/chuanyun/ChuanyunSaveReturnData.java

@@ -0,0 +1,21 @@
+package com.galaxis.manatee.entity.chuanyun;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+
+/**
+ * @author zcj
+ * @version 0.1
+ * @date 2020/2/5 10:16 下午
+ */
+@Data
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class ChuanyunSaveReturnData {
+
+    /**
+     * 保存对象的主键
+     */
+    @JsonProperty(value = "BizObjectId")
+    private String bizObjectId;
+}

+ 86 - 0
src/main/java/com/galaxis/manatee/entity/chuanyun/Filter.java

@@ -0,0 +1,86 @@
+package com.galaxis.manatee.entity.chuanyun;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * 氚云批量查询过滤条件,氚云技术人员建议查询全部数据,自己进行筛选
+ * @author zcj
+ * @version 0.1
+ * @date 2020/2/5 10:01 下午
+ */
+@Getter
+@Setter
+public class Filter {
+    /**
+     *
+     * @param fromRowNumber 从第几行开始
+     * @param toRowNumber   到第几行
+     * @param requireCount  是否需要总数
+     * @return  Filter对象
+     */
+    public static Filter instance(Integer fromRowNumber,Integer toRowNumber,Boolean requireCount){
+        return new Filter(fromRowNumber,toRowNumber,requireCount,new String[0],new String[0],"And",new String[0]);
+    }
+    /**
+     * 分页查询,从第几条开始
+     */
+    @JsonProperty(value = "FromRowNum")
+    private Integer fromRowNumber;
+    /**
+     * 分页查询,第几条结束
+     */
+    @JsonProperty(value = "ToRowNum")
+    private Integer toRowNumber;
+    /**
+     * 查询的总行数
+     */
+    @JsonProperty(value = "RequireCount")
+    private Boolean requireCount;
+    /**
+     * 返回的字段,不填返回所有
+     */
+    @JsonProperty(value = "ReturnItems")
+    private String[] returnItem;
+    /**
+     * 排序字段,目前不支持使用,默认置空
+     */
+    @JsonProperty(value = "SortByCollection")
+    private String[] sortByCollection;
+    /**
+     * 查询条件
+     */
+    @JsonProperty(value = "Matcher")
+    private Matcher matcher;
+
+    private Filter(Integer fromRowNumber, Integer toRowNumber, Boolean requireCount, String[] returnItem, String[] sortByCollection, String type,String[] matchers) {
+        this.fromRowNumber = fromRowNumber;
+        this.toRowNumber = toRowNumber;
+        this.requireCount = requireCount;
+        this.returnItem = returnItem;
+        this.sortByCollection = sortByCollection;
+        this.matcher = new Matcher(type,matchers);
+    }
+
+    @Getter
+    @Setter
+    static class Matcher{
+        /**
+         * 判断符号:与或非
+         */
+        @JsonProperty(value = "Type")
+        private String type;
+
+        /**
+         * 判断条件
+         */
+        @JsonProperty(value = "Matchers")
+        private String[] matchers;
+
+        public Matcher(String type, String[] matchers) {
+            this.type = type;
+            this.matchers = matchers;
+        }
+    }
+}

+ 238 - 0
src/main/java/com/galaxis/manatee/entity/chuanyun/bo/MaterialResendBO.java

@@ -0,0 +1,238 @@
+package com.galaxis.manatee.entity.chuanyun.bo;
+
+import com.dingtalk.api.response.OapiProcessinstanceGetResponse;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.galaxis.manatee.constant.ChuanYunConstant;
+import com.galaxis.manatee.constant.StringConstant;
+import com.galaxis.manatee.entity.chuanyun.data.object.BasicDO;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.Getter;
+import lombok.extern.slf4j.Slf4j;
+
+import java.time.LocalDate;
+import java.time.format.DateTimeFormatter;
+import java.util.List;
+
+/**
+ * @author zcj
+ * @version 0.1
+ * @date 2020/2/6 2:34 下午
+ */
+@Slf4j
+@EqualsAndHashCode(callSuper = true)
+@Data
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class MaterialResendBO extends BasicDO {
+
+    /**
+     * 表单编码
+     */
+    @JsonIgnore
+    public static final String SCHEMA_CODE = "D001789materialResend";
+
+    /**
+     * 归属项目
+     */
+    private String project;
+    /**
+     * 请求日期
+     */
+    private LocalDate requestDate;
+    /**
+     * 请求类型:
+     * 1.临时采购
+     * 2.损坏补发
+     * 3.售后服务
+     * 4.研发缺料
+     * 5.稳定性改善
+     * 6.其他
+     */
+    private String requestType;
+    /**
+     * 请求原因
+     */
+    private String requestReason;
+    /**
+     * 交付日期
+     */
+    private LocalDate deadline;
+    /**
+     * 紧急程度
+     */
+    private String level;
+    /**
+     * 收货信息
+     */
+    private String receiverInformation;
+
+    /**
+     * 备注
+     */
+    private String content;
+    /**
+     * 物料明细列表
+     */
+    List<MaterialResendDetail> detailList;
+    /**
+     * 创建人
+     */
+    @JsonProperty(value = "CreatedByObjectObject")
+    RelationObject createdByObjectObject;
+    /**
+     * 拥有者
+     */
+    @JsonProperty(value = "OwnerIdObjectObject")
+    RelationObject ownerIdObjectObject;
+    /**
+     * 拥有部门
+     */
+    @JsonProperty(value = "OwnerDeptIdObjectObject")
+    RelationObject ownerDeptIdObjectObject;
+
+    /**
+     * 申请日期编码
+     */
+    @Getter
+    private enum FormComponent {
+        /**
+         * 申请日期
+         */
+        REQUEST_DATE("申请日期", "DDDateField-IV7F9M1Z"),
+        /**
+         * 申请类型
+         */
+        REQUEST_TYPE("申请类型", "DDSelectField-JUF43OUB"),
+        REQUEST_REASON("申请原因", "TextField-IH4T9JQ9"),
+        RESEARCH_PROJECT("研发项目号", "DDSelectField-JLLO6AZ2"),
+        INTEGRATION_PROJECT("实施项目号", "DDSelectField-K4XUUCJA"),
+        OLD_INTEGRATION_PROJECT_1("老项目号1","DDSelectField-IV7F9M20"),
+        OLD_INTEGRATION_PROJECT_2("老项目号2","DDSelectField-JPHQ1P7F"),
+        AFTER_SALE_PROJECT("售后项目号", "DDMultiSelectField-K3TG0TSA"),
+        DEAD_LINE("交付日期", "DDDateField-IH4T9JQ8"),
+        LEVEL("紧急程度", "DDSelectField-IV7F9M21"),
+        RECEIVE_INFORMATION("收货信息", "TextareaField-IV7F9M22"),
+        MATERIAL_DETAIL("物料明细", "TableField-IH4T9JQB"),
+        CONTENT("备注", "TextareaField-IH4T9JQK");
+        /**
+         * 名称
+         */
+        private String name;
+        /**
+         * ID
+         */
+        private String id;
+
+        FormComponent(String name, String id) {
+            this.name = name;
+            this.id = id;
+        }
+
+        /**
+         * 根据Id获取对象
+         *
+         * @param id id
+         * @return 枚举值
+         * @throws Exception ID无法找到的异常
+         */
+        public static FormComponent fromId(String id) throws Exception {
+            for (FormComponent formComponent : FormComponent.values()) {
+                if (formComponent.getId().equals(id)) {
+                    return formComponent;
+                }
+            }
+            throw new Exception("can't find by id");
+        }
+    }
+
+    /**
+     * 根据钉钉中的数据获取
+     *
+     * @return 可以被氚云保存的对象
+     */
+    @SuppressWarnings("AlibabaSwitchStatement")
+    public static MaterialResendBO fromDingTak(OapiProcessinstanceGetResponse.ProcessInstanceTopVo dingTalkProcessInstance) {
+        MaterialResendBO materialResendBO = new MaterialResendBO();
+        //由于物料补发功能在2020年一月份发生了变更,需要根据
+        if(dingTalkProcessInstance.getFormComponentValues()==null){
+            log.info("test");
+        }
+        dingTalkProcessInstance.getFormComponentValues().forEach(formComponentValueVo -> {
+            FormComponent formComponent;
+            try {
+                String nullString="null";
+                formComponent = FormComponent.fromId(formComponentValueVo.getId());
+                switch (formComponent) {
+                    case REQUEST_DATE -> materialResendBO.setRequestDate(LocalDate.parse(formComponentValueVo.getValue(), DateTimeFormatter.ofPattern("yyyy-MM-dd")));
+                    case DEAD_LINE -> materialResendBO.setDeadline(LocalDate.parse(formComponentValueVo.getValue(), DateTimeFormatter.ofPattern("yyyy-MM-dd")));
+                    case REQUEST_TYPE -> materialResendBO.setRequestType(formComponentValueVo.getValue());
+                    case REQUEST_REASON -> materialResendBO.setRequestReason(formComponentValueVo.getValue());
+                    case LEVEL -> materialResendBO.setLevel(formComponentValueVo.getValue());
+                    case RECEIVE_INFORMATION -> materialResendBO.setReceiverInformation(formComponentValueVo.getValue());
+                    case RESEARCH_PROJECT, INTEGRATION_PROJECT, AFTER_SALE_PROJECT,OLD_INTEGRATION_PROJECT_1,OLD_INTEGRATION_PROJECT_2 -> {
+                        if (!formComponentValueVo.getValue().equals(nullString)) {
+                            if(formComponentValueVo.getValue().contains(StringConstant.TAB_STRING)){
+                                String projectId = formComponentValueVo.getValue().split(StringConstant.TAB_STRING)[0];
+                                materialResendBO.setProject(ChuanYunConstant.PROJECT_CODE.get(projectId));
+                            }else if(formComponentValueVo.getValue().contains(StringConstant.SPACE_STRING)){
+                                String projectId = formComponentValueVo.getValue().split(StringConstant.SPACE_STRING)[0];
+                                materialResendBO.setProject(ChuanYunConstant.PROJECT_CODE.get(projectId));
+                            }
+                        }
+                    }
+                    case CONTENT -> materialResendBO.setContent(formComponentValueVo.getValue());
+                    case MATERIAL_DETAIL -> log.info(formComponentValueVo.getValue());
+                    default -> log.warn(formComponentValueVo + "异常");
+                }
+            } catch (Exception e) {
+                log.error(formComponentValueVo + "");
+                log.error("根据formComponent内容解析异常");
+            }
+        });
+        return materialResendBO;
+    }
+
+    /**
+     * 物料明细对象
+     */
+    @Data
+    static class MaterialResendDetail {
+        /**
+         * 主键
+         */
+        @JsonProperty(value = "ObjectId")
+        private String objectId;
+        /**
+         * 物料名称
+         */
+        @JsonProperty(value = "Name")
+        private String name = null;
+        /**
+         * 父ID,即物料补发明细Id
+         */
+        @JsonProperty(value = "ParentObjectId")
+        private String parentObjectId;
+        /**
+         * 物料明细类型
+         */
+        private String detailType;
+        /**
+         * 物料明细名称
+         */
+        private String detailName;
+        /**
+         * 物料编码
+         */
+        private String code;
+        /**
+         * 物料数量
+         */
+        private Integer quantity;
+        /**
+         * 用途
+         */
+        private String usage;
+    }
+}

+ 83 - 0
src/main/java/com/galaxis/manatee/entity/chuanyun/data/object/BasicDO.java

@@ -0,0 +1,83 @@
+package com.galaxis.manatee.entity.chuanyun.data.object;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import com.galaxis.manatee.util.ChuanyunLocalDateTimeDeserializer;
+import com.galaxis.manatee.util.ChuanyunLocalDateTimeSerializer;
+import lombok.Data;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.Inheritance;
+import javax.persistence.InheritanceType;
+import java.time.LocalDateTime;
+
+/**
+ * @author zcj
+ * @version 0.1
+ * @date 2020/2/13 5:22 下午
+ */
+@Data
+@Entity(name = "BASIC_DO")
+@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
+public class BasicDO {
+    /**
+     * 项目Id
+     */
+    @JsonProperty(value = "ObjectId")
+    @Id
+    private String objectId;
+    /**
+     * 数据标题
+     */
+    @JsonProperty("Name")
+    private String name;
+    /**
+     * 创建时间
+     */
+    @JsonProperty("CreatedTime")
+    @JsonSerialize(using = ChuanyunLocalDateTimeSerializer.class)
+    @JsonDeserialize(using = ChuanyunLocalDateTimeDeserializer.class)
+    @DateTimeFormat(pattern = "yyyy/MM/dd HH:mm:ss")
+    private LocalDateTime createdTime;
+    /**
+     * 被谁修改
+     */
+    @JsonProperty("ModifiedBy")
+    private String modifiedBy;
+    /**
+     * 修改时间
+     */
+    @JsonProperty("ModifiedTime")
+    @JsonSerialize(using = ChuanyunLocalDateTimeSerializer.class)
+    @JsonDeserialize(using = ChuanyunLocalDateTimeDeserializer.class)
+    @DateTimeFormat(pattern = "yyyy/MM/dd HH:mm:ss")
+    private LocalDateTime modifiedTime;
+    /**
+     * 工作流Id
+     */
+    @JsonProperty("WorkflowInstanceId")
+    private String workflowInstanceId;
+    /**
+     * 状态(具体值的含义需要查询)
+     * 0----暂存
+     * 2----提交
+     */
+    @JsonProperty("Status")
+    private Integer status;
+    /**
+     * 拥有者所在部门Id
+     */
+    @JsonProperty("OwnerDeptId")
+    private String ownerDepartmentId;
+
+    @Data
+    public static class RelationObject {
+        @JsonProperty("ObjectId")
+        private String objectId;
+        @JsonProperty("Name")
+        private String name;
+    }
+}

+ 113 - 0
src/main/java/com/galaxis/manatee/entity/chuanyun/data/object/ProjectDO.java

@@ -0,0 +1,113 @@
+package com.galaxis.manatee.entity.chuanyun.data.object;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import javax.persistence.Entity;
+
+/**
+ * @author zcj
+ * @version 0.1
+ * @date 2020/2/13 4:09 下午
+ */
+@EqualsAndHashCode(callSuper = true)
+@Data
+@Entity(name = "CHUANYUN_PROJECT")
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class ProjectDO extends BasicDO {
+
+    /**
+     * 表名
+     */
+    public static final String SCHEMA_CODE ="ldx1vawvx19gf8iqxxkusjy05";
+    /**
+     * 项目编号
+     */
+    @JsonProperty(value = "F0000002")
+    private String projectCode;
+    /**
+     * 项目名称
+     */
+    @JsonProperty(value = "F0000001")
+    private String projectName;
+//    @JsonProperty(value = "Name")
+//    private String F0000007;
+//    @JsonProperty(value = "Name")
+//    private String F0000025 = null;
+//    @JsonProperty(value = "Name")
+//    private String F0000026 = null;
+//
+//    @JsonProperty(value = "Name")
+//    private String F0000027 = null;
+//    @JsonProperty(value = "Name")
+//    private String F0000019;
+//    @JsonProperty(value = "Name")
+//    private String F0000015;
+//    @JsonProperty(value = "Name")
+//    private String F0000021;
+//    @JsonProperty(value = "Name")
+//    private String F0000016;
+//    @JsonProperty(value = "Name")
+//    private String F0000028 = null;
+//    @JsonProperty(value = "Name")
+//    private String F0000029 = null;
+//    @JsonProperty(value = "Name")
+//    private String F0000030 = null;
+//    @JsonProperty(value = "Name")
+//    private String F0000005;
+//    @JsonProperty(value = "Name")
+//    private String F0000031;
+//    @JsonProperty(value = "Name")
+//    private String F0000010;
+//    @JsonProperty(value = "Name")
+//    private String F0000022;
+//    @JsonProperty(value = "Name")
+//    private String F0000024;
+//    @JsonProperty(value = "Name")
+//    private String F0000033;
+//    @JsonProperty(value = "Name")
+//    private String F0000032;
+//    @JsonProperty(value = "Name")
+//    private String F0000034 = null;
+//    @JsonProperty(value = "Name")
+//    private String F0000035 = null;
+//    @JsonProperty(value = "Name")
+//    private String F0000036 = null;
+//    @JsonProperty(value = "Name")
+//    private String F0000037 = null;
+//    @JsonProperty(value = "Name")
+//    private String F0000038 = null;
+//    private String F0000039 = null;
+//    @JsonProperty(value = "Name")
+//    private String F0000040 = null;
+//    @JsonProperty(value = "Name")
+//    private String F0000041 = null;
+//    @JsonProperty(value = "Name")
+//    private String F0000042 = null;
+//    @JsonProperty(value = "Name")
+//    private String F0000043 = null;
+//    @JsonProperty(value = "Name")
+//    private String F0000044 = null;
+//    @JsonProperty(value = "Name")
+//    private String OwnerDeptId;
+//    @JsonProperty(value = "Name")
+//    private String F0000023;
+//    @JsonProperty(value = "Name")
+//    private String F0000011;
+//    @JsonProperty(value = "Name")
+//    private String F0000018;
+//    @JsonProperty(value = "Name")
+//    private String F0000004;
+//    @JsonProperty(value = "Name")
+//    InformationObject CreatedByObjectObject;
+//    @JsonProperty(value = "Name")
+//    InformationObject ModifiedByObjectObject;
+//    @JsonProperty(value = "Name")
+//    InformationObject OwnerIdObjectObject;
+//    @JsonProperty(value = "Name")
+//    InformationObject F0000010ObjectObject;
+//    @JsonProperty(value = "Name")
+//    InformationObject OwnerDeptIdObjectObject;
+}

+ 170 - 0
src/main/java/com/galaxis/manatee/entity/chuanyun/data/object/ProjectLogDO.java

@@ -0,0 +1,170 @@
+package com.galaxis.manatee.entity.chuanyun.data.object;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import javax.persistence.Entity;
+import javax.persistence.Transient;
+import java.time.LocalDateTime;
+import java.util.List;
+
+/**
+ * @author zcj
+ * @version 0.1
+ */
+@EqualsAndHashCode(callSuper = true)
+@Entity(name = "CHUANYUN_PROJECT_LOG")
+@Data
+public class ProjectLogDO extends BasicDO {
+
+    /**
+     * 表单编码
+     */
+    public static final String SCHEMA_CODE ="mgo6ka70vm0m8yau0qvaj6h93";
+
+    /**
+     * 人员类型,关联人员类型表单
+     */
+    @JsonProperty("F0000016")
+    private String colleagueRole;
+    /**
+     * 日志日期
+     */
+    @DateTimeFormat(pattern = "yyyy/MM/dd HH:mm:ss")
+    @JsonProperty("F0000004")
+    private LocalDateTime logDate;
+    /**
+     * 项目1的Id
+     */
+    @JsonProperty("F0000005")
+    private String projectOneId;
+    /**
+     * 项目1工时
+     */
+    @JsonProperty("F0000010")
+    private Integer projectOneWorkHours;
+    /**
+     * 项目负责人
+     */
+    @JsonProperty("F0000027")
+    private String projectOnePersonInCharge;
+    /**
+     * 项目1状态
+     */
+    @JsonProperty("F0000023")
+    private String projectOneStatus;
+    /**
+     * 项目1当天日志内容
+     */
+    @JsonProperty("F0000008")
+    private String projectOneLogContent;
+    /**
+     * 项目2
+     */
+    @JsonProperty("F0000020")
+    private String projectTwo;
+    /**
+     * 项目2工时
+     */
+    @JsonProperty("F0000021")
+    private String projectTwoWorkHour;
+    /**
+     * 项目2状态
+     */
+    @JsonProperty("F0000024")
+    private String projectTwoStatus;
+    /**
+     * 项目2当天日志内容
+     */
+    @JsonProperty("F0000022")
+    private String projectTwoLogContent;
+    /**
+     * 抄送人员列表
+     */
+    @JsonProperty("F0000019")
+    @Transient
+    private List<String> carbonCopyList;
+    /**
+     * 现场照片列表
+     */
+    @JsonProperty("F0000018")
+    @Transient
+    private List<String> pictureList;
+    /**
+     * 明日计划
+     */
+    @JsonProperty("F0000007")
+    private String tomorrowPlan;
+    /**
+     * 明日需要协调的资源
+     */
+    @JsonProperty("F0000017")
+    private String tomorrowAssociation;
+    /**
+     * 明日安全隐患
+     */
+    @JsonProperty("F0000011")
+    private String tomorrowSafetyHazard;
+    /**
+     * 明日电气工程师人数
+     */
+    @JsonProperty("F0000012")
+    private Integer electricalEngineerAmount;
+    /**
+     * 明日软件工程师人数
+     */
+    @JsonProperty("F0000013")
+    private Integer softwareEngineerAmount;
+    /**
+     * 明日设备工程师人数
+     */
+    @JsonProperty("F0000014")
+    private Integer equipmentEngineerAmount;
+    /**
+     * 外包人员数量
+     */
+    @JsonProperty("F0000015")
+    private String outsourceAmount;
+    /**
+     * 拥有者姓名
+     */
+    @JsonProperty("OwnerId")
+    private String ownerId;
+    /**
+     * 创建人姓名
+     */
+    @JsonProperty("CreatedBy")
+    private String createdBy;
+    /**
+     * 拥有者所在部门
+     */
+    @JsonProperty("OwnerDeptIdObject")
+    @Transient
+    private RelationObject ownerDepartmentIdObject;
+    /**
+     * 项目1负责人对象
+     */
+    @JsonProperty("F0000027Object")
+    @Transient
+    private RelationObject projectOnePersonInChargeObject;
+    /**
+     * 抄送人员对象列表
+     */
+    @JsonProperty("F0000019Object")
+    @Transient
+    private List<RelationObject> carbonCopyObjectList;
+    /**
+     * 拥有者对象
+     */
+    @JsonProperty("OwnerIdObject")
+    @Transient
+    private RelationObject ownerIdObject;
+    /**
+     * 创建人对象
+     */
+    @JsonProperty("CreatedByObject")
+    @Transient
+    private RelationObject createdByObject;
+}

+ 61 - 0
src/main/java/com/galaxis/manatee/entity/ding/DingTalkProcessInstance.java

@@ -0,0 +1,61 @@
+package com.galaxis.manatee.entity.ding;
+
+import com.dingtalk.api.response.OapiProcessinstanceGetResponse;
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.vladmihalcea.hibernate.type.json.JsonStringType;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import org.hibernate.annotations.Type;
+import org.hibernate.annotations.TypeDef;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+
+/**
+ * @author zcj
+ * @version 0.1
+ * @date 2020/1/9 11:28 上午
+ */
+@JsonIgnoreProperties(ignoreUnknown = true)
+@EqualsAndHashCode(callSuper = true)
+@Data
+@Entity
+@TypeDef(name = "json", typeClass = JsonStringType.class)
+public class DingTalkProcessInstance extends DingTalkResponse {
+
+    /**
+     * 审批流程实例Id
+     */
+    @Id
+    @Column(length = 40)
+    private String id;
+
+    /**
+     * 审批流程Id
+     */
+    @Column(length = 40)
+    private String processInstanceId;
+
+    /**
+     * 是否和氚云同步
+     */
+    @Column
+    private Boolean updatedInChuanyun = false;
+
+    public DingTalkProcessInstance() {
+        super();
+    }
+
+    public DingTalkProcessInstance(String id, String processInstanceId) {
+        super();
+        this.id = id;
+        this.processInstanceId = processInstanceId;
+    }
+
+    @Type(type = "json")
+    @Column(columnDefinition = "json")
+    @JsonProperty(value = "process_instance")
+    private OapiProcessinstanceGetResponse.ProcessInstanceTopVo processInstance;
+}

+ 29 - 0
src/main/java/com/galaxis/manatee/entity/ding/DingTalkResponse.java

@@ -0,0 +1,29 @@
+package com.galaxis.manatee.entity.ding;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+
+/**
+ * @author zcj
+ * @version 0.1
+ * @date 2020/1/9 11:39 上午
+ */
+@Data
+public class DingTalkResponse {
+
+    /**
+     * 错误消息
+     */
+    @JsonProperty(value = "errmsg")
+    protected String errorMessage;
+
+    /**
+     * 错误码
+     */
+    @JsonProperty(value = "errcode")
+    protected String errorCode;
+
+    public DingTalkResponse() {
+    }
+}

+ 57 - 0
src/main/java/com/galaxis/manatee/entity/ding/DingTalkRobot.java

@@ -0,0 +1,57 @@
+package com.galaxis.manatee.entity.ding;
+
+import lombok.Data;
+import org.hibernate.annotations.GenericGenerator;
+
+import javax.persistence.*;
+
+/**
+ * @author zcj
+ * @version 0.1
+ * @date 2020/1/8 10:43 下午
+ */
+@Data
+@Entity
+public class DingTalkRobot {
+    @Id
+    @GeneratedValue(generator = "idGeneratorBasicTrade")
+    @GenericGenerator(name ="idGeneratorBasicTrade" ,strategy="com.galaxis.manatee.util.impl.GalaxisIdGenerator")
+    private Long id;
+
+    /**
+     * 机器人名称
+     */
+    @Column(unique = true)
+    private String name;
+
+    /**
+     * 调用钉钉机器人的url
+     */
+    private String url;
+
+    /**
+     * 加密方式
+     */
+    @Enumerated(EnumType.STRING)
+    private EncryptionMethod encryptionMethod;
+
+    public enum EncryptionMethod {
+        /**
+         * 关键字加密
+         */
+        KEY_WORD,
+        /**
+         * 密钥签名加密
+         */
+        SECRET,
+        /**
+         * ip白名单
+         */
+        IP
+    }
+
+    /**
+     * 加密内容
+     */
+    private String encryption;
+}

+ 192 - 0
src/main/java/com/galaxis/manatee/entity/ding/DingTalkRobotRequest.java

@@ -0,0 +1,192 @@
+package com.galaxis.manatee.entity.ding;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.Getter;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author zcj
+ * @version 0.1
+ * @date 2020/1/9 9:01 上午
+ */
+@Data
+@AllArgsConstructor
+public class DingTalkRobotRequest {
+
+    @JsonProperty(value = "msgtype")
+    private String messageType;
+
+    @JsonProperty(value = "at")
+    private At at;
+
+    /**
+     * 创建请求
+     * @param params        参数信息
+     *                      text类型请求参数:1.content
+     *                      link类型请求参数: 1.text   2.title    3.messageUrl   4.picUrl
+     * @param messageType   请求机器人类型
+     * @param at            需要@的人
+     * @return      请求对象
+     */
+    public static DingTalkRobotRequest instanceOf(Map<String,String> params, MessageType messageType, At at){
+
+        return switch (messageType){
+            case LINK -> new LinkRequest(params, messageType, at);
+            default -> new TextRequest(params,messageType,at);
+        };
+    }
+
+    /**
+     * 需要被@的手机号
+     */
+    @Data
+    @AllArgsConstructor
+    public static class At{
+        /**
+         * 需要被@的手机号列表
+         */
+        private List<String> atMobiles;
+
+        /**
+         * 是否@所有人
+         */
+        private boolean isAtAll;
+
+        /**
+         * 获取实例方法
+         * @param atMobiles 需要@的人员列表
+         * @param isAtAll   是否@所有人
+         * @return  需要@的实例
+         */
+        public static At instance(List<String> atMobiles, Boolean isAtAll){
+            return new At(atMobiles,isAtAll);
+        }
+    }
+
+    /**
+     * 消息类型
+     */
+    @AllArgsConstructor
+    @Getter
+    public enum MessageType{
+        /**
+         * 文本类型
+         */
+        TEXT("text"),
+        /**
+         * 链接类型
+         */
+        LINK("link"),
+        /**
+         * markDown类型
+         */
+        MARK_DOWN("markdown"),
+        /**
+         * 跳转卡
+         */
+        ACTION_CARD("actionCard"),
+        /**
+         * 信息组卡
+         */
+        FEED_CARD("feedCard");
+
+        private String value;
+
+    }
+}
+
+/**
+ * Text内容
+ */
+@Data
+@AllArgsConstructor
+class Text{
+    /**
+     * 需要让机器人发布的内容
+     */
+    private String content;
+}
+
+/**
+ * link内容
+ */
+@Data
+@AllArgsConstructor
+class Link{
+    /**
+     * 消息内容。如果太长只会部分展示
+     */
+    private String text;
+
+    /**
+     * 消息标题
+     */
+    private String title;
+
+    /**
+     * 点击消息跳转的URL
+     */
+    private String messageUrl;
+
+    /**
+     * 图片URL
+     */
+    private String picUrl;
+}
+
+/**
+ * markdown内容
+ */
+class MarkDown{
+
+}
+
+/**
+ * actionCard内容
+ */
+class ActionCard{
+
+}
+
+/**
+ * feedCard内容
+ */
+class FeedCard{
+
+}
+
+/**
+ * text请求体
+ */
+@EqualsAndHashCode(callSuper = true)
+@Data
+class TextRequest extends DingTalkRobotRequest{
+    /**
+     * text消息
+     */
+    private Text text;
+
+    public TextRequest(Map<String,String> params,MessageType messageType,At at) {
+        super(messageType.getValue(),at);
+        this.text = new Text(params.get("content"));
+    }
+}
+
+@EqualsAndHashCode(callSuper = true)
+@Data
+class LinkRequest extends DingTalkRobotRequest{
+    /**
+     * 链接数据对象
+     */
+    private Link link;
+
+    public LinkRequest(Map<String,String> params,MessageType messageType, At at) {
+        super(messageType.getValue(), at);
+        this.link = new Link(params.get("text"),params.get("title"),params.get("messageUrl"),params.get("picUrl"));
+    }
+}

+ 12 - 0
src/main/java/com/galaxis/manatee/entity/ding/DingTalkRobotResponse.java

@@ -0,0 +1,12 @@
+package com.galaxis.manatee.entity.ding;
+
+import lombok.Data;
+
+/**
+ * @author zcj
+ * @version 0.1
+ * @date 2020/1/9 8:57 上午
+ */
+@Data
+public class DingTalkRobotResponse extends DingTalkResponse{
+}

+ 12 - 0
src/main/java/com/galaxis/manatee/entity/ding/bo/MaterialResendBO.java

@@ -0,0 +1,12 @@
+package com.galaxis.manatee.entity.ding.bo;
+
+import lombok.Data;
+
+/**
+ * @author zcj
+ * @version 0.1
+ * @date 2020/2/14 9:29 上午
+ */
+@Data
+public class MaterialResendBO {
+}

+ 54 - 0
src/main/java/com/galaxis/manatee/manager/ChuanYunManager.java

@@ -0,0 +1,54 @@
+package com.galaxis.manatee.manager;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.galaxis.manatee.entity.chuanyun.*;
+
+import java.util.List;
+
+/**
+ * @author zcj
+ * @version 0.1
+ * @date 2020/1/9 11:57 下午
+ */
+public interface ChuanYunManager {
+
+    /**
+     * 查询单条数据
+     *
+     * @param schemaCode  表单编码
+     * @param bizObjectId 数据Id
+     * @param <T>         查询数据类型
+     * @return 单条数据返回结果
+     */
+    <T> ChuanyunFindResponse<T> find(String schemaCode, String bizObjectId);
+
+    /**
+     * 根据filter批量查询
+     *
+     * @param schemaCode 表单编码
+     * @param filter     查询条件
+     * @param <T>        查询数据类型
+     * @throws JsonProcessingException 抛出异常
+     * @return 批量返回结果
+     */
+    <T> ChuanyunFindAllResponse<T> findAll(String schemaCode, Filter filter) throws JsonProcessingException;
+
+    /**
+     * 保存
+     *
+     * @param isSubmit   是否为提交状态
+     * @param schemaCode 表单编码
+     * @param bizObject  数据字符串
+     * @return 保存结果
+     */
+    ChuanyunSaveResponse save(String schemaCode, String bizObject, Boolean isSubmit);
+
+    /**
+     * 批量保存
+     * @param isSubmit       是否直接提交
+     * @param schemaCode     表单编码
+     * @param bizObjectArray 数据字符串
+     * @return 保存结果
+     */
+    ChuanyunSaveAllResponse saveAll(String schemaCode, List<String> bizObjectArray, Boolean isSubmit);
+}

+ 23 - 0
src/main/java/com/galaxis/manatee/manager/DingTalkRobotWebHook.java

@@ -0,0 +1,23 @@
+package com.galaxis.manatee.manager;
+
+import com.galaxis.manatee.entity.ding.DingTalkRobot;
+import com.galaxis.manatee.entity.ding.DingTalkRobotRequest;
+import com.galaxis.manatee.entity.ding.DingTalkRobotResponse;
+
+/**
+ * @author zcj
+ * @version 0.1
+ * @date 2020/1/9 8:54 上午
+ */
+public interface DingTalkRobotWebHook {
+
+    /**
+     * 调用机器人
+     *
+     * @param dingTalkRobotRequest 请求体
+     * @param dingTalkRobot        需要调用的机器人
+     * @return 请求结果
+     * @throws Exception 接口调用异常
+     */
+    DingTalkRobotResponse invoke(DingTalkRobotRequest dingTalkRobotRequest, DingTalkRobot dingTalkRobot) throws Exception;
+}

+ 145 - 0
src/main/java/com/galaxis/manatee/manager/impl/DefaultChuanyunManagerImpl.java

@@ -0,0 +1,145 @@
+package com.galaxis.manatee.manager.impl;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.galaxis.manatee.constant.ChuanYunConstant;
+import com.galaxis.manatee.entity.chuanyun.*;
+import com.galaxis.manatee.manager.ChuanYunManager;
+import lombok.Data;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.http.HttpEntity;
+import org.springframework.http.HttpHeaders;
+import org.springframework.stereotype.Service;
+import org.springframework.web.client.RestTemplate;
+
+import java.util.List;
+
+/**
+ * @author zcj
+ * @version 0.1
+ * @date 2020/2/5 4:02 下午
+ */
+@Slf4j
+@Service
+public class DefaultChuanyunManagerImpl implements ChuanYunManager {
+
+    private ObjectMapper objectMapper;
+
+    public DefaultChuanyunManagerImpl(ObjectMapper objectMapper) {
+        this.objectMapper = objectMapper;
+    }
+
+    @Override
+    public <T> ChuanyunFindResponse<T> find(String schemaCode, String bizObjectId) {
+        @Data
+        class Find{
+            @JsonProperty(value = "ActionName")
+            private String actionName="LoadBizObject";
+            @JsonProperty(value = "SchemaCode")
+            private String schemaCode;
+            @JsonProperty(value = "BizObjectId")
+            private String bizObjectId;
+        }
+        //构建请求体
+        Find find=new Find();
+        find.setSchemaCode(schemaCode);
+        find.setBizObjectId(bizObjectId);
+        //请求客户端
+        RestTemplate restTemplate=new RestTemplate();
+        HttpHeaders httpHeaders=new HttpHeaders();
+        httpHeaders.add("EngineCode",ChuanYunConstant.ENGINE_CODE);
+        httpHeaders.add("EngineSecret",ChuanYunConstant.ENGINE_SECRET);
+        HttpEntity<Find> httpEntity=new HttpEntity<>(find,httpHeaders);
+        ChuanyunFindResponse<T> chuanyunFindResponse =new ChuanyunFindResponse<>();
+        return restTemplate.postForObject(ChuanYunConstant.CHUAN_YUN_INVOKE_URL,httpEntity, chuanyunFindResponse.getClass());
+    }
+
+    @Override
+    public <T> ChuanyunFindAllResponse<T> findAll(String schemaCode, Filter filter) throws JsonProcessingException {
+        @Data
+        class FindList{
+            @JsonProperty(value = "ActionName")
+            private String actionName="LoadBizObjects";
+            @JsonProperty(value = "SchemaCode")
+            private String schemaCode;
+            @JsonProperty(value = "Filter")
+            private String filter;
+
+            public FindList(String schemaCode, String filter) {
+                this.schemaCode = schemaCode;
+                this.filter = filter;
+            }
+        }
+        //构建请求体
+        FindList findList=new FindList(schemaCode,objectMapper.writeValueAsString(filter));
+        //请求客户端
+        RestTemplate restTemplate=new RestTemplate();
+        HttpHeaders httpHeaders=new HttpHeaders();
+        httpHeaders.add("EngineCode",ChuanYunConstant.ENGINE_CODE);
+        httpHeaders.add("EngineSecret",ChuanYunConstant.ENGINE_SECRET);
+        HttpEntity<FindList> httpEntity=new HttpEntity<>(findList,httpHeaders);
+        ChuanyunFindAllResponse<T> chuanyunFindAllResponse =new ChuanyunFindAllResponse<>();
+        return restTemplate.postForObject(ChuanYunConstant.CHUAN_YUN_INVOKE_URL,httpEntity, chuanyunFindAllResponse.getClass());
+    }
+
+    @Override
+    public ChuanyunSaveResponse save(String schemaCode, String bizObject, Boolean isSubmit) {
+        @Data
+        class Save{
+            @JsonProperty(value = "ActionName")
+            private String actionName="CreateBizObject";
+            @JsonProperty(value = "SchemaCode")
+            private String schemaCode;
+            @JsonProperty(value = "BizObject")
+            private String bizObject;
+            @JsonProperty(value = "IsSubmit")
+            private Boolean isSubmit;
+
+            public Save(String schemaCode, String bizObject, Boolean isSubmit) {
+                this.schemaCode = schemaCode;
+                this.bizObject = bizObject;
+                this.isSubmit = isSubmit;
+            }
+        }
+        Save save=new Save(schemaCode,bizObject,isSubmit);
+        //请求客户端
+        RestTemplate restTemplate=new RestTemplate();
+        HttpHeaders httpHeaders=new HttpHeaders();
+        httpHeaders.add("EngineCode",ChuanYunConstant.ENGINE_CODE);
+        httpHeaders.add("EngineSecret",ChuanYunConstant.ENGINE_SECRET);
+        HttpEntity<Save> httpEntity=new HttpEntity<>(save,httpHeaders);
+        ChuanyunSaveResponse chuanyunSaveResponse =new ChuanyunSaveResponse();
+        return restTemplate.postForObject(ChuanYunConstant.CHUAN_YUN_INVOKE_URL,httpEntity, chuanyunSaveResponse.getClass());
+    }
+
+    @Override
+    public ChuanyunSaveAllResponse saveAll(String schemaCode, List<String> bizObjectArray, Boolean isSubmit) {
+        @Data
+        class SaveAll{
+            @JsonProperty(value = "ActionName")
+            private String actionName="CreateBizObjects";
+            @JsonProperty(value = "SchemaCode")
+            private String schemaCode;
+            @JsonProperty(value = "BizObjectArray")
+            private List<String> bizObjectArray;
+            @JsonProperty(value = "IsSubmit")
+            private Boolean isSubmit;
+
+            public SaveAll(String schemaCode, List<String> bizObjectArray, Boolean isSubmit) {
+                this.schemaCode = schemaCode;
+                this.bizObjectArray = bizObjectArray;
+                this.isSubmit = isSubmit;
+            }
+        }
+        SaveAll saveAll=new SaveAll(schemaCode,bizObjectArray,isSubmit);
+        //请求客户端
+        RestTemplate restTemplate=new RestTemplate();
+        HttpHeaders httpHeaders=new HttpHeaders();
+        httpHeaders.add("EngineCode",ChuanYunConstant.ENGINE_CODE);
+        httpHeaders.add("EngineSecret",ChuanYunConstant.ENGINE_SECRET);
+        HttpEntity<SaveAll> httpEntity=new HttpEntity<>(saveAll,httpHeaders);
+        ChuanyunSaveAllResponse chuanyunSaveAllResponse =new ChuanyunSaveAllResponse();
+        return restTemplate.postForObject(ChuanYunConstant.CHUAN_YUN_INVOKE_URL,httpEntity, chuanyunSaveAllResponse.getClass());
+    }
+}

+ 34 - 0
src/main/java/com/galaxis/manatee/manager/impl/DingTalkRobotWebHookImpl.java

@@ -0,0 +1,34 @@
+package com.galaxis.manatee.manager.impl;
+
+import com.galaxis.manatee.entity.ding.DingTalkRobot;
+import com.galaxis.manatee.entity.ding.DingTalkRobotRequest;
+import com.galaxis.manatee.entity.ding.DingTalkRobotResponse;
+import com.galaxis.manatee.manager.DingTalkRobotWebHook;
+import com.galaxis.manatee.util.DingTalkRobotUtils;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+import org.springframework.web.client.RestTemplate;
+
+/**
+ * @author zcj
+ * @version 0.1
+ * @date 2020/1/9 9:40 上午
+ */
+@Slf4j
+@Service
+public class DingTalkRobotWebHookImpl implements DingTalkRobotWebHook {
+    @Override
+    public DingTalkRobotResponse invoke(DingTalkRobotRequest dingTalkRobotRequest, DingTalkRobot dingTalkRobot) throws Exception {
+        RestTemplate restTemplate=new RestTemplate();
+        Long timeStamp=System.currentTimeMillis();
+        if(dingTalkRobot.getEncryptionMethod()==DingTalkRobot.EncryptionMethod.SECRET){
+            return restTemplate.postForObject(dingTalkRobot.getUrl(),dingTalkRobotRequest,DingTalkRobotResponse.class,timeStamp.toString(),DingTalkRobotUtils.sign(dingTalkRobot.getEncryption(),timeStamp));
+        }else {
+            return restTemplate.postForObject(dingTalkRobot.getUrl(),dingTalkRobotRequest,DingTalkRobotResponse.class);
+        }
+//        return switch(dingTalkRobot.getEncryptionMethod()){
+//            case SECRET-> restTemplate.postForObject(dingTalkRobot.getUrl(),dingTalkRobotRequest,DingTalkRobotResponse.class,timeStamp.toString(),DingTalkRobotUtils.sign(dingTalkRobot.getEncryption(),timeStamp));
+//            default -> restTemplate.postForObject(dingTalkRobot.getUrl(),dingTalkRobotRequest,DingTalkRobotResponse.class);
+//        };
+    }
+}

+ 147 - 0
src/main/java/com/galaxis/manatee/service/ChuanyunScheduledTask.java

@@ -0,0 +1,147 @@
+package com.galaxis.manatee.service;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.SerializationFeature;
+import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
+import com.galaxis.manatee.constant.ChuanYunConstant;
+import com.galaxis.manatee.constant.DingTalkConstant;
+import com.galaxis.manatee.dao.DingTalkProcessInstanceDao;
+import com.galaxis.manatee.dao.ProjectDao;
+import com.galaxis.manatee.entity.chuanyun.ChuanyunFindAllResponse;
+import com.galaxis.manatee.entity.chuanyun.ChuanyunSaveAllResponse;
+import com.galaxis.manatee.entity.chuanyun.Filter;
+import com.galaxis.manatee.entity.chuanyun.data.object.ProjectDO;
+import com.galaxis.manatee.entity.chuanyun.bo.MaterialResendBO;
+import com.galaxis.manatee.entity.ding.DingTalkProcessInstance;
+import com.galaxis.manatee.manager.ChuanYunManager;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.data.domain.Example;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.PageRequest;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author zcj
+ * @version 0.1
+ * @date 2020/2/13 11:53 上午
+ */
+@Service
+@Slf4j
+public class ChuanyunScheduledTask {
+
+    private ChuanYunManager chuanYunManager;
+    private ProjectDao projectDao;
+    private DingTalkProcessInstanceDao dingTalkProcessInstanceDao;
+
+    public ChuanyunScheduledTask(ChuanYunManager chuanYunManager, ProjectDao projectDao, DingTalkProcessInstanceDao dingTalkProcessInstanceDao) {
+        this.chuanYunManager = chuanYunManager;
+        this.projectDao = projectDao;
+        this.dingTalkProcessInstanceDao = dingTalkProcessInstanceDao;
+    }
+
+
+    /**
+     * 定时将氚云中的数据保存到
+     */
+    @Scheduled(fixedDelay = 300000L)
+    private void getProcessInstanceFromChuanyun(){
+        //获取项目数据
+        getProjectInformationFromChuanyun();
+    }
+
+    /**
+     * 定时将钉钉同步的审批记录同步到氚云当中
+     */
+    @Scheduled(fixedDelay = 600000L)
+    private void putProcessInstanceToChuanyun(){
+        //同步物料补发数据
+        putMaterialResendInstance();
+    }
+
+    /**
+     * 将物料补发数据同步到氚云
+     * 预计2020年4月份之后逐步将各个部门物料补发数据迁移到氚云进行审批,这个功能逐步废弃
+     */
+    private void putMaterialResendInstance(){
+        int currentPage=0;
+        int totalPage=Integer.MAX_VALUE;
+
+        ObjectMapper objectMapper=new ObjectMapper();
+        objectMapper.registerModule(new JavaTimeModule());
+        objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
+
+        while (currentPage<totalPage){
+            List<String> strings=new ArrayList<>();
+            PageRequest pageRequest=PageRequest.of(currentPage,20);
+            DingTalkProcessInstance dingTalkProcessInstance=new DingTalkProcessInstance();
+            dingTalkProcessInstance.setProcessInstanceId(DingTalkConstant.PROCESS_CODE_MATERIAL_RESEND);
+            dingTalkProcessInstance.setUpdatedInChuanyun(false);
+            Page<DingTalkProcessInstance> pageList=dingTalkProcessInstanceDao.findAll(Example.of(dingTalkProcessInstance),pageRequest);
+            if(totalPage==Integer.MAX_VALUE){
+                totalPage=pageList.getTotalPages();
+            }
+
+            pageList.getContent().forEach(content->{
+                if(content.getProcessInstance()==null){
+                    log.info("观察异常内容"+content+"");
+                }else {
+                    if (content.getProcessInstanceId().equals(DingTalkConstant.PROCESS_CODE_MATERIAL_RESEND)){
+                        MaterialResendBO materialResendBO = MaterialResendBO.fromDingTak(content.getProcessInstance());
+                        try {
+                            strings.add(objectMapper.writeValueAsString(materialResendBO));
+                        } catch (JsonProcessingException e) {
+                            log.error(e.getMessage());
+                        }
+                    }
+                }
+            });
+            ChuanyunSaveAllResponse chuanyunSaveAllResponse= chuanYunManager.saveAll(MaterialResendBO.SCHEMA_CODE,strings,true);
+            log.info("氚云保存物料补发数据结果的错误信息为 "+chuanyunSaveAllResponse.getErrorMessage());
+            log.info(chuanyunSaveAllResponse+"");
+            pageList.getContent().forEach(content->content.setUpdatedInChuanyun(true));
+            log.info("开始更新钉钉审批数据上传状态");
+            log.info(dingTalkProcessInstanceDao.saveAll(pageList.getContent())+"");
+            log.info("已更新上传状态的钉钉审批数据");
+            currentPage++;
+        }
+    }
+
+    /**
+     * 定时更新项目信息
+     */
+    private void getProjectInformationFromChuanyun(){
+        int start=0;
+        long totalCount=0;
+        boolean flag=true;
+        while (flag){
+            try {
+                //从氚云查询数据
+                Filter filter=Filter.instance(start,start+20,true);
+                ChuanyunFindAllResponse<ProjectDO> chuanyunFindAllResponse=chuanYunManager.findAll(ProjectDO.SCHEMA_CODE,filter);
+                if(chuanyunFindAllResponse.getReturnData().getTotalCount()>=start+20){
+                    start+=20;
+                }else{
+                    flag=false;
+                }
+                //转化为POJO
+                ObjectMapper objectMapper=new ObjectMapper();
+                List<ProjectDO> result=objectMapper.convertValue(chuanyunFindAllResponse.getReturnData().getBizObjectArray(), new TypeReference<>(){});
+                //更新缓存中的项目映射表
+                result.forEach(projectBO -> ChuanYunConstant.PROJECT_CODE.put(projectBO.getProjectCode(),projectBO.getObjectId()));
+                totalCount=chuanyunFindAllResponse.getReturnData().getTotalCount();
+                //保存
+                projectDao.saveAll(result);
+            }catch (Exception e){
+                log.error(e.getMessage());
+            }
+        }
+        log.info("项目信息保存保存"+totalCount+"项目映射更新完成");
+    }
+
+}

+ 61 - 0
src/main/java/com/galaxis/manatee/service/DingTalkAuthorization.java

@@ -0,0 +1,61 @@
+package com.galaxis.manatee.service;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.galaxis.manatee.constant.DingTalkConstant;
+import lombok.Data;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Service;
+import org.springframework.web.client.RestTemplate;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.time.LocalDateTime;
+
+/**
+ * @author zcj
+ * @version 0.1
+ * @date 2020/1/8 5:42 下午
+ */
+@Slf4j
+@Service
+public class DingTalkAuthorization {
+
+    @Value(value = "${dingTalk.getTokenUri}")
+    private String getTokenUri;
+
+    /**
+     * 自动获取钉钉授权
+     * @throws URISyntaxException   URI异常
+     */
+    @Scheduled(fixedDelay = 7000000L)
+    private void getToken() throws URISyntaxException {
+        RestTemplate restTemplate=new RestTemplate();
+        URI uri=new URI(getTokenUri+"?appkey="+ DingTalkConstant.DING_TALK_APP_KEY +"&appsecret="+DingTalkConstant.DING_TALK_APP_SECRET);
+        DingTalkToken dingTalkToken=restTemplate.getForObject(uri,DingTalkToken.class);
+        DingTalkConstant.DING_TALK_TOKEN =dingTalkToken.getAccessToken();
+        log.info("获得token"+ LocalDateTime.now());
+    }
+
+    /**
+     * 钉钉token数据结构
+     */
+    @Data
+    @JsonIgnoreProperties(ignoreUnknown = true)
+    private static class DingTalkToken{
+
+        @JsonProperty(value = "errcode")
+        private String errorCode;
+
+        @JsonProperty(value = "access_token")
+        private String accessToken;
+
+        @JsonProperty(value = "errmsg")
+        private String errorMessage;
+
+        @JsonProperty(value = "expired_in")
+        private Integer expiredIn;
+    }
+}

+ 11 - 0
src/main/java/com/galaxis/manatee/service/DingTalkRobotService.java

@@ -0,0 +1,11 @@
+package com.galaxis.manatee.service;
+
+/**
+ * 钉钉机器人调用方法
+ * @author zcj
+ * @version 0.1
+ * @date 2020/1/8 10:40 下午
+ */
+public interface DingTalkRobotService {
+
+}

+ 125 - 0
src/main/java/com/galaxis/manatee/service/DingTalkScheduledTask.java

@@ -0,0 +1,125 @@
+package com.galaxis.manatee.service;
+
+import com.dingtalk.api.DingTalkClient;
+import com.dingtalk.api.request.OapiProcessinstanceGetRequest;
+import com.dingtalk.api.request.OapiProcessinstanceListidsRequest;
+import com.dingtalk.api.response.OapiProcessinstanceGetResponse;
+import com.dingtalk.api.response.OapiProcessinstanceListidsResponse;
+import com.galaxis.manatee.constant.DingTalkConstant;
+import com.galaxis.manatee.dao.DingTalkProcessInstanceDao;
+import com.galaxis.manatee.entity.ding.DingTalkProcessInstance;
+import com.taobao.api.ApiException;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Service;
+
+import java.time.LocalDateTime;
+import java.time.ZoneOffset;
+import java.time.temporal.ChronoUnit;
+import java.util.*;
+
+/**
+ * 钉钉定时任务
+ * @author zcj
+ * @version 0.1
+ * @date 2020/1/10 2:28 下午
+ */
+@Slf4j
+@Service
+public class DingTalkScheduledTask {
+
+    /**
+     * 审批Id列表客户端
+     */
+    private DingTalkClient processInstanceListIdsClient;
+
+    /**
+     * 审批实例客户端
+     */
+    private DingTalkClient processInstanceClient;
+
+    /**
+     * 钉钉审批实例保存方法
+     */
+    private DingTalkProcessInstanceDao dingTalkProcessInstanceDao;
+
+    public DingTalkScheduledTask(DingTalkClient processInstanceListIdsClient, DingTalkClient processInstanceClient, DingTalkProcessInstanceDao dingTalkProcessInstanceDao) {
+        this.processInstanceListIdsClient = processInstanceListIdsClient;
+        this.processInstanceClient = processInstanceClient;
+        this.dingTalkProcessInstanceDao = dingTalkProcessInstanceDao;
+    }
+
+    /**
+     * 每小时更新
+     */
+    @Scheduled(fixedDelay = 3600000L)
+    private void updateBusinessTripProcessInstance(){
+    }
+
+    /**
+     * 每个小时定期更新出差申请数据
+     */
+    @Scheduled(fixedDelay = 3600000L)
+    void updateBusinessTripProcessInstanceIdList() throws ApiException {
+        updateProcessInstanceIdList(DingTalkConstant.PROCESS_CODE_BUSINESS_TRIP);
+    }
+
+    /**
+     * 每小时根据出差申请Id跟新出差申请信息。
+     */
+    @Scheduled(fixedDelay = 3600000L)
+    void updateProcessInstanceList() throws ApiException {
+        updateProcessInstanceIdList(DingTalkConstant.PROCESS_CODE_MATERIAL_RESEND);
+    }
+
+    private void updateProcessInstanceIdList(String businessTripProcessCode) throws ApiException {
+        boolean flag=true;
+        //单个请求
+        OapiProcessinstanceListidsRequest oapiProcessinstanceListidsRequest=new OapiProcessinstanceListidsRequest();
+        oapiProcessinstanceListidsRequest.setProcessCode(businessTripProcessCode);
+        oapiProcessinstanceListidsRequest.setStartTime(LocalDateTime.of(2019,1,1,0,0).toInstant(ZoneOffset.UTC).toEpochMilli());
+        oapiProcessinstanceListidsRequest.setEndTime(LocalDateTime.now().toInstant(ZoneOffset.UTC).toEpochMilli());
+        oapiProcessinstanceListidsRequest.setCursor(0L);
+        oapiProcessinstanceListidsRequest.setSize(20L);
+        while(flag){
+            LocalDateTime start=LocalDateTime.now();
+            OapiProcessinstanceListidsResponse oapiProcessinstanceListidsResponse=processInstanceListIdsClient.execute(oapiProcessinstanceListidsRequest,DingTalkConstant.DING_TALK_TOKEN);
+            List<DingTalkProcessInstance> dingTalkProcessInstanceList=new ArrayList<>();
+            if(oapiProcessinstanceListidsResponse.getErrcode()!=0){
+                log.info(oapiProcessinstanceListidsResponse.getErrmsg());
+                try {
+                    Thread.sleep(5000);
+                } catch (InterruptedException e) {
+                    log.error(e.getMessage());
+                }
+                continue;
+            }
+            //逐个请求
+            oapiProcessinstanceListidsResponse.getResult().getList().forEach(resultId->{
+                Optional<DingTalkProcessInstance> instance=dingTalkProcessInstanceDao.findById(resultId);
+                if(!instance.isEmpty()&&instance.get()==null){
+                    //淘宝SDK方法
+                    OapiProcessinstanceGetRequest request=new OapiProcessinstanceGetRequest();
+                    request.setProcessInstanceId(resultId);
+                    DingTalkProcessInstance dingTalkProcessInstance=new DingTalkProcessInstance(resultId,businessTripProcessCode);
+                    try {
+                        OapiProcessinstanceGetResponse oapiProcessinstanceGetResponse = processInstanceClient.execute(request, DingTalkConstant.DING_TALK_TOKEN);
+                        dingTalkProcessInstance.setProcessInstance(oapiProcessinstanceGetResponse.getProcessInstance());
+                    } catch (ApiException e) {
+                        e.printStackTrace();
+                    }
+                    //淘宝SDK方法结束
+                    dingTalkProcessInstanceList.add(dingTalkProcessInstance);
+                }
+            });
+
+            //保存id列表和实例列表
+            dingTalkProcessInstanceDao.saveAll(dingTalkProcessInstanceList);
+            log.info(businessTripProcessCode+"下一个cursor为"+oapiProcessinstanceListidsResponse.getResult().getNextCursor()+"保存成功"+"耗时"+ ChronoUnit.SECONDS.between(start,LocalDateTime.now())+"秒");
+            flag=null!=oapiProcessinstanceListidsResponse.getResult().getNextCursor();
+            if (flag){
+                oapiProcessinstanceListidsRequest.setCursor(oapiProcessinstanceListidsResponse.getResult().getNextCursor());
+            }
+        }
+    }
+}

+ 10 - 0
src/main/java/com/galaxis/manatee/service/ProcessService.java

@@ -0,0 +1,10 @@
+package com.galaxis.manatee.service;
+
+/**
+ * 钉钉审批流接口
+ * @author zcj
+ * @version 0.1
+ * @date 2020/1/8 6:06 下午
+ */
+public interface ProcessService {
+}

+ 18 - 0
src/main/java/com/galaxis/manatee/util/ChuanyunLocalDateTimeDeserializer.java

@@ -0,0 +1,18 @@
+package com.galaxis.manatee.util;
+
+import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
+
+import java.time.format.DateTimeFormatter;
+
+/**
+ * 氚云日期反序列化类
+ * @author zcj
+ * @version 0.1
+ * @date 2020/2/13 5:37 下午
+ */
+public class ChuanyunLocalDateTimeDeserializer extends LocalDateTimeDeserializer{
+
+    public ChuanyunLocalDateTimeDeserializer(){
+        super(DateTimeFormatter.ofPattern("yyyy/M/d H:m:s"));
+    }
+}

+ 18 - 0
src/main/java/com/galaxis/manatee/util/ChuanyunLocalDateTimeSerializer.java

@@ -0,0 +1,18 @@
+package com.galaxis.manatee.util;
+
+import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
+
+import java.time.format.DateTimeFormatter;
+
+/**
+ * 氚云日期序列化类
+ * @author zcj
+ * @version 0.1
+ * @date 2020/2/14 9:00 上午
+ */
+public class ChuanyunLocalDateTimeSerializer extends LocalDateTimeSerializer {
+
+    public ChuanyunLocalDateTimeSerializer() {
+        super(DateTimeFormatter.ofPattern("yyyy/M/d H:m:s"));
+    }
+}

+ 36 - 0
src/main/java/com/galaxis/manatee/util/DingTalkRobotUtils.java

@@ -0,0 +1,36 @@
+package com.galaxis.manatee.util;
+
+import org.apache.tomcat.util.codec.binary.Base64;
+
+import javax.crypto.Mac;
+import javax.crypto.spec.SecretKeySpec;
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
+import java.nio.charset.StandardCharsets;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+
+/**
+ * @author zcj
+ * @version 0.1
+ * @date 2020/1/8 10:36 下午
+ */
+public class DingTalkRobotUtils {
+
+    /**
+     * 给url签名的工具方法
+     * @param secret        对应机器人的签名密钥
+     * @param timestamp     时间戳
+     * @return  完成签名的
+     * @throws NoSuchAlgorithmException     算法名不对的异常
+     * @throws UnsupportedEncodingException 不支持的编码
+     * @throws InvalidKeyException          非法的关键字
+     */
+    public static String sign(String secret,Long timestamp) throws NoSuchAlgorithmException, UnsupportedEncodingException, InvalidKeyException {
+        String stringToSign = timestamp + "\n" + secret;
+        Mac mac = Mac.getInstance("HmacSHA256");
+        mac.init(new SecretKeySpec(secret.getBytes(StandardCharsets.UTF_8), "HmacSHA256"));
+        byte[] signData = mac.doFinal(stringToSign.getBytes(StandardCharsets.UTF_8));
+        return URLEncoder.encode(new String(Base64.encodeBase64(signData)),StandardCharsets.UTF_8);
+    }
+}

+ 15 - 0
src/main/java/com/galaxis/manatee/util/IdGenerate.java

@@ -0,0 +1,15 @@
+package com.galaxis.manatee.util;
+
+/**
+ * @author zcj
+ * @version 0.1
+ * @date 2020/1/8 11:39 下午
+ */
+public interface IdGenerate<T> {
+
+    /**
+     * 下一个id
+     * @return 下一个id
+     */
+    T nextId();
+}

+ 48 - 0
src/main/java/com/galaxis/manatee/util/impl/GalaxisIdGenerator.java

@@ -0,0 +1,48 @@
+package com.galaxis.manatee.util.impl;
+
+import org.hibernate.HibernateException;
+import org.hibernate.MappingException;
+import org.hibernate.engine.spi.SessionImplementor;
+import org.hibernate.engine.spi.SharedSessionContractImplementor;
+import org.hibernate.id.Configurable;
+import org.hibernate.id.IdentifierGenerator;
+import org.hibernate.service.ServiceRegistry;
+import org.hibernate.type.Type;
+
+import java.io.Serializable;
+import java.net.InetAddress;
+import java.util.Properties;
+
+/**
+ * @author zcj
+ * @version 0.1
+ * @date 2020/1/8 11:53 下午
+ */
+public class GalaxisIdGenerator implements Configurable, IdentifierGenerator {
+    /** 数据中心ID(0~31) */
+    private long dataCenterId = 0L;
+
+    @Override
+    public void configure(Type type, Properties params, ServiceRegistry serviceRegistry) throws MappingException {
+        try {
+            InetAddress addr = InetAddress.getLocalHost();
+            String[] a=addr.getHostName().split("-");
+            dataCenterId =Long.parseLong(a[a.length-1]);
+        }
+        catch (Exception e){
+            //10位长度最大值1023,这里简单写为1000,相信不会用到
+            dataCenterId =1000L;
+        }
+    }
+
+    public Serializable generate(SessionImplementor session, Object o) throws HibernateException {
+        SnowflakeIdGenerator snowflakeIdWorker = SnowflakeIdGenerator.getSnowflakeIdGenerator(this.dataCenterId);
+        return snowflakeIdWorker.nextId();
+    }
+
+    @Override
+    public Serializable generate(SharedSessionContractImplementor sharedSessionContractImplementor, Object o) throws HibernateException {
+        SnowflakeIdGenerator snowflakeIdWorker = SnowflakeIdGenerator.getSnowflakeIdGenerator(this.dataCenterId);
+        return snowflakeIdWorker.nextId();
+    }
+}

+ 127 - 0
src/main/java/com/galaxis/manatee/util/impl/SnowflakeIdGenerator.java

@@ -0,0 +1,127 @@
+package com.galaxis.manatee.util.impl;
+
+import com.galaxis.manatee.util.IdGenerate;
+
+/**
+ * 雪花算法生成Id
+ * @author zcj
+ * @version 0.1
+ * @date 2020/1/8 11:40 下午
+ */
+public class SnowflakeIdGenerator implements IdGenerate<Long> {
+    private static SnowflakeIdGenerator snowflakeIdWorker;
+
+    private static final Object LOOK = new Object();
+
+    /**
+     * 获取 snowflake
+     * @param dataCenterId 数据中心ID (0~31)
+     */
+    public static SnowflakeIdGenerator getSnowflakeIdGenerator(long dataCenterId){
+        if(null == snowflakeIdWorker){
+            snowflakeIdWorker=new SnowflakeIdGenerator(dataCenterId);
+        }
+        return snowflakeIdWorker;
+    }
+
+    // ==============================Fields===========================================
+
+    /** 数据标识id所占的位数 */
+    private final long dataCenterIdBits = 10L;
+
+    /** 数据中心ID(0~31) */
+    private long dataCenterId;
+
+    /** 毫秒内序列(0~4095) */
+    private long sequence = 0L;
+
+    /** 上次生成ID的时间截 */
+    private long lastTimestamp = -1L;
+
+    //==============================Constructors=====================================
+    /**
+     * 构造函数
+     * @param dataCenterId 数据中心ID (0~31)
+     */
+    private SnowflakeIdGenerator(long dataCenterId) {
+        // 支持的最大数据标识id,结果是31
+        long maxDataCenterId = ~(-1L << dataCenterIdBits);
+        if (dataCenterId > maxDataCenterId || dataCenterId < 0) {
+            throw new IllegalArgumentException(String.format("dataCenter Id can't be greater than %d or less than 0", maxDataCenterId));
+        }
+        this.dataCenterId = dataCenterId;
+    }
+
+    // ==============================Methods==========================================
+    /**
+     * 获得下一个ID (该方法是线程安全的)
+     * @return SnowflakeId
+     */
+    @Override
+    public synchronized Long nextId() {
+
+        synchronized (LOOK){
+            long timeStamp = timeGen();
+
+            //如果当前时间小于上一次ID生成的时间戳,说明系统时钟回退过这个时候应当抛出异常
+            if (timeStamp < lastTimestamp) {
+                throw new RuntimeException(
+                        String.format("Clock moved backwards.  Refusing to generate id for %d milliseconds", lastTimestamp - timeStamp));
+            }
+
+            //如果是同一时间生成的,则进行毫秒内序列
+            // 序列在id中占的位数 */
+            long sequenceBits = 12L;
+            if (lastTimestamp == timeStamp) {
+                // 生成序列的掩码,这里为4095 (0b111111111111=0xfff=4095) */
+                long sequenceMask = ~(-1L << sequenceBits);
+                sequence = (sequence + 1) & sequenceMask;
+                //毫秒内序列溢出
+                if (sequence == 0) {
+                    //阻塞到下一个毫秒,获得新的时间戳
+                    timeStamp = tilNextMillis(lastTimestamp);
+                }
+            }
+            //时间戳改变,毫秒内序列重置
+            else {
+                sequence = 0L;
+            }
+
+            //上次生成ID的时间截
+            lastTimestamp = timeStamp;
+
+            //移位并通过或运算拼到一起组成64位的ID
+            // 开始时间截 (2015-01-01)
+            long startTimeStamp = 1420041600000L;
+            // 时间截向左移22位(5+5+12) */
+            long timestampLeftShift = sequenceBits + dataCenterIdBits;
+            // 数据标识id向左移17位(12+5) */
+            return ((timeStamp - startTimeStamp) << timestampLeftShift)
+                    | (dataCenterId << sequenceBits)
+                    | sequence;
+        }
+
+
+    }
+
+    /**
+     * 阻塞到下一个毫秒,直到获得新的时间戳
+     * @param lastTimestamp 上次生成ID的时间截
+     * @return 当前时间戳
+     */
+    private long tilNextMillis(long lastTimestamp) {
+        long timestamp = timeGen();
+        while (timestamp <= lastTimestamp) {
+            timestamp = timeGen();
+        }
+        return timestamp;
+    }
+
+    /**
+     * 返回以毫秒为单位的当前时间
+     * @return 当前时间(毫秒)
+     */
+    private long timeGen() {
+        return System.currentTimeMillis();
+    }
+}

+ 43 - 0
src/main/resources/application.yml

@@ -0,0 +1,43 @@
+#氚云
+chuanYun:
+  engine:
+    code: qgvjpgbs50powyd6xyzxzakg3
+    secret: BsuPomgoblb0gDdrCBmzkq5KcWlz+2OXgetN1gFgnZgXmdgHdDpGgA==
+  url:
+    invoke: https://www.h3yun.com/OpenApi/Invoke
+
+#钉钉
+dingTalk:
+  #获取token的uri
+  getTokenUri: https://oapi.dingtalk.com/gettoken
+  #钉钉appKey
+  appKey : ding8orokzhrrnfc898k
+  #钉钉appSecret
+  appSecret : xIwNfl7lVIBwQgKeLBNsDOuKZ-KJWRRBnr_we_-S3GFP32BkdeWzVMsm8z-rTJv8
+  processUrl:
+    #获取审批列表
+    listIds: https://oapi.dingtalk.com/topapi/processinstance/listids
+    #获取审批内容
+    instance: https://oapi.dingtalk.com/topapi/processinstance/get
+
+  #业务流程编码
+  processCode:
+    #出差流程
+    businessTrip: PROC-EF6Y0XWVO2-GBP690HMRWVELM4WJ0WT1-HFP53YII-RR1
+    #物料补发
+    materialResend: PROC-FF6YHERSO2-J9GFWKONMK1QXZH153MV1-4G2HF7VI-2P
+
+#spring data jpa database
+spring:
+  task:
+    scheduling:
+      pool:
+        size: 50
+      thread-name-prefix: scheduled-task-
+  datasource:
+    url: jdbc:mysql://localhost:3306/manatee?autoReconnect=true&characterEncoding=utf-8
+    username: root
+    password: kcsm@111
+  jpa:
+    hibernate:
+      ddl-auto: update

+ 13 - 0
src/test/java/com/galaxis/manatee/ManateeApplicationTests.java

@@ -0,0 +1,13 @@
+package com.galaxis.manatee;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.boot.test.context.SpringBootTest;
+
+@SpringBootTest
+class ManateeApplicationTests {
+
+    @Test
+    void contextLoads() {
+    }
+
+}