unknown il y a 3 ans
commit
bd18444736
100 fichiers modifiés avec 8509 ajouts et 0 suppressions
  1. 353 0
      pom.xml
  2. 22 0
      src/main/java/com/persagy/WorkCalendarApplication.java
  3. 29 0
      src/main/java/com/persagy/calendar/aop/GlobalExceptionHandler.java
  4. 27 0
      src/main/java/com/persagy/calendar/client/RwdObjectClient.java
  5. 29 0
      src/main/java/com/persagy/calendar/client/fallback/RwdObjectClientFallBack.java
  6. 39 0
      src/main/java/com/persagy/calendar/client/model/BaseModel.java
  7. 35 0
      src/main/java/com/persagy/calendar/client/model/BaseQueryModel.java
  8. 28 0
      src/main/java/com/persagy/calendar/client/model/RwdObjectModel.java
  9. 18 0
      src/main/java/com/persagy/calendar/config/CustomIdentifierGenerator.java
  10. 83 0
      src/main/java/com/persagy/calendar/config/SpringMVCConfig.java
  11. 104 0
      src/main/java/com/persagy/calendar/constant/WorkCalendarConstant.java
  12. 103 0
      src/main/java/com/persagy/calendar/controller/CommonController.java
  13. 330 0
      src/main/java/com/persagy/calendar/controller/OldWorkCalendarController.java
  14. 207 0
      src/main/java/com/persagy/calendar/controller/RwdObjectController.java
  15. 170 0
      src/main/java/com/persagy/calendar/controller/WorkCalendarController.java
  16. 154 0
      src/main/java/com/persagy/calendar/controller/WorkCalendarDateController.java
  17. 12 0
      src/main/java/com/persagy/calendar/controller/WorkCalendarDictController.java
  18. 119 0
      src/main/java/com/persagy/calendar/controller/WorkCalendarLabelController.java
  19. 126 0
      src/main/java/com/persagy/calendar/controller/WorkCalendarRuleController.java
  20. 45 0
      src/main/java/com/persagy/calendar/controller/WorkTimeEngineController.java
  21. 658 0
      src/main/java/com/persagy/calendar/handle/WorkCalendarDateHandler.java
  22. 506 0
      src/main/java/com/persagy/calendar/handle/WorkCalendarHandler.java
  23. 241 0
      src/main/java/com/persagy/calendar/handle/WorkCalendarLabelHandler.java
  24. 133 0
      src/main/java/com/persagy/calendar/handle/WorkCalendarRuleHandler.java
  25. 26 0
      src/main/java/com/persagy/calendar/mapper/OldWorkCalendarMapper.java
  26. 37 0
      src/main/java/com/persagy/calendar/mapper/WorkCalendarDateMapper.java
  27. 48 0
      src/main/java/com/persagy/calendar/mapper/WorkCalendarDictMapper.java
  28. 27 0
      src/main/java/com/persagy/calendar/mapper/WorkCalendarLabelMapper.java
  29. 29 0
      src/main/java/com/persagy/calendar/mapper/WorkCalendarMapper.java
  30. 36 0
      src/main/java/com/persagy/calendar/mapper/WorkCalendarObjectMapper.java
  31. 19 0
      src/main/java/com/persagy/calendar/mapper/WorkCalendarRuleMapper.java
  32. 44 0
      src/main/java/com/persagy/calendar/pojo/dto/OldWorkCalendar.java
  33. 206 0
      src/main/java/com/persagy/calendar/pojo/dto/WorkCalendar.java
  34. 398 0
      src/main/java/com/persagy/calendar/pojo/dto/WorkCalendarDate.java
  35. 114 0
      src/main/java/com/persagy/calendar/pojo/dto/WorkCalendarDict.java
  36. 241 0
      src/main/java/com/persagy/calendar/pojo/dto/WorkCalendarLabel.java
  37. 158 0
      src/main/java/com/persagy/calendar/pojo/dto/WorkCalendarObject.java
  38. 329 0
      src/main/java/com/persagy/calendar/pojo/dto/WorkCalendarRule.java
  39. 29 0
      src/main/java/com/persagy/calendar/pojo/old/DataRangeVO.java
  40. 46 0
      src/main/java/com/persagy/calendar/pojo/old/OldCalendarIntervalCreateVO.java
  41. 40 0
      src/main/java/com/persagy/calendar/pojo/old/OldCalendarIntervalDeleteVO.java
  42. 48 0
      src/main/java/com/persagy/calendar/pojo/old/OldCalendarIntervalsByTag.java
  43. 35 0
      src/main/java/com/persagy/calendar/pojo/old/OldCalendarIntervalsVO.java
  44. 40 0
      src/main/java/com/persagy/calendar/pojo/old/OldCalendarQueryVO.java
  45. 29 0
      src/main/java/com/persagy/calendar/pojo/old/OldCalendarResponseVO.java
  46. 50 0
      src/main/java/com/persagy/calendar/pojo/old/OldCalendarRuleCreateVO.java
  47. 40 0
      src/main/java/com/persagy/calendar/pojo/old/OldCalendarRuleDeleteVO.java
  48. 30 0
      src/main/java/com/persagy/calendar/pojo/old/OldCalendarRuleVO.java
  49. 33 0
      src/main/java/com/persagy/calendar/pojo/old/OldCalendarSetIntervalVO.java
  50. 33 0
      src/main/java/com/persagy/calendar/pojo/old/OldCalendarTagQueryVO.java
  51. 40 0
      src/main/java/com/persagy/calendar/pojo/old/OldCalendarTagVO.java
  52. 34 0
      src/main/java/com/persagy/calendar/pojo/old/OldCalendarTagsVO.java
  53. 35 0
      src/main/java/com/persagy/calendar/pojo/old/OldWorkCalendarVO.java
  54. 24 0
      src/main/java/com/persagy/calendar/pojo/vo/BaseQueryVO.java
  55. 29 0
      src/main/java/com/persagy/calendar/pojo/vo/BaseUpdateVO.java
  56. 31 0
      src/main/java/com/persagy/calendar/pojo/vo/BaseVO.java
  57. 40 0
      src/main/java/com/persagy/calendar/pojo/vo/CalendarDateResult.java
  58. 35 0
      src/main/java/com/persagy/calendar/pojo/vo/CustomCalendarVO.java
  59. 31 0
      src/main/java/com/persagy/calendar/pojo/vo/DictCodeCreate.java
  60. 40 0
      src/main/java/com/persagy/calendar/pojo/vo/DictCreateVO.java
  61. 37 0
      src/main/java/com/persagy/calendar/pojo/vo/DictQueryVO.java
  62. 55 0
      src/main/java/com/persagy/calendar/pojo/vo/RwdObjectQueryVO.java
  63. 44 0
      src/main/java/com/persagy/calendar/pojo/vo/WorkCalendarDateCreateVO.java
  64. 45 0
      src/main/java/com/persagy/calendar/pojo/vo/WorkCalendarDateDeleteVO.java
  65. 65 0
      src/main/java/com/persagy/calendar/pojo/vo/WorkCalendarDateQueryVO.java
  66. 39 0
      src/main/java/com/persagy/calendar/pojo/vo/WorkCalendarDateResultVO.java
  67. 48 0
      src/main/java/com/persagy/calendar/pojo/vo/WorkCalendarDateUpdateVO.java
  68. 60 0
      src/main/java/com/persagy/calendar/pojo/vo/WorkCalendarLabelQueryVO.java
  69. 58 0
      src/main/java/com/persagy/calendar/pojo/vo/WorkCalendarLabelUpdateVO.java
  70. 57 0
      src/main/java/com/persagy/calendar/pojo/vo/WorkCalendarMoreDateCreateVO.java
  71. 46 0
      src/main/java/com/persagy/calendar/pojo/vo/WorkCalendarObjectUpdateVO.java
  72. 44 0
      src/main/java/com/persagy/calendar/pojo/vo/WorkCalendarQueryVO.java
  73. 61 0
      src/main/java/com/persagy/calendar/pojo/vo/WorkCalendarRuleCreateVO.java
  74. 25 0
      src/main/java/com/persagy/calendar/pojo/vo/WorkCalendarRuleDeleteVO.java
  75. 38 0
      src/main/java/com/persagy/calendar/pojo/vo/WorkCalendarRuleQueryVO.java
  76. 65 0
      src/main/java/com/persagy/calendar/pojo/vo/WorkCalendarRuleUpdateVO.java
  77. 39 0
      src/main/java/com/persagy/calendar/pojo/vo/WorkCalendarUpdateVO.java
  78. 39 0
      src/main/java/com/persagy/calendar/pojo/vo/WorkLabelBatchUpdateVO.java
  79. 49 0
      src/main/java/com/persagy/calendar/service/IWorkCalendarDateService.java
  80. 43 0
      src/main/java/com/persagy/calendar/service/IWorkCalendarDictService.java
  81. 23 0
      src/main/java/com/persagy/calendar/service/IWorkCalendarLabelService.java
  82. 33 0
      src/main/java/com/persagy/calendar/service/IWorkCalendarObjectService.java
  83. 69 0
      src/main/java/com/persagy/calendar/service/IWorkCalendarRuleService.java
  84. 50 0
      src/main/java/com/persagy/calendar/service/IWorkCalendarService.java
  85. 98 0
      src/main/java/com/persagy/calendar/service/OldWorkCalendarDateService.java
  86. 24 0
      src/main/java/com/persagy/calendar/service/RwdObjectService.java
  87. 294 0
      src/main/java/com/persagy/calendar/service/impl/OldWorkCalendarDateServiceImpl.java
  88. 122 0
      src/main/java/com/persagy/calendar/service/impl/RwdObjectServiceImpl.java
  89. 100 0
      src/main/java/com/persagy/calendar/service/impl/WorkCalendarDateServiceImpl.java
  90. 43 0
      src/main/java/com/persagy/calendar/service/impl/WorkCalendarDictServiceImpl.java
  91. 29 0
      src/main/java/com/persagy/calendar/service/impl/WorkCalendarLabelServiceImpl.java
  92. 34 0
      src/main/java/com/persagy/calendar/service/impl/WorkCalendarObjectServiceImpl.java
  93. 134 0
      src/main/java/com/persagy/calendar/service/impl/WorkCalendarRuleServiceImpl.java
  94. 129 0
      src/main/java/com/persagy/calendar/service/impl/WorkCalendarServiceImpl.java
  95. 42 0
      src/main/java/com/persagy/calendar/utils/ApplicationContextUtil.java
  96. 78 0
      src/main/java/com/persagy/calendar/utils/NTPClientUtil.java
  97. 65 0
      src/main/java/com/persagy/calendar/utils/ResponseOldResult.java
  98. 99 0
      src/main/java/com/persagy/calendar/utils/ResponseOldResultUtil.java
  99. 11 0
      src/main/resources/application.yml
  100. 0 0
      src/main/resources/bootstrap.yml

+ 353 - 0
pom.xml

@@ -0,0 +1,353 @@
+<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>
+	<groupId>com.persagy</groupId>
+	<artifactId>calendar-center</artifactId>
+	<version>1.0.0</version>
+
+	<properties>
+		<!-- java版本 -->
+		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+		<java.encoding>UTF-8</java.encoding>
+		<java.version>8</java.version>
+		<java.source.version>1.8</java.source.version>
+		<java.target.version>1.8</java.target.version>
+
+		<!-- spring版本依赖 -->
+		<integrated-platform.version>2.0.0</integrated-platform.version>
+		<spring-boot-dependencies.version>2.1.14.RELEASE</spring-boot-dependencies.version>
+		<spring-cloud-dependencies.version>Greenwich.SR6</spring-cloud-dependencies.version>
+		<mybatis-spring-boot-starter.version>1.3.2</mybatis-spring-boot-starter.version>
+
+		<!-- 三方jar依赖 -->
+		<mybatis-plus.version>3.3.1</mybatis-plus.version>
+		<guava.version>20.0</guava.version>
+
+		<!-- maven依赖 -->
+		<maven.compiler.version>3.8.0</maven.compiler.version>
+		<maven.surefire.version>2.22.1</maven.surefire.version>
+		<maven.source.version>3.0.1</maven.source.version>
+		<maven.javadoc.version>3.0.1</maven.javadoc.version>
+		<maven.gpg.version>1.6</maven.gpg.version>
+		<maven.jacoco.version>0.8.3</maven.jacoco.version>
+		<maven.jar.version>3.1.0</maven.jar.version>
+		<maven.pmd.version>3.8</maven.pmd.version>
+	</properties>
+
+	<dependencyManagement>
+		<dependencies>
+			<dependency>
+				<groupId>com.persagy</groupId>
+				<artifactId>integrated-platform</artifactId>
+				<version>${integrated-platform.version}</version>
+				<type>pom</type>
+				<scope>import</scope>
+			</dependency>
+		</dependencies>
+	</dependencyManagement>
+
+	<!-- 服务依赖 -->
+	<dependencies>
+		<!-- 依赖集成自定义jar -->
+		<dependency>
+			<groupId>com.persagy</groupId>
+			<artifactId>integrated-config-client</artifactId>
+		</dependency>
+		<dependency>
+			<groupId>com.persagy</groupId>
+			<artifactId>integrated-common-core</artifactId>
+		</dependency>
+		<dependency>
+			<groupId>com.persagy</groupId>
+			<artifactId>integrated-db-spring-boot-starter</artifactId>
+		</dependency>
+		<dependency>
+			<groupId>com.persagy</groupId>
+			<artifactId>integrated-ribbon-spring-boot-starter</artifactId>
+		</dependency>
+		<dependency>
+			<groupId>com.persagy</groupId>
+			<artifactId>integrated-swagger-spring-boot-starter</artifactId>
+		</dependency>
+		<!-- <dependency>
+			<groupId>com.persagy</groupId>
+			<artifactId>integrated-redis-spring-boot-starter</artifactId>
+		</dependency> -->
+
+		<!-- web -->
+		<dependency>
+			<groupId>org.springframework.boot</groupId>
+			<artifactId>spring-boot-starter-web</artifactId>
+		</dependency>
+
+		<!-- 服务注册 -->
+		<dependency>
+			<groupId>org.springframework.cloud</groupId>
+			<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
+		</dependency>
+
+		<!-- mysql -->
+		<dependency>
+			<groupId>mysql</groupId>
+			<artifactId>mysql-connector-java</artifactId>
+		</dependency>
+
+		<dependency>
+			<groupId>org.springframework</groupId>
+			<artifactId>spring-context-support</artifactId>
+		</dependency>
+
+		<dependency>
+			<groupId>org.springframework.boot</groupId>
+			<artifactId>spring-boot-starter-actuator</artifactId>
+		</dependency>
+
+		<dependency>
+			<groupId>io.micrometer</groupId>
+			<artifactId>micrometer-registry-prometheus</artifactId>
+		</dependency>
+
+		<dependency>
+			<groupId>org.springframework.social</groupId>
+			<artifactId>spring-social-security</artifactId>
+		</dependency>
+		
+		<dependency>
+			<groupId>org.springframework.boot</groupId>
+			<artifactId>spring-boot-starter</artifactId>
+		</dependency>
+
+		<dependency>
+			<groupId>org.springframework.boot</groupId>
+			<artifactId>spring-boot-starter-test</artifactId>
+		</dependency>
+
+		<dependency>
+			<groupId>org.springframework.cloud</groupId>
+			<artifactId>spring-cloud-context</artifactId>
+		</dependency>
+
+		<dependency>
+			<groupId>cn.hutool</groupId>
+			<artifactId>hutool-all</artifactId>
+		</dependency>
+
+		<!-- fastjson -->
+		<dependency>
+			<groupId>com.alibaba</groupId>
+			<artifactId>fastjson</artifactId>
+		</dependency>
+
+		<dependency>
+			<groupId>org.projectlombok</groupId>
+			<artifactId>lombok</artifactId>
+		</dependency>
+	</dependencies>
+
+	<build>
+		<finalName>${project.artifactId}</finalName>
+		<plugins>
+			<plugin>
+				<groupId>org.springframework.boot</groupId>
+				<artifactId>spring-boot-maven-plugin</artifactId>
+				<executions>
+					<execution>
+						<goals>
+							<goal>repackage</goal>
+						</goals>
+					</execution>
+				</executions>
+			</plugin>
+			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-pmd-plugin</artifactId>
+				<version>${maven.pmd.version}</version>
+				<configuration>
+					<sourceEncoding>${project.build.sourceEncoding}</sourceEncoding>
+					<minimumPriority>1</minimumPriority>
+					<excludeRoots>
+						<excludeRoot>com/alibaba/csp/sentinel/benchmark</excludeRoot>
+					</excludeRoots>
+					<excludes>
+						<exclude>**/*_jmhTest.java</exclude>
+					</excludes>
+					<printFailingErrors>true</printFailingErrors>
+					<rulesets>
+						<ruleset>rulesets/java/ali-comment.xml</ruleset>
+						<ruleset>rulesets/java/ali-concurrent.xml</ruleset>
+						<ruleset>rulesets/java/ali-constant.xml</ruleset>
+						<ruleset>rulesets/java/ali-exception.xml</ruleset>
+						<ruleset>rulesets/java/ali-flowcontrol.xml</ruleset>
+						<ruleset>rulesets/java/ali-naming.xml</ruleset>
+						<ruleset>rulesets/java/ali-oop.xml</ruleset>
+						<ruleset>rulesets/java/ali-orm.xml</ruleset>
+						<ruleset>rulesets/java/ali-other.xml</ruleset>
+						<ruleset>rulesets/java/ali-set.xml</ruleset>
+					</rulesets>
+				</configuration>
+				<executions>
+					<execution>
+						<phase>verify</phase>
+						<goals>
+							<goal>check</goal>
+						</goals>
+					</execution>
+				</executions>
+				<dependencies>
+					<dependency>
+						<groupId>com.alibaba.p3c</groupId>
+						<artifactId>p3c-pmd</artifactId>
+						<version>1.3.6</version>
+					</dependency>
+				</dependencies>
+			</plugin>
+			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-compiler-plugin</artifactId>
+				<version>${maven.compiler.version}</version>
+				<configuration>
+					<source>${java.source.version}</source>
+					<target>${java.target.version}</target>
+					<encoding>${java.encoding}</encoding>
+				</configuration>
+			</plugin>
+			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-surefire-plugin</artifactId>
+				<configuration>
+					<!-- CircleCI build workaround -->
+					<argLine>@{argLine} -Xms1024m -Xmx2048m</argLine>
+					<argLine>-Dfile.encoding=UTF-8</argLine>
+					<useSystemClassLoader>false</useSystemClassLoader>
+				</configuration>
+			</plugin>
+			<plugin>
+				<groupId>org.jacoco</groupId>
+				<artifactId>jacoco-maven-plugin</artifactId>
+				<version>${maven.jacoco.version}</version>
+				<executions>
+					<execution>
+						<goals>
+							<goal>prepare-agent</goal>
+						</goals>
+					</execution>
+					<execution>
+						<id>report</id>
+						<phase>test</phase>
+						<goals>
+							<goal>report</goal>
+						</goals>
+					</execution>
+				</executions>
+			</plugin>
+		</plugins>
+		<pluginManagement>
+			<plugins>
+				<plugin>
+					<groupId>org.apache.maven.plugins</groupId>
+					<artifactId>maven-surefire-plugin</artifactId>
+					<version>${maven.surefire.version}</version>
+				</plugin>
+				<plugin>
+					<groupId>org.apache.maven.plugins</groupId>
+					<artifactId>maven-jar-plugin</artifactId>
+					<version>${maven.jar.version}</version>
+				</plugin>
+				<plugin>
+					<groupId>org.apache.maven.plugins</groupId>
+					<artifactId>maven-gpg-plugin</artifactId>
+					<version>${maven.gpg.version}</version>
+				</plugin>
+			</plugins>
+		</pluginManagement>
+	</build>
+
+	<profiles>
+		<profile>
+			<build>
+				<plugins>
+					<!-- Source -->
+					<plugin>
+						<groupId>org.apache.maven.plugins</groupId>
+						<artifactId>maven-source-plugin</artifactId>
+						<version>${maven.source.version}</version>
+						<executions>
+							<execution>
+								<phase>package</phase>
+								<goals>
+									<goal>jar-no-fork</goal>
+								</goals>
+							</execution>
+						</executions>
+					</plugin>
+					<!-- Javadoc -->
+					<plugin>
+						<groupId>org.apache.maven.plugins</groupId>
+						<artifactId>maven-javadoc-plugin</artifactId>
+						<version>${maven.javadoc.version}</version>
+						<executions>
+							<execution>
+								<phase>package</phase>
+								<goals>
+									<goal>jar</goal>
+								</goals>
+								<configuration>
+									<locale>en_US</locale>
+									<encoding>UTF-8</encoding>
+									<charset>UTF-8</charset>
+									<doclint>none</doclint>
+								</configuration>
+							</execution>
+						</executions>
+					</plugin>
+					<!-- GPG -->
+					<plugin>
+						<groupId>org.apache.maven.plugins</groupId>
+						<artifactId>maven-gpg-plugin</artifactId>
+						<version>${maven.gpg.version}</version>
+						<executions>
+							<execution>
+								<phase>verify</phase>
+								<goals>
+									<goal>sign</goal>
+								</goals>
+							</execution>
+						</executions>
+					</plugin>
+				</plugins>
+			</build>
+
+		</profile>
+	</profiles>
+
+	<repositories>
+		<repository>
+			<id>persagy</id>
+			<name>releases Repository</name>
+			<url>http://47.93.132.139:8081/nexus/content/repositories/persagy/</url>
+		</repository>
+
+		<repository>
+			<id>integrated</id>
+			<name>releases Repository</name>
+			<url>http://47.93.132.139:8081/nexus/content/repositories/integrated/</url>
+			<snapshots>
+				<enabled>false</enabled>
+			</snapshots>
+		</repository>
+		<repository>
+			<id>aliyun</id>
+			<name>releases Repository</name>
+			<url>http://maven.aliyun.com/nexus/content/groups/public</url>
+		</repository>
+	</repositories>
+
+	<pluginRepositories>
+		<pluginRepository>
+			<id>central</id>
+			<url>http://maven.aliyun.com/nexus/content/groups/public</url>
+		</pluginRepository>
+	</pluginRepositories>
+
+</project>

+ 22 - 0
src/main/java/com/persagy/WorkCalendarApplication.java

@@ -0,0 +1,22 @@
+package com.persagy;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
+import org.springframework.cloud.openfeign.EnableFeignClients;
+import org.springframework.transaction.annotation.EnableTransactionManagement;
+
+import com.persagy.common.annotation.EnableControllerLog;
+
+@EnableControllerLog
+@EnableDiscoveryClient
+@SpringBootApplication
+@EnableTransactionManagement
+@EnableFeignClients(basePackages = "com.persagy.calendar.client")
+public class WorkCalendarApplication {
+
+	public static void main(String[] args) {
+		SpringApplication.run(WorkCalendarApplication.class, args);
+	}
+	
+}

+ 29 - 0
src/main/java/com/persagy/calendar/aop/GlobalExceptionHandler.java

@@ -0,0 +1,29 @@
+package com.persagy.calendar.aop;
+
+import org.springframework.dao.DuplicateKeyException;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.bind.annotation.RestControllerAdvice;
+
+import com.persagy.common.aop.CommonExceptionHandler;
+import com.persagy.common.enums.ResponseCode;
+import com.persagy.common.utils.ResponseResult;
+import com.persagy.common.utils.ResponseUtil;
+
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * @description 
+ * @author zhangqiankun
+ * @since 2020年8月26日:	下午5:17:08
+ */
+@Slf4j
+@RestControllerAdvice
+public class GlobalExceptionHandler extends CommonExceptionHandler {
+	
+	@ExceptionHandler(DuplicateKeyException.class)
+	public ResponseResult handleDuplicateKeyException(Exception e) {
+		log.error(e.getMessage(), e);
+		return ResponseUtil.errorResult(ResponseCode.C0341.getCode(), ResponseCode.C0341.getDesc());
+	}
+	
+}

+ 27 - 0
src/main/java/com/persagy/calendar/client/RwdObjectClient.java

@@ -0,0 +1,27 @@
+package com.persagy.calendar.client;
+
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.cloud.openfeign.SpringQueryMap;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+
+import com.persagy.calendar.client.fallback.RwdObjectClientFallBack;
+import com.persagy.calendar.client.model.BaseModel;
+import com.persagy.calendar.client.model.BaseQueryModel;
+import com.persagy.calendar.client.model.RwdObjectModel;
+import com.persagy.common.constant.ServiceNameConstants;
+
+/**
+ * @version 
+ * @description 
+ * @company persagy
+ * @author zhangqiankun
+ * @since 2021年3月1日:	上午10:16:42
+ */
+@FeignClient(name = ServiceNameConstants.DMP_RWD_SERVICE, fallback = RwdObjectClientFallBack.class, decode404 = true)
+public interface RwdObjectClient {
+	
+	@PostMapping("/rwd/instance/object/query")
+    String queryProjectObjects(@SpringQueryMap BaseModel baseModel, @RequestBody BaseQueryModel<RwdObjectModel> object);
+
+}

+ 29 - 0
src/main/java/com/persagy/calendar/client/fallback/RwdObjectClientFallBack.java

@@ -0,0 +1,29 @@
+package com.persagy.calendar.client.fallback;
+
+import org.springframework.stereotype.Component;
+
+import com.persagy.calendar.client.RwdObjectClient;
+import com.persagy.calendar.client.model.BaseModel;
+import com.persagy.calendar.client.model.BaseQueryModel;
+import com.persagy.calendar.client.model.RwdObjectModel;
+
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * @version 
+ * @description 
+ * @company persagy
+ * @author zhangqiankun
+ * @since 2021年3月2日:	下午3:01:16
+ */
+@Slf4j
+@Component
+public class RwdObjectClientFallBack implements RwdObjectClient {
+
+	@Override
+	public String queryProjectObjects(BaseModel baseModel, BaseQueryModel<RwdObjectModel> object) {
+		log.error("数据中台物理世界,查询对象数据异常");
+		return null;
+	}
+
+}

+ 39 - 0
src/main/java/com/persagy/calendar/client/model/BaseModel.java

@@ -0,0 +1,39 @@
+package com.persagy.calendar.client.model;
+
+import javax.validation.constraints.NotBlank;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Getter;
+import lombok.Setter;
+import lombok.ToString;
+
+/**
+ * @version 
+ * @description 基础类,所有请求必带参数
+ * @company persagy
+ * @author zhangqiankun
+ * @since 2020年11月25日:	下午8:02:38
+ */
+@Getter
+@Setter
+@ApiModel
+@ToString
+public class BaseModel {
+	
+	@NotBlank(message = "userId不可为空")
+	@ApiModelProperty(value = "用户ID", required = true)
+	private String userId;
+	
+	@NotBlank(message = "groupCode不可为空")
+	@ApiModelProperty(value = "集团编码", required = true)
+	private String groupCode;
+	
+	@NotBlank(message = "项目ID不可为空")
+	@ApiModelProperty(value = "项目ID")
+	private String projectId;
+	
+	@ApiModelProperty(value = "应用ID")
+	private String appId;
+	
+}

+ 35 - 0
src/main/java/com/persagy/calendar/client/model/BaseQueryModel.java

@@ -0,0 +1,35 @@
+package com.persagy.calendar.client.model;
+
+import java.util.List;
+import java.util.Set;
+
+import com.alibaba.fastjson.JSONObject;
+
+import lombok.Getter;
+import lombok.Setter;
+import lombok.ToString;
+
+/**
+ * @version 
+ * @description 所有 查询操作的验证基类
+ * @company persagy
+ * @author zhangqiankun
+ * @since 2020年9月28日:	下午9:18:00
+ */
+
+@Getter
+@Setter
+@ToString
+public class BaseQueryModel<T> {
+	
+	private T criteria;
+
+	private List<JSONObject> orders;
+
+	private Integer page;
+
+	private Integer size;
+
+    private Set<String> withColumns;
+
+}

+ 28 - 0
src/main/java/com/persagy/calendar/client/model/RwdObjectModel.java

@@ -0,0 +1,28 @@
+package com.persagy.calendar.client.model;
+
+import java.util.Set;
+
+import lombok.Getter;
+import lombok.Setter;
+import lombok.ToString;
+
+/**
+ * @version 
+ * @description 
+ * @company persagy
+ * @author zhangqiankun
+ * @since 2021年3月2日:	下午3:08:48
+ */
+@Getter
+@Setter
+@ToString
+public class RwdObjectModel {
+
+	private String id;
+	
+	private String classCode;
+	
+	private Integer valid = 1;
+	
+	private Set<String> objType;
+}

+ 18 - 0
src/main/java/com/persagy/calendar/config/CustomIdentifierGenerator.java

@@ -0,0 +1,18 @@
+package com.persagy.calendar.config;
+
+import org.springframework.stereotype.Component;
+
+import com.persagy.common.config.DefaultIdentifierGenerator;
+
+/**
+ * @version 
+ * @description 
+ * @company persagy
+ * @author zhangqiankun
+ * @since 2020年9月29日:	下午12:38:21
+ */
+
+@Component
+public class CustomIdentifierGenerator extends DefaultIdentifierGenerator {
+	
+}

+ 83 - 0
src/main/java/com/persagy/calendar/config/SpringMVCConfig.java

@@ -0,0 +1,83 @@
+package com.persagy.calendar.config;
+
+import java.io.IOException;
+import java.nio.charset.Charset;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpOutputMessage;
+import org.springframework.http.MediaType;
+import org.springframework.http.converter.HttpMessageNotWritableException;
+import org.springframework.util.StreamUtils;
+
+import com.alibaba.fastjson.serializer.SerializerFeature;
+import com.alibaba.fastjson.support.config.FastJsonConfig;
+import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
+
+/**
+ * @description 
+ * @author zhangqiankun
+ * @since 2020年8月26日:	下午5:17:08
+ */
+@Configuration
+public class SpringMVCConfig {
+	private static final String ENCODE_UTF_8 = "UTF-8";
+	
+	/**
+	 * HttpMessageConverters - FastJson
+	 * 首字母会改为小写,如有必要,手动在实体类上加上@JSONField 注解
+	 */
+	@Bean
+	public HttpMessageConverters fastJsonHttpMessageConverters() {
+		// 1、定义一个convert转换消息的对象
+		FastJsonHttpMessageConverter fastConverter = new FastJsonHttpMessageConverterConfig();
+
+		// 2、添加fastjson的配置信息
+		FastJsonConfig fastJsonConfig = new FastJsonConfig();
+
+		SerializerFeature[] serializerFeatures = new SerializerFeature[] {
+				// 循环引用
+				SerializerFeature.DisableCircularReferenceDetect
+			};
+
+		fastJsonConfig.setSerializerFeatures(serializerFeatures);
+		fastJsonConfig.setCharset(Charset.forName(ENCODE_UTF_8));
+		
+		//3、设置类型
+		List<MediaType> mediaTypes = new ArrayList<MediaType>();
+		mediaTypes.add(MediaType.APPLICATION_JSON_UTF8);
+		mediaTypes.add(MediaType.TEXT_PLAIN);
+		mediaTypes.add(MediaType.ALL);
+		fastConverter.setSupportedMediaTypes(mediaTypes);
+        
+        //4、将转换规则应用于转换对象 
+        fastConverter.setFastJsonConfig(fastJsonConfig);
+        fastConverter.setDefaultCharset(Charset.forName(ENCODE_UTF_8));
+        
+        return new HttpMessageConverters(fastConverter);
+	}
+
+}
+
+class FastJsonHttpMessageConverterConfig extends FastJsonHttpMessageConverter{
+	
+	@Override
+	protected void writeInternal(Object obj, HttpOutputMessage outputMessage)
+			throws IOException, HttpMessageNotWritableException {
+		if (obj instanceof String) {
+			//设置 字符串返回的 ContentType 类型
+			HttpHeaders headers = outputMessage.getHeaders();
+			//headers.setContentType(MediaType.TEXT_PLAIN);
+			headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
+			Charset charset = this.getDefaultCharset();
+	        StreamUtils.copy((String) obj, charset, outputMessage.getBody());
+		} else {
+			super.writeInternal(obj, outputMessage);
+		}
+	}
+
+}

+ 104 - 0
src/main/java/com/persagy/calendar/constant/WorkCalendarConstant.java

@@ -0,0 +1,104 @@
+package com.persagy.calendar.constant;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @version 
+ * @description 
+ * @company persagy
+ * @author zhangqiankun
+ * @since 2020年9月1日:	下午1:59:38
+ */
+public class WorkCalendarConstant {
+	
+	/**
+	 * 日期正则表达式,格式:yyyyMMddHHmmss
+	 */
+	public static final String DATE_REG_YYYYMMDDHHMMSS = "[\\d]{4}[0-1][0-9][0-3][0-9][0-2][0-9][0-6][0-9][0-6][0-9]";
+	
+	/** 
+	 * 日期正则表达式,格式:yyyyMMdd
+	 */
+	public static final String DATE_REG_YYYYMMDD = "(([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]{1}|[0-9]{1}[1-9][0-9]{2}|[1-9][0-9]{3})(((0[13578]|1[02])(0[1-9]|[12][0-9]|3[01]))|((0[469]|11)(0[1-9]|[12][0-9]|30))|(02(0[1-9]|[1][0-9]|2[0-8]))))|((([0-9]{2})(0[48]|[2468][048]|[13579][26])|((0[48]|[2468][048]|[3579][26])00))0229)";
+	
+	/** 
+	 * 日期正则表达式,格式:hhmmss
+	 */
+	public static final String DATE_REG_HHMMSS = "[0-2][0-9][0-6][0-9][0-6][0-9]";
+	
+	
+	// dOfW为按周设置,例如: 1 2 3 1 (Monday), 7 (Sunday)
+	public static final String WORK_CALENDAR_D_OF_W = "dOfW";
+	
+	// dOfM为按每月的几号设置,例如:1 12 15-20
+	public static final String WORK_CALENDAR_D_OF_M = "dOfM";
+	
+	// mAndD为按一年中的几月几号设置,例如: 0221 0830 0925-1028
+	public static final String WORK_CALENDAR_M_AND_D = "mAndD";
+	
+	// 工作历ID前缀
+	public static final String WORK_CALENDAR_ID_PREFIX = "WC";
+
+	// 工作历规则ID前缀
+	public static final String WORK_CALENDAR_RULE_ID_PREFIX = "WR";
+	
+	// 工作历标签ID前缀
+	public static final String WORK_CALENDAR_LABEL_ID_PREFIX = "WL";
+	
+	// 作息时间表ID前缀
+	public static final String WORK_CALENDAR_DATE_ID_PREFIX = "WD";
+	
+	public static final String WORK_CALENDAR_DEL_FLAG_NOR = "0";		// 正常
+	
+	public static final String WORK_CALENDAR_DEL_FLAG_DEL = "1";		// 删除	
+	
+	public static final String WORK_CALENDAR_RULE_FLAG_NEW = "0";		// 时间引擎解析规则
+	
+	public static final String WORK_CALENDAR_RULE_FLAG_OLD = "1";		// 时间引擎不解析规则,老版进来的
+	
+	public static final String CUSTOM_CALENDAR_DATE_NO = "0";		// 非自定义
+	
+	public static final String CUSTOM_CALENDAR_DATE_YES = "1";		// 自定义
+	
+	public static final String CUSTOM_CALENDAR_DICT_TYPE = "custom-type";	// 自定义类型
+	
+	/**
+	 * day of week
+	 */
+	public static final Map<Integer, String> DAY_OF_WEEK = new HashMap<Integer, String>(8);
+	
+	/**
+	 * 所有的类型
+	 */
+	public static final Map<String, String> DICT_TYPE = new HashMap<String, String>(2);
+	
+	/**
+	 * 类型和code的映射
+	 */
+	public static final Map<String, Map<String, String>> DICT_TYPE_CODE = new HashMap<String, Map<String, String>>(2);
+	
+	/**
+	 * 开闭店类型
+	 */
+	public static final Map<String, String> SHOP_TYPE_CODE = new HashMap<String, String>(4);
+	
+	static {
+		SHOP_TYPE_CODE.put("2", "开店时间");
+		SHOP_TYPE_CODE.put("3", "商业闭店时间");
+		SHOP_TYPE_CODE.put("4", "娱乐闭店时间");
+		DICT_TYPE_CODE.put("shop", SHOP_TYPE_CODE);
+		
+		DICT_TYPE.put("shop", "开闭店类型");
+		
+		
+		DAY_OF_WEEK.put(1, "日");
+		DAY_OF_WEEK.put(2, "一");
+		DAY_OF_WEEK.put(3, "二");
+		DAY_OF_WEEK.put(4, "三");
+		DAY_OF_WEEK.put(5, "四");
+		DAY_OF_WEEK.put(6, "五");
+		DAY_OF_WEEK.put(7, "六");
+	}
+	
+}

+ 103 - 0
src/main/java/com/persagy/calendar/controller/CommonController.java

@@ -0,0 +1,103 @@
+package com.persagy.calendar.controller;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RestController;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.google.common.collect.Lists;
+import com.persagy.calendar.constant.WorkCalendarConstant;
+import com.persagy.calendar.handle.WorkCalendarDateHandler;
+import com.persagy.calendar.pojo.dto.WorkCalendarDict;
+import com.persagy.calendar.pojo.vo.DictCodeCreate;
+import com.persagy.calendar.pojo.vo.DictCreateVO;
+import com.persagy.calendar.pojo.vo.DictQueryVO;
+import com.persagy.calendar.pojo.vo.WorkCalendarDateQueryVO;
+import com.persagy.calendar.service.IWorkCalendarDictService;
+import com.persagy.common.utils.ResponseResult;
+import com.persagy.common.utils.ResponseUtil;
+import com.persagy.common.utils.StringUtil;
+
+import cn.hutool.core.collection.CollectionUtil;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+
+/**
+ * 通用接口
+ * @version 1.0.0
+ * @company persagy 
+ * @author zhangqiankun
+ * @date 2020-10-03 13:54:22
+ */
+@Api(tags = "通用接口")
+@RestController
+@RequestMapping(value = "/v2.0/common", method = RequestMethod.POST)
+public class CommonController {
+
+	@Autowired
+	private IWorkCalendarDictService workCalendarDictService;
+	
+	@Autowired
+	private WorkCalendarDateHandler workCalendarDateHandler;
+	
+	/**
+     * 手动解析规则信息
+     * 非自定义已存在的作息时间信息被更新,不存在的被插入,自定义的不动
+     */
+    @ApiOperation(value = "立即解析规则信息")
+    @RequestMapping(value = "handleParseCalendarRule")
+    public ResponseResult handleParseCalendarRule(@RequestBody @Validated WorkCalendarDateQueryVO queryVO) {
+    	if ("pj1111111111".equals(queryVO.getProjectId())) {
+    		queryVO.setProjectId(null);
+		}
+    	boolean result = this.workCalendarDateHandler.handleParseCalendarRule(queryVO);
+		return result ? ResponseUtil.successResult("执行成功") : ResponseUtil.errorResult("执行失败");
+    }
+    
+	/**
+     * 字典值查询
+     */
+    @ApiOperation(value = "字典查询")
+    @RequestMapping(value = "dictQuery")
+    public ResponseResult dictQuery(@RequestBody @Validated DictQueryVO queryVO) {
+    	QueryWrapper<WorkCalendarDict> queryWrapper = new WorkCalendarDict.Builder().createQueryWrapper()
+    			.groupCodeEq(queryVO.getGroupCode()).calendarIdEq(queryVO.getCalendarId())
+    			.dictTypeEq(queryVO.getDictType()).builderQueryWrapper();
+    	List<WorkCalendarDict> list = this.workCalendarDictService.list(queryWrapper);
+    	if (CollectionUtil.isEmpty(list)) {
+			return ResponseUtil.successResult(Lists.newArrayList());
+		}
+    	
+    	//Map<String, Map<String, String>> dictTypeMap = new HashMap<String, Map<String, String>>(2);
+    	Map<String, String> dictTypeCode = new HashMap<String, String>(8);
+    	String dictType = null;
+    	for (WorkCalendarDict dict : list) {
+    		dictType = dict.getDictType();
+    		if (WorkCalendarConstant.CUSTOM_CALENDAR_DICT_TYPE.equals(dictType)) {
+    			dictTypeCode.put(StringUtil.isBlank(dict.getDictCode()) ? dict.getDictDesc() : dict.getDictCode(), dict.getDictDesc());
+			} else {
+				dictTypeCode.put(dict.getDictCode(), dict.getDictDesc());
+			}
+		}
+    	//dictTypeMap.put(dictType, dictTypeCode);
+		return ResponseUtil.successResult(dictTypeCode);
+    }
+    
+    @ApiOperation(value = "字典值创建")
+    @RequestMapping(value = "dictCreate")
+    public ResponseResult dictCreate(@RequestBody @Validated DictCreateVO<DictCodeCreate> createVO) {
+    	WorkCalendarDict calendarDict = new WorkCalendarDict();
+    	BeanUtils.copyProperties(createVO, calendarDict);
+    	boolean result = this.workCalendarDictService.batchCreateOrUpdateDict(calendarDict, createVO.getCodes());
+    	return result ? ResponseUtil.successResult("创建成功") : ResponseUtil.successResult("创建失败");
+    }
+    
+}

+ 330 - 0
src/main/java/com/persagy/calendar/controller/OldWorkCalendarController.java

@@ -0,0 +1,330 @@
+package com.persagy.calendar.controller;
+
+import java.util.List;
+import java.util.Map;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RestController;
+
+import com.persagy.calendar.handle.WorkCalendarHandler;
+import com.persagy.calendar.pojo.dto.OldWorkCalendar;
+import com.persagy.calendar.pojo.dto.WorkCalendar;
+import com.persagy.calendar.pojo.old.OldCalendarIntervalCreateVO;
+import com.persagy.calendar.pojo.old.OldCalendarIntervalDeleteVO;
+import com.persagy.calendar.pojo.old.OldCalendarIntervalsByTag;
+import com.persagy.calendar.pojo.old.OldCalendarIntervalsVO;
+import com.persagy.calendar.pojo.old.OldCalendarQueryVO;
+import com.persagy.calendar.pojo.old.OldCalendarResponseVO;
+import com.persagy.calendar.pojo.old.OldCalendarRuleCreateVO;
+import com.persagy.calendar.pojo.old.OldCalendarRuleDeleteVO;
+import com.persagy.calendar.pojo.old.OldCalendarRuleVO;
+import com.persagy.calendar.pojo.old.OldCalendarTagsVO;
+import com.persagy.calendar.pojo.old.OldWorkCalendarVO;
+import com.persagy.calendar.service.IWorkCalendarService;
+import com.persagy.calendar.service.OldWorkCalendarDateService;
+import com.persagy.calendar.utils.ResponseOldResult;
+import com.persagy.calendar.utils.ResponseOldResultUtil;
+import com.persagy.common.constant.HistoryConstant;
+import com.persagy.common.utils.StringUtil;
+
+import cn.hutool.core.collection.CollectionUtil;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+
+/**
+ * @version 
+ * @description 老服务兼容controller
+ * @company persagy
+ * @author zhangqiankun
+ * @since 2020年10月3日:	下午2:41:21
+ */
+
+@Api(tags = "老版工作历服务接口")
+@RestController
+@RequestMapping(value = "/data-platform-3/calendar", method = RequestMethod.POST)
+public class OldWorkCalendarController {
+	
+	// 老版工作历默认projectId
+	private static final String DEFAULT_PROJECT_ID = HistoryConstant.DEFAULT_PROJECT_ID;
+	
+	@Autowired
+    private IWorkCalendarService workCalendarService;
+    
+    @Autowired
+    private WorkCalendarHandler workCalendarHandler;
+    
+    @Autowired
+    private OldWorkCalendarDateService oldWorkCalendarDateService;
+	
+    /**
+     * 创建工作历,name groupId联合唯一
+     */
+    @ApiOperation(value = "创建工作历")
+	@RequestMapping(value = "create")
+	public ResponseOldResult create(@RequestBody @Validated OldWorkCalendarVO oldWorkCalendar) {
+		// 判断是否唯一
+		boolean result = workCalendarService.checkProjetcIdAndName(null, DEFAULT_PROJECT_ID, null, oldWorkCalendar.getName());
+		if (!result) {
+			return ResponseOldResultUtil.errorResultMsg("name已存在");
+		}
+		
+		WorkCalendar workCalendar = new WorkCalendar();
+		workCalendar.setProjectId(DEFAULT_PROJECT_ID);
+		workCalendar.setCalendarName(oldWorkCalendar.getName());
+		workCalendar.setCalendarDesc(oldWorkCalendar.getDesc());
+		result = workCalendarService.save(workCalendar);
+		
+		return result ? ResponseOldResultUtil.successResultId(workCalendar.getId())
+				: ResponseOldResultUtil.errorResultMsg("创建工作历失败");
+	}
+	
+	/**
+     * 创建一套与已有工作历内容一样的工作历,name groupId联合唯一
+     */
+	@ApiOperation(value = "从模板创建工作历")
+	@RequestMapping(value = "create_from")
+	public ResponseOldResult create_from(@RequestBody @Validated OldWorkCalendarVO oldWorkCalendar) {
+		String from_id = oldWorkCalendar.getFrom_id();
+		if (StringUtil.isBlank(from_id)) {
+			return ResponseOldResultUtil.errorResultMsg("from_id不可为空");
+		}
+		//判断原信息是否存在
+		WorkCalendar calendar = workCalendarService.getById(from_id, DEFAULT_PROJECT_ID);
+		if (calendar == null) {
+			return ResponseOldResultUtil.errorResultMsg("原工作历信息不存在");
+		}
+		
+		// 判断是否唯一
+		boolean result = workCalendarService.checkProjetcIdAndName(null, DEFAULT_PROJECT_ID, null, oldWorkCalendar.getName());
+		if (!result) {
+			return ResponseOldResultUtil.errorResultMsg("name已存在");
+		}
+		
+		WorkCalendar workCalendar = new WorkCalendar();
+		workCalendar.setProjectId(DEFAULT_PROJECT_ID);
+		workCalendar.setCalendarName(oldWorkCalendar.getName());
+		workCalendar.setCalendarDesc(oldWorkCalendar.getDesc());
+		result = this.workCalendarHandler.createOldWorkCalendarFromId(from_id, DEFAULT_PROJECT_ID, workCalendar);
+		return result ? ResponseOldResultUtil.successResultId(workCalendar.getId()) : ResponseOldResultUtil.errorResultMsg("创建工作历失败");
+	}
+	
+    /**
+     * 修改工作历,name groupId联合唯一
+     */
+	@ApiOperation(value = "更新工作历")
+	@RequestMapping(value = "update")
+	public ResponseOldResult update(@RequestBody @Validated OldWorkCalendarVO oldWorkCalendar) {
+		String id = oldWorkCalendar.getId();
+		if (StringUtil.isBlank(id)) {
+			return ResponseOldResultUtil.errorResultMsg("id不可为空");
+		}
+		// 判断是否唯一
+		boolean result = workCalendarService.checkProjetcIdAndName(id, DEFAULT_PROJECT_ID, null, oldWorkCalendar.getName());
+		if (!result) {
+			return ResponseOldResultUtil.errorResultMsg("name已存在");
+		}
+		
+		WorkCalendar workCalendar = new WorkCalendar();
+		workCalendar.setId(id);
+		workCalendar.setProjectId(DEFAULT_PROJECT_ID);
+		workCalendar.setCalendarName(oldWorkCalendar.getName());
+		workCalendar.setCalendarDesc(oldWorkCalendar.getDesc());
+		result = workCalendarService.updateWorkCalendar(workCalendar);
+		
+		return result ? ResponseOldResultUtil.successResult()
+				: ResponseOldResultUtil.errorResultMsg("更新工作历失败");
+	}
+	
+	/**
+     * 删除工作历,级联删除规则
+     */
+	@ApiOperation(value = "删除工作历")
+	@RequestMapping(value = "delete")
+	public ResponseOldResult delete(@RequestBody Map<String, String> requestMap) {
+		String id = requestMap.get("id");
+		if (StringUtil.isBlank(id)) {
+			return ResponseOldResultUtil.errorResultMsg("id不可为空");
+		}
+		
+		return this.workCalendarHandler.deleteWorkCalendar(id);
+	}
+	
+	/**
+     * 查询工作历,默认只查老的工作历信息
+     * 无需参数
+     */
+	@ApiOperation(value = "查询工作历")
+	@RequestMapping(value = "query")
+	public ResponseOldResult query(@RequestBody Map<String, String> map) {
+		// 默认只查正常的
+		OldWorkCalendar oldWorkCalendar = new OldWorkCalendar();
+		oldWorkCalendar.setProjectId(DEFAULT_PROJECT_ID);
+		List<OldWorkCalendar> calendarList = oldWorkCalendarDateService.queryOldCalendarList(oldWorkCalendar);
+		return ResponseOldResultUtil.successResultContent(calendarList, 
+				CollectionUtil.isEmpty(calendarList) ? 0 : calendarList.size());
+	}
+	
+	/**
+     * 创建规则
+     */
+	@ApiOperation(value = "创建规则")
+	@RequestMapping(value = "create_rules")
+	public ResponseOldResult createRules(@RequestBody @Validated OldCalendarRuleVO<OldCalendarRuleCreateVO> requestData) {
+		boolean result = this.oldWorkCalendarDateService.createOldCalendarRule(requestData);
+		return result ? ResponseOldResultUtil.successResultContent("", requestData.getRules().size())
+				: ResponseOldResultUtil.errorResultMsg("创建规则失败");
+	}
+	
+	/**
+     * 删除规则
+     */
+	@ApiOperation(value = "删除规则")
+	@RequestMapping(value = "del_rules")
+	public ResponseOldResult delRules(@RequestBody @Validated OldCalendarRuleVO<OldCalendarRuleDeleteVO> requestData) {
+		boolean result = this.oldWorkCalendarDateService.deleteOldCalendarRule(requestData);
+		return result ? ResponseOldResultUtil.successResultContent("", requestData.getRules().size())
+				: ResponseOldResultUtil.errorResultMsg("删除规则失败");
+	}
+	
+	/**
+     * 更新规则
+     */
+	@ApiOperation(value = "更新规则")
+	@RequestMapping(value = "update_rule")
+	public ResponseOldResult updateRule(@RequestBody @Validated OldCalendarRuleCreateVO requestData) {
+		// 判断工作历信息是否存在
+		WorkCalendar calendar = workCalendarService.getById(requestData.getId(), DEFAULT_PROJECT_ID);
+		if (calendar == null) {
+			return ResponseOldResultUtil.errorResultMsg("工作历信息不存在");
+		}
+		
+		boolean result = this.oldWorkCalendarDateService.updateOldCalendarRule(requestData);
+		return result ? ResponseOldResultUtil.successResult()
+				: ResponseOldResultUtil.errorResultMsg("更新规则失败");
+	}
+	
+	/**
+     * 查询规则
+     * id 必填 tag选填
+     */
+	@ApiOperation(value = "查询规则")
+	@RequestMapping(value = "query_rules")
+	public ResponseOldResult queryRules(@RequestBody @Validated Map<String, String> requestData) {
+		String id = requestData.get("id");
+		if (StringUtil.isBlank(id)) {
+			return ResponseOldResultUtil.errorResultMsg("id不可为空");
+		}
+		List<OldWorkCalendar> list = this.oldWorkCalendarDateService.queryOldCalendarRuleList(id, requestData.get("tag"), DEFAULT_PROJECT_ID);
+		return ResponseOldResultUtil.successResultContent(list, CollectionUtil.isEmpty(list) ? 0 : list.size());
+	}
+	
+	/**
+     * 设置作息日期
+     */
+	@ApiOperation(value = "设置作息日期")
+	@RequestMapping(value = "set_tags")
+	public ResponseOldResult setTags(@RequestBody @Validated OldCalendarTagsVO requestData) {
+		// 判断工作历信息是否存在
+		WorkCalendar calendar = workCalendarService.getById(requestData.getId(), DEFAULT_PROJECT_ID);
+		if (calendar == null) {
+			return ResponseOldResultUtil.errorResultMsg("工作历信息不存在");
+		}
+		
+		boolean result = this.oldWorkCalendarDateService.setTags(requestData.getId(), requestData.getTags());
+		return result ? ResponseOldResultUtil.successResult() : ResponseOldResultUtil.errorResultMsg("设置作息日期失败");
+	}
+	
+	/**
+     * 删除作息日期
+     */
+	@ApiOperation(value = "删除作息日期")
+	@RequestMapping(value = "unset_tags")
+	public ResponseOldResult unsetTags(@RequestBody @Validated OldCalendarTagsVO requestData) {
+		// 判断工作历信息是否存在
+		WorkCalendar calendar = workCalendarService.getById(requestData.getId(), DEFAULT_PROJECT_ID);
+		if (calendar == null) {
+			return ResponseOldResultUtil.errorResultMsg("工作历信息不存在");
+		}
+		
+		boolean result = this.oldWorkCalendarDateService.unsetTags(requestData.getId(), requestData.getTags());
+		return result ? ResponseOldResultUtil.successResult()
+				: ResponseOldResultUtil.errorResultMsg("删除作息日期失败");
+	}
+	
+	/**
+     * 设置作息时间段
+     */
+	@ApiOperation(value = "设置作息时间段")
+	@RequestMapping(value = "set_intervals")
+	public ResponseOldResult setIntervals(@RequestBody @Validated OldCalendarIntervalsVO<OldCalendarIntervalCreateVO> requestData) {
+		// 判断工作历信息是否存在
+		WorkCalendar calendar = workCalendarService.getById(requestData.getId(), DEFAULT_PROJECT_ID);
+		if (calendar == null) {
+			return ResponseOldResultUtil.errorResultMsg("工作历信息不存在");
+		}
+		
+		boolean result = this.oldWorkCalendarDateService.setIntervals(requestData.getId(), requestData.getIntervals());
+		return result ? ResponseOldResultUtil.successResult()
+				: ResponseOldResultUtil.errorResultMsg("设置作息日期失败");
+	}
+	
+	/**
+     * 删除作息时间段
+     */
+	@ApiOperation(value = "删除作息时间段")
+	@RequestMapping(value = "unset_intervals")
+	public ResponseOldResult unsetIntervals(@RequestBody @Validated OldCalendarIntervalsVO<OldCalendarIntervalDeleteVO> requestData) {
+		// 判断工作历信息是否存在
+		WorkCalendar calendar = workCalendarService.getById(requestData.getId(), DEFAULT_PROJECT_ID);
+		if (calendar == null) {
+			return ResponseOldResultUtil.errorResultMsg("工作历信息不存在");
+		}
+		
+		boolean result = this.oldWorkCalendarDateService.unsetIntervals(requestData.getId(), requestData.getIntervals());
+		return result ? ResponseOldResultUtil.successResult()
+				: ResponseOldResultUtil.errorResultMsg("设置作息日期失败");
+	}
+	
+	/**
+     * 根据tag设置作息时段
+     */
+	@ApiOperation(value = "根据tag设置作息时段")
+	@RequestMapping(value = "set_intervals_by_tag")
+	public ResponseOldResult setIntervalsByTag(@RequestBody @Validated OldCalendarIntervalsByTag requestData) {
+		// 判断工作历信息是否存在
+		WorkCalendar calendar = workCalendarService.getById(requestData.getId(), DEFAULT_PROJECT_ID);
+		if (calendar == null) {
+			return ResponseOldResultUtil.errorResultMsg("工作历信息不存在");
+		}
+		
+		boolean result = this.oldWorkCalendarDateService.setIntervalsByTag(requestData);
+		return result ? ResponseOldResultUtil.successResult()
+				: ResponseOldResultUtil.errorResultMsg("设置作息日期失败");
+	}
+	
+	/**
+	 * 查询工作历详情,包含解析过程
+	 * @param requestData
+	 * @return
+	 */
+	@ApiOperation(value = "查询工作历详情")
+	@RequestMapping(value = "query_details")
+	public ResponseOldResult queryDetails(@RequestBody @Validated OldCalendarQueryVO requestData) {
+		// 判断工作历信息是否存在
+		WorkCalendar calendar = workCalendarService.getById(requestData.getId(), DEFAULT_PROJECT_ID);
+		if (calendar == null) {
+			return ResponseOldResultUtil.errorResultMsg("工作历信息不存在");
+		}
+		
+		if (CollectionUtil.isEmpty(requestData.getTags()) && CollectionUtil.isEmpty(requestData.getIntervals())) {
+			return ResponseOldResultUtil.errorResultMsg("tags和intervals必填其一");
+		}
+		
+		List<OldCalendarResponseVO> details = this.workCalendarHandler.queryOldCalendarDetails(requestData);
+		return ResponseOldResultUtil.successResultContent(details, details.size());
+	}
+}

+ 207 - 0
src/main/java/com/persagy/calendar/controller/RwdObjectController.java

@@ -0,0 +1,207 @@
+package com.persagy.calendar.controller;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RestController;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
+import com.persagy.calendar.client.model.BaseModel;
+import com.persagy.calendar.client.model.RwdObjectModel;
+import com.persagy.calendar.constant.WorkCalendarConstant;
+import com.persagy.calendar.pojo.dto.WorkCalendar;
+import com.persagy.calendar.pojo.dto.WorkCalendarObject;
+import com.persagy.calendar.pojo.vo.RwdObjectQueryVO;
+import com.persagy.calendar.pojo.vo.WorkCalendarObjectUpdateVO;
+import com.persagy.calendar.pojo.vo.WorkCalendarQueryVO;
+import com.persagy.calendar.service.IWorkCalendarObjectService;
+import com.persagy.calendar.service.IWorkCalendarService;
+import com.persagy.calendar.service.RwdObjectService;
+import com.persagy.common.enums.ResponseCode;
+import com.persagy.common.utils.DateUtil;
+import com.persagy.common.utils.ResponseResult;
+import com.persagy.common.utils.ResponseUtil;
+import com.persagy.common.utils.StringUtil;
+
+import cn.hutool.core.collection.CollectionUtil;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+
+/**
+ * @version 
+ * @description 
+ * @company persagy
+ * @author zhangqiankun
+ * @since 2021年3月2日:	下午3:16:15
+ */
+@RestController
+@Api(tags = "物理世界对象管理")
+@RequestMapping(value = "/v2.0/rwdObject", method = RequestMethod.POST)
+public class RwdObjectController {
+	
+	@Autowired
+	private RwdObjectService rwdObjectService;
+	
+    @Autowired
+    private IWorkCalendarService workCalendarService;
+    
+	@Autowired
+	private IWorkCalendarObjectService workCalendarObjectService;
+	
+	/**
+	 * 物理世界对象列表查询
+	 * @param queryVO
+	 * @return
+	 */
+	@ApiOperation(value = "物理世界对象列表查询")
+    @RequestMapping(value = "queryRwdObjects")
+	public ResponseResult queryRwdObjects(@RequestBody @Validated RwdObjectQueryVO queryVO) {
+		BaseModel baseModel = new BaseModel();
+		BeanUtils.copyProperties(queryVO, baseModel);
+		RwdObjectModel objectModel = new RwdObjectModel();
+		BeanUtils.copyProperties(queryVO, objectModel);
+		return this.rwdObjectService.queryRwdObjects(baseModel, objectModel);
+	}
+	
+	/**
+	 * 查询工作历对象列表
+	 * @param queryVO
+	 * @return
+	 */
+	@ApiOperation(value = "查询工作历对象列表")
+    @RequestMapping(value = "queryCalendarObjectList")
+    public ResponseResult queryCalendarObjectList(@RequestBody @Validated WorkCalendarQueryVO queryVO) {
+		QueryWrapper<WorkCalendarObject> queryWrapper = null;
+    	if (StringUtil.isNotBlank(queryVO.getObjId()) && StringUtil.isBlank(queryVO.getId())) {
+    		queryWrapper = new WorkCalendarObject.Builder().createQueryWrapper()
+    				.groupCodeEq(queryVO.getGroupCode()).projectIdEq(queryVO.getProjectId())
+    				.objectIdEq(queryVO.getObjId()).builderQueryWrapper();
+			WorkCalendarObject calendarObject = this.workCalendarObjectService.getOne(queryWrapper);
+			if (calendarObject == null) {
+				return ResponseUtil.successResult(Lists.newArrayList(), 0L);
+			}
+			queryVO.setId(calendarObject.getCalendarId());
+		}
+    	// 默认只查正常的
+    	QueryWrapper<WorkCalendar> calendarWrapper = new WorkCalendar.Builder().createQueryWrapper()
+    			.idEq(queryVO.getId()).groupCodeEq(queryVO.getGroupCode())
+    			.projectIdEq(queryVO.getProjectId()).calendarNameLike(queryVO.getCalendarName())
+    			.delFlagEq(WorkCalendarConstant.WORK_CALENDAR_DEL_FLAG_NOR).builderQueryWrapper();
+    	List<WorkCalendar> list = this.workCalendarService.list(calendarWrapper);
+    	if (CollectionUtil.isEmpty(list)) {
+    		return ResponseUtil.successResult(Lists.newArrayList(), 0L);
+		}
+    	// 遍历获取对象名称
+		BaseModel baseModel = new BaseModel();
+		BeanUtils.copyProperties(queryVO, baseModel);
+		RwdObjectModel objectModel = new RwdObjectModel();
+		objectModel.setObjType(Sets.newHashSet("space", "floor", "building", "project"));
+    	for (WorkCalendar workCalendar : list) {
+    		queryWrapper = new WorkCalendarObject.Builder().createQueryWrapper()
+    				.groupCodeEq(queryVO.getGroupCode()).projectIdEq(queryVO.getProjectId())
+    				.calendarIdEq(workCalendar.getId()).builderQueryWrapper();
+			List<WorkCalendarObject> calendarObjects = this.workCalendarObjectService.list(queryWrapper);
+			if (CollectionUtil.isNotEmpty(calendarObjects)) {
+				List<JSONObject> objects = workCalendar.getObjects();
+				objects = CollectionUtil.isEmpty(objects) ? new ArrayList<JSONObject>() : objects;
+				for (WorkCalendarObject object : calendarObjects) {
+					objectModel.setId(object.getObjectId());
+					ResponseResult result = this.rwdObjectService.queryRwdObjects(baseModel, objectModel);
+					Object content = result.getContent();
+					if (content != null) {
+						JSONArray array = JSONArray.parseArray(JSON.toJSONString(content));
+						if (array != null && array.size() > 0) {
+							JSONObject jsonObject = array.getJSONObject(0);
+							String objectName = jsonObject.getString("name");
+							jsonObject = new JSONObject();
+							jsonObject.put("objectName", objectName);
+							jsonObject.put("objectId", object.getObjectId());
+							objects.add(jsonObject);
+						}
+					}
+				}
+				workCalendar.setObjects(objects);
+			}
+		}
+    	return ResponseUtil.successResult(list, (long)list.size());
+    }
+	
+	/**
+	 * 添加对象工作历
+	 */
+	@ApiOperation(value = "添加对象工作历")
+	@RequestMapping(value = "addCalendarObject")
+	public ResponseResult addCalendarObject(@RequestBody @Validated WorkCalendarObjectUpdateVO updateVO) {
+		if (StringUtil.isBlank(updateVO.getCalendarId())) {
+			return ResponseUtil.errorResult(ResponseCode.A0402.getCode(), "工作历ID不可为空");
+		}
+		if (StringUtil.isBlank(updateVO.getObjId()) && CollectionUtil.isEmpty(updateVO.getObjIds())) {
+			return ResponseUtil.errorResult(ResponseCode.A0402.getCode(), "对象ID或对象ID集合,必须存在其一");
+		}
+		WorkCalendarObject calendarObject = new WorkCalendarObject();
+		BeanUtils.copyProperties(updateVO, calendarObject);
+		if (CollectionUtil.isEmpty(updateVO.getObjIds())) {
+			updateVO.setObjIds(Sets.newHashSet(updateVO.getObjId()));
+		} else {
+			updateVO.getObjIds().add(updateVO.getObjId());
+		}
+		this.workCalendarObjectService.batchInsertObjects(calendarObject, updateVO.getObjIds());
+		return ResponseUtil.successResult("添加成功");
+	}
+	
+	/**
+	 * 删除加对象工作历
+	 */
+	@ApiOperation(value = "删除加对象工作历")
+	@RequestMapping(value = "deleteCalendarObject")
+	public ResponseResult deleteCalendarObject(@RequestBody @Validated WorkCalendarObjectUpdateVO updateVO) {
+		if (StringUtil.isBlank(updateVO.getObjId()) && CollectionUtil.isEmpty(updateVO.getObjIds())) {
+			return ResponseUtil.errorResult(ResponseCode.A0402.getCode(), "对象ID或对象ID集合,必须存在其一");
+		}
+		WorkCalendarObject calendarObject = new WorkCalendarObject();
+		BeanUtils.copyProperties(updateVO, calendarObject);
+		if (CollectionUtil.isEmpty(updateVO.getObjIds())) {
+			updateVO.setObjIds(Sets.newHashSet(updateVO.getObjId()));
+		} else {
+			updateVO.getObjIds().add(updateVO.getObjId());
+		}
+		QueryWrapper<WorkCalendarObject> queryWrapper = new WorkCalendarObject.Builder().createQueryWrapper()
+				.groupCodeEq(updateVO.getGroupCode()).calendarIdEq(updateVO.getCalendarId())
+				.projectIdEq(updateVO.getProjectId()).objectIdIn(updateVO.getObjIds()).builderQueryWrapper();
+		boolean result = this.workCalendarObjectService.remove(queryWrapper);
+		return result ? ResponseUtil.successResult("删除成功") : ResponseUtil.errorResult("删除失败");
+	}
+	
+    /**
+     * 对象变更所属工作历
+     */
+    @ApiOperation(value = "对象变更所属工作历")
+    @RequestMapping(value = "changeCalendarObject")
+    public ResponseResult changeCalendarObject(@RequestBody @Validated WorkCalendarObjectUpdateVO updateVO) {
+    	if (StringUtil.isBlank(updateVO.getCalendarId())) {
+			return ResponseUtil.errorResult(ResponseCode.A0402.getCode(), "工作历ID不可为空");
+		}
+    	if (CollectionUtil.isEmpty(updateVO.getObjIds())) {
+			return ResponseUtil.errorResult(ResponseCode.A0402.getCode(), "对象ID集合不可为空");
+		}
+    	WorkCalendarObject calendarObject = new WorkCalendarObject();
+    	BeanUtils.copyProperties(updateVO, calendarObject);
+    	calendarObject.setUpdateUser(updateVO.getUserId());
+    	calendarObject.setCreateTime(DateUtil.format(new Date(), DateUtil.FORMAT_DATE_YYYYMMDDHHMMSS));
+    	boolean result = this.workCalendarObjectService.replaceCalendarObject(calendarObject, updateVO.getObjIds());
+    	return result ? ResponseUtil.successResult("操作成功") : ResponseUtil.errorResult("操作失败");
+    }
+	
+}

+ 170 - 0
src/main/java/com/persagy/calendar/controller/WorkCalendarController.java

@@ -0,0 +1,170 @@
+package com.persagy.calendar.controller;
+
+import java.util.List;
+
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RestController;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.google.common.collect.Lists;
+import com.persagy.calendar.constant.WorkCalendarConstant;
+import com.persagy.calendar.handle.WorkCalendarHandler;
+import com.persagy.calendar.pojo.dto.WorkCalendar;
+import com.persagy.calendar.pojo.dto.WorkCalendar.Builder;
+import com.persagy.calendar.pojo.dto.WorkCalendarObject;
+import com.persagy.calendar.pojo.vo.BaseUpdateVO;
+import com.persagy.calendar.pojo.vo.WorkCalendarQueryVO;
+import com.persagy.calendar.pojo.vo.WorkCalendarUpdateVO;
+import com.persagy.calendar.service.IWorkCalendarObjectService;
+import com.persagy.calendar.service.IWorkCalendarService;
+import com.persagy.common.enums.ResponseCode;
+import com.persagy.common.utils.ResponseResult;
+import com.persagy.common.utils.ResponseUtil;
+import com.persagy.common.utils.StringUtil;
+
+import cn.hutool.core.collection.CollectionUtil;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+
+/**
+ * 工作历主表
+ * 
+ * @version 1.0.0
+ * @company persagy 
+ * @author zhangqiankun
+ * @date 2020-10-02 11:33:00
+ */
+
+@Api(tags = "工作历类型")
+@RestController
+@RequestMapping(value = "/v2.0/workCalendar", method = RequestMethod.POST)
+public class WorkCalendarController {
+    
+    @Autowired
+    private IWorkCalendarService workCalendarService;
+    
+    @Autowired
+    private WorkCalendarHandler workCalendarHandler;
+    
+    @Autowired
+    private IWorkCalendarObjectService workCalendarObjectService;
+    
+    /**
+     * 列表查询
+     */
+    @ApiOperation(value = "普通列表查询")
+    @RequestMapping(value = "queryWorkCalendarList")
+    public ResponseResult queryWorkCalendarList(@RequestBody @Validated WorkCalendarQueryVO queryVO) {
+    	if (StringUtil.isNotBlank(queryVO.getObjId()) && StringUtil.isBlank(queryVO.getId())) {
+    		QueryWrapper<WorkCalendarObject> queryWrapper = new WorkCalendarObject.Builder().createQueryWrapper()
+    				.groupCodeEq(queryVO.getGroupCode()).projectIdEq(queryVO.getProjectId())
+    				.objectIdEq(queryVO.getObjId()).builderQueryWrapper();
+			WorkCalendarObject calendarObject = this.workCalendarObjectService.getOne(queryWrapper);
+			if (calendarObject == null) {
+				return ResponseUtil.successResult(Lists.newArrayList());
+			}
+			queryVO.setId(calendarObject.getCalendarId());
+		}
+    	// 默认只查正常的
+    	Builder builder = new WorkCalendar.Builder().createQueryWrapper();
+    	QueryWrapper<WorkCalendar> queryWrapper = builder.idEq(queryVO.getId()).groupCodeEq(queryVO.getGroupCode())
+    		.projectIdEq(queryVO.getProjectId()).calendarNameLike(queryVO.getCalendarName())
+    		.delFlagEq(WorkCalendarConstant.WORK_CALENDAR_DEL_FLAG_NOR).builderQueryWrapper();
+    	List<WorkCalendar> list = workCalendarService.list(queryWrapper);
+    	return ResponseUtil.successResult(list, CollectionUtil.isEmpty(list) ? 0L : list.size());
+    }
+    
+    /**
+	 * 根据原有的工作历ID创建新的工作历信息和规则信息
+	 */
+    @ApiOperation(value = "根据原有的工作历创建")
+    @RequestMapping(value = "createWorkCalendarFromId")
+    public ResponseResult createWorkCalendarFromId(@RequestBody @Validated WorkCalendarUpdateVO updateVO) {
+    	if (StringUtil.isBlank(updateVO.getFromId())) {
+			return ResponseUtil.errorResult(ResponseCode.A0400.getCode(), "工作历来源ID不可为空");
+		}
+    	// 判断原有的工作历信息是否存在
+		WorkCalendar workCalendar = workCalendarService.getById(updateVO.getFromId(), updateVO.getProjectId());
+		if (workCalendar == null) {
+			return ResponseUtil.errorResult(ResponseCode.C0320.getCode(), "原工作历信息不存在");
+		}
+		// 验证projectId和name是否联合唯一
+		boolean result = workCalendarService.checkProjetcIdAndName(null, updateVO.getProjectId(), updateVO.getGroupCode(), updateVO.getCalendarName());
+		if (!result) {
+			return ResponseUtil.errorResult(ResponseCode.C0341.getCode(), "工作历名称已存在");
+		}
+		workCalendar = new WorkCalendar();
+		BeanUtils.copyProperties(updateVO, workCalendar);
+		workCalendar.setId(null);	// 置空
+		workCalendar.setUpdateUser(updateVO.getUserId());
+    	return this.workCalendarHandler.createWorkCalendarFromId(updateVO.getFromId(), workCalendar);
+    }
+    
+    /**
+     * 新增
+     */
+	@ApiOperation(value = "新增")
+	@RequestMapping(value = "createWorkCalendar")
+    public ResponseResult createWorkCalendar(@RequestBody @Validated WorkCalendarUpdateVO updateVO) {
+		// 判断projectId和name是否联合唯一
+		boolean result = workCalendarService.checkProjetcIdAndName(null, updateVO.getProjectId(), updateVO.getGroupCode(), updateVO.getCalendarName());
+		if (!result) {
+			return ResponseUtil.errorResult(ResponseCode.C0341.getCode(), "名称重复");
+		}
+		
+		WorkCalendar workCalendar = new WorkCalendar();
+		BeanUtils.copyProperties(updateVO, workCalendar);
+		workCalendar.setId(null);	// 置空
+		workCalendar.setUpdateUser(updateVO.getUserId());
+        result = this.workCalendarService.createWorkCalendar(workCalendar, updateVO.getObjIds());
+        return result ? ResponseUtil.successResult("新增成功", workCalendar.getId()) : ResponseUtil.errorResult("新增失败");
+    }
+    
+    /**
+     * 更新
+     */
+	@ApiOperation(value = "更新")
+	@RequestMapping(value = "updateWorkCalendar")
+    public ResponseResult updateWorkCalendar(@RequestBody @Validated WorkCalendarUpdateVO updateVO) {
+		if (StringUtil.isBlank(updateVO.getId())) {
+			return ResponseUtil.errorResult(ResponseCode.A0400.getCode(), "工作历ID不可为空");
+		}
+		// 判断原数据是否存在
+		WorkCalendar calendar = workCalendarService.getById(updateVO.getId(), updateVO.getProjectId());
+		if (calendar == null) {
+			return ResponseUtil.errorResult(ResponseCode.C0320.getCode(), ResponseCode.C0320.getDesc());
+		}
+		
+		// 判断projectId和name是否联合唯一
+		boolean result = workCalendarService.checkProjetcIdAndName(updateVO.getId(), updateVO.getProjectId(), updateVO.getGroupCode(), updateVO.getCalendarName());
+		if (!result) {
+			return ResponseUtil.errorResult(ResponseCode.C0341.getCode(), "数据重复");
+		}
+		
+		WorkCalendar workCalendar = new WorkCalendar();
+		BeanUtils.copyProperties(updateVO, workCalendar);
+		workCalendar.setUpdateUser(updateVO.getUserId());
+        result = workCalendarService.updateWorkCalendar(workCalendar);
+        return result ? ResponseUtil.successResult("更新成功") : ResponseUtil.errorResult("更新失败");
+    }
+
+    /**
+     * 逻辑删除,且级联删除
+     */
+    @ApiOperation(value = "删除")
+    @RequestMapping(value = "deleteWorkCalendar")
+    public ResponseResult deleteWorkCalendar(@RequestBody @Validated BaseUpdateVO baseUpdateVO) {
+    	// 判断原数据是否存在
+		WorkCalendar calendar = workCalendarService.getById(baseUpdateVO.getId(), baseUpdateVO.getProjectId());
+		if (calendar == null) {
+			return ResponseUtil.errorResult(ResponseCode.C0320.getCode(), ResponseCode.C0320.getDesc());
+		}
+		return workCalendarHandler.deleteWorkCalendar(baseUpdateVO);
+    }
+    
+}

+ 154 - 0
src/main/java/com/persagy/calendar/controller/WorkCalendarDateController.java

@@ -0,0 +1,154 @@
+package com.persagy.calendar.controller;
+
+import java.util.List;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RestController;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.persagy.calendar.constant.WorkCalendarConstant;
+import com.persagy.calendar.handle.WorkCalendarDateHandler;
+import com.persagy.calendar.pojo.dto.WorkCalendar;
+import com.persagy.calendar.pojo.dto.WorkCalendarDate;
+import com.persagy.calendar.pojo.dto.WorkCalendarObject;
+import com.persagy.calendar.pojo.vo.CalendarDateResult;
+import com.persagy.calendar.pojo.vo.CustomCalendarVO;
+import com.persagy.calendar.pojo.vo.WorkCalendarDateCreateVO;
+import com.persagy.calendar.pojo.vo.WorkCalendarDateDeleteVO;
+import com.persagy.calendar.pojo.vo.WorkCalendarDateQueryVO;
+import com.persagy.calendar.pojo.vo.WorkCalendarDateUpdateVO;
+import com.persagy.calendar.pojo.vo.WorkCalendarMoreDateCreateVO;
+import com.persagy.calendar.service.IWorkCalendarDateService;
+import com.persagy.calendar.service.IWorkCalendarObjectService;
+import com.persagy.calendar.service.IWorkCalendarService;
+import com.persagy.common.enums.ResponseCode;
+import com.persagy.common.exception.BusinessException;
+import com.persagy.common.utils.ResponseResult;
+import com.persagy.common.utils.ResponseUtil;
+import com.persagy.common.utils.StringUtil;
+
+import cn.hutool.core.collection.CollectionUtil;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+
+/**
+ * 工作历作息时间表
+ * 
+ * @version 1.0.0
+ * @company persagy 
+ * @author zhangqiankun
+ * @date 2020-10-03 13:54:22
+ */
+@Api(tags = "工作历作息时间")
+@RestController
+@RequestMapping(value = "/v2.0/workCalendarDate", method = RequestMethod.POST)
+public class WorkCalendarDateController {
+  
+    @Autowired
+    private IWorkCalendarService workCalendarService;
+	
+	@Autowired
+	private WorkCalendarDateHandler workCalendarDateHandler;
+
+    @Autowired
+    private IWorkCalendarDateService workCalendarDateService;
+    
+    @Autowired
+    private IWorkCalendarObjectService workCalendarObjectService;
+    
+    /**
+     * 列表查询
+     */
+    @ApiOperation(value = "列表查询")
+    @RequestMapping(value = "queryWorkCalendarDateList")
+    public ResponseResult queryWorkCalendarDateList(@RequestBody @Validated WorkCalendarDateQueryVO queryVO) {
+    	/*if (StringUtil.isBlank(queryVO.getProjectId())) {
+			return ResponseUtil.errorResult("项目ID不可为空");
+		}*/
+    	if (StringUtil.isNotBlank(queryVO.getObjId())) {
+    		QueryWrapper<WorkCalendarObject> queryWrapper = new WorkCalendarObject.Builder().createQueryWrapper()
+    				.projectIdEq(queryVO.getProjectId()).objectIdEq(queryVO.getObjId()).builderQueryWrapper();
+			WorkCalendarObject calendarObject = this.workCalendarObjectService.getOne(queryWrapper);
+			if (calendarObject == null || StringUtil.isBlank(calendarObject.getCalendarId())) {
+				return ResponseUtil.errorResult("此对象ID,不存在工作历作息时间信息");
+			}
+			if (StringUtil.isNotBlank(queryVO.getCalendarId()) && !queryVO.getCalendarId().equals(calendarObject.getCalendarId())) {
+				return ResponseUtil.errorResult("此对象ID,不属于此工作历");
+			}
+			queryVO.setCalendarId(calendarObject.getCalendarId());
+		}
+		List<CalendarDateResult> dateList = this.workCalendarDateHandler.queryWorkCalendarDateList(queryVO);
+		return ResponseUtil.successResult(dateList, CollectionUtil.isEmpty(dateList) ? 0L : dateList.size());
+    }
+    
+	/**
+     * 添加自定义作息时间
+     * 同项目下,同天、同类型+code只允许存在一条自定义信息,且自定义的时间需大于当日
+     */
+	@ApiOperation(value = "添加自定义作息时间")
+	@RequestMapping(value = "createCustomCalendarDate")
+    public ResponseResult createCustomCalendarDate(@RequestBody @Validated CustomCalendarVO<WorkCalendarDateCreateVO> createVO) {
+		this.workCalendarDateHandler.batchCreateCalendarDate(createVO);
+		return ResponseUtil.successResult("添加成功");
+	}
+	
+	/**
+     * 多时间段添加工作历作息时间信息,且自定义的开始时间需大于当日,先删除此dictType下数据,再添加
+     */
+	@ApiOperation(value = "多时间段添加工作历作息时间信息")
+	@RequestMapping(value = "createCustomCalendarMoreDate")
+    public ResponseResult createCustomCalendarMoreDate(@RequestBody @Validated WorkCalendarMoreDateCreateVO createVO) {
+		/*if (BooleanUtil.isFalse(createVO.getIsDelete()) && CollectionUtil.isEmpty(createVO.getTimetable())) {
+			return ResponseUtil.errorResult(ResponseCode.A0400.getCode(), "作息时间点集合timetable,不可为空");
+		}*/
+		
+		// 判断日期是否合法
+		boolean thanToday = WorkCalendarDateHandler.isMoreThanToday(createVO.getWorkDateStart());
+		if (!thanToday) {
+			return ResponseUtil.errorResult(ResponseCode.A0402.getCode(), "开始作息日期不合法,历史时间不允许再添加自定义作息时间点");
+		}
+		// 判断工作历类型是否存在
+		WorkCalendar calendar = this.workCalendarService.getById(createVO.getCalendarId(), createVO.getProjectId());
+		if (calendar == null) {
+			throw new BusinessException("工作历类型不存在");
+		}
+		this.workCalendarDateHandler.batchCreateCalendarMoreDate(createVO, calendar);
+		return ResponseUtil.successResult("添加成功");
+	}
+	
+    /**
+     * 更新自定义作息时间
+     * 同项目下,同天、同类型+code只允许存在一条自定义信息,且自定义的时间需大于当日
+     */
+	@ApiOperation(value = "更新自定义作息时间")
+	@RequestMapping(value = "updateCustomCalendarDate")
+    public ResponseResult updateCustomCalendarDate(@RequestBody @Validated CustomCalendarVO<WorkCalendarDateUpdateVO> updateVO) {
+		this.workCalendarDateHandler.batchUpdateCalendarDate(updateVO);
+		return ResponseUtil.successResult("更新成功");
+	}
+	
+    /**
+     * 物理删除自定义作息时间,自定义的时间需大于当日
+     */
+	@ApiOperation(value = "物理删除自定义作息时间")
+	@RequestMapping(value = "deleteCustomCalendarDate")
+    public ResponseResult deleteCustomCalendarDate(@RequestBody @Validated WorkCalendarDateDeleteVO deleteVO) {
+		// 判断日期是否合法
+		boolean thanToday = WorkCalendarDateHandler.isMoreThanToday(deleteVO.getWorkDateStart());
+		if (!thanToday) {
+			return ResponseUtil.errorResult(ResponseCode.A0402.getCode(), "作息日期不合法,历史数据不允许被删除");
+		}
+		QueryWrapper<WorkCalendarDate> queryWrapper = new WorkCalendarDate.Builder().createQueryWrapper()
+				.workDateGe(deleteVO.getWorkDateStart()).workDateLe(deleteVO.getWorkDateEnd())
+				.projectIdEq(deleteVO.getProjectId()).idEq(deleteVO.getId())
+				.dictTypeEq(deleteVO.getDictType()).dictCodeIn(deleteVO.getDictCode())
+				.customFlagEq(WorkCalendarConstant.CUSTOM_CALENDAR_DATE_YES).builderQueryWrapper();
+		boolean result = this.workCalendarDateService.remove(queryWrapper);
+		return result ? ResponseUtil.successResult("删除成功") : ResponseUtil.errorResult("删除失败");
+	}
+	
+}

+ 12 - 0
src/main/java/com/persagy/calendar/controller/WorkCalendarDictController.java

@@ -0,0 +1,12 @@
+package com.persagy.calendar.controller;
+
+/**
+ * @version 
+ * @description 
+ * @company persagy
+ * @author zhangqiankun
+ * @since 2021年3月4日:	下午2:28:22
+ */
+public class WorkCalendarDictController {
+
+}

+ 119 - 0
src/main/java/com/persagy/calendar/controller/WorkCalendarLabelController.java

@@ -0,0 +1,119 @@
+package com.persagy.calendar.controller;
+
+import java.util.List;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RestController;
+
+import com.google.common.collect.Lists;
+import com.persagy.calendar.handle.WorkCalendarDateHandler;
+import com.persagy.calendar.handle.WorkCalendarLabelHandler;
+import com.persagy.calendar.pojo.dto.WorkCalendarLabel;
+import com.persagy.calendar.pojo.vo.WorkCalendarLabelQueryVO;
+import com.persagy.calendar.pojo.vo.WorkCalendarLabelUpdateVO;
+import com.persagy.calendar.pojo.vo.WorkCalendarMoreDateCreateVO;
+import com.persagy.calendar.pojo.vo.WorkLabelBatchUpdateVO;
+import com.persagy.common.utils.ResponseResult;
+import com.persagy.common.utils.ResponseUtil;
+
+import cn.hutool.core.collection.CollectionUtil;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+
+/**
+ * @version 
+ * @description 
+ * @company persagy
+ * @author zhangqiankun
+ * @since 2021年3月3日:	下午5:48:32
+ */
+@RestController
+@Api(tags = "标签管理")
+@RequestMapping(value = "/v2.0/calendarLabel", method = RequestMethod.POST)
+public class WorkCalendarLabelController {
+	
+	@Autowired
+	private WorkCalendarLabelHandler workCalendarLabelHandler;
+	
+	/**
+     * 日期标签属性列表查询
+     */
+    @ApiOperation(value = "列表查询")
+    @RequestMapping(value = "queryCalendarLabelList")
+    public ResponseResult queryCalendarLabelList(@RequestBody @Validated WorkCalendarLabelQueryVO queryVO) {
+		List<WorkCalendarLabel> dateList = this.workCalendarLabelHandler.queryCalendarLabelList(queryVO);
+		if (CollectionUtil.isEmpty(dateList)) {
+			return ResponseUtil.successResult(Lists.newArrayList(), 0L);
+		}
+		return ResponseUtil.successResult(dateList, (long)dateList.size());
+    }
+    
+	/**
+     * 查询标签的有效期
+     */
+    @ApiOperation(value = "查询标签的有效期")
+    @RequestMapping(value = "queryCalendarLabelValid")
+    public ResponseResult queryCalendarLabelValid(@RequestBody @Validated WorkCalendarLabelQueryVO queryVO) {
+		List<WorkCalendarLabel> dateList = this.workCalendarLabelHandler.queryCalendarLabelValid(queryVO);
+		if (CollectionUtil.isEmpty(dateList)) {
+			return ResponseUtil.successResult(Lists.newArrayList(), 0L);
+		}
+		return ResponseUtil.successResult(dateList, (long)dateList.size());
+    }
+	
+	/**
+	 * 创建或更新日期标签属性
+	 * @param updateVO
+	 * @return
+	 */
+	@ApiOperation(value = "创建或更新日期标签属性")
+    @RequestMapping(value = "updateLabelInfo")
+	public ResponseResult updateLabelInfo(@RequestBody @Validated WorkCalendarLabelUpdateVO updateVO) {
+		ResponseResult validity = WorkCalendarLabelHandler.checkDataValidity(updateVO);
+		if (validity != null) {
+			return validity;
+		}
+		this.workCalendarLabelHandler.updateLabelInfo(updateVO);
+		return ResponseUtil.successResult("更新成功");
+	}
+	
+	/**
+	 * 定义工作历单日属性
+	 * @param updateVO
+	 * @return
+	 */
+	@ApiOperation(value = "更新日期标签属性集")
+    @RequestMapping(value = "updateCalendarDateAttribute")
+	public ResponseResult updateCalendarDateAttribute(@RequestBody @Validated WorkLabelBatchUpdateVO updateVO) {
+		List<WorkCalendarLabelUpdateVO> labels = updateVO.getLabels();
+		List<WorkCalendarMoreDateCreateVO> times = updateVO.getTimes();
+		if (CollectionUtil.isNotEmpty(labels) || CollectionUtil.isNotEmpty(times)) {
+			if (CollectionUtil.isNotEmpty(labels)) {
+				ResponseResult validity = null;
+				for (WorkCalendarLabelUpdateVO workCalendarLabelUpdateVO : labels) {
+					validity = WorkCalendarLabelHandler.checkDataValidity(workCalendarLabelUpdateVO);
+					if (validity != null) {
+						return validity;
+					}
+				}
+			}
+			
+			if (CollectionUtil.isNotEmpty(times)) {
+				for (WorkCalendarMoreDateCreateVO workCalendarMoreDateCreateVO : times) {
+					boolean valid = WorkCalendarDateHandler.isMoreThanToday(workCalendarMoreDateCreateVO.getWorkDateStart());
+					if (!valid) {
+						return ResponseUtil.errorResult("times中的开始日期必须大于当日");
+					}
+				}
+			}
+			this.workCalendarLabelHandler.updateCalendarDateAttribute(updateVO);
+			return ResponseUtil.successResult("更新成功");
+		}
+		return ResponseUtil.errorResult("labels和times必须存在一个");
+	}
+	
+}

+ 126 - 0
src/main/java/com/persagy/calendar/controller/WorkCalendarRuleController.java

@@ -0,0 +1,126 @@
+package com.persagy.calendar.controller;
+
+import java.util.List;
+
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RestController;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.persagy.calendar.constant.WorkCalendarConstant;
+import com.persagy.calendar.handle.WorkCalendarRuleHandler;
+import com.persagy.calendar.pojo.dto.WorkCalendar;
+import com.persagy.calendar.pojo.dto.WorkCalendarRule;
+import com.persagy.calendar.pojo.vo.CustomCalendarVO;
+import com.persagy.calendar.pojo.vo.WorkCalendarRuleCreateVO;
+import com.persagy.calendar.pojo.vo.WorkCalendarRuleDeleteVO;
+import com.persagy.calendar.pojo.vo.WorkCalendarRuleQueryVO;
+import com.persagy.calendar.pojo.vo.WorkCalendarRuleUpdateVO;
+import com.persagy.calendar.service.IWorkCalendarRuleService;
+import com.persagy.calendar.service.IWorkCalendarService;
+import com.persagy.common.enums.ResponseCode;
+import com.persagy.common.utils.ResponseResult;
+import com.persagy.common.utils.ResponseUtil;
+import com.persagy.common.utils.StringUtil;
+
+import cn.hutool.core.collection.CollectionUtil;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+
+/**
+ * 工作历规则表
+ * 
+ * @version 1.0.0
+ * @company persagy 
+ * @author zhangqiankun
+ * @date 2020-10-02 18:26:14
+ */
+
+@Api(tags = "工作历规则")
+@RestController
+@RequestMapping(value = "/v2.0/workCalendarRule", method = RequestMethod.POST)
+public class WorkCalendarRuleController {
+    
+	@Autowired
+    private IWorkCalendarService workCalendarService;
+    
+    @Autowired
+    private IWorkCalendarRuleService workCalendarRuleService;
+    
+    @Autowired
+    private WorkCalendarRuleHandler workCalendarRuleHandler;
+    
+    /**
+     * 普通列表查询
+     */
+    @ApiOperation(value = "普通列表查询")
+    @RequestMapping(value = "queryWorkCalendarRuleList")
+    public ResponseResult queryWorkCalendarRuleList(@RequestBody @Validated WorkCalendarRuleQueryVO workCalendarRuleQueryVO) {
+    	QueryWrapper<WorkCalendarRule> queryWrapper = new WorkCalendarRule.Builder().createQueryWrapper()
+    			.idEq(workCalendarRuleQueryVO.getId()).calendarIdEq(workCalendarRuleQueryVO.getCalendarId())
+    			.dictTypeEq(workCalendarRuleQueryVO.getDictType()).dictCodeIn(workCalendarRuleQueryVO.getDictCode())
+    			.delFlagEq(WorkCalendarConstant.WORK_CALENDAR_DEL_FLAG_NOR).builderQueryWrapper();
+    	List<WorkCalendarRule> list = workCalendarRuleService.list(queryWrapper);
+    	return ResponseUtil.successResult(list, CollectionUtil.isEmpty(list) ? 0L : list.size());
+    }
+    
+    /**
+     * 新增
+     * isValid为true时,同项目同工作历类型下,dictType+dictCode唯一
+     */
+	@ApiOperation(value = "保存")
+	@RequestMapping(value = "createWorkCalendarRule")
+    public ResponseResult createWorkCalendarRule(@RequestBody @Validated CustomCalendarVO<WorkCalendarRuleCreateVO> createVO) {
+		this.workCalendarRuleHandler.batchCreateCalednarRule(createVO);
+        return ResponseUtil.successResult("保存成功");
+    }
+    
+    /**
+     * 更新
+     * isValid为true时,同项目同工作历类型下,dictType+dictCode唯一
+     */
+	@ApiOperation(value = "更新")
+	@RequestMapping(value = "updateWorkCalendarRule")
+    public ResponseResult updateWorkCalendarRule(@RequestBody @Validated CustomCalendarVO<WorkCalendarRuleUpdateVO> updateVO) {
+		this.workCalendarRuleHandler.batchUpdateCalednarRule(updateVO);
+        return ResponseUtil.successResult("更新成功");
+    }
+
+    /**
+     * 删除
+     */
+    @ApiOperation(value = "删除")
+    @RequestMapping(value = "deleteWorkCalendarRule")
+    public ResponseResult deleteWorkCalendarRule(@RequestBody @Validated WorkCalendarRuleDeleteVO deleteVO) {
+    	// 规则ID和工作历ID必须存在其一
+    	String ruleId = deleteVO.getId();
+    	String calendarId = deleteVO.getCalendarId();
+    	if (StringUtil.isBlank(ruleId) && StringUtil.isBlank(calendarId)) {
+    		return ResponseUtil.errorResult(ResponseCode.A0400.getCode(), "规则ID和工作历ID至少存在其一");
+		}
+    	if (ruleId != null) {
+    		//先判断原规则数据是否存在
+    		WorkCalendarRule calendarRule = workCalendarRuleService.getById(ruleId, deleteVO.getProjectId());
+    		if (calendarRule == null) {
+    			return ResponseUtil.errorResult(ResponseCode.C0320.getCode(), "规则信息不存在");
+    		}
+		}
+    	if (calendarId != null) {
+    		// 判断工作历信息是否存在
+    		WorkCalendar workCalendar = workCalendarService.getById(calendarId, deleteVO.getProjectId());
+    		if (workCalendar == null) {
+    			return ResponseUtil.errorResult(ResponseCode.C0320.getCode(), "工作历主信息不存在");
+    		}
+		}
+    	WorkCalendarRule workCalendarRule = new WorkCalendarRule();
+    	BeanUtils.copyProperties(deleteVO, workCalendarRule);
+    	workCalendarRule.setUpdateUser(deleteVO.getUserId());
+    	boolean result = workCalendarRuleService.deleteWorkCalendarRule(workCalendarRule);
+        return result ? ResponseUtil.successResult("删除成功") : ResponseUtil.errorResult("删除失败");
+    }
+    
+}

+ 45 - 0
src/main/java/com/persagy/calendar/controller/WorkTimeEngineController.java

@@ -0,0 +1,45 @@
+package com.persagy.calendar.controller;
+
+import java.util.Map;
+
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RestController;
+
+import com.persagy.calendar.utils.NTPClientUtil;
+import com.persagy.common.enums.ResponseCode;
+import com.persagy.common.utils.ResponseResult;
+import com.persagy.common.utils.ResponseUtil;
+import com.persagy.common.utils.StringUtil;
+
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+
+/**
+ * @version 
+ * @description 
+ * @company persagy
+ * @author zhangqiankun
+ * @since 2020年10月3日:	下午2:32:36
+ */
+@Api(tags = "NTP服务时间")
+@RestController
+@RequestMapping(value = "/v2.0/ntp", method = RequestMethod.POST)
+public class WorkTimeEngineController {
+	
+	/**
+     * 获取NTP服务时间
+     */
+    @ApiOperation(value = "获取NTP服务时间")
+    @RequestMapping(value = "getNTPServerTime")
+    public ResponseResult queryWorkCalendarDateList(@RequestBody @Validated Map<String, String> map) {
+    	String ntpServerTime = NTPClientUtil.getNTPServerTime();
+		if (StringUtil.isNotBlank(ntpServerTime)) {
+			return ResponseUtil.successResult(null, ntpServerTime);
+		}
+		return ResponseUtil.errorResult(ResponseCode.Z9999.getCode(), ResponseCode.Z9999.getDesc());
+	}
+	
+}

+ 658 - 0
src/main/java/com/persagy/calendar/handle/WorkCalendarDateHandler.java

@@ -0,0 +1,658 @@
+package com.persagy.calendar.handle;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import org.springframework.transaction.annotation.Transactional;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.google.common.collect.Lists;
+import com.persagy.calendar.constant.WorkCalendarConstant;
+import com.persagy.calendar.pojo.dto.WorkCalendar;
+import com.persagy.calendar.pojo.dto.WorkCalendarDate;
+import com.persagy.calendar.pojo.dto.WorkCalendarRule;
+import com.persagy.calendar.pojo.vo.CalendarDateResult;
+import com.persagy.calendar.pojo.vo.CustomCalendarVO;
+import com.persagy.calendar.pojo.vo.WorkCalendarDateCreateVO;
+import com.persagy.calendar.pojo.vo.WorkCalendarDateQueryVO;
+import com.persagy.calendar.pojo.vo.WorkCalendarDateUpdateVO;
+import com.persagy.calendar.pojo.vo.WorkCalendarMoreDateCreateVO;
+import com.persagy.calendar.service.IWorkCalendarDateService;
+import com.persagy.calendar.service.IWorkCalendarRuleService;
+import com.persagy.calendar.service.IWorkCalendarService;
+import com.persagy.common.exception.BusinessException;
+import com.persagy.common.utils.DateUtil;
+import com.persagy.common.utils.IdGenerator;
+import com.persagy.common.utils.StringUtil;
+
+import cn.hutool.core.collection.CollectionUtil;
+import cn.hutool.core.date.DateField;
+import cn.hutool.core.date.DateTime;
+import cn.hutool.core.date.DateUnit;
+import cn.hutool.core.util.BooleanUtil;
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * @version 
+ * @description 
+ * @company persagy
+ * @author zhangqiankun
+ * @since 2020年10月3日:	下午1:03:19
+ */
+@Slf4j
+@Component
+public class WorkCalendarDateHandler {
+
+	@Autowired
+    private IWorkCalendarService workCalendarService;
+    
+    @Autowired
+    private IWorkCalendarRuleService workCalendarRuleService;
+    
+    @Autowired
+    private IWorkCalendarDateService workCalendarDateService;
+    
+    /**
+     * 实时查询作息时间信息,包括自定义的
+     * @param queryVO
+     * @return
+     */
+    public List<CalendarDateResult> queryWorkCalendarDateList(WorkCalendarDateQueryVO queryVO) {
+    	// key-日期,value-此日对应的作息时间集合
+    	Map<String, List<WorkCalendarDate>> resultMap = new HashMap<String, List<WorkCalendarDate>>();
+    	// key-项目+日期+type+code,value-true存在自定义信息,false 不存在自定义信息
+    	Map<String, Boolean> existsCustom = new HashMap<String, Boolean>();
+    	
+    	// 1.优先获取start~end的作息时间信息,包含自定义的,判断对应日期内是否包含自定义的
+    	this.selectHistoryDate(resultMap, existsCustom, queryVO);
+    	
+    	// 2.获取满足 明日/start~end日期 的规则信息集合
+    	String format = DateUtil.format(new Date(), DateUtil.FORMAT_DATE_YYYYMMDD);
+    	DateTime currentDate = DateUtil.parse(format, DateUtil.FORMAT_DATE_YYYYMMDD);
+    	String dateStartStr = queryVO.getWorkDateStart();
+    	String dateEndStr = queryVO.getWorkDateEnd();
+    	DateTime dateStart = DateUtil.parse(dateStartStr, DateUtil.FORMAT_DATE_YYYYMMDD);
+		DateTime dateEnd = DateUtil.parse(dateEndStr, DateUtil.FORMAT_DATE_YYYYMMDD);
+		if (currentDate.before(dateStart)) {
+			currentDate = dateStart;
+		} else {
+			currentDate.offset(DateField.DAY_OF_YEAR, 1);
+		}
+    	if (currentDate.before(dateEnd) || currentDate.equals(dateEnd)) {
+    		// 因为dataEnd时分秒一定是000000,所以这里只要当前日期时间点在dateEnd之前,就说明偏移后最坏与dateEnd相同
+    		String offsetStr = currentDate.toString(DateUtil.FORMAT_DATE_YYYYMMDD);
+    		List<WorkCalendarRule> ruleList = this.selectWorkCalendarRuleList(offsetStr, dateEndStr, queryVO);
+    		if (CollectionUtil.isNotEmpty(ruleList)) {
+				// 3.实时解析规则,并判断是否存在自定义的作息时间信息,最后封装返回数据
+				long betweenDay = DateUtil.between(currentDate, dateEnd, DateUnit.DAY) + 1;
+				this.paserWorkCalendarRule(betweenDay, currentDate, ruleList, resultMap, existsCustom);
+			}
+    	}
+    	
+		// 获取start~end之间的天数,+1 包括首尾
+    	dateStart = DateUtil.parse(dateStartStr, DateUtil.FORMAT_DATE_YYYYMMDD);
+		long betweenDay = DateUtil.between(dateStart, dateEnd, DateUnit.DAY) + 1;
+		
+		return this.setResultList(queryVO.getCalendarId(), betweenDay, dateStart, resultMap);
+    }
+    
+    /**
+     * 响应数据,最后处理加工,根据dictCode,剔除某天多余的数据
+     * @param calendarId
+     * @param betweenDay
+     * @param dateStart
+     * @param resultMap
+     * @return
+     */
+    private List<CalendarDateResult> setResultList(String calendarId, long betweenDay, DateTime dateStart, 
+    		Map<String, List<WorkCalendarDate>> resultMap) {
+    	List<CalendarDateResult> resultList = new ArrayList<CalendarDateResult>();
+    	
+    	String nextDay = null;
+		for (int i = 0; i < betweenDay; i++) {
+			nextDay = dateStart.toString(DateUtil.FORMAT_DATE_YYYYMMDD);
+			CalendarDateResult result = new CalendarDateResult();
+			int dayOfWeek = DateUtil.dayOfWeek(dateStart);
+			if (dayOfWeek == 1 || dayOfWeek == 7) {
+				result.setWorkday(false);
+			}
+			result.setWorkDate(nextDay);
+			result.setCalendarId(calendarId);
+			result.setDate(DateUtil.dayOfMonth(dateStart));
+			result.setWeek(WorkCalendarConstant.DAY_OF_WEEK.get(dayOfWeek));
+			List<WorkCalendarDate> list = resultMap.get(nextDay);
+			if (CollectionUtil.isNotEmpty(list)) {
+				for (int j = list.size() - 1; j >= 0; j--) {
+					WorkCalendarDate calendarDate = list.get(j);
+					// 是工作日,剔除非工作日的数据,目前仅有OpenTime-1,工作日,OpenTime-2,休息日
+					if (result.isWorkday() && "OpenTime-2".equals(calendarDate.getDictCode())) {
+						list.remove(j);
+					} else if (!result.isWorkday() && "OpenTime-1".equals(calendarDate.getDictCode())) {
+						list.remove(j);
+					}
+				}
+			}
+			
+			result.setTimeTable(CollectionUtil.isEmpty(list) ? Lists.newArrayList() : list);
+			resultList.add(result);
+			dateStart.offset(DateField.DAY_OF_YEAR, 1);	 	// 下一天
+		}
+		resultMap.clear();   //释放
+		return resultList;
+    }
+    
+    /**
+     * 
+     * @param resultMap	key-日期,value-此日对应的作息时间集合,包含未来自定义的
+     * @param existsCustom key-项目+日期+type+code,value-true存在自定义信息,false 不存在自定义信息
+     */
+    public void selectHistoryDate(Map<String, List<WorkCalendarDate>> resultMap, Map<String, Boolean> existsCustom, WorkCalendarDateQueryVO queryVO) {
+		List<WorkCalendarDate> dates = this.selectWorkCalendarDateList(queryVO);
+		for (WorkCalendarDate calendarDate : dates) {
+			// 是否存在自定义,存在true就不在更新
+			String existsKey = calendarDate.getCalendarId() + calendarDate.getProjectId() + calendarDate.getWorkDate() + calendarDate.getDictType() + (StringUtil.isBlank(calendarDate.getDictCode()) ? "" : calendarDate.getDictCode());
+			boolean exists = WorkCalendarConstant.CUSTOM_CALENDAR_DATE_YES.equals(calendarDate.getCustomFlag());
+			if (!BooleanUtil.isTrue(existsCustom.get(existsKey))) {
+				existsCustom.put(existsKey, exists);
+			}
+			// 将自定义的或历史的,按照日期,分组
+			if (resultMap != null) {
+				if (resultMap.containsKey(calendarDate.getWorkDate())) {
+					List<WorkCalendarDate> list = resultMap.get(calendarDate.getWorkDate());
+					list.add(calendarDate);
+				} else {
+					List<WorkCalendarDate> list = new ArrayList<WorkCalendarDate>();
+					list.add(calendarDate);
+					resultMap.put(calendarDate.getWorkDate(), list);
+				}
+			}
+		}
+    }
+    
+	 /**
+     * 获取满足条件的所有已存在的作息时间信息,包括自定义的
+     * @param workCalendarDateQueryVO
+     * @return
+     */
+	public List<WorkCalendarDate> selectWorkCalendarDateList(WorkCalendarDateQueryVO workCalendarDateQueryVO) {
+		QueryWrapper<WorkCalendarDate> queryWrapper = new WorkCalendarDate.Builder().createQueryWrapper()
+				.projectIdEq(workCalendarDateQueryVO.getProjectId())
+				.idEq(workCalendarDateQueryVO.getId())
+				.ruleIdEq(workCalendarDateQueryVO.getRuleId())
+				.calendarIdEq(workCalendarDateQueryVO.getCalendarId())
+				.workDateGe(workCalendarDateQueryVO.getWorkDateStart())
+				.workDateLe(workCalendarDateQueryVO.getWorkDateEnd())
+				.dictTypeEq(workCalendarDateQueryVO.getDictType())
+				.dictTypeIn(workCalendarDateQueryVO.getDictTypes())
+				.dictCodeIn(workCalendarDateQueryVO.getDictCode())
+				.calendarNameLike(workCalendarDateQueryVO.getCalendarName())
+				.builderQueryWrapper();
+		queryWrapper.select("ID, RULE_ID, CALENDAR_ID, PROJECT_ID, CALENDAR_NAME, CALENDAR_DESC, DICT_TYPE, "
+				+ "DICT_CODE, WORK_DATE, WORK_TIME, CUSTOM_FLAG");
+    	List<WorkCalendarDate> list = workCalendarDateService.list(queryWrapper);
+    	return list == null ? new ArrayList<WorkCalendarDate>() : list;
+	}
+	
+    /**
+	 * 解析此段时间的规则
+	 * @param betweenDay 时间范围
+     * @param workDateEnd 
+     * @param workDateStart 
+	 * @param ruleList 规则信息
+	 * @param resultMap 已有的作息时间信息
+	 * @param existsCusetom key-项目+日期+type+code,value-true存在自定义信息,false 不存在自定义信息
+	 */
+	public void paserWorkCalendarRule(long betweenDay, DateTime currentDate, List<WorkCalendarRule> ruleList, 
+			Map<String, List<WorkCalendarDate>> resultMap, Map<String, Boolean> existsCustom) {
+		Map<String, WorkCalendar> calendarMap = new HashMap<String, WorkCalendar>();
+		for(int i = 0; i < betweenDay; i++) {
+			// 判断此天有没有对应的规则信息,每次都要循环全部,生成多条信息
+			for (WorkCalendarRule rule : ruleList) {
+				// 判断当前规则是否
+				this.parseWorkCalendarRule(rule, currentDate, calendarMap, resultMap, existsCustom);
+			}
+			
+			currentDate.offset(DateField.DAY_OF_YEAR, 1);
+		}
+		calendarMap.clear();
+	}
+	
+	/**
+	 * 解析规则信息,生成对应作息时间记录
+	 * 
+	 * @param rule
+	 * @param currentDate 日期
+	 * @param calendarMap 工作历类型集合
+	 * @param resultMap 等于null时,插库,否则添加进此map
+	 * @param existsCusetom key-项目+日期+type+code,value-true存在自定义信息,false 不存在自定义信息
+	 * @return
+	 */
+	private void parseWorkCalendarRule(WorkCalendarRule rule, DateTime currentDate, Map<String, WorkCalendar> calendarMap, 
+			Map<String, List<WorkCalendarDate>> resultMap, Map<String, Boolean> existsCustom) {
+		String workDate = currentDate.toString(DateUtil.FORMAT_DATE_YYYYMMDD);
+		String dictCode = StringUtil.isBlank(rule.getDictCode()) ? "" : rule.getDictCode();
+		int indexOf = dictCode.indexOf(WorkCalendarConstant.WORK_CALENDAR_D_OF_W);
+		if (indexOf <= 0) {
+			indexOf = dictCode.indexOf(WorkCalendarConstant.WORK_CALENDAR_D_OF_M);
+			if (indexOf <= 0) {
+				indexOf = dictCode.indexOf(WorkCalendarConstant.WORK_CALENDAR_M_AND_D);
+			}
+		}
+		if (indexOf > 0) {
+			dictCode = dictCode.substring(0, indexOf - 1);
+		}
+		String existsKey = rule.getCalendarId() + rule.getProjectId() + workDate + rule.getDictType() + (StringUtil.isBlank(dictCode) ? "" : dictCode);
+		// 优先判断当日是否存在同类型 同编码的自定义作息时间
+		if (existsCustom != null && BooleanUtil.isTrue(existsCustom.get(existsKey))) {
+			return;
+		}
+		
+		// 当不存在自定义的作息时间时
+		// 解析规则,生成数据
+		int work = Integer.valueOf(workDate);
+		String ruleStart = rule.getRuleDateStart();
+		String ruleEnd = rule.getRuleDateEnd();
+		if (StringUtil.isNotBlank(ruleStart) && StringUtil.isNotBlank(ruleEnd)) {
+			int start = Integer.valueOf(ruleStart);
+			int end = Integer.valueOf(ruleEnd);
+			if (work >= start && work <= end) {
+				// 当日期生效
+				if (indexOf > 0) {
+					// 验证value是否存在,存在按周 月 解析,判断是否生效
+					boolean result = this.parseRuleValue(rule, currentDate, workDate);
+					if (!result) {
+						return;
+					}
+				}
+				
+				// 组合数据
+				WorkCalendarDate calendarDate = this.comWorkCalendarOrRule(rule, workDate, dictCode, calendarMap);
+				if (calendarDate == null) {
+					return;
+				}
+				// 数据添加
+				this.addCalendarDateResult(workDate, calendarDate, resultMap);
+			}
+		}
+	}
+	
+	/**
+	 * 解析rule 的 value属性,判断其是否生效
+	 * @param rule
+	 * @param workDate
+	 * @return value为空,默认返回true
+	 */
+	private boolean parseRuleValue(WorkCalendarRule rule, DateTime currentDate, String workDate) {
+		if (CollectionUtil.isEmpty(rule.getValue())) {
+			return true;
+		}
+		// 获取月日
+		String mmddStr = workDate.substring(4, 8);
+		Integer mmdd = Integer.valueOf(mmddStr);
+		
+		Set<String> values = rule.getValue();
+		String dictCode = rule.getDictCode();
+		String[] split = dictCode.split("-");
+		dictCode = split[0];		// 真实的code编码
+		String type = split[1];		// 类型
+		switch (type) {
+			case WorkCalendarConstant.WORK_CALENDAR_D_OF_W:	 //周
+				// 1表示周日,2表示周一
+				int dayOfWeek = DateUtil.dayOfWeek(currentDate);	
+				dayOfWeek = dayOfWeek - 1;
+				if (dayOfWeek == 0) {
+					dayOfWeek = 7;
+				}
+				String num = String.valueOf(dayOfWeek);
+				if (values.contains(num)) {
+					return true;
+				}
+				break;
+			case WorkCalendarConstant.WORK_CALENDAR_D_OF_M:	 //月
+				// 当前日期为此月的第几天
+				int ofMonth = DateUtil.dayOfMonth(currentDate);
+				Iterator<String> iterator = values.iterator();
+				while(iterator.hasNext()) {
+					String next = iterator.next();
+					if (next.contains("-")) {
+						String[] split2 = next.split("-");
+						int start = Integer.parseInt(split2[0]);
+						int end = Integer.parseInt(split2[1]);
+						if (ofMonth >= start && ofMonth <= end) {
+							return true;
+						}
+					} else if (next.equals(String.valueOf(ofMonth))) {
+						return true;
+					}
+				}
+				break;
+			case WorkCalendarConstant.WORK_CALENDAR_M_AND_D: //年
+				iterator = values.iterator();
+				while(iterator.hasNext()) {
+					String next = iterator.next();
+					if (next.contains("-")) {
+						String[] split2 = next.split("-");
+						Integer startInt = Integer.valueOf(split2[0]);
+						Integer endInt = Integer.valueOf(split2[1]);
+						if (mmdd >= startInt && mmdd <= endInt) {
+							return true;
+						}
+					} else if (mmddStr.equals(next)) {
+						return true;
+					}
+				}
+				break;
+			default: 
+				break;
+		}
+		return false;
+	}
+
+	/**
+	 * 响应数据添加
+	 * @param resultMap 为null时插库
+	 */
+	public void addCalendarDateResult(String workDate, WorkCalendarDate calendarDate, Map<String, List<WorkCalendarDate>> resultMap) {
+		if (resultMap == null) {
+			boolean result = this.workCalendarDateService.save(calendarDate);
+			//boolean result = this.workCalendarDateService.replaceIntoCalendarDate(calendarDate);
+			if (!result) {
+				throw new BusinessException("新增作息时间信息失败,规则ID: " + calendarDate.getRuleId());
+			}
+			return;
+		}
+		
+		if (!resultMap.containsKey(workDate)) {
+			List<WorkCalendarDate> list = new ArrayList<WorkCalendarDate>();
+			list.add(calendarDate);
+			resultMap.put(workDate, list);
+			return;
+		}
+		
+		List<WorkCalendarDate> list = resultMap.get(workDate);
+		list.add(calendarDate);
+	}
+	
+	/**
+	 * 组合出作息时间对象
+	 * @param workCalendar
+	 * @param rule
+	 * @param calendarIds 
+	 * @return
+	 */
+	public WorkCalendarDate comWorkCalendarOrRule(WorkCalendarRule rule, String workDate, String dictCode, 
+			Map<String, WorkCalendar> calendarMap) {
+		// 首先判断工作历是否还存在
+		WorkCalendar workCalendar = null;
+		if (calendarMap.containsKey(rule.getCalendarId())) {
+			workCalendar = calendarMap.get(rule.getCalendarId());
+		} else {
+			workCalendar = this.workCalendarService.getById(rule.getCalendarId(), rule.getProjectId());
+			calendarMap.put(rule.getCalendarId(), workCalendar);
+		}
+		if (workCalendar == null) {
+			log.warn("规则ID为[{}]的规则,所对应的工作历信息不存在", rule.getId());
+			return null;
+		}
+				
+		WorkCalendarDate workCalendarDate = new WorkCalendarDate();
+		workCalendarDate.setGroupCode(rule.getGroupCode());
+		workCalendarDate.setCalendarId(workCalendar.getId());
+		workCalendarDate.setRuleId(rule.getId());
+		workCalendarDate.setCalendarName(workCalendar.getCalendarName());
+		workCalendarDate.setCalendarDesc(workCalendar.getCalendarDesc());
+		workCalendarDate.setProjectId(rule.getProjectId());
+		workCalendarDate.setDictType(rule.getDictType());
+		workCalendarDate.setDictCode(dictCode);
+		workCalendarDate.setWorkDateStart(rule.getRuleDateStart());
+		workCalendarDate.setWorkDateEnd(rule.getRuleDateEnd());
+		workCalendarDate.setWorkDate(workDate);
+		
+		workCalendarDate.setWorkTime(StringUtil.isBlank(rule.getRuleTime()) ? 
+				(CollectionUtil.isEmpty(rule.getValue()) ? null : rule.getValue().stream().collect(Collectors.joining(","))) 
+				: rule.getRuleTime());
+		// 自定义的一定是查出来的,封装的一定是非自定义添加的
+		workCalendarDate.setCustomFlag(WorkCalendarConstant.CUSTOM_CALENDAR_DATE_NO);
+		workCalendarDate.setUpdateUser(rule.getUpdateUser());
+		return workCalendarDate;
+	}
+	
+	/**
+	 * 获取满足条件的所有新版规则信息
+	 * @param workDatestart
+	 * @param workDateEnd
+	 * @param workCalendarDateQueryVO
+	 * @return
+	 */
+	public List<WorkCalendarRule> selectWorkCalendarRuleList(String workDatestart, String workDateEnd, WorkCalendarDateQueryVO queryVO) {
+		QueryWrapper<WorkCalendarRule> queryWrapper = new WorkCalendarRule.Builder().createQueryWrapper()
+				.projectIdEq(queryVO.getProjectId()).idEq(queryVO.getRuleId())
+				.calendarIdEq(queryVO.getCalendarId()).ruleDateBetween(workDatestart, workDateEnd)
+				.dictTypeEq(queryVO.getDictType()).dictCodeIn(queryVO.getDictCode())
+				.dictTypeIn(queryVO.getDictTypes())
+				.delFlagEq(WorkCalendarConstant.WORK_CALENDAR_DEL_FLAG_NOR)
+				.ruleFlagEq(WorkCalendarConstant.WORK_CALENDAR_RULE_FLAG_NEW).builderQueryWrapper();
+    	return this.workCalendarRuleService.list(queryWrapper);
+	}
+	
+	/**
+	 * 解析规则信息,并插库
+	 * @param queryVO
+	 * @return
+	 */
+	@Transactional
+	public boolean handleParseCalendarRule(WorkCalendarDateQueryVO queryVO) {
+		// 1.防止重复执行,优先删除从今日开始的非自定义的作息时间信息
+		QueryWrapper<WorkCalendarDate> queryWrapper = new WorkCalendarDate.Builder().createQueryWrapper()
+				.projectIdEq(queryVO.getProjectId()).calendarIdEq(queryVO.getCalendarId())
+				.calendarNameEq(queryVO.getCalendarName()).dictTypeEq(queryVO.getDictType())
+				.dictCodeIn(queryVO.getDictCode()).workDateGe(queryVO.getWorkDateStart())
+				.workDateLe(queryVO.getWorkDateEnd()).customFlagEq(WorkCalendarConstant.CUSTOM_CALENDAR_DATE_NO)
+				.builderQueryWrapper();
+		this.workCalendarDateService.remove(queryWrapper);
+		
+		// 1.查询出满足条件的所有的规则信息
+		List<WorkCalendarRule> ruleList = this.selectWorkCalendarRuleList(queryVO.getWorkDateStart(), queryVO.getWorkDateEnd(), queryVO);
+		if (CollectionUtil.isNotEmpty(ruleList)) {
+			// 2.获取此日期内,已存在的自定义的作息时间
+			// key-项目+日期+type+code,value-true存在自定义信息,false 不存在自定义信息
+	    	Map<String, Boolean> existsCustom = new HashMap<String, Boolean>();
+	    	// 1.优先获取start~end的作息时间信息,包含自定义的,判断对应日期内是否包含自定义的
+	    	this.selectHistoryDate(null, existsCustom, queryVO);
+	    	
+			// 3.解析规则信息
+			DateTime dateStart = DateUtil.parse(queryVO.getWorkDateStart(), DateUtil.FORMAT_DATE_YYYYMMDD);
+			DateTime dateEnd = DateUtil.parse(queryVO.getWorkDateEnd(), DateUtil.FORMAT_DATE_YYYYMMDD);
+			long between = DateUtil.between(dateStart, dateEnd, DateUnit.DAY) + 1;
+			this.paserWorkCalendarRule(between, dateStart, ruleList, null, existsCustom);
+		}
+		return true;
+	}
+	
+	
+	/**
+	 * 批量自定义作息时间信息
+	 * @return 
+	 */
+	public void batchCreateCalendarDate(CustomCalendarVO<WorkCalendarDateCreateVO> createVO) {
+		boolean result = false;
+		List<WorkCalendarDateCreateVO> batchInfos = createVO.getBatchInfo();
+		for (WorkCalendarDateCreateVO batchInfo : batchInfos) {
+			// 判断日期是否合法
+			DateTime now = DateUtil.date();
+			now = now.offset(DateField.DAY_OF_YEAR, 1);	//明天
+			String format = DateUtil.format(now, DateUtil.FORMAT_DATE_YYYYMMDD);
+			Integer current = Integer.valueOf(format);
+			Integer workDate = Integer.valueOf(batchInfo.getWorkDate());
+			if (workDate < current) {
+				throw new BusinessException("作息日期不合法,必须大于今日");
+			}
+			// 判断工作历类型是否存在
+			WorkCalendar calendar = this.workCalendarService.getById(batchInfo.getCalendarId(), createVO.getProjectId());
+			if (calendar == null) {
+				throw new BusinessException("工作历类型不存在");
+			}
+			
+			WorkCalendarDate calendarDate = new WorkCalendarDate();
+			BeanUtils.copyProperties(batchInfo, calendarDate);
+			// 验证数据有效性
+			result = this.workCalendarDateService.checkWorkDateValid(calendarDate);
+			if (!result) {
+				throw new BusinessException("当天已存在相同类型额定义,不可重复添加");
+			}
+			calendarDate.setGroupCode(createVO.getGroupCode());
+			calendarDate.setProjectId(createVO.getProjectId());
+			calendarDate.setUpdateUser(createVO.getUserId());
+			calendarDate.setCalendarName(calendar.getCalendarName());
+			calendarDate.setCalendarDesc(calendar.getCalendarDesc());
+			calendarDate.setCustomFlag(WorkCalendarConstant.CUSTOM_CALENDAR_DATE_YES);
+			result = this.workCalendarDateService.save(calendarDate);
+			if (!result) {
+				throw new BusinessException("自定义工作历作息时间添加失败");
+			}
+		}
+	}
+	
+	/**
+	 * 批量自定义作息时间信息
+	 * @return 
+	 */
+	public <T> void batchUpdateCalendarDate(CustomCalendarVO<WorkCalendarDateUpdateVO> updateVO) {
+		boolean result = false;
+		List<WorkCalendarDateUpdateVO> batchInfos = updateVO.getBatchInfo();
+		for (WorkCalendarDateUpdateVO batchInfo : batchInfos) {
+			// 判断日期是否合法
+			DateTime now = DateUtil.date();
+			now = now.offset(DateField.DAY_OF_YEAR, 1);	//明天
+			String format = DateUtil.format(now, DateUtil.FORMAT_DATE_YYYYMMDD);
+			Integer current = Integer.valueOf(format);
+			Integer workDate = Integer.valueOf(batchInfo.getWorkDate());
+			if (workDate < current) {
+				throw new BusinessException("作息日期不合法,必须大于今日");
+			}
+			// 判断工作历类型是否存在
+			WorkCalendar calendar = this.workCalendarService.getById(batchInfo.getCalendarId(), updateVO.getProjectId());
+			if (calendar == null) {
+				throw new BusinessException("工作历类型不存在");
+			}
+			
+			WorkCalendarDate calendarDate = new WorkCalendarDate();
+			BeanUtils.copyProperties(batchInfo, calendarDate);
+			// 验证数据有效性
+			result = this.workCalendarDateService.checkWorkDateValid(calendarDate);
+			if (!result) {
+				throw new BusinessException("当天已存在相同类型的定义,不可重复添加");
+			}
+			calendarDate.setGroupCode(updateVO.getGroupCode());
+			calendarDate.setProjectId(updateVO.getProjectId());
+			calendarDate.setUpdateUser(updateVO.getUserId());
+			calendarDate.setCalendarName(calendar.getCalendarName());
+			calendarDate.setCalendarDesc(calendar.getCalendarDesc());
+			calendarDate.setCustomFlag(WorkCalendarConstant.CUSTOM_CALENDAR_DATE_YES);
+			result = this.workCalendarDateService.updateById(calendarDate);
+			if (!result) {
+				throw new BusinessException("自定义工作历作息时间添加失败");
+			}
+		}
+	}
+
+	/**
+	 * 多时间段添加工作历作息时间信息,先删除此dictType下数据,再添加
+	 * @param createVO
+	 * @param calendar 
+	 */
+	@Transactional
+	public void batchCreateCalendarMoreDate(WorkCalendarMoreDateCreateVO createVO, WorkCalendar calendar) {
+		String calendarId = createVO.getCalendarId();
+		String projectId = createVO.getProjectId();
+		String now = DateUtil.format(new Date(), DateUtil.FORMAT_DATE_YYYYMMDDHHMMSS);
+		DateTime dateStart = DateUtil.parse(createVO.getWorkDateStart(), DateUtil.FORMAT_DATE_YYYYMMDD);
+		DateTime dateEnd = DateUtil.parse(createVO.getWorkDateEnd(), DateUtil.FORMAT_DATE_YYYYMMDD);
+		long betweenDay = DateUtil.between(dateStart, dateEnd, DateUnit.DAY) + 1;
+		
+		Set<String> timetables = createVO.getTimetable();
+		List<WorkCalendarDate> datas = new ArrayList<WorkCalendarDate>();
+		for (int i = 0; i < betweenDay; i++) {
+			String currentDay = DateUtil.format(dateStart, DateUtil.FORMAT_DATE_YYYYMMDD);
+			if (CollectionUtil.isEmpty(timetables)) {
+				WorkCalendarDate calendarDate = this.setCalendarDate(createVO, calendar, currentDay, null, now);
+				datas.add(calendarDate);
+			} else {
+				for (String timetable : timetables) {
+					// 数据库数据组装
+					WorkCalendarDate calendarDate = this.setCalendarDate(createVO, calendar, currentDay, timetable, now);
+					datas.add(calendarDate);
+				}
+			}
+			
+			// 偏移天数
+			dateStart.offset(DateField.DAY_OF_YEAR, 1);
+		}
+		// 先删除
+		QueryWrapper<WorkCalendarDate> queryWrapper = new WorkCalendarDate.Builder().createQueryWrapper()
+				.calendarIdEq(calendarId).projectIdEq(projectId).dictTypeEq(createVO.getDictType())
+				.workDateGe(createVO.getWorkDateStart()).workDateLe(createVO.getWorkDateEnd())
+				.customFlagEq(createVO.getCustomFlag()).builderQueryWrapper();
+		this.workCalendarDateService.remove(queryWrapper);
+		
+		// 批量添加数据
+		this.workCalendarDateService.batchCreateCalendarDate(datas);
+	}
+	
+	/**
+	 * 参数赋值
+	 * @param createVO
+	 * @param calendar
+	 * @param currentDay
+	 * @param timetable
+	 * @param now
+	 * @return
+	 */
+	private WorkCalendarDate setCalendarDate(WorkCalendarMoreDateCreateVO createVO, WorkCalendar calendar, 
+			String currentDay, String timetable, String now) {
+		WorkCalendarDate calendarDate = new WorkCalendarDate();
+		calendarDate.setId(IdGenerator.getSnowIdStr(WorkCalendarConstant.WORK_CALENDAR_DATE_ID_PREFIX));
+		calendarDate.setGroupCode(createVO.getGroupCode());
+		calendarDate.setProjectId(createVO.getProjectId());
+		calendarDate.setCalendarId(createVO.getCalendarId());
+		calendarDate.setCustomFlag(WorkCalendarConstant.CUSTOM_CALENDAR_DATE_YES);
+		calendarDate.setCalendarName(calendar.getCalendarName());
+		calendarDate.setCalendarDesc(calendar.getCalendarDesc());
+		calendarDate.setDictType(createVO.getDictType());
+		calendarDate.setDictCode(createVO.getDictCode());
+		calendarDate.setWorkDate(currentDay);
+		calendarDate.setWorkTime(timetable);
+		calendarDate.setCreateTime(now);
+		calendarDate.setUpdateTime(now);
+		calendarDate.setUpdateUser(createVO.getUserId());
+		
+		return calendarDate;
+	}
+	
+	/**
+	 * 检查参数日期是否大于当前日期
+	 * @param workDate 工作日期 yyyyMMdd
+	 * @return
+	 */
+	public static boolean isMoreThanToday(String workDate) {
+		DateTime now = DateUtil.date();
+		now = now.offset(DateField.DAY_OF_YEAR, 1);		//明天
+		String format = DateUtil.format(now, DateUtil.FORMAT_DATE_YYYYMMDD);
+		Integer current = Integer.valueOf(format);
+		Integer dateInt = Integer.valueOf(workDate);
+		if (dateInt < current) {
+			return false;
+		}
+		return true;
+	}
+	
+}

+ 506 - 0
src/main/java/com/persagy/calendar/handle/WorkCalendarHandler.java

@@ -0,0 +1,506 @@
+package com.persagy.calendar.handle;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import org.springframework.transaction.annotation.Transactional;
+
+import com.alibaba.fastjson.JSON;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.persagy.calendar.constant.WorkCalendarConstant;
+import com.persagy.calendar.pojo.dto.WorkCalendar;
+import com.persagy.calendar.pojo.dto.WorkCalendarDate;
+import com.persagy.calendar.pojo.dto.WorkCalendarDict;
+import com.persagy.calendar.pojo.dto.WorkCalendarLabel;
+import com.persagy.calendar.pojo.dto.WorkCalendarObject;
+import com.persagy.calendar.pojo.dto.WorkCalendarRule;
+import com.persagy.calendar.pojo.old.OldCalendarIntervalCreateVO;
+import com.persagy.calendar.pojo.old.OldCalendarQueryVO;
+import com.persagy.calendar.pojo.old.OldCalendarResponseVO;
+import com.persagy.calendar.pojo.vo.BaseUpdateVO;
+import com.persagy.calendar.service.IWorkCalendarDateService;
+import com.persagy.calendar.service.IWorkCalendarDictService;
+import com.persagy.calendar.service.IWorkCalendarLabelService;
+import com.persagy.calendar.service.IWorkCalendarObjectService;
+import com.persagy.calendar.service.IWorkCalendarRuleService;
+import com.persagy.calendar.service.IWorkCalendarService;
+import com.persagy.calendar.utils.ResponseOldResult;
+import com.persagy.calendar.utils.ResponseOldResultUtil;
+import com.persagy.common.enums.ResponseCode;
+import com.persagy.common.exception.BusinessException;
+import com.persagy.common.utils.DateUtil;
+import com.persagy.common.utils.IdGenerator;
+import com.persagy.common.utils.ResponseResult;
+import com.persagy.common.utils.ResponseUtil;
+import com.persagy.common.utils.StringUtil;
+
+import cn.hutool.core.collection.CollectionUtil;
+import cn.hutool.core.date.DateField;
+import cn.hutool.core.date.DateUnit;
+
+/**
+ * @version 
+ * @description 
+ * @company persagy
+ * @author zhangqiankun
+ * @since 2020年10月3日:	下午1:03:19
+ */
+@Component
+public class WorkCalendarHandler {
+	
+	@Autowired
+    private IWorkCalendarService workCalendarService;
+    
+    @Autowired
+    private IWorkCalendarRuleService workCalendarRuleService;
+    
+	@Autowired
+	private IWorkCalendarDictService workCalendarDictService;
+	
+    @Autowired
+    private IWorkCalendarDateService workCalendarDateService;
+
+	@Autowired
+	private IWorkCalendarLabelService workCalendarLabelService;
+	
+	@Autowired
+	private IWorkCalendarObjectService workCalendarObjectService;
+	
+	/**
+	 * 根据原有的工作历ID创建新的工作历信息和规则信息
+	 */
+    @Transactional
+	public ResponseResult createWorkCalendarFromId(String fromId, WorkCalendar workCalendar) {
+		// 1.添加工作历和对象信息
+    	boolean result = this.workCalendarService.save(workCalendar);
+    	if (!result) {
+    		return ResponseUtil.errorResult("新增失败");
+    	}
+    	// 2.创建对象关联信息
+    	if (CollectionUtil.isNotEmpty(workCalendar.getObjIds())) {
+    		// 插入对象与工作历的关联表中
+			WorkCalendarObject object = new WorkCalendarObject();
+			object.setGroupCode(workCalendar.getGroupCode());
+			object.setCalendarId(workCalendar.getId());
+			object.setCreateTime(workCalendar.getCreateTime());
+			object.setUpdateUser(workCalendar.getUpdateUser());
+			object.setProjectId(workCalendar.getProjectId());
+			this.workCalendarObjectService.batchInsertObjects(object, workCalendar.getObjIds());
+		}
+    	// 3.复制规则信息
+		List<WorkCalendarRule> ruleList = this.workCalendarRuleService.queryRuleByCalendarId(fromId, workCalendar.getProjectId());
+		if (result && CollectionUtil.isNotEmpty(ruleList)) {
+			for (WorkCalendarRule workCalendarRule : ruleList) {
+				workCalendarRule.setId(null);
+				workCalendarRule.setGroupCode(workCalendar.getGroupCode());
+				workCalendarRule.setCalendarId(workCalendar.getId());
+				workCalendarRule.setUpdateUser(workCalendar.getUpdateUser());
+				workCalendarRule.setCreateTime(null);
+				workCalendarRule.setUpdateTime(null);
+				result = workCalendarRuleService.save(workCalendarRule);
+				if (!result) {
+					throw new BusinessException(ResponseCode.B0001.getCode(), "复制原有规则信息失败");
+				}
+			}
+		}
+		// 4.复制自定义作息时间信息
+		this.copyCustomCalendarDate(fromId, workCalendar);
+		// 5.复制自定义标签信息
+		this.copyCustomCalendarLabel(fromId, workCalendar);
+		// 6.复制属于工作历类型级别的字典值
+		this.copyCustomCalendarDict(fromId, workCalendar);
+		
+		return ResponseUtil.successResult("新增成功", workCalendar.getId());
+    }
+    
+    /**
+     * 复制自定义的作息时间信息
+     * @param fromId
+     * @param workCalendar
+     */
+    private void copyCustomCalendarDate(String fromId, WorkCalendar workCalendar) {
+    	QueryWrapper<WorkCalendarDate> queryWrapper = new WorkCalendarDate.Builder().createQueryWrapper()
+    			.calendarIdEq(fromId).projectIdEq(workCalendar.getProjectId())
+    			.customFlagEq(WorkCalendarConstant.CUSTOM_CALENDAR_DATE_YES).builderQueryWrapper();
+    	List<WorkCalendarDate> calendarDates = this.workCalendarDateService.list(queryWrapper);
+    	if (CollectionUtil.isNotEmpty(calendarDates)) {
+    		calendarDates.forEach(calendarDate -> {
+    			calendarDate.setId(IdGenerator.getSnowIdStr(WorkCalendarConstant.WORK_CALENDAR_DATE_ID_PREFIX));
+    			calendarDate.setCalendarId(workCalendar.getId());
+    			calendarDate.setCreateTime(workCalendar.getCreateTime());
+    			calendarDate.setUpdateTime(workCalendar.getUpdateTime());
+    			calendarDate.setUpdateUser(workCalendar.getUpdateUser());
+    		});
+			this.workCalendarDateService.batchCreateCalendarDate(calendarDates);
+		}
+    }
+    
+    /**
+     * 复制自定义标签信息
+     * @param fromId
+     * @param workCalendar
+     */
+    private void copyCustomCalendarLabel(String fromId, WorkCalendar workCalendar) {
+    	QueryWrapper<WorkCalendarLabel> queryWrapper = new WorkCalendarLabel.Builder().createQueryWrapper()
+    			.calendarIdEq(fromId).projectIdEq(workCalendar.getProjectId()).builderQueryWrapper();
+    	List<WorkCalendarLabel> calendarLabels = this.workCalendarLabelService.list(queryWrapper);
+    	if (CollectionUtil.isNotEmpty(calendarLabels)) {
+    		calendarLabels.forEach(calendarLabel -> {
+    			calendarLabel.setId(IdGenerator.getSnowIdStr(WorkCalendarConstant.WORK_CALENDAR_LABEL_ID_PREFIX));
+    			calendarLabel.setCalendarId(workCalendar.getId());
+    			calendarLabel.setDiyValueStr(CollectionUtil.isEmpty(calendarLabel.getDiyValue()) ? null : JSON.toJSONString(calendarLabel.getDiyValue()));
+    			calendarLabel.setCreateTime(workCalendar.getCreateTime());
+    			calendarLabel.setUpdateTime(workCalendar.getUpdateTime());
+    			calendarLabel.setUpdateUser(workCalendar.getUpdateUser());
+    		});
+			this.workCalendarLabelService.batchCreateCalendarLabel(calendarLabels);
+		}
+    }
+    
+    /**
+     * 复制属于工作历类型字典数据
+     * @param fromId
+     * @param workCalendar
+     */
+    private void copyCustomCalendarDict(String fromId, WorkCalendar workCalendar) {
+    	QueryWrapper<WorkCalendarDict> queryWrapper = new WorkCalendarDict.Builder().createQueryWrapper()
+    			.groupCodeEq(workCalendar.getGroupCode()).calendarIdEq(fromId).builderQueryWrapper();
+    	List<WorkCalendarDict> calendarDicts = this.workCalendarDictService.list(queryWrapper);
+    	if (CollectionUtil.isNotEmpty(calendarDicts)) {
+    		calendarDicts.forEach(calendarDict -> {
+    			calendarDict.setCalendarId(workCalendar.getId());
+    		});
+			this.workCalendarDictService.batchCreateCalendarDict(calendarDicts);
+		}
+    }
+    
+    /**
+     * 逻辑删除工作历类型数据,且级联删除规则、对象、标签、自定义作息时间
+     */
+    @Transactional
+	public ResponseResult deleteWorkCalendar(BaseUpdateVO baseUpdateVO) {
+    	String id = baseUpdateVO.getId();
+    	String projectId = baseUpdateVO.getProjectId();
+    	String updateUser = baseUpdateVO.getUserId();
+		// 1.逻辑删除工作历信息
+    	boolean result = this.workCalendarService.deleteWorkCalendar(baseUpdateVO.getId(), baseUpdateVO.getUserId());
+    	if (!result) {
+			return ResponseUtil.errorResult("删除工作历类型失败");
+		}
+    	// 2.取消关联的对象数据信息
+    	QueryWrapper<WorkCalendarObject> objectWrapper = new WorkCalendarObject.Builder().createQueryWrapper()
+    			.groupCodeEq(baseUpdateVO.getGroupCode()).projectIdEq(projectId)
+    			.calendarIdEq(baseUpdateVO.getId()).builderQueryWrapper();
+    	this.workCalendarObjectService.remove(objectWrapper);
+    	// 3.逻辑删除规则信息
+    	WorkCalendarRule workCalendarRule = new WorkCalendarRule();
+    	workCalendarRule.setCalendarId(id);
+    	workCalendarRule.setUpdateUser(updateUser);
+    	this.workCalendarRuleService.deleteWorkCalendarRule(workCalendarRule);
+    	// 4.物理删除自动义作息时间信息
+    	QueryWrapper<WorkCalendarDate> dateWrapper = new WorkCalendarDate.Builder().createQueryWrapper()
+    			.calendarIdEq(id).projectIdEq(projectId).builderQueryWrapper();
+    	this.workCalendarDateService.remove(dateWrapper);
+		// 5.物理删除自定义标签信息
+    	QueryWrapper<WorkCalendarLabel> labelWrapper = new WorkCalendarLabel.Builder().createQueryWrapper()
+    			.calendarIdEq(id).projectIdEq(projectId).builderQueryWrapper();
+    	this.workCalendarLabelService.remove(labelWrapper);
+		// 6.物理删除属于工作历类型级别的字典值
+    	QueryWrapper<WorkCalendarDict> dictWrapper = new WorkCalendarDict.Builder().createQueryWrapper()
+    			.calendarIdEq(id).builderQueryWrapper();
+    	this.workCalendarDictService.remove(dictWrapper);
+		
+		return ResponseUtil.successResult("删除工作历类型成功");
+    }
+    
+    
+    /**
+     * 模板创建工作历信息--老版服务
+     * @param from_id 来源ID
+     * @param workCalendar
+     * @return
+     */
+    @Transactional
+	public boolean createOldWorkCalendarFromId(String from_id, String projectId, WorkCalendar workCalendar) {
+    	// 工作历信息插入
+    	boolean result = this.workCalendarService.save(workCalendar);;
+    	if (!result) {
+			throw new BusinessException(ResponseCode.B0001.getCode(), "创建工作历信息失败");
+		}
+    	// 新工作历ID
+    	String calendarId = workCalendar.getId();
+    	
+    	// 获取规则信息
+    	QueryWrapper<WorkCalendarRule> queryRule = new WorkCalendarRule.Builder().createQueryWrapper()
+    			.calendarIdEq(from_id).projectIdEq(workCalendar.getProjectId())
+    			.delFlagEq(WorkCalendarConstant.WORK_CALENDAR_DEL_FLAG_NOR).builderQueryWrapper();
+    	List<WorkCalendarRule> ruleList = this.workCalendarRuleService.list(queryRule);
+    	
+    	WorkCalendarRule calendarRule = null;
+    	if (CollectionUtil.isNotEmpty(ruleList)) {
+			for (WorkCalendarRule rule : ruleList) {
+				calendarRule = new WorkCalendarRule();
+				calendarRule.setCalendarId(calendarId);
+				calendarRule.setDictType(rule.getDictType());
+				calendarRule.setDictCode(rule.getDictCode());
+				calendarRule.setValue(rule.getValue());
+				calendarRule.setProjectId(projectId);
+				calendarRule.setRuleFlag(rule.getRuleFlag());
+				result = this.workCalendarRuleService.save(calendarRule);
+				if (!result) {
+					throw new BusinessException(ResponseCode.B0001.getCode(), "级联创建规则信息失败");
+				}
+			}
+		}
+    	// 获取作息时间信息
+    	QueryWrapper<WorkCalendarDate> queryDate = new WorkCalendarDate.Builder().createQueryWrapper()
+    			.calendarIdEq(from_id).projectIdEq(workCalendar.getProjectId()).builderQueryWrapper();
+    	List<WorkCalendarDate> dateList = this.workCalendarDateService.list(queryDate);
+    	
+    	WorkCalendarDate calendarDate = null;
+    	if (CollectionUtil.isNotEmpty(dateList)) {
+    		for (WorkCalendarDate date : dateList) {
+    			calendarDate = new WorkCalendarDate();
+    			calendarDate.setCalendarId(calendarId);
+    			calendarDate.setProjectId(projectId);
+    			calendarDate.setDictType(date.getDictType());
+    			calendarDate.setDictCode(date.getDictCode());
+    			calendarDate.setWorkTime(date.getWorkTime());
+    			calendarDate.setCustomFlag(WorkCalendarConstant.CUSTOM_CALENDAR_DATE_NO);
+    			calendarDate.setWorkDateStart(date.getWorkDateStart());
+    			calendarDate.setWorkDateEnd(date.getWorkDateEnd());
+    			result = this.workCalendarDateService.save(calendarDate);
+				if (!result) {
+					throw new BusinessException(ResponseCode.B0001.getCode(), "级联创建作息时间信息失败");
+				}
+    		}
+    	}
+    	
+    	return result;
+	}
+    
+    /**
+     * 老版服务删除工作历,级联删除,工作历和规则
+     * @param id
+     * @return
+     */
+    @Transactional
+	public ResponseOldResult deleteWorkCalendar(String id) {
+		boolean result = workCalendarService.deleteWorkCalendar(id, null);
+		if (result) {
+			WorkCalendarRule workCalendarRule = new WorkCalendarRule();
+			workCalendarRule.setCalendarId(id);
+			result = workCalendarRuleService.deleteWorkCalendarRule(workCalendarRule);
+			if (!result) {
+				return ResponseOldResultUtil.errorResultMsg("工作历删除成功,对应规则删除失败");
+			}
+		}
+		return ResponseOldResultUtil.successResult();
+	}
+    
+    /**
+     * workdateStart[start~end] OR workDateEnd[start-end] 是否如此待定
+     * 解析老版工作历规则,组装响应数据
+     * @param requestData
+     */
+	public List<OldCalendarResponseVO> queryOldCalendarDetails(OldCalendarQueryVO requestData) {
+		// 获取数据,tag由于需要like in 不在sql语句中处理,在此对返回结果做处理
+		QueryWrapper<WorkCalendarDate> queryWrapper = new WorkCalendarDate.Builder()
+				.createQueryWrapper().calendarIdEq(requestData.getId())
+				.dictCodeIn(requestData.getIntervals())
+				.workDateStartGe(requestData.getDates().getFrom())
+				.workDateEndLe(requestData.getDates().getTo())
+				.builderQueryWrapper();
+		// 其中的数据包括作息日期 作息时间段
+		List<WorkCalendarDate> dateList = this.workCalendarDateService.list(queryWrapper);
+		if (CollectionUtil.isEmpty(dateList)) {
+			dateList = new ArrayList<WorkCalendarDate>();
+		}
+		
+		// 再获取规则数据
+		QueryWrapper<WorkCalendarRule> queryRule = new WorkCalendarRule.Builder()
+				.createQueryWrapper().calendarIdEq(requestData.getId())
+				.delFlagEq(WorkCalendarConstant.WORK_CALENDAR_DEL_FLAG_NOR)
+				.ruleFlagEq(WorkCalendarConstant.WORK_CALENDAR_RULE_FLAG_OLD).builderQueryWrapper();
+		List<WorkCalendarRule> ruleList = this.workCalendarRuleService.list(queryRule);
+		if (CollectionUtil.isEmpty(ruleList)) {
+			ruleList = new ArrayList<WorkCalendarRule>();
+		}
+		
+		return this.handleDataList(dateList, ruleList, requestData);
+	}
+	
+	/**
+	 * 组装响应数据,并解析规则
+	 * @param dateList
+	 * @param ruleList
+	 * @param tags 
+	 * @return
+	 */
+	private List<OldCalendarResponseVO> handleDataList(List<WorkCalendarDate> dateList, 
+			List<WorkCalendarRule> ruleList, OldCalendarQueryVO requestData) {
+		List<OldCalendarResponseVO> result = new ArrayList<OldCalendarResponseVO>();
+		OldCalendarResponseVO responseVO = null;
+		OldCalendarIntervalCreateVO interval = null;
+		List<OldCalendarIntervalCreateVO> intervals = null;
+		
+		// 条件
+		Set<String> tagsCon = requestData.getTags();
+		String workFrom = requestData.getDates().getFrom();
+		String workTo = requestData.getDates().getTo();
+		
+		// 获取天数差
+		Date startCon = DateUtil.parse(workFrom, DateUtil.FORMAT_DATE_YYYYMMDDHHMMSS);
+		Date endCon = DateUtil.parse(workTo, DateUtil.FORMAT_DATE_YYYYMMDDHHMMSS);
+		long betweenDay = DateUtil.between(startCon, endCon, DateUnit.DAY);
+		
+		// 开始~结束日期
+		String from = null;
+		String to = null;
+		// 开始~结束日期对应的date类型
+		Date start = null;
+		Date end = null;
+		// 偏移后的某天
+		Date offsetDate = null;
+		String formatDate = null;
+		Set<String> tags = null;
+		for(int i = 0; i <= betweenDay; i++) {
+			responseVO = new OldCalendarResponseVO();
+			interval = new OldCalendarIntervalCreateVO();
+			intervals = new ArrayList<OldCalendarIntervalCreateVO>();
+			tags = new HashSet<String>();
+			
+			// 计算出偏移后日期
+			offsetDate = DateUtil.offset(startCon, DateField.DAY_OF_YEAR, i);		// 偏移后时间
+			formatDate = DateUtil.format(offsetDate, DateUtil.FORMAT_DATE_YYYYMMDDHHMMSS);
+			responseVO.setDate(formatDate);
+			
+			for (WorkCalendarDate calendarDate : dateList) {
+				// 判断是否满足tags条件,不论满足不满足都需要去解析规则,判断此天是否有对应的tag
+				if (CollectionUtil.isNotEmpty(tagsCon) 
+						&& tagsCon.contains(calendarDate.getDictType().split("-")[0])) {
+					tags.add(calendarDate.getDictType());	// 添加date对应的tag
+				}
+				
+				// 解析规则,判断此天是否有着对应的规则信息,规则不包含code,只有tag
+				if (CollectionUtil.isNotEmpty(ruleList)) {
+					this.parseCalendarRules(ruleList, tags, offsetDate, formatDate);
+				}
+				
+				// 获取作息日期段
+				from = calendarDate.getWorkDateStart();
+				to = calendarDate.getWorkDateEnd();
+				start = DateUtil.parse(from, DateUtil.FORMAT_DATE_YYYYMMDDHHMMSS);
+				end = DateUtil.parse(to, DateUtil.FORMAT_DATE_YYYYMMDDHHMMSS);
+				
+				// 判断当前日期,是否位于此段时间内 [start~end]
+				if (offsetDate.equals(start) || offsetDate.equals(end)
+						|| (offsetDate.after(start) && offsetDate.before(end))) {
+					// 满足条件,封装code、tag、time信息,intervals已经作为sql条件的一部分,这里不再过滤
+					String workTime = calendarDate.getWorkTime();
+					interval.setCode(calendarDate.getDictCode());
+					if (StringUtil.isNotBlank(workTime)) {
+						String[] split = workTime.split(",");
+						interval.setTime(Arrays.asList(split));
+					}
+					intervals.add(interval);
+				}
+			}
+			
+			// 添加进响应对象中
+			responseVO.setDate(formatDate);
+			responseVO.setTags(tags);
+			responseVO.setIntervals(intervals);
+			result.add(responseVO);
+		}
+		
+		return result;
+	}
+	
+	/**
+	 * 解析老版服务中的规则信息,判断是否需要添加tag
+	 * @param ruleList
+	 * @param tags
+	 * @param offsetDate 这一天
+	 * @param formatDate 这一天的字符串形式,YYYYMMDDHHMMSS
+	 */
+	private void parseCalendarRules(List<WorkCalendarRule> ruleList, Set<String> tags, Date offsetDate,
+			String formatDate) {
+		// 获取月日
+		String mmddStr = formatDate.substring(4, 8);
+		Integer mmdd = Integer.valueOf(mmddStr);
+		
+		String tag = null;
+		String type = null;
+		Set<String> values = null;
+		for (WorkCalendarRule rule : ruleList) {
+			tag = rule.getDictType();
+			type = rule.getDictCode();
+			values = rule.getValue();
+			
+			switch (type) {
+				case WorkCalendarConstant.WORK_CALENDAR_D_OF_W:	 //周
+					// 1表示周日,2表示周一
+					int dayOfWeek = DateUtil.dayOfWeek(offsetDate);	
+					dayOfWeek = dayOfWeek - 1;
+					if (dayOfWeek == 0) {
+						dayOfWeek = 7;
+					}
+					String num = String.valueOf(dayOfWeek);
+					if (values.contains(num)) {
+						tags.add(tag);
+					}
+					break;
+				case WorkCalendarConstant.WORK_CALENDAR_D_OF_M:	 //月
+					// 当前日期为此月的第几天
+					int ofMonth = DateUtil.dayOfMonth(offsetDate);
+					String day = String.valueOf(ofMonth);
+					Iterator<String> iterator = values.iterator();
+					while(iterator.hasNext()) {
+						String next = iterator.next();
+						if (next.contains("-")) {
+							String[] split2 = next.split("-");
+							int start = Integer.parseInt(split2[0]);
+							int end = Integer.parseInt(split2[1]);
+							if (ofMonth >= start && ofMonth <= end) {
+								tags.add(tag);
+								break;
+							}
+						} else if (day.equals(next)) {
+							tags.add(tag);
+							break;
+						}
+					}
+					break;
+				case WorkCalendarConstant.WORK_CALENDAR_M_AND_D: //年
+					iterator = values.iterator();
+					while(iterator.hasNext()) {
+						String next = iterator.next();
+						if (next.contains("-")) {
+							String[] split2 = next.split("-");
+							Integer startInt = Integer.valueOf(split2[0]);
+							Integer endInt = Integer.valueOf(split2[1]);
+							if (mmdd >= startInt && mmdd <= endInt) {
+								tags.add(tag);
+								break;
+							}
+						} else if (mmddStr.equals(next)) {
+							tags.add(tag);
+							break;
+						}
+					}
+					break;
+				default: 
+					break;
+			}
+		}
+	}
+	
+}

+ 241 - 0
src/main/java/com/persagy/calendar/handle/WorkCalendarLabelHandler.java

@@ -0,0 +1,241 @@
+package com.persagy.calendar.handle;
+
+import java.util.Date;
+import java.util.List;
+
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import org.springframework.transaction.annotation.Transactional;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.google.common.collect.Lists;
+import com.persagy.calendar.constant.WorkCalendarConstant;
+import com.persagy.calendar.pojo.dto.WorkCalendar;
+import com.persagy.calendar.pojo.dto.WorkCalendarDict;
+import com.persagy.calendar.pojo.dto.WorkCalendarLabel;
+import com.persagy.calendar.pojo.dto.WorkCalendarLabel.Builder;
+import com.persagy.calendar.pojo.dto.WorkCalendarObject;
+import com.persagy.calendar.pojo.vo.WorkCalendarLabelQueryVO;
+import com.persagy.calendar.pojo.vo.WorkCalendarLabelUpdateVO;
+import com.persagy.calendar.pojo.vo.WorkCalendarMoreDateCreateVO;
+import com.persagy.calendar.pojo.vo.WorkLabelBatchUpdateVO;
+import com.persagy.calendar.service.IWorkCalendarDictService;
+import com.persagy.calendar.service.IWorkCalendarLabelService;
+import com.persagy.calendar.service.IWorkCalendarObjectService;
+import com.persagy.calendar.service.IWorkCalendarService;
+import com.persagy.common.enums.ResponseCode;
+import com.persagy.common.exception.BusinessException;
+import com.persagy.common.utils.DateUtil;
+import com.persagy.common.utils.ResponseResult;
+import com.persagy.common.utils.ResponseUtil;
+import com.persagy.common.utils.StringUtil;
+
+import cn.hutool.core.collection.CollectionUtil;
+import cn.hutool.core.date.DateField;
+import cn.hutool.core.date.DateTime;
+import cn.hutool.core.date.DateUnit;
+import cn.hutool.core.util.BooleanUtil;
+
+/**
+ * @version 
+ * @description 
+ * @company persagy
+ * @author zhangqiankun
+ * @since 2021年3月3日:	下午6:14:49
+ */
+@Component
+public class WorkCalendarLabelHandler {
+	
+	public static final String LABEL_COLUMN = "GROUP_CODE, PROJECT_ID, CALENDAR_ID, DICT_TYPE, DICT_CODE, DIY_LABEL, DIY_VALUE, LABEL_DATE, CONVERT(SUBSTR(LABEL_DATE, 5, 2), SIGNED) AS labelMonth, CREATE_TIME, UPDATE_TIME, UPDATE_USER";
+	
+    @Autowired
+    private IWorkCalendarService workCalendarService;
+    
+	@Autowired
+	private IWorkCalendarLabelService workCalendarLabelService;
+	
+	@Autowired
+	private IWorkCalendarDictService workCalendarDictService;
+	
+	@Autowired
+	private WorkCalendarDateHandler workCalendarDateHandler;
+	
+	@Autowired
+	private IWorkCalendarObjectService workCalendarObjectService;
+
+	/**
+	 * 日期标签属性列表查询
+	 * @param queryVO
+	 * @return
+	 */
+	public List<WorkCalendarLabel> queryCalendarLabelList(WorkCalendarLabelQueryVO queryVO) {
+		if (StringUtil.isNotBlank(queryVO.getObjId())) {
+			//查询出此对象对应的工作历ID和项目ID
+			QueryWrapper<WorkCalendarObject> objectWrapper = new WorkCalendarObject.Builder().createQueryWrapper()
+					.groupCodeEq(queryVO.getGroupCode()).objectIdEq(queryVO.getObjId())
+					.projectIdEq(queryVO.getProjectId()).builderQueryWrapper();
+			WorkCalendarObject calendarObject = this.workCalendarObjectService.getOne(objectWrapper);
+			if (calendarObject == null) {
+				return null;
+			}
+			queryVO.setCalendarId(calendarObject.getCalendarId());
+		}
+		QueryWrapper<WorkCalendarLabel> queryWrapper = new WorkCalendarLabel.Builder().createQueryWrapper()
+				.calendarIdEq(queryVO.getCalendarId()).projectIdEq(queryVO.getProjectId())
+				.dictTypeEq(queryVO.getDictType()).dictCodeEq(queryVO.getDictCode())
+				.labelDateGe(queryVO.getLabelDateStart()).labelDateLe(queryVO.getLabelDateEnd())
+				.builderQueryWrapper();
+		return this.workCalendarLabelService.list(queryWrapper.select(LABEL_COLUMN).orderByAsc(Lists.newArrayList("LABEL_DATE", "ID")));
+	}
+	
+	/**
+	 * 查询标签的有效期
+	 * @param queryVO
+	 * @return
+	 */
+	public List<WorkCalendarLabel> queryCalendarLabelValid(WorkCalendarLabelQueryVO queryVO) {
+		if (StringUtil.isNotBlank(queryVO.getObjId())) {
+			//查询出此对象对应的工作历ID和项目ID
+			QueryWrapper<WorkCalendarObject> objectWrapper = new WorkCalendarObject.Builder().createQueryWrapper()
+					.groupCodeEq(queryVO.getGroupCode()).objectIdEq(queryVO.getObjId())
+					.projectIdEq(queryVO.getProjectId()).builderQueryWrapper();
+			WorkCalendarObject calendarObject = this.workCalendarObjectService.getOne(objectWrapper);
+			if (calendarObject == null) {
+				return null;
+			}
+			queryVO.setCalendarId(calendarObject.getCalendarId());
+		}
+		QueryWrapper<WorkCalendarLabel> queryWrapper = new WorkCalendarLabel.Builder().createQueryWrapper()
+				.groupCodeEq(queryVO.getGroupCode()).calendarIdEq(queryVO.getCalendarId())
+				.projectIdEq(queryVO.getProjectId()).dictTypeEq(queryVO.getDictType())
+				.dictCodeEq(queryVO.getDictCode()).diyLabelEq(queryVO.getDiyLabel())
+				.labelDateGe(queryVO.getLabelDateStart()).labelDateLe(queryVO.getLabelDateEnd())
+				.builderQueryWrapper();
+		queryWrapper.select(queryVO.getGroupBy() + ", MIN(LABEL_DATE) AS labelDateStart, MAX(LABEL_DATE) AS labelDateEnd");
+		queryWrapper.groupBy(queryVO.getGroupBy());
+		return this.workCalendarLabelService.list(queryWrapper);
+	}
+	
+	/**
+	 * 创建或更新日期标签属性
+	 * @param createVO
+	 */
+	@Transactional
+	public void updateLabelInfo(WorkCalendarLabelUpdateVO updateVO) {
+		boolean result = false;
+		if (BooleanUtil.isTrue(updateVO.getIsDelete())) {
+			Builder builder = new WorkCalendarLabel.Builder().createQueryWrapper();
+			QueryWrapper<WorkCalendarLabel> queryWrapper = builder.labelDateGe(updateVO.getLabelDateStart())
+					.labelDateLe(updateVO.getLabelDateEnd()).calendarIdEq(updateVO.getCalendarId())
+					.projectIdEq(updateVO.getProjectId()).dictTypeEq(updateVO.getDictType())
+					.diyLabelEq(updateVO.getDiyLabel()).builderQueryWrapper();
+			this.workCalendarLabelService.remove(queryWrapper);
+			return;
+		} else if (BooleanUtil.isTrue(updateVO.getIsUpdate())) {
+			Builder builder = new WorkCalendarLabel.Builder().createQueryWrapper();
+			QueryWrapper<WorkCalendarLabel> queryWrapper = builder.labelDateGe(updateVO.getLabelDateStart())
+					.labelDateLe(updateVO.getLabelDateEnd()).calendarIdEq(updateVO.getCalendarId())
+					.projectIdEq(updateVO.getProjectId()).dictTypeEq(updateVO.getDictType())
+					.diyLabelEq(updateVO.getDiyLabel()).builderQueryWrapper();
+			this.workCalendarLabelService.remove(queryWrapper);
+		}
+		
+		WorkCalendarLabel calendarLabel = new WorkCalendarLabel();
+		BeanUtils.copyProperties(updateVO, calendarLabel);
+		String now = DateUtil.format(new Date(), DateUtil.FORMAT_DATE_YYYYMMDDHHMMSS);
+		calendarLabel.setCreateTime(now);
+		calendarLabel.setUpdateTime(now);
+		calendarLabel.setUpdateUser(updateVO.getUserId());
+		calendarLabel.setGroupCode(updateVO.getGroupCode());
+		
+		DateTime dateStart = DateUtil.parse(updateVO.getLabelDateStart(), DateUtil.FORMAT_DATE_YYYYMMDD);
+		DateTime dateEnd = DateUtil.parse(updateVO.getLabelDateEnd(), DateUtil.FORMAT_DATE_YYYYMMDD);
+		long betweenDay = DateUtil.between(dateStart, dateEnd, DateUnit.DAY) + 1;
+		for (int i = 0; i < betweenDay; i++) {
+			calendarLabel.setId(null);
+			calendarLabel.setLabelDate(DateUtil.format(dateStart, DateUtil.FORMAT_DATE_YYYYMMDD));
+			if (WorkCalendarConstant.CUSTOM_CALENDAR_DATE_YES.equals(updateVO.getDiyLabel())) {
+				calendarLabel.setDictType(WorkCalendarConstant.CUSTOM_CALENDAR_DICT_TYPE);
+			}
+			result = this.workCalendarLabelService.save(calendarLabel);
+			if (!result) {
+				throw new BusinessException("日期标签属性设置失败");
+			}
+			
+			dateStart.offset(DateField.DAY_OF_YEAR, 1);
+		}
+		
+		// 设置成功后,将自定义的标签插入到字典表中
+		if (WorkCalendarConstant.CUSTOM_CALENDAR_DATE_YES.equals(updateVO.getDiyLabel())) {
+			// 当自定义标签时,存入字典表
+			WorkCalendarDict calendarDict = new WorkCalendarDict();
+			calendarDict.setCalendarId(updateVO.getCalendarId());
+			calendarDict.setGroupCode(updateVO.getGroupCode());
+			calendarDict.setDictType(WorkCalendarConstant.CUSTOM_CALENDAR_DICT_TYPE);
+			this.workCalendarDictService.batchCreateOrUpdateDictType(calendarDict, updateVO.getDiyValue());
+		}
+		
+	}
+
+	/**
+	 * 重新定义日期段内每天的属性标签
+	 * @param updateVO
+	 */
+	@Transactional
+	public void updateCalendarDateAttribute(WorkLabelBatchUpdateVO updateVO) {
+		List<WorkCalendarMoreDateCreateVO> times = updateVO.getTimes();
+		if (CollectionUtil.isNotEmpty(times)) {
+			for (WorkCalendarMoreDateCreateVO moreDateCreateVO : times) {
+				// 判断工作历类型是否存在
+				WorkCalendar calendar = this.workCalendarService.getById(moreDateCreateVO.getCalendarId(), moreDateCreateVO.getProjectId());
+				if (calendar == null) {
+					throw new BusinessException("工作历类型不存在");
+				}
+				moreDateCreateVO.setGroupCode(updateVO.getGroupCode());
+				this.workCalendarDateHandler.batchCreateCalendarMoreDate(moreDateCreateVO, calendar);
+			}
+		}
+		
+		List<WorkCalendarLabelUpdateVO> labels = updateVO.getLabels();
+		if (CollectionUtil.isNotEmpty(labels)) {
+			for (WorkCalendarLabelUpdateVO labelUpdateVO : labels) {
+				labelUpdateVO.setGroupCode(updateVO.getGroupCode());
+				this.updateLabelInfo(labelUpdateVO);
+			}
+		}
+	}
+	
+	/**
+	 * 检查数据的有效性
+	 * @param updateVO
+	 * @return null - 有效
+	 */
+	public static ResponseResult checkDataValidity(WorkCalendarLabelUpdateVO updateVO) {
+		if (WorkCalendarConstant.CUSTOM_CALENDAR_DATE_NO.equals(updateVO.getDiyLabel())) {
+			if (StringUtil.isBlank(updateVO.getDictType())) {
+				return ResponseUtil.errorResult(ResponseCode.A0400.getCode(), "字典类型不可为空");
+			}
+			if (BooleanUtil.isFalse(updateVO.getIsDelete())) {
+				if (StringUtil.isBlank(updateVO.getDictCode())) {
+					return ResponseUtil.errorResult(ResponseCode.A0400.getCode(), "字典编码不可为空");
+				}
+				if (CollectionUtil.isNotEmpty(updateVO.getDiyValue())) {
+					return ResponseUtil.errorResult(ResponseCode.A0400.getCode(), "非自定义情况下,diyValue必须为空");
+				}
+			}
+		} else {
+			if (BooleanUtil.isFalse(updateVO.getIsDelete())) {
+				if (CollectionUtil.isEmpty(updateVO.getDiyValue())) {
+					return ResponseUtil.errorResult(ResponseCode.A0400.getCode(), "自定义标签值不可为空");
+				}
+				if (StringUtil.isNotBlank(updateVO.getDictType()) || StringUtil.isNotBlank(updateVO.getDictCode())) {
+					return ResponseUtil.errorResult(ResponseCode.A0400.getCode(), "自定义情况下,字典类型和字典编码必须为空");
+				}
+			}
+		}
+		
+		return null;
+	}
+
+}

+ 133 - 0
src/main/java/com/persagy/calendar/handle/WorkCalendarRuleHandler.java

@@ -0,0 +1,133 @@
+package com.persagy.calendar.handle;
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import org.springframework.transaction.annotation.Transactional;
+
+import com.persagy.calendar.pojo.dto.WorkCalendar;
+import com.persagy.calendar.pojo.dto.WorkCalendarRule;
+import com.persagy.calendar.pojo.vo.CustomCalendarVO;
+import com.persagy.calendar.pojo.vo.WorkCalendarRuleCreateVO;
+import com.persagy.calendar.pojo.vo.WorkCalendarRuleUpdateVO;
+import com.persagy.calendar.service.IWorkCalendarRuleService;
+import com.persagy.calendar.service.IWorkCalendarService;
+import com.persagy.common.enums.ResponseCode;
+import com.persagy.common.exception.BusinessException;
+
+import cn.hutool.core.collection.CollectionUtil;
+import cn.hutool.core.util.BooleanUtil;
+
+/**
+ * @version 定义规则信息
+ * @description 
+ * @company persagy
+ * @author zhangqiankun
+ * @since 2020年10月3日:	下午1:03:19
+ */
+@Component
+public class WorkCalendarRuleHandler {
+	
+	@Autowired
+	private IWorkCalendarService workCalendarService;
+	
+	@Autowired
+	private IWorkCalendarRuleService workCalendarRuleService;
+	
+	/**
+	 * 批量创建规则信息
+	 */
+	@Transactional
+	public void batchCreateCalednarRule(CustomCalendarVO<WorkCalendarRuleCreateVO> createVO) {
+		boolean result = false;
+		WorkCalendarRule workCalendarRule = null;
+		List<WorkCalendarRuleCreateVO> batchInfo = createVO.getBatchInfo();
+		Set<String> calendarIds = new HashSet<String>();
+		for (WorkCalendarRuleCreateVO rule : batchInfo) {
+			// 优先判断工作历信息是否存在
+			if (!calendarIds.contains(rule.getCalendarId())) {
+				WorkCalendar workCalendar = this.workCalendarService.getById(rule.getCalendarId(), createVO.getProjectId());
+				if (workCalendar == null) {
+					throw new BusinessException("工作历主信息不存在");
+				}
+			}
+			workCalendarRule = new WorkCalendarRule();
+			BeanUtils.copyProperties(rule, workCalendarRule);
+			workCalendarRule.setId(null);
+			workCalendarRule.setGroupCode(createVO.getGroupCode());
+			workCalendarRule.setProjectId(createVO.getProjectId());
+			workCalendarRule.setUpdateUser(createVO.getUserId());
+			// 为兼容IBMS,紧急修改内容: shop 类型的工作历规则,一个项目的dictType+dictCode+value已存在的话,直接更新
+			if ("shop".equals(rule.getDictType()) && CollectionUtil.isNotEmpty(workCalendarRule.getValue())) {
+				String ruleId = this.workCalendarRuleService.getCalendarRule(workCalendarRule);
+				if (ruleId != null ) {
+					// 直接更新
+					workCalendarRule.setId(ruleId);
+					result = workCalendarRuleService.updateWorkCalendarRule(workCalendarRule);
+					if (!result) {
+						throw new BusinessException("工作历规则信息添加失败");
+					}
+					calendarIds.add(rule.getCalendarId());
+					continue;
+				}
+			}
+			// 是否需要删除旧规则
+			if (BooleanUtil.isTrue(createVO.getIsDelete()) && !calendarIds.contains(rule.getCalendarId())) {
+				workCalendarRuleService.removeWorkCalendarRule(null, rule.getCalendarId(), rule.getDictType());
+				//throw new BusinessException("工作历ID为:" + rule.getCalendarId() + "的工作历,删除规则信息失败");
+			}
+			result = this.workCalendarRuleService.createWorkCalendarRule(workCalendarRule);
+			if (!result) {
+				throw new BusinessException("工作历规则信息创建失败");
+			}
+			calendarIds.add(rule.getCalendarId());
+		}
+		calendarIds.clear();
+	}
+	
+	/**
+	 * 批量更新规则信息
+	 */
+	@Transactional
+	public void batchUpdateCalednarRule(CustomCalendarVO<WorkCalendarRuleUpdateVO> updateVO) {
+		boolean result = false;
+		WorkCalendarRule workCalendarRule = null;
+		List<WorkCalendarRuleUpdateVO> batchInfo = updateVO.getBatchInfo();
+		Set<String> calendarIds = new HashSet<String>();
+		for (WorkCalendarRuleUpdateVO rule : batchInfo) {
+			// 优先判断工作历信息是否存在
+			if (!calendarIds.contains(rule.getCalendarId())) {
+				WorkCalendar workCalendar = this.workCalendarService.getById(rule.getCalendarId(), updateVO.getProjectId());
+				if (workCalendar == null) {
+					throw new BusinessException("工作历主信息不存在");
+				}
+			}
+			// 再判断原规则数据是否存在
+			WorkCalendarRule calendar = workCalendarRuleService.getById(rule.getId(), updateVO.getProjectId());
+			if (calendar == null) {
+				throw new BusinessException(ResponseCode.C0320.getDesc());
+			}
+			// 是否需要删除旧规则
+			if (BooleanUtil.isTrue(updateVO.getIsDelete()) && !calendarIds.contains(rule.getCalendarId())) {
+				workCalendarRuleService.removeWorkCalendarRule(null, rule.getCalendarId(), rule.getDictCode());
+				//throw new BusinessException("工作历ID为:" + rule.getCalendarId() + "的工作历,删除规则信息失败");
+			}
+			workCalendarRule = new WorkCalendarRule();
+			BeanUtils.copyProperties(rule, workCalendarRule);
+			workCalendarRule.setGroupCode(updateVO.getGroupCode());
+			workCalendarRule.setProjectId(updateVO.getProjectId());
+			workCalendarRule.setUpdateUser(updateVO.getUserId());
+			result = workCalendarRuleService.updateWorkCalendarRule(workCalendarRule);
+			if (!result) {
+				throw new BusinessException("工作历规则信息更新失败");
+			}
+			calendarIds.add(rule.getCalendarId());
+		}
+		calendarIds.clear();
+	}
+	
+}

+ 26 - 0
src/main/java/com/persagy/calendar/mapper/OldWorkCalendarMapper.java

@@ -0,0 +1,26 @@
+package com.persagy.calendar.mapper;
+
+import java.util.List;
+
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+import com.persagy.calendar.pojo.dto.OldWorkCalendar;
+
+/**
+ * 工作历主表
+ * 
+ * @version 1.0.0
+ * @company persagy 
+ * @author zhangqiankun
+ * @date 2020-10-02 11:33:00
+ */
+@Mapper
+public interface OldWorkCalendarMapper {
+	
+	List<OldWorkCalendar> queryOldCalendarList(OldWorkCalendar oldWorkCalendar);
+
+	List<OldWorkCalendar> queryOldCalendarRuleList(@Param("id") String id, @Param("tag") String tag, 
+			@Param("projectId") String projectId, @Param("delFlag") String delFlag, @Param("ruleFlag") String ruleFlag);
+	
+}

+ 37 - 0
src/main/java/com/persagy/calendar/mapper/WorkCalendarDateMapper.java

@@ -0,0 +1,37 @@
+package com.persagy.calendar.mapper;
+
+import java.util.List;
+
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.persagy.calendar.pojo.dto.WorkCalendarDate;
+
+/**
+ * 工作历作息时间表,此表只有新增,无修改[新版]
+ * 
+ * @version 1.0.0
+ * @company persagy 
+ * @author zhangqiankun
+ * @date 2020-10-03 13:54:22
+ */
+@Mapper
+public interface WorkCalendarDateMapper extends BaseMapper<WorkCalendarDate> {
+
+	/**
+	 * 不存在新增,存在更新
+	 * @param calendarDate
+	 * @return
+	 */
+	Integer replaceIntoCalendarDate(WorkCalendarDate calendarDate);
+
+	/**
+	 * 批量创建自定义作息时间信息
+	 * 
+	 * @param datas
+	 * @return
+	 */
+	Integer batchCreateCalendarDate(@Param("datas") List<WorkCalendarDate> datas);
+
+}

+ 48 - 0
src/main/java/com/persagy/calendar/mapper/WorkCalendarDictMapper.java

@@ -0,0 +1,48 @@
+package com.persagy.calendar.mapper;
+
+import java.util.List;
+import java.util.Set;
+
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.persagy.calendar.pojo.dto.WorkCalendarDict;
+import com.persagy.calendar.pojo.vo.DictCodeCreate;
+
+/**
+ * @version 
+ * @description 
+ * @company persagy
+ * @author zhangqiankun
+ * @since 2021年3月3日:	下午7:51:51
+ */
+@Mapper
+public interface WorkCalendarDictMapper extends BaseMapper<WorkCalendarDict> {
+
+	/**
+	 * 批量创建字典类型,此接口,不存在dictCode
+	 * 
+	 * @param calendarDict
+	 * @param diyValue
+	 */
+	Integer batchCreateOrUpdateDictType(@Param("calendarDict") WorkCalendarDict calendarDict, @Param("diyValues") Set<String> diyValues);
+
+	/**
+	 * 批量创建字典类型
+	 * 
+	 * @param calendarDict
+	 * @param codes
+	 * @return
+	 */
+	Integer batchCreateOrUpdateDict(@Param("calendarDict") WorkCalendarDict calendarDict, @Param("codes") List<DictCodeCreate> codes);
+
+	/**
+	 * 批量创建字典类型
+	 * 
+	 * @param calendarDicts
+	 * @return
+	 */
+	Integer batchCreateCalendarDict(@Param("calendarDicts") List<WorkCalendarDict> calendarDicts);
+
+}

+ 27 - 0
src/main/java/com/persagy/calendar/mapper/WorkCalendarLabelMapper.java

@@ -0,0 +1,27 @@
+package com.persagy.calendar.mapper;
+
+import java.util.List;
+
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.persagy.calendar.pojo.dto.WorkCalendarLabel;
+
+/**
+ * 
+ * @version 1.0.0
+ * @company persagy 
+ * @author zhangqiankun
+ * @date 2020-10-02 18:26:14
+ */
+@Mapper
+public interface WorkCalendarLabelMapper extends BaseMapper<WorkCalendarLabel> {
+
+	/**
+	 * 批量创建标签信息
+	 * @param calendarLabels
+	 */
+	Integer batchCreateCalendarLabel(@Param("labels") List<WorkCalendarLabel> calendarLabels);
+	
+}

+ 29 - 0
src/main/java/com/persagy/calendar/mapper/WorkCalendarMapper.java

@@ -0,0 +1,29 @@
+package com.persagy.calendar.mapper;
+
+import java.util.List;
+
+import org.apache.ibatis.annotations.Mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.persagy.calendar.pojo.dto.WorkCalendar;
+
+/**
+ * 工作历主表
+ * 
+ * @version 1.0.0
+ * @company persagy 
+ * @author zhangqiankun
+ * @date 2020-10-02 11:33:00
+ */
+@Mapper
+public interface WorkCalendarMapper extends BaseMapper<WorkCalendar> {
+
+	/**
+	 * 查询工作历类型列表,包含所对应的对象,多表关联
+	 * 
+	 * @param calendar
+	 * @return
+	 */
+	List<WorkCalendar> queryCalendarObjectList(WorkCalendar calendar);
+
+}

+ 36 - 0
src/main/java/com/persagy/calendar/mapper/WorkCalendarObjectMapper.java

@@ -0,0 +1,36 @@
+package com.persagy.calendar.mapper;
+
+import java.util.Set;
+
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.persagy.calendar.pojo.dto.WorkCalendarObject;
+
+/**
+ * @version 1.0.0
+ * @company persagy 
+ * @author zhangqiankun
+ * @date 2020-10-02 18:26:14
+ */
+@Mapper
+public interface WorkCalendarObjectMapper extends BaseMapper<WorkCalendarObject> {
+
+	/**
+	 * 批量插入对象关系数据
+	 * @param object
+	 * @param objIds
+	 * @return
+	 */
+	Integer batchInsertObjects(@Param("object") WorkCalendarObject object, @Param("objIds") Set<String> objIds);
+
+	/**
+	 * 对象变更所属工作历
+	 * @param calendarObject
+	 * @param objIds 
+	 * @return
+	 */
+	Integer replaceCalendarObject(@Param("calendarObject") WorkCalendarObject calendarObject, @Param("objIds") Set<String> objIds);
+
+}

+ 19 - 0
src/main/java/com/persagy/calendar/mapper/WorkCalendarRuleMapper.java

@@ -0,0 +1,19 @@
+package com.persagy.calendar.mapper;
+
+import org.apache.ibatis.annotations.Mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.persagy.calendar.pojo.dto.WorkCalendarRule;
+
+/**
+ * 工作历规则表
+ * 
+ * @version 1.0.0
+ * @company persagy 
+ * @author zhangqiankun
+ * @date 2020-10-02 18:26:14
+ */
+@Mapper
+public interface WorkCalendarRuleMapper extends BaseMapper<WorkCalendarRule> {
+
+}

+ 44 - 0
src/main/java/com/persagy/calendar/pojo/dto/OldWorkCalendar.java

@@ -0,0 +1,44 @@
+package com.persagy.calendar.pojo.dto;
+
+import java.io.Serializable;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+
+import lombok.EqualsAndHashCode;
+import lombok.Getter;
+import lombok.Setter;
+import lombok.ToString;
+
+/**
+ * 工作历主表
+ * 
+ * @version 1.0.0
+ * @company persagy
+ * @author zhangqiankun
+ * @date 2020-10-02 11:33:00
+ */
+@Getter
+@Setter
+@ToString
+@EqualsAndHashCode(callSuper = false)
+public class OldWorkCalendar implements Serializable {
+	private static final long serialVersionUID = 3777758228884011839L;
+	
+	private String id;		// 主键id
+	
+	private String projectId; // 项目ID
+
+	private String name; // 同一GROUP_ID下唯一,代码判断
+
+	private String desc; // 工作历描述
+	
+	private String tag; // 字典类型
+	
+	private String type; // 字典数据code
+	
+	private String value;
+
+	@JsonIgnore
+	private String delFlag; // 0-正常;1-删除
+
+}

+ 206 - 0
src/main/java/com/persagy/calendar/pojo/dto/WorkCalendar.java

@@ -0,0 +1,206 @@
+package com.persagy.calendar.pojo.dto;
+
+import java.util.List;
+import java.util.Set;
+
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.FieldStrategy;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
+import com.persagy.calendar.constant.WorkCalendarConstant;
+import com.persagy.common.annotation.IdGenerator;
+import com.persagy.common.enums.IdGeneratorAlgorithm;
+import com.persagy.common.model.BaseEntity;
+import com.persagy.common.utils.StringUtil;
+
+import lombok.EqualsAndHashCode;
+import lombok.Getter;
+import lombok.Setter;
+import lombok.ToString;
+
+/**
+ * 工作历主表
+ * 
+ * @version 1.0.0
+ * @company persagy
+ * @author zhangqiankun
+ * @date 2020-10-02 11:33:00
+ */
+@Getter
+@Setter
+@ToString
+@TableName("work_calendar")
+@EqualsAndHashCode(callSuper = false)
+@IdGenerator(prefix = WorkCalendarConstant.WORK_CALENDAR_ID_PREFIX, algorithm = IdGeneratorAlgorithm.SNOW_STR)
+public class WorkCalendar extends BaseEntity<WorkCalendar> {
+	private static final long serialVersionUID = -1507838782036817943L;
+
+	@TableField(updateStrategy = FieldStrategy.NOT_EMPTY)
+	private String groupCode; // 集团编码
+	
+	@TableField(updateStrategy = FieldStrategy.NOT_EMPTY)
+	private String projectId; // 工作历分类ID
+
+	@TableField(updateStrategy = FieldStrategy.NOT_EMPTY)
+	private String calendarName; // 同一PROJECT_ID下唯一,代码判断
+
+	@TableField(updateStrategy = FieldStrategy.NOT_EMPTY)
+	private String calendarDesc; // 工作历描述
+
+	@TableField(fill = FieldFill.INSERT, updateStrategy = FieldStrategy.NOT_EMPTY)
+	private String createTime; // 创建时间
+
+	@TableField(fill = FieldFill.INSERT_UPDATE, updateStrategy = FieldStrategy.NOT_EMPTY)
+	private String updateTime; // 更新时间
+
+	@TableField(updateStrategy = FieldStrategy.NOT_EMPTY)
+	private String updateUser; // 操作用户ID
+
+	@TableField(updateStrategy = FieldStrategy.NOT_EMPTY)
+	private String delFlag; // 0-正常;1-删除
+
+	// objectId, objectName
+	@TableField(exist = false)
+	private List<JSONObject> objects;
+	
+	@TableField(exist = false)
+	private Set<String> objIds;	//对象ID集合,空间、建筑、楼层、项目
+	
+	public static class Builder {
+
+		private QueryWrapper<WorkCalendar> queryWrapper = null;
+
+		private UpdateWrapper<WorkCalendar> updateWrapper = null;
+
+		public Builder createQueryWrapper() {
+			queryWrapper = new QueryWrapper<WorkCalendar>();
+			return this;
+		}
+
+		public Builder createUpdateWrapper() {
+			updateWrapper = new UpdateWrapper<WorkCalendar>();
+			return this;
+		}
+
+		public Builder idEq(String id) {
+			if (StringUtil.isNotBlank(id)) {
+				if (updateWrapper != null) {
+					updateWrapper.eq("ID", id);
+				} else {
+					queryWrapper.eq("ID", id);
+				}
+			}
+			return this;
+		}
+
+		public Builder groupCodeEq(String groupCode) {
+			if (StringUtil.isNotBlank(groupCode)) {
+				if (updateWrapper != null) {
+					updateWrapper.eq("GROUP_CODE", groupCode);
+				} else {
+					queryWrapper.eq("GROUP_CODE", groupCode);
+				}
+			}
+			return this;
+		}
+		
+		public Builder projectIdEq(String projectId) {
+			if (StringUtil.isNotBlank(projectId)) {
+				if (updateWrapper != null) {
+					updateWrapper.eq("PROJECT_ID", projectId);
+				} else {
+					queryWrapper.eq("PROJECT_ID", projectId);
+				}
+			}
+			return this;
+		}
+
+		public Builder calendarNameEq(String calendarName) {
+			if (StringUtil.isNotBlank(calendarName)) {
+				if (updateWrapper != null) {
+					updateWrapper.eq("CALENDAR_NAME", calendarName);
+				} else {
+					queryWrapper.eq("CALENDAR_NAME", calendarName);
+				}
+			}
+			return this;
+		}
+		
+		public Builder calendarNameLike(String calendarName) {
+			if (StringUtil.isNotBlank(calendarName)) {
+				if (updateWrapper != null) {
+					updateWrapper.like("CALENDAR_NAME", calendarName);
+				} else {
+					queryWrapper.like("CALENDAR_NAME", calendarName);
+				}
+			}
+			return this;
+		}
+
+		public Builder calendarDescEq(String calendarDesc) {
+			if (StringUtil.isNotBlank(calendarDesc)) {
+				if (updateWrapper != null) {
+					updateWrapper.eq("CALENDAR_DESC", calendarDesc);
+				} else {
+					queryWrapper.eq("CALENDAR_DESC", calendarDesc);
+				}
+			}
+			return this;
+		}
+
+		public Builder createTimeEq(String createTime) {
+			if (StringUtil.isNotBlank(createTime)) {
+				if (updateWrapper != null) {
+					updateWrapper.eq("CREATE_TIME", createTime);
+				} else {
+					queryWrapper.eq("CREATE_TIME", createTime);
+				}
+			}
+			return this;
+		}
+
+		public Builder updateTimeEq(String updateTime) {
+			if (StringUtil.isNotBlank(updateTime)) {
+				if (updateWrapper != null) {
+					updateWrapper.eq("UPDATE_TIME", updateTime);
+				} else {
+					queryWrapper.eq("UPDATE_TIME", updateTime);
+				}
+			}
+			return this;
+		}
+
+		public Builder updateUserEq(String updateUser) {
+			if (StringUtil.isNotBlank(updateUser)) {
+				if (updateWrapper != null) {
+					updateWrapper.eq("UPDATE_USER", updateUser);
+				} else {
+					queryWrapper.eq("UPDATE_USER", updateUser);
+				}
+			}
+			return this;
+		}
+
+		public Builder delFlagEq(String delFlag) {
+			if (StringUtil.isNotBlank(delFlag)) {
+				if (updateWrapper != null) {
+					updateWrapper.eq("DEL_FLAG", delFlag);
+				} else {
+					queryWrapper.eq("DEL_FLAG", delFlag);
+				}
+			}
+			return this;
+		}
+
+		public QueryWrapper<WorkCalendar> builderQueryWrapper() {
+			return queryWrapper;
+		}
+
+		public UpdateWrapper<WorkCalendar> builderUpdateWrapper() {
+			return updateWrapper;
+		}
+	}
+}

+ 398 - 0
src/main/java/com/persagy/calendar/pojo/dto/WorkCalendarDate.java

@@ -0,0 +1,398 @@
+package com.persagy.calendar.pojo.dto;
+
+import java.util.Set;
+
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.FieldStrategy;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
+import com.persagy.calendar.constant.WorkCalendarConstant;
+import com.persagy.common.annotation.IdGenerator;
+import com.persagy.common.enums.IdGeneratorAlgorithm;
+import com.persagy.common.model.BaseEntity;
+import com.persagy.common.utils.StringUtil;
+
+import cn.hutool.core.collection.CollectionUtil;
+import lombok.EqualsAndHashCode;
+import lombok.Getter;
+import lombok.Setter;
+import lombok.ToString;
+
+/**
+ * 工作历作息时间表
+ * 
+ * @version 1.0.0
+ * @company persagy
+ * @author zhangqiankun
+ * @date 2020-10-03 13:54:22
+ */
+@Getter
+@Setter
+@ToString
+@EqualsAndHashCode(callSuper = false)
+@TableName("work_calendar_date")
+@IdGenerator(prefix = WorkCalendarConstant.WORK_CALENDAR_DATE_ID_PREFIX, algorithm = IdGeneratorAlgorithm.SNOW_STR)
+public class WorkCalendarDate extends BaseEntity<WorkCalendarDate> {
+	private static final long serialVersionUID = 2631725708285230622L;
+
+	@TableField(updateStrategy = FieldStrategy.NOT_EMPTY)
+	private String groupCode; // 集团编码
+	
+	@TableField(updateStrategy = FieldStrategy.NOT_EMPTY)
+	private String ruleId; // 规则ID
+
+	@TableField(updateStrategy = FieldStrategy.NOT_EMPTY)
+	private String calendarId; // 工作历ID
+
+	@TableField(updateStrategy = FieldStrategy.NOT_EMPTY)
+	private String projectId; // PROJECT_ID
+
+	@TableField(updateStrategy = FieldStrategy.NOT_EMPTY)
+	private String calendarName; // 工作历名称
+
+	@TableField(updateStrategy = FieldStrategy.NOT_EMPTY)
+	private String calendarDesc; // 工作历描述
+
+	@TableField(updateStrategy = FieldStrategy.NOT_EMPTY)
+	private String dictType; // 字典类型
+
+	@TableField(updateStrategy = FieldStrategy.NOT_EMPTY)
+	private String dictCode; // 字典数据的code
+	
+	@TableField(updateStrategy = FieldStrategy.NOT_EMPTY)
+	private String workDateStart; // 新版YYYYMMDD,新版中和规则同步;老版YYYYMMDDHHMMSS,老版中和规则没有关系
+
+	@TableField(updateStrategy = FieldStrategy.NOT_EMPTY)
+	private String workDateEnd; // 新版YYYYMMDD,新版中和规则同步;老版YYYYMMDDHHMMSS,老版中和规则没有关系
+
+	@TableField(updateStrategy = FieldStrategy.NOT_EMPTY)
+	private String workDate; // 具体执行日期,新接口YYYYMMDD
+
+	@TableField(updateStrategy = FieldStrategy.NOT_EMPTY)
+	private String workTime; // 具体时间段
+
+	@TableField(fill = FieldFill.INSERT, updateStrategy = FieldStrategy.NOT_EMPTY)
+	private String createTime; // 创建时间
+
+	@TableField(fill = FieldFill.INSERT_UPDATE, updateStrategy = FieldStrategy.NOT_EMPTY)
+	private String updateTime; // 更新时间
+
+	@TableField(updateStrategy = FieldStrategy.NOT_EMPTY)
+	private String updateUser; // 操作用户ID
+
+	@TableField(updateStrategy = FieldStrategy.NOT_EMPTY)
+	private String customFlag; // 0-非自定义;1-自定义
+
+	public static class Builder {
+
+		private QueryWrapper<WorkCalendarDate> queryWrapper = null;
+
+		private UpdateWrapper<WorkCalendarDate> updateWrapper = null;
+
+		public Builder createQueryWrapper() {
+			queryWrapper = new QueryWrapper<WorkCalendarDate>();
+			return this;
+		}
+
+		public Builder createUpdateWrapper() {
+			updateWrapper = new UpdateWrapper<WorkCalendarDate>();
+			return this;
+		}
+
+		public Builder idEq(String id) {
+			if (StringUtil.isNotBlank(id)) {
+				if (updateWrapper != null) {
+					updateWrapper.eq("ID", id);
+				} else {
+					queryWrapper.eq("ID", id);
+				}
+			}
+			return this;
+		}
+		
+		public Builder groupCodeEq(String groupCode) {
+			if (StringUtil.isNotBlank(groupCode)) {
+				if (updateWrapper != null) {
+					updateWrapper.eq("GROUP_CODE", groupCode);
+				} else {
+					queryWrapper.eq("GROUP_CODE", groupCode);
+				}
+			}
+			return this;
+		}
+
+		public Builder ruleIdEq(String ruleId) {
+			if (StringUtil.isNotBlank(ruleId)) {
+				if (updateWrapper != null) {
+					updateWrapper.eq("RULE_ID", ruleId);
+				} else {
+					queryWrapper.eq("RULE_ID", ruleId);
+				}
+			}
+			return this;
+		}
+
+		public Builder calendarIdEq(String calendarId) {
+			if (StringUtil.isNotBlank(calendarId)) {
+				if (updateWrapper != null) {
+					updateWrapper.eq("CALENDAR_ID", calendarId);
+				} else {
+					queryWrapper.eq("CALENDAR_ID", calendarId);
+				}
+			}
+			return this;
+		}
+
+		public Builder projectIdEq(String projectId) {
+			if (StringUtil.isNotBlank(projectId)) {
+				if (updateWrapper != null) {
+					updateWrapper.eq("PROJECT_ID", projectId);
+				} else {
+					queryWrapper.eq("PROJECT_ID", projectId);
+				}
+			}
+			return this;
+		}
+
+		public Builder calendarNameEq(String calendarName) {
+			if (StringUtil.isNotBlank(calendarName)) {
+				if (updateWrapper != null) {
+					updateWrapper.eq("CALENDAR_NAME", calendarName);
+				} else {
+					queryWrapper.eq("CALENDAR_NAME", calendarName);
+				}
+			}
+			return this;
+		}
+		
+		public Builder calendarNameLike(String calendarName) {
+			if (StringUtil.isNotBlank(calendarName)) {
+				if (updateWrapper != null) {
+					updateWrapper.like("CALENDAR_NAME", calendarName);
+				} else {
+					queryWrapper.like("CALENDAR_NAME", calendarName);
+				}
+			}
+			return this;
+		}
+
+		public Builder calendarDescEq(String calendarDesc) {
+			if (StringUtil.isNotBlank(calendarDesc)) {
+				if (updateWrapper != null) {
+					updateWrapper.eq("CALENDAR_DESC", calendarDesc);
+				} else {
+					queryWrapper.eq("CALENDAR_DESC", calendarDesc);
+				}
+			}
+			return this;
+		}
+
+		public Builder dictTypeEq(String dictType) {
+			if (StringUtil.isNotBlank(dictType)) {
+				if (updateWrapper != null) {
+					updateWrapper.eq("DICT_TYPE", dictType);
+				} else {
+					queryWrapper.eq("DICT_TYPE", dictType);
+				}
+			}
+			return this;
+		}
+		
+		public Builder dictTypeIn(Set<String> dictType) {
+			if (CollectionUtil.isNotEmpty(dictType)) {
+				if (updateWrapper != null) {
+					updateWrapper.in("DICT_TYPE", dictType);
+				} else {
+					queryWrapper.in("DICT_TYPE", dictType);
+				}
+			}
+			return this;
+		}
+
+		public Builder dictCodeEq(String dictCode) {
+			if (StringUtil.isNotBlank(dictCode)) {
+				if (updateWrapper != null) {
+					updateWrapper.eq("DICT_CODE", dictCode);
+				} else {
+					queryWrapper.eq("DICT_CODE", dictCode);
+				}
+			}
+			return this;
+		}
+		
+		public Builder dictCodeIn(Set<String> dictCode) {
+			if (CollectionUtil.isNotEmpty(dictCode)) {
+				if (updateWrapper != null) {
+					updateWrapper.in("DICT_CODE", dictCode);
+				} else {
+					queryWrapper.in("DICT_CODE", dictCode);
+				}
+			}
+			return this;
+		}
+		
+		public Builder dictCodeLikeRight(String dictCode) {
+			if (StringUtil.isNotBlank(dictCode)) {
+				if (updateWrapper != null) {
+					updateWrapper.likeRight("DICT_CODE", dictCode);
+				} else {
+					queryWrapper.likeRight("DICT_CODE", dictCode);
+				}
+			}
+			return this;
+		}
+
+		public Builder workDateStartEq(String workDateStart) {
+			if (StringUtil.isNotBlank(workDateStart)) {
+				if (updateWrapper != null) {
+					updateWrapper.eq("WORK_DATE_START", workDateStart);
+				} else {
+					queryWrapper.eq("WORK_DATE_START", workDateStart);
+				}
+			}
+			return this;
+		}
+
+		public Builder workDateStartGe(String workDateStart) {
+			if (StringUtil.isNotBlank(workDateStart)) {
+				if (updateWrapper != null) {
+					updateWrapper.ge("WORK_DATE_START", workDateStart);
+				} else {
+					queryWrapper.ge("WORK_DATE_START", workDateStart);
+				}
+			}
+			return this;
+		}
+		
+		public Builder workDateStartLe(String workDateStart) {
+			if (StringUtil.isNotBlank(workDateStart)) {
+				if (updateWrapper != null) {
+					updateWrapper.le("WORK_DATE_START", workDateStart);
+				} else {
+					queryWrapper.le("WORK_DATE_START", workDateStart);
+				}
+			}
+			return this;
+		}
+		
+		public Builder workDateEndEq(String workDateEnd) {
+			if (StringUtil.isNotBlank(workDateEnd)) {
+				if (updateWrapper != null) {
+					updateWrapper.eq("WORK_DATE_END", workDateEnd);
+				} else {
+					queryWrapper.eq("WORK_DATE_END", workDateEnd);
+				}
+			}
+			return this;
+		}
+		
+		public Builder workDateEndLe(String workDateEnd) {
+			if (StringUtil.isNotBlank(workDateEnd)) {
+				if (updateWrapper != null) {
+					updateWrapper.le("WORK_DATE_END", workDateEnd);
+				} else {
+					queryWrapper.le("WORK_DATE_END", workDateEnd);
+				}
+			}
+			return this;
+		}
+
+		public Builder workDateEq(String workDate) {
+			if (StringUtil.isNotBlank(workDate)) {
+				if (updateWrapper != null) {
+					updateWrapper.eq("WORK_DATE", workDate);
+				} else {
+					queryWrapper.eq("WORK_DATE", workDate);
+				}
+			}
+			return this;
+		}
+		
+		public Builder workDateGe(String workDate) {
+			if (StringUtil.isNotBlank(workDate)) {
+				if (updateWrapper != null) {
+					updateWrapper.ge("WORK_DATE", workDate);
+				} else {
+					queryWrapper.ge("WORK_DATE", workDate);
+				}
+			}
+			return this;
+		}
+		
+		public Builder workDateLe(String workDate) {
+			if (StringUtil.isNotBlank(workDate)) {
+				if (updateWrapper != null) {
+					updateWrapper.le("WORK_DATE", workDate);
+				} else {
+					queryWrapper.le("WORK_DATE", workDate);
+				}
+			}
+			return this;
+		}
+
+		public Builder workTimeEq(String workTime) {
+			if (StringUtil.isNotBlank(workTime)) {
+				if (updateWrapper != null) {
+					updateWrapper.eq("WORK_TIME", workTime);
+				} else {
+					queryWrapper.eq("WORK_TIME", workTime);
+				}
+			}
+			return this;
+		}
+
+		public Builder createTimeEq(String createTime) {
+			if (StringUtil.isNotBlank(createTime)) {
+				if (updateWrapper != null) {
+					updateWrapper.eq("CREATE_TIME", createTime);
+				} else {
+					queryWrapper.eq("CREATE_TIME", createTime);
+				}
+			}
+			return this;
+		}
+
+		public Builder updateTimeEq(String updateTime) {
+			if (StringUtil.isNotBlank(updateTime)) {
+				if (updateWrapper != null) {
+					updateWrapper.eq("UPDATE_TIME", updateTime);
+				} else {
+					queryWrapper.eq("UPDATE_TIME", updateTime);
+				}
+			}
+			return this;
+		}
+
+		public Builder updateUserEq(String updateUser) {
+			if (StringUtil.isNotBlank(updateUser)) {
+				if (updateWrapper != null) {
+					updateWrapper.eq("UPDATE_USER", updateUser);
+				} else {
+					queryWrapper.eq("UPDATE_USER", updateUser);
+				}
+			}
+			return this;
+		}
+
+		public Builder customFlagEq(String customFlag) {
+			if (StringUtil.isNotBlank(customFlag)) {
+				if (updateWrapper != null) {
+					updateWrapper.eq("CUSTOM_FLAG", customFlag);
+				} else {
+					queryWrapper.eq("CUSTOM_FLAG", customFlag);
+				}
+			}
+			return this;
+		}
+
+		public QueryWrapper<WorkCalendarDate> builderQueryWrapper() {
+			return queryWrapper;
+		}
+
+		public UpdateWrapper<WorkCalendarDate> builderUpdateWrapper() {
+			return updateWrapper;
+		}
+	}
+}

+ 114 - 0
src/main/java/com/persagy/calendar/pojo/dto/WorkCalendarDict.java

@@ -0,0 +1,114 @@
+package com.persagy.calendar.pojo.dto;
+
+import com.baomidou.mybatisplus.annotation.FieldStrategy;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+import com.persagy.common.utils.StringUtil;
+
+import lombok.EqualsAndHashCode;
+import lombok.Getter;
+import lombok.Setter;
+import lombok.ToString;
+
+/**
+ * @version
+ * @description
+ * @company persagy
+ * @author zhangqiankun
+ * @since 2021年3月3日: 下午7:49:44
+ */
+@Getter
+@Setter
+@ToString
+@EqualsAndHashCode(callSuper = false)
+@TableName("work_calendar_dict")
+public class WorkCalendarDict extends Model<WorkCalendarDict> {
+	private static final long serialVersionUID = -4969298760644522850L;
+
+	@TableField(updateStrategy = FieldStrategy.NOT_EMPTY)
+	private String groupCode; 	// 集团编码
+
+	@TableField(updateStrategy = FieldStrategy.NOT_EMPTY)
+	private String calendarId; // 工作历ID
+	
+	@TableField(updateStrategy = FieldStrategy.NOT_EMPTY)
+	private String dictType; // 字典类型
+
+	@TableField(updateStrategy = FieldStrategy.NOT_EMPTY)
+	private String dictCode; // 字典数据的code
+
+	@TableField(updateStrategy = FieldStrategy.NOT_EMPTY)
+	private String dictDesc; // 字典类型的描述
+	
+	public static class Builder {
+
+		private QueryWrapper<WorkCalendarDict> queryWrapper = null;
+
+		private UpdateWrapper<WorkCalendarDict> updateWrapper = null;
+
+		public Builder createQueryWrapper() {
+			queryWrapper = new QueryWrapper<WorkCalendarDict>();
+			return this;
+		}
+
+		public Builder createUpdateWrapper() {
+			updateWrapper = new UpdateWrapper<WorkCalendarDict>();
+			return this;
+		}
+
+		public Builder groupCodeEq(String groupCode) {
+			if (StringUtil.isNotBlank(groupCode)) {
+				if (updateWrapper != null) {
+					updateWrapper.eq("GROUP_CODE", groupCode);
+				} else {
+					queryWrapper.eq("GROUP_CODE", groupCode);
+				}
+			}
+			return this;
+		}
+
+		public Builder calendarIdEq(String calendarId) {
+			if (StringUtil.isNotBlank(calendarId)) {
+				if (updateWrapper != null) {
+					updateWrapper.eq("CALENDAR_ID", calendarId);
+				} else {
+					queryWrapper.eq("CALENDAR_ID", calendarId);
+				}
+			}
+			return this;
+		}
+		
+		public Builder dictTypeEq(String dictType) {
+			if (StringUtil.isNotBlank(dictType)) {
+				if (updateWrapper != null) {
+					updateWrapper.eq("DICT_TYPE", dictType);
+				} else {
+					queryWrapper.eq("DICT_TYPE", dictType);
+				}
+			}
+			return this;
+		}
+
+		public Builder dictCodeEq(String dictCode) {
+			if (StringUtil.isNotBlank(dictCode)) {
+				if (updateWrapper != null) {
+					updateWrapper.eq("DICT_CODE", dictCode);
+				} else {
+					queryWrapper.eq("DICT_CODE", dictCode);
+				}
+			}
+			return this;
+		}
+		
+		public QueryWrapper<WorkCalendarDict> builderQueryWrapper() {
+			return queryWrapper;
+		}
+
+		public UpdateWrapper<WorkCalendarDict> builderUpdateWrapper() {
+			return updateWrapper;
+		}
+	}
+}

+ 241 - 0
src/main/java/com/persagy/calendar/pojo/dto/WorkCalendarLabel.java

@@ -0,0 +1,241 @@
+package com.persagy.calendar.pojo.dto;
+
+import java.util.Date;
+import java.util.Set;
+
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.FieldStrategy;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
+import com.baomidou.mybatisplus.extension.handlers.FastjsonTypeHandler;
+import com.persagy.calendar.constant.WorkCalendarConstant;
+import com.persagy.common.annotation.IdGenerator;
+import com.persagy.common.enums.IdGeneratorAlgorithm;
+import com.persagy.common.model.BaseEntity;
+import com.persagy.common.utils.StringUtil;
+
+import lombok.EqualsAndHashCode;
+import lombok.Getter;
+import lombok.Setter;
+import lombok.ToString;
+
+/**
+ * @version 
+ * @description 
+ * @company persagy
+ * @author zhangqiankun
+ * @since 2021年3月2日:	下午4:57:22
+ */
+@Getter
+@Setter
+@ToString
+@EqualsAndHashCode(callSuper = false)
+@TableName(value = "work_calendar_label", autoResultMap = true)
+@IdGenerator(prefix = WorkCalendarConstant.WORK_CALENDAR_LABEL_ID_PREFIX, algorithm = IdGeneratorAlgorithm.SNOW_STR)
+public class WorkCalendarLabel extends BaseEntity<WorkCalendarLabel> {
+	private static final long serialVersionUID = 6895232648769300864L;
+
+	@TableField(updateStrategy = FieldStrategy.NOT_EMPTY)
+	private String groupCode; // 集团编码
+	
+	@TableField(updateStrategy = FieldStrategy.NOT_EMPTY)
+	private String calendarId; // 工作历ID
+
+	@TableField(updateStrategy = FieldStrategy.NOT_EMPTY)
+	private String projectId; // 工作历分类ID
+
+	@TableField(exist = false)
+	private Integer labelMonth; 	// 标签所属日期
+	
+	@TableField(updateStrategy = FieldStrategy.NOT_EMPTY)
+	private String labelDate; 	// 标签所属日期
+
+	@TableField(updateStrategy = FieldStrategy.NOT_EMPTY)
+	private String dictType;
+	
+	@TableField(updateStrategy = FieldStrategy.NOT_EMPTY)
+	private String dictCode;
+	
+	@TableField(updateStrategy = FieldStrategy.NOT_EMPTY)
+	private String diyLabel;	// 是否自定义,0-非自定义,1-自定义
+	
+	@TableField(updateStrategy = FieldStrategy.NOT_EMPTY, typeHandler = FastjsonTypeHandler.class)
+	private Set<String> diyValue;
+	
+	@TableField(exist = false)
+	private String diyValueStr;
+	
+	@TableField(fill = FieldFill.INSERT, updateStrategy = FieldStrategy.NOT_EMPTY)
+	private String createTime; // 创建时间
+	
+	@TableField(fill = FieldFill.INSERT_UPDATE, updateStrategy = FieldStrategy.NOT_EMPTY)
+	private String updateTime; // 更新时间
+
+	@TableField(updateStrategy = FieldStrategy.NOT_EMPTY)
+	private String updateUser; // 最后操作者ID
+	
+	@TableField(exist = false)
+	private String labelDateStart; 		// 标签所属开始日期
+	
+	@TableField(exist = false)
+	private String labelDateEnd; 		// 标签所属结束日期
+
+	public static class Builder {
+
+		private QueryWrapper<WorkCalendarLabel> queryWrapper = null;
+
+		private UpdateWrapper<WorkCalendarLabel> updateWrapper = null;
+
+		public Builder createQueryWrapper() {
+			queryWrapper = new QueryWrapper<WorkCalendarLabel>();
+			return this;
+		}
+
+		public Builder createUpdateWrapper() {
+			updateWrapper = new UpdateWrapper<WorkCalendarLabel>();
+			return this;
+		}
+
+		public Builder groupCodeEq(String groupCode) {
+			if (StringUtil.isNotBlank(groupCode)) {
+				if (updateWrapper != null) {
+					updateWrapper.eq("GROUP_CODE", groupCode);
+				} else {
+					queryWrapper.eq("GROUP_CODE", groupCode);
+				}
+			}
+			return this;
+		}
+		
+		public Builder projectIdEq(String projectId) {
+			if (StringUtil.isNotBlank(projectId)) {
+				if (updateWrapper != null) {
+					updateWrapper.eq("PROJECT_ID", projectId);
+				} else {
+					queryWrapper.eq("PROJECT_ID", projectId);
+				}
+			}
+			return this;
+		}
+		
+		public Builder calendarIdEq(String calendarId) {
+			if (StringUtil.isNotBlank(calendarId)) {
+				if (updateWrapper != null) {
+					updateWrapper.eq("CALENDAR_ID", calendarId);
+				} else {
+					queryWrapper.eq("CALENDAR_ID", calendarId);
+				}
+			}
+			return this;
+		}
+
+		public Builder dictTypeEq(String dictType) {
+			if (StringUtil.isNotBlank(dictType)) {
+				if (updateWrapper != null) {
+					updateWrapper.eq("DICT_TYPE", dictType);
+				} else {
+					queryWrapper.eq("DICT_TYPE", dictType);
+				}
+			}
+			return this;
+		}
+
+		public Builder dictCodeEq(String dictCode) {
+			if (StringUtil.isNotBlank(dictCode)) {
+				if (updateWrapper != null) {
+					updateWrapper.eq("DICT_CODE", dictCode);
+				} else {
+					queryWrapper.eq("DICT_CODE", dictCode);
+				}
+			}
+			return this;
+		}
+		
+		public Builder diyLabelEq(String diyLabel) {
+			if (StringUtil.isNotBlank(diyLabel)) {
+				if (updateWrapper != null) {
+					updateWrapper.eq("DIY_LABEL", diyLabel);
+				} else {
+					queryWrapper.eq("DIY_LABEL", diyLabel);
+				}
+			}
+			return this;
+		}
+		
+		public Builder labelDateEq(String labelDate) {
+			if (StringUtil.isNotBlank(labelDate)) {
+				if (updateWrapper != null) {
+					updateWrapper.eq("LABEL_DATE", labelDate);
+				} else {
+					queryWrapper.eq("LABEL_DATE", labelDate);
+				}
+			}
+			return this;
+		}
+		
+		public Builder labelDateGe(String labelDate) {
+			if (StringUtil.isNotBlank(labelDate)) {
+				if (updateWrapper != null) {
+					updateWrapper.ge("LABEL_DATE", labelDate);
+				} else {
+					queryWrapper.ge("LABEL_DATE", labelDate);
+				}
+			}
+			return this;
+		}
+		
+		public Builder labelDateLe(String labelDate) {
+			if (StringUtil.isNotBlank(labelDate)) {
+				if (updateWrapper != null) {
+					updateWrapper.le("LABEL_DATE", labelDate);
+				} else {
+					queryWrapper.le("LABEL_DATE", labelDate);
+				}
+			}
+			return this;
+		}
+		
+		public Builder createTimeEq(Date createTime) {
+			if (null != createTime) {
+				if (updateWrapper != null) {
+					updateWrapper.eq("CREATE_TIME", createTime);
+				} else {
+					queryWrapper.eq("CREATE_TIME", createTime);
+				}
+			}
+			return this;
+		}
+		
+		public Builder updateTimeEq(Date updateTime) {
+			if (null != updateTime) {
+				if (updateWrapper != null) {
+					updateWrapper.eq("UPDATE_TIME", updateTime);
+				} else {
+					queryWrapper.eq("UPDATE_TIME", updateTime);
+				}
+			}
+			return this;
+		}
+
+		public Builder updateUserEq(String updateUser) {
+			if (StringUtil.isNotBlank(updateUser)) {
+				if (updateWrapper != null) {
+					updateWrapper.eq("UPDATE_USER", updateUser);
+				} else {
+					queryWrapper.eq("UPDATE_USER", updateUser);
+				}
+			}
+			return this;
+		}
+
+		public QueryWrapper<WorkCalendarLabel> builderQueryWrapper() {
+			return queryWrapper;
+		}
+
+		public UpdateWrapper<WorkCalendarLabel> builderUpdateWrapper() {
+			return updateWrapper;
+		}
+	}
+}

+ 158 - 0
src/main/java/com/persagy/calendar/pojo/dto/WorkCalendarObject.java

@@ -0,0 +1,158 @@
+package com.persagy.calendar.pojo.dto;
+
+import java.util.Date;
+import java.util.Set;
+
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.FieldStrategy;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+import com.persagy.common.utils.StringUtil;
+
+import cn.hutool.core.collection.CollectionUtil;
+import lombok.EqualsAndHashCode;
+import lombok.Getter;
+import lombok.Setter;
+import lombok.ToString;
+
+/**
+ * @version 
+ * @description 
+ * @company persagy
+ * @author zhangqiankun
+ * @since 2021年3月2日:	下午4:57:22
+ */
+@Getter
+@Setter
+@ToString
+@EqualsAndHashCode(callSuper = false)
+@TableName("work_calendar_object")
+public class WorkCalendarObject extends Model<WorkCalendarObject> {
+	private static final long serialVersionUID = -3559409863078752929L;
+	
+	@TableField(updateStrategy = FieldStrategy.NOT_EMPTY)
+	private String groupCode; // 集团编码
+	
+	@TableField(updateStrategy = FieldStrategy.NOT_EMPTY)
+	private String calendarId; // 工作历ID
+
+	@TableField(updateStrategy = FieldStrategy.NOT_EMPTY)
+	private String projectId; // 工作历分类ID
+
+	@TableField(updateStrategy = FieldStrategy.NOT_EMPTY)
+	private String objectId; 	// 对象ID
+	
+	@TableField(exist = false)
+	private String objectName; 	// 对象名称
+
+	@TableField(fill = FieldFill.INSERT, updateStrategy = FieldStrategy.NOT_EMPTY)
+	private String createTime; // 创建时间
+
+	@TableField(updateStrategy = FieldStrategy.NOT_EMPTY)
+	private String updateUser; // 最后操作者ID
+
+	public static class Builder {
+
+		private QueryWrapper<WorkCalendarObject> queryWrapper = null;
+
+		private UpdateWrapper<WorkCalendarObject> updateWrapper = null;
+
+		public Builder createQueryWrapper() {
+			queryWrapper = new QueryWrapper<WorkCalendarObject>();
+			return this;
+		}
+
+		public Builder createUpdateWrapper() {
+			updateWrapper = new UpdateWrapper<WorkCalendarObject>();
+			return this;
+		}
+
+		public Builder groupCodeEq(String groupCode) {
+			if (StringUtil.isNotBlank(groupCode)) {
+				if (updateWrapper != null) {
+					updateWrapper.eq("GROUP_CODE", groupCode);
+				} else {
+					queryWrapper.eq("GROUP_CODE", groupCode);
+				}
+			}
+			return this;
+		}
+		
+		public Builder calendarIdEq(String calendarId) {
+			if (StringUtil.isNotBlank(calendarId)) {
+				if (updateWrapper != null) {
+					updateWrapper.eq("CALENDAR_ID", calendarId);
+				} else {
+					queryWrapper.eq("CALENDAR_ID", calendarId);
+				}
+			}
+			return this;
+		}
+		
+		public Builder objectIdEq(String objectId) {
+			if (StringUtil.isNotBlank(objectId)) {
+				if (updateWrapper != null) {
+					updateWrapper.eq("OBJECT_ID", objectId);
+				} else {
+					queryWrapper.eq("OBJECT_ID", objectId);
+				}
+			}
+			return this;
+		}
+		
+		public Builder objectIdIn(Set<String> objectIds) {
+			if (CollectionUtil.isNotEmpty(objectIds)) {
+				if (updateWrapper != null) {
+					updateWrapper.in("OBJECT_ID", objectIds);
+				} else {
+					queryWrapper.in("OBJECT_ID", objectIds);
+				}
+			}
+			return this;
+		}
+
+		public Builder projectIdEq(String projectId) {
+			if (StringUtil.isNotBlank(projectId)) {
+				if (updateWrapper != null) {
+					updateWrapper.eq("PROJECT_ID", projectId);
+				} else {
+					queryWrapper.eq("PROJECT_ID", projectId);
+				}
+			}
+			return this;
+		}
+
+		public Builder createTimeEq(Date createTime) {
+			if (null != createTime) {
+				if (updateWrapper != null) {
+					updateWrapper.eq("CREATE_TIME", createTime);
+				} else {
+					queryWrapper.eq("CREATE_TIME", createTime);
+				}
+			}
+			return this;
+		}
+
+		public Builder updateUserEq(String updateUser) {
+			if (StringUtil.isNotBlank(updateUser)) {
+				if (updateWrapper != null) {
+					updateWrapper.eq("UPDATE_USER", updateUser);
+				} else {
+					queryWrapper.eq("UPDATE_USER", updateUser);
+				}
+			}
+			return this;
+		}
+
+		public QueryWrapper<WorkCalendarObject> builderQueryWrapper() {
+			return queryWrapper;
+		}
+
+		public UpdateWrapper<WorkCalendarObject> builderUpdateWrapper() {
+			return updateWrapper;
+		}
+	}
+}

+ 329 - 0
src/main/java/com/persagy/calendar/pojo/dto/WorkCalendarRule.java

@@ -0,0 +1,329 @@
+package com.persagy.calendar.pojo.dto;
+
+import java.util.Set;
+
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.FieldStrategy;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
+import com.baomidou.mybatisplus.extension.handlers.FastjsonTypeHandler;
+import com.persagy.calendar.constant.WorkCalendarConstant;
+import com.persagy.common.annotation.IdGenerator;
+import com.persagy.common.enums.IdGeneratorAlgorithm;
+import com.persagy.common.model.BaseEntity;
+import com.persagy.common.utils.StringUtil;
+
+import cn.hutool.core.collection.CollectionUtil;
+import lombok.EqualsAndHashCode;
+import lombok.Getter;
+import lombok.Setter;
+import lombok.ToString;
+
+/**
+ * 工作历规则表
+ * 
+ * @version 1.0.0
+ * @company persagy
+ * @author zhangqiankun
+ * @date 2020-10-02 18:26:14
+ */
+@Getter
+@Setter
+@ToString
+@EqualsAndHashCode(callSuper = false)
+@TableName(value = "work_calendar_rule", autoResultMap = true)
+@IdGenerator(prefix = WorkCalendarConstant.WORK_CALENDAR_RULE_ID_PREFIX, algorithm = IdGeneratorAlgorithm.SNOW_STR)
+public class WorkCalendarRule extends BaseEntity<WorkCalendarRule> {
+	private static final long serialVersionUID = -6758862747401349143L;
+
+	@TableField(updateStrategy = FieldStrategy.NOT_EMPTY)
+	private String groupCode; // 集团编码
+	
+	@TableField(updateStrategy = FieldStrategy.NOT_EMPTY)
+	private String calendarId; // 工作历ID
+
+	@TableField(updateStrategy = FieldStrategy.NOT_EMPTY)
+	private String projectId; // 工作历分类ID
+
+	@TableField(updateStrategy = FieldStrategy.NOT_EMPTY)
+	private String dictType; // 字典类型
+
+	@TableField(updateStrategy = FieldStrategy.NOT_EMPTY)
+	private String dictCode; // 字典数据的code
+
+	@TableField(updateStrategy = FieldStrategy.NOT_EMPTY)
+	private String ruleDateStart; // 规则生效的开始日期YYYYMMDD
+
+	@TableField(updateStrategy = FieldStrategy.NOT_EMPTY)
+	private String ruleDateEnd; // 规则生效的结束日期YYYYMMDD
+
+	@TableField(updateStrategy = FieldStrategy.NOT_EMPTY)
+	private String ruleTime; // 规则生效的具体时间点HHMMSS
+
+	@TableField(fill = FieldFill.INSERT, updateStrategy = FieldStrategy.NOT_EMPTY)
+	private String createTime; // 创建时间
+
+	@TableField(fill = FieldFill.INSERT_UPDATE, updateStrategy = FieldStrategy.NOT_EMPTY)
+	private String updateTime; // 更新时间
+
+	@TableField(updateStrategy = FieldStrategy.NOT_EMPTY)
+	private String updateUser; // 最后操作者ID
+
+	@TableField(updateStrategy = FieldStrategy.NOT_EMPTY)
+	private String delFlag; // 0-正常;1-删除
+
+	@TableField(updateStrategy = FieldStrategy.NOT_EMPTY)
+	private String ruleFlag; // 0-新接口规则;1-老接口规则,方便后续解析
+
+	@TableField(updateStrategy = FieldStrategy.NOT_EMPTY, typeHandler = FastjsonTypeHandler.class)
+	private Set<String> value; // 当存多时间段时,或按周、月等解析时,日期时间点存入此字段内,假如 ruleTime 存在,已 ruleTime 为准
+
+	public static class Builder {
+
+		private QueryWrapper<WorkCalendarRule> queryWrapper = null;
+
+		private UpdateWrapper<WorkCalendarRule> updateWrapper = null;
+
+		public Builder createQueryWrapper() {
+			queryWrapper = new QueryWrapper<WorkCalendarRule>();
+			return this;
+		}
+
+		public Builder createUpdateWrapper() {
+			updateWrapper = new UpdateWrapper<WorkCalendarRule>();
+			return this;
+		}
+
+		public Builder idEq(String id) {
+			if (StringUtil.isNotBlank(id)) {
+				if (updateWrapper != null) {
+					updateWrapper.eq("ID", id);
+				} else {
+					queryWrapper.eq("ID", id);
+				}
+			}
+			return this;
+		}
+
+		public Builder groupCodeEq(String groupCode) {
+			if (StringUtil.isNotBlank(groupCode)) {
+				if (updateWrapper != null) {
+					updateWrapper.eq("GROUP_CODE", groupCode);
+				} else {
+					queryWrapper.eq("GROUP_CODE", groupCode);
+				}
+			}
+			return this;
+		}
+		
+		public Builder calendarIdEq(String calendarId) {
+			if (StringUtil.isNotBlank(calendarId)) {
+				if (updateWrapper != null) {
+					updateWrapper.eq("CALENDAR_ID", calendarId);
+				} else {
+					queryWrapper.eq("CALENDAR_ID", calendarId);
+				}
+			}
+			return this;
+		}
+
+		public Builder projectIdEq(String projectId) {
+			if (StringUtil.isNotBlank(projectId)) {
+				if (updateWrapper != null) {
+					updateWrapper.eq("PROJECT_ID", projectId);
+				} else {
+					queryWrapper.eq("PROJECT_ID", projectId);
+				}
+			}
+			return this;
+		}
+
+		public Builder dictTypeEq(String dictType) {
+			if (StringUtil.isNotBlank(dictType)) {
+				if (updateWrapper != null) {
+					updateWrapper.eq("DICT_TYPE", dictType);
+				} else {
+					queryWrapper.eq("DICT_TYPE", dictType);
+				}
+			}
+			return this;
+		}
+		
+		public Builder dictTypeIn(Set<String> dictType) {
+			if (CollectionUtil.isNotEmpty(dictType)) {
+				if (updateWrapper != null) {
+					updateWrapper.in("DICT_TYPE", dictType);
+				} else {
+					queryWrapper.in("DICT_TYPE", dictType);
+				}
+			}
+			return this;
+		}
+
+		public Builder dictCodeEq(String dictCode) {
+			if (StringUtil.isNotBlank(dictCode)) {
+				if (updateWrapper != null) {
+					updateWrapper.eq("DICT_CODE", dictCode);
+				} else {
+					queryWrapper.eq("DICT_CODE", dictCode);
+				}
+			}
+			return this;
+		}
+		
+		public Builder dictCodeIn(Set<String> dictCode) {
+			if (CollectionUtil.isNotEmpty(dictCode)) {
+				if (updateWrapper != null) {
+					updateWrapper.in("DICT_CODE", dictCode);
+				} else {
+					queryWrapper.in("DICT_CODE", dictCode);
+				}
+			}
+			return this;
+		}
+		
+		/**
+		 * start[ruleDateStart~ruleDateEnd] OR end[ruleDateStart~ruleDateEnd]
+		 */
+		public Builder ruleDateBetween(String start, String end) {
+			if (StringUtil.isNotBlank(start) && StringUtil.isNotBlank(end)) {
+				if (updateWrapper != null) {
+					updateWrapper.and(wrapper -> wrapper
+							.ge("RULE_DATE_END", end)
+							.le("RULE_DATE_START", end)
+							.or()
+							.le("RULE_DATE_END", end)
+							.le("RULE_DATE_END", start));
+				} else {
+					queryWrapper.and(wrapper -> wrapper
+							.ge("RULE_DATE_END", end)
+							.le("RULE_DATE_START", end)
+							.or()
+							.le("RULE_DATE_END", end)
+							.ge("RULE_DATE_END", start));
+				}
+			}
+			return this;
+		}
+
+		public Builder ruleDateStartEq(String ruleDateStart) {
+			if (StringUtil.isNotBlank(ruleDateStart)) {
+				if (updateWrapper != null) {
+					updateWrapper.eq("RULE_DATE_START", ruleDateStart);
+				} else {
+					queryWrapper.eq("RULE_DATE_START", ruleDateStart);
+				}
+			}
+			return this;
+		}
+
+		public Builder ruleDateStartBetween(String start, String end) {
+			if (StringUtil.isNotBlank(start) && StringUtil.isNotBlank(end)) {
+				if (updateWrapper != null) {
+					updateWrapper.between("RULE_DATE_START", start, end);
+				} else {
+					queryWrapper.between("RULE_DATE_START", start, end);
+				}
+			}
+			return this;
+		}
+		
+		public Builder ruleDateEndEq(String ruleDateEnd) {
+			if (StringUtil.isNotBlank(ruleDateEnd)) {
+				if (updateWrapper != null) {
+					updateWrapper.eq("RULE_DATE_END", ruleDateEnd);
+				} else {
+					queryWrapper.eq("RULE_DATE_END", ruleDateEnd);
+				}
+			}
+			return this;
+		}
+		
+		public Builder ruleDateEndBetween(String start, String end) {
+			if (StringUtil.isNotBlank(start) && StringUtil.isNotBlank(end)) {
+				if (updateWrapper != null) {
+					updateWrapper.between("RULE_DATE_END", start, end);
+				} else {
+					queryWrapper.between("RULE_DATE_END", start, end);
+				}
+			}
+			return this;
+		}
+
+		public Builder ruleTimeEq(String ruleTime) {
+			if (StringUtil.isNotBlank(ruleTime)) {
+				if (updateWrapper != null) {
+					updateWrapper.eq("RULE_TIME", ruleTime);
+				} else {
+					queryWrapper.eq("RULE_TIME", ruleTime);
+				}
+			}
+			return this;
+		}
+
+		public Builder createTimeEq(String createTime) {
+			if (StringUtil.isNotBlank(createTime)) {
+				if (updateWrapper != null) {
+					updateWrapper.eq("CREATE_TIME", createTime);
+				} else {
+					queryWrapper.eq("CREATE_TIME", createTime);
+				}
+			}
+			return this;
+		}
+
+		public Builder updateTimeEq(String updateTime) {
+			if (StringUtil.isNotBlank(updateTime)) {
+				if (updateWrapper != null) {
+					updateWrapper.eq("UPDATE_TIME", updateTime);
+				} else {
+					queryWrapper.eq("UPDATE_TIME", updateTime);
+				}
+			}
+			return this;
+		}
+
+		public Builder updateUserEq(String updateUser) {
+			if (StringUtil.isNotBlank(updateUser)) {
+				if (updateWrapper != null) {
+					updateWrapper.eq("UPDATE_USER", updateUser);
+				} else {
+					queryWrapper.eq("UPDATE_USER", updateUser);
+				}
+			}
+			return this;
+		}
+
+		public Builder delFlagEq(String delFlag) {
+			if (StringUtil.isNotBlank(delFlag)) {
+				if (updateWrapper != null) {
+					updateWrapper.eq("DEL_FLAG", delFlag);
+				} else {
+					queryWrapper.eq("DEL_FLAG", delFlag);
+				}
+			}
+			return this;
+		}
+
+		public Builder ruleFlagEq(String ruleFlag) {
+			if (StringUtil.isNotBlank(ruleFlag)) {
+				if (updateWrapper != null) {
+					updateWrapper.eq("RULE_FLAG", ruleFlag);
+				} else {
+					queryWrapper.eq("RULE_FLAG", ruleFlag);
+				}
+			}
+			return this;
+		}
+
+		public QueryWrapper<WorkCalendarRule> builderQueryWrapper() {
+			return queryWrapper;
+		}
+
+		public UpdateWrapper<WorkCalendarRule> builderUpdateWrapper() {
+			return updateWrapper;
+		}
+	}
+}

+ 29 - 0
src/main/java/com/persagy/calendar/pojo/old/DataRangeVO.java

@@ -0,0 +1,29 @@
+package com.persagy.calendar.pojo.old;
+
+import javax.validation.constraints.NotBlank;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * @version 
+ * @description 
+ * @company persagy
+ * @author zhangqiankun
+ * @since 2020年10月3日:	下午8:03:26
+ */
+
+@Getter
+@Setter
+public class DataRangeVO {
+	
+	@NotBlank(message = "开始时间from不可为空[YYYYMMDDHHMMSS]")
+	@ApiModelProperty(value = "开始时间", required = true)
+	private String from;
+	
+	@NotBlank(message = "结束时间to不可为空[YYYYMMDDHHMMSS]")
+	@ApiModelProperty(value = "结束时间", required = true)
+	private String to;
+	
+}

+ 46 - 0
src/main/java/com/persagy/calendar/pojo/old/OldCalendarIntervalCreateVO.java

@@ -0,0 +1,46 @@
+package com.persagy.calendar.pojo.old;
+
+import java.util.List;
+
+import javax.validation.Valid;
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotEmpty;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.persagy.common.constant.CommonConstant;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * @version 
+ * @description 
+ * @company persagy
+ * @author zhangqiankun
+ * @since 2020年10月4日:	下午1:30:03
+ */
+@Getter
+@Setter
+@ApiModel
+public class OldCalendarIntervalCreateVO {
+	
+	@NotBlank(message = "code不可为空")
+	@ApiModelProperty(value = "作息时段编码", required = true)
+	private String code;			// 对应 dictCode
+	
+	@NotEmpty(message = "time不可为空")
+	@ApiModelProperty(value = "一天内的时段", required = true)
+	private List<String> time;		// 对应 value
+	
+	@Valid
+	@NotEmpty(message = "dates不可为空")
+	@ApiModelProperty(value = "dates", required = true)
+	private List<DataRangeVO> dates;
+	
+	@JsonIgnore
+	@ApiModelProperty(hidden = true)
+	private String projectId = CommonConstant.DEFAULT_USER_ID;
+	
+}

+ 40 - 0
src/main/java/com/persagy/calendar/pojo/old/OldCalendarIntervalDeleteVO.java

@@ -0,0 +1,40 @@
+package com.persagy.calendar.pojo.old;
+
+import java.util.List;
+
+import javax.validation.Valid;
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotEmpty;
+
+import com.persagy.common.constant.CommonConstant;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * @version 
+ * @description 
+ * @company persagy
+ * @author zhangqiankun
+ * @since 2020年10月4日:	下午1:30:03
+ */
+@Getter
+@Setter
+@ApiModel
+public class OldCalendarIntervalDeleteVO {
+	
+	@NotBlank(message = "code不可为空")
+	@ApiModelProperty(value = "作息时段编码", required = true)
+	private String code;
+	
+	@Valid
+	@NotEmpty(message = "dates不可为空")
+	@ApiModelProperty(value = "dates", required = true)
+	private List<DataRangeVO> dates;
+	
+	@ApiModelProperty(hidden = true)
+	private String projectId = CommonConstant.DEFAULT_USER_ID;
+	
+}

+ 48 - 0
src/main/java/com/persagy/calendar/pojo/old/OldCalendarIntervalsByTag.java

@@ -0,0 +1,48 @@
+package com.persagy.calendar.pojo.old;
+
+import javax.validation.Valid;
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+
+import com.persagy.calendar.constant.WorkCalendarConstant;
+import com.persagy.common.constant.CommonConstant;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * @version 
+ * @description 
+ * @company persagy
+ * @author zhangqiankun
+ * @since 2020年10月4日:	下午1:48:06
+ */
+@Getter
+@Setter
+@ApiModel
+public class OldCalendarIntervalsByTag {
+
+	@NotBlank(message = "id不可为空")
+	@ApiModelProperty(value = "工作历ID", required = true)
+	private String id;
+	
+	@Valid
+	@NotNull(message = "query不可为空")
+	@ApiModelProperty(value = "query", required = true)
+	private OldCalendarTagQueryVO query;
+	
+	@Valid
+	@NotNull(message = "set_interval不可为空")
+	@ApiModelProperty(value = "要设置的作息信息", required = true)
+	private OldCalendarSetIntervalVO set_interval;
+	
+	@ApiModelProperty(hidden = true)
+	private String projectId = CommonConstant.DEFAULT_USER_ID;
+	
+	// 0-新接口规则;1-老接口规则,方便后续解析
+	@ApiModelProperty(hidden = true)
+	private String ruleFlag = WorkCalendarConstant.WORK_CALENDAR_RULE_FLAG_OLD; 
+	
+}

+ 35 - 0
src/main/java/com/persagy/calendar/pojo/old/OldCalendarIntervalsVO.java

@@ -0,0 +1,35 @@
+package com.persagy.calendar.pojo.old;
+
+import java.util.List;
+
+import javax.validation.Valid;
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotEmpty;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * @version 
+ * @description 
+ * @company persagy
+ * @author zhangqiankun
+ * @since 2020年10月4日:	下午12:54:08
+ */
+@Getter
+@Setter
+@ApiModel
+public class OldCalendarIntervalsVO<T> {
+	
+	@NotBlank(message = "id不可为空")
+	@ApiModelProperty(value = "工作历ID", required = true)
+	private String id;
+	
+	@Valid
+	@NotEmpty(message = "intervals不可为空")
+	@ApiModelProperty(value = "intervals", required = true)
+	private List<T> intervals;
+	
+}

+ 40 - 0
src/main/java/com/persagy/calendar/pojo/old/OldCalendarQueryVO.java

@@ -0,0 +1,40 @@
+package com.persagy.calendar.pojo.old;
+
+import java.util.Set;
+
+import javax.validation.Valid;
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * @version 
+ * @description 
+ * @company persagy
+ * @author zhangqiankun
+ * @since 2020年10月4日:	下午2:13:50
+ */
+@Getter
+@Setter
+@ApiModel
+public class OldCalendarQueryVO {
+	
+	@NotBlank(message = "id不可为空")
+	@ApiModelProperty(value = "工作历ID", required = true)
+	private String id;
+	
+	@ApiModelProperty(value = "tags和intervals必填其一")
+	private Set<String> tags;
+	
+	@ApiModelProperty(value = "tags和intervals必填其一")
+	private Set<String> intervals;
+	
+	@Valid
+	@NotNull(message = "dates不可为空")
+	@ApiModelProperty(value = "dates日期段[YYYMMDD000000]", required = true)
+	private DataRangeVO dates;
+}

+ 29 - 0
src/main/java/com/persagy/calendar/pojo/old/OldCalendarResponseVO.java

@@ -0,0 +1,29 @@
+package com.persagy.calendar.pojo.old;
+
+import java.util.List;
+import java.util.Set;
+
+import lombok.Getter;
+import lombok.Setter;
+
+
+/**
+ * @version 
+ * @description 
+ * @company persagy
+ * @author zhangqiankun
+ * @since 2020年10月5日:	下午3:58:59
+ */
+
+@Getter
+@Setter
+public class OldCalendarResponseVO {
+	
+	private String date;			// 具体日期 YYYYMMDDHHMMSS
+	
+	// 需要 code time 数据
+	private List<OldCalendarIntervalCreateVO> intervals;		
+	
+	private Set<String> tags;		// tags
+	
+}

+ 50 - 0
src/main/java/com/persagy/calendar/pojo/old/OldCalendarRuleCreateVO.java

@@ -0,0 +1,50 @@
+package com.persagy.calendar.pojo.old;
+
+import java.util.Set;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotEmpty;
+
+import com.persagy.calendar.constant.WorkCalendarConstant;
+import com.persagy.common.constant.CommonConstant;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * @version 
+ * @description 
+ * @company persagy
+ * @author zhangqiankun
+ * @since 2020年10月3日:	下午8:02:47
+ */
+@Getter
+@Setter
+@ApiModel
+public class OldCalendarRuleCreateVO {
+	
+	@NotBlank(message = "id不可为空")
+	@ApiModelProperty(value = "工作历ID", required = true)
+	private String id;
+	
+	@NotBlank(message = "tag不可为空")
+	@ApiModelProperty(value = "tag值", required = true)
+	private String tag;
+	
+	@NotBlank(message = "type不可为空")
+	@ApiModelProperty(value = "type值", required = true)
+	private String type;
+	
+	@NotEmpty(message = "value不可为空")
+	@ApiModelProperty(value = "value值", required = true)
+	private Set<String> value;
+	
+	@ApiModelProperty(hidden = true)
+	private String projectId = CommonConstant.DEFAULT_USER_ID;
+	
+	// 0-新接口规则;1-老接口规则,方便后续解析
+	@ApiModelProperty(hidden = true)
+	private String ruleFlag = WorkCalendarConstant.WORK_CALENDAR_RULE_FLAG_OLD; 
+}

+ 40 - 0
src/main/java/com/persagy/calendar/pojo/old/OldCalendarRuleDeleteVO.java

@@ -0,0 +1,40 @@
+package com.persagy.calendar.pojo.old;
+
+import javax.validation.constraints.NotBlank;
+
+import com.persagy.calendar.constant.WorkCalendarConstant;
+import com.persagy.common.constant.CommonConstant;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * @version 
+ * @description 
+ * @company persagy
+ * @author zhangqiankun
+ * @since 2020年10月3日:	下午9:08:40
+ */
+@Getter
+@Setter
+@ApiModel
+public class OldCalendarRuleDeleteVO {
+
+	@NotBlank(message = "id不可为空")
+	@ApiModelProperty(value = "工作历ID", required = true)
+	private String id;
+	
+	@NotBlank(message = "tag不可为空")
+	@ApiModelProperty(value = "tag值", required = true)
+	private String tag;
+	
+	@ApiModelProperty(hidden = true)
+	private String projectId = CommonConstant.DEFAULT_USER_ID;
+	
+	// 0-新接口规则;1-老接口规则,方便后续解析
+	@ApiModelProperty(hidden = true)
+	private String ruleFlag = WorkCalendarConstant.WORK_CALENDAR_RULE_FLAG_OLD; 
+
+}

+ 30 - 0
src/main/java/com/persagy/calendar/pojo/old/OldCalendarRuleVO.java

@@ -0,0 +1,30 @@
+package com.persagy.calendar.pojo.old;
+
+import java.util.List;
+
+import javax.validation.Valid;
+import javax.validation.constraints.NotEmpty;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * @version 
+ * @description 
+ * @company persagy
+ * @author zhangqiankun
+ * @since 2020年10月3日:	下午8:56:12
+ */
+@Getter
+@Setter
+@ApiModel
+public class OldCalendarRuleVO<T> {
+	
+	@Valid
+	@NotEmpty(message = "rules不可为空")
+	@ApiModelProperty(value = "规则集合", required = true)
+	private List<T> rules;
+	
+}

+ 33 - 0
src/main/java/com/persagy/calendar/pojo/old/OldCalendarSetIntervalVO.java

@@ -0,0 +1,33 @@
+package com.persagy.calendar.pojo.old;
+
+import java.util.List;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotEmpty;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * @version 
+ * @description 
+ * @company persagy
+ * @author zhangqiankun
+ * @since 2020年10月4日:	下午1:52:24
+ */
+@Getter
+@Setter
+@ApiModel
+public class OldCalendarSetIntervalVO {
+	
+	@NotBlank(message = "code不可为空")
+	@ApiModelProperty(value = "作息时段编码", required = true)
+	private String code;
+	
+	@NotEmpty(message = "time不可为空")
+	@ApiModelProperty(value = "一天内的时段", required = true)
+	private List<String> time;
+	
+}

+ 33 - 0
src/main/java/com/persagy/calendar/pojo/old/OldCalendarTagQueryVO.java

@@ -0,0 +1,33 @@
+package com.persagy.calendar.pojo.old;
+
+import javax.validation.Valid;
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * @version 
+ * @description 
+ * @company persagy
+ * @author zhangqiankun
+ * @since 2020年10月4日:	下午1:49:34
+ */
+@Getter
+@Setter
+@ApiModel
+public class OldCalendarTagQueryVO {
+	
+	@NotBlank(message = "tag不可为空")
+	@ApiModelProperty(value = "tag值", required = true)
+	private String tag;
+	
+	@Valid
+	@NotNull(message = "dates不可为空")
+	@ApiModelProperty(value = "dates", required = true)
+	private DataRangeVO dates;
+	
+}

+ 40 - 0
src/main/java/com/persagy/calendar/pojo/old/OldCalendarTagVO.java

@@ -0,0 +1,40 @@
+package com.persagy.calendar.pojo.old;
+
+import java.util.List;
+
+import javax.validation.Valid;
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotEmpty;
+
+import com.persagy.common.constant.CommonConstant;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * @version 
+ * @description 
+ * @company persagy
+ * @author zhangqiankun
+ * @since 2020年10月4日:	下午12:55:39
+ */
+@Getter
+@Setter
+@ApiModel
+public class OldCalendarTagVO {
+	
+	@NotBlank(message = "tag不可为空")
+	@ApiModelProperty(value = "tag值", required = true)
+	private String tag;
+	
+	@Valid
+	@NotEmpty(message = "dates不可为空")
+	@ApiModelProperty(value = "dates", required = true)
+	private List<DataRangeVO> dates;
+	
+	@ApiModelProperty(hidden = true)
+	private String projectId = CommonConstant.DEFAULT_USER_ID;
+	
+}

+ 34 - 0
src/main/java/com/persagy/calendar/pojo/old/OldCalendarTagsVO.java

@@ -0,0 +1,34 @@
+package com.persagy.calendar.pojo.old;
+
+import java.util.List;
+
+import javax.validation.Valid;
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotEmpty;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * @version 
+ * @description 
+ * @company persagy
+ * @author zhangqiankun
+ * @since 2020年10月4日:	下午12:54:08
+ */
+@Getter
+@Setter
+@ApiModel
+public class OldCalendarTagsVO {
+	
+	@NotBlank(message = "id不可为空")
+	@ApiModelProperty(value = "工作历ID", required = true)
+	private String id;
+	
+	@Valid
+	@NotEmpty(message = "tags不可为空")
+	@ApiModelProperty(value = "tags", required = true)
+	private List<OldCalendarTagVO> tags;
+}

+ 35 - 0
src/main/java/com/persagy/calendar/pojo/old/OldWorkCalendarVO.java

@@ -0,0 +1,35 @@
+package com.persagy.calendar.pojo.old;
+
+import javax.validation.constraints.NotBlank;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * @version 
+ * @description 
+ * @company persagy
+ * @author zhangqiankun
+ * @since 2020年10月3日:	下午4:00:24
+ */
+
+@Getter
+@Setter
+@ApiModel
+public class OldWorkCalendarVO {
+	
+	private String id;
+	
+	private String from_id;
+	
+	@NotBlank(message = "name不可为空")
+	@ApiModelProperty(value = "工作历名称", required = true)
+	private String name;
+	
+	@NotBlank(message = "desc不可为空")
+	@ApiModelProperty(value = "工作历描述", required = true)
+	private String desc;
+	
+}

+ 24 - 0
src/main/java/com/persagy/calendar/pojo/vo/BaseQueryVO.java

@@ -0,0 +1,24 @@
+package com.persagy.calendar.pojo.vo;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Getter;
+import lombok.Setter;
+import lombok.ToString;
+
+/**
+ * @version 
+ * @description 
+ * @company persagy
+ * @author zhangqiankun
+ * @since 2020年10月2日:	下午12:11:22
+ */
+
+@Getter
+@Setter
+@ToString
+public class BaseQueryVO extends BaseVO {
+	
+	@ApiModelProperty(name = "ID", value = "主键ID,更新时不可为空")
+	private String id;
+	
+}

+ 29 - 0
src/main/java/com/persagy/calendar/pojo/vo/BaseUpdateVO.java

@@ -0,0 +1,29 @@
+package com.persagy.calendar.pojo.vo;
+
+import javax.validation.constraints.NotBlank;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Getter;
+import lombok.Setter;
+import lombok.ToString;
+
+/**
+ * @version 
+ * @description
+ * @company persagy
+ * @author zhangqiankun
+ * @since 2020年10月2日:	下午12:17:34
+ */
+
+@Getter
+@Setter
+@ToString
+@ApiModel
+public class BaseUpdateVO extends BaseVO {
+	
+	@NotBlank(message = "ID不可为空")
+	@ApiModelProperty(value = "主键ID", required = true)
+	private String id;
+	
+}

+ 31 - 0
src/main/java/com/persagy/calendar/pojo/vo/BaseVO.java

@@ -0,0 +1,31 @@
+package com.persagy.calendar.pojo.vo;
+
+import javax.validation.constraints.NotBlank;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * @version 
+ * @description 所有操作的验证基类,任何操作都需要传输groupId和userId字段
+ * @company persagy
+ * @author zhangqiankun
+ * @since 2020年10月2日:	下午8:51:44
+ */
+@Getter
+@Setter
+public class BaseVO {
+
+	@NotBlank(message = "用户ID不可为空")
+	@ApiModelProperty(value = "用户ID", required = true)
+	private String userId;
+	
+	@ApiModelProperty(value = "集团编码", required = true)
+	private String groupCode;
+	
+	@NotBlank(message = "项目ID不可为空")
+	@ApiModelProperty(value = "项目ID", required = true)
+	private String projectId; 		// 项目
+	
+}

+ 40 - 0
src/main/java/com/persagy/calendar/pojo/vo/CalendarDateResult.java

@@ -0,0 +1,40 @@
+package com.persagy.calendar.pojo.vo;
+
+import java.util.List;
+
+import com.persagy.calendar.pojo.dto.WorkCalendarDate;
+
+import lombok.Getter;
+import lombok.Setter;
+import lombok.ToString;
+
+/**
+ * @version 
+ * @description 
+ * @company persagy
+ * @author zhangqiankun
+ * @since 2020年10月3日:	下午2:26:22
+ */
+@Getter
+@Setter
+@ToString
+public class CalendarDateResult {
+	
+	// 周几
+	private String week;
+	
+	// 第几天
+	private Integer date;
+	
+	// 年月日
+	private String workDate;
+	
+	// 是否是工作日
+	private boolean workday = true;
+	
+	// 工作历ID
+	private String calendarId;
+	
+	private List<WorkCalendarDate> timeTable;
+	
+}

+ 35 - 0
src/main/java/com/persagy/calendar/pojo/vo/CustomCalendarVO.java

@@ -0,0 +1,35 @@
+package com.persagy.calendar.pojo.vo;
+
+import java.util.List;
+
+import javax.validation.Valid;
+import javax.validation.constraints.NotEmpty;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Getter;
+import lombok.Setter;
+import lombok.ToString;
+
+/**
+ * @version 
+ * @description 
+ * @company persagy
+ * @author zhangqiankun
+ * @since 2020年12月11日:	下午7:49:57
+ */
+@Getter
+@Setter
+@ToString
+@ApiModel(description = "批量请求参数")
+public class CustomCalendarVO<T> extends BaseVO {
+
+	@ApiModelProperty(value = "是否删除此工作历下已存在的规则,重新添加,默认false")
+	private Boolean isDelete;
+	
+	@Valid
+	@NotEmpty(message = "批量信息集合,不可为空")
+	@ApiModelProperty(value = "批量信息不可为空", required = true)
+	private List<T>  batchInfo;
+	
+}

+ 31 - 0
src/main/java/com/persagy/calendar/pojo/vo/DictCodeCreate.java

@@ -0,0 +1,31 @@
+package com.persagy.calendar.pojo.vo;
+
+import javax.validation.constraints.NotBlank;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Getter;
+import lombok.Setter;
+import lombok.ToString;
+
+/**
+ * @version 
+ * @description 
+ * @company persagy
+ * @author zhangqiankun
+ * @since 2021年3月4日:	下午3:31:22
+ */
+@Getter
+@Setter
+@ToString
+@ApiModel
+public class DictCodeCreate {
+	
+	@ApiModelProperty(value = "字典编码", required = true)
+	private String dictCode; // 字典编码
+	
+	@NotBlank(message = "字典编码描述不可为空")
+	@ApiModelProperty(value = "字典编码描述", required = true)
+	private String dictDesc; // 字典编码描述
+	
+}

+ 40 - 0
src/main/java/com/persagy/calendar/pojo/vo/DictCreateVO.java

@@ -0,0 +1,40 @@
+package com.persagy.calendar.pojo.vo;
+
+import java.util.List;
+
+import javax.validation.Valid;
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotEmpty;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Getter;
+import lombok.Setter;
+import lombok.ToString;
+
+/**
+ * @version 
+ * @description 
+ * @company persagy
+ * @author zhangqiankun
+ * @since 2020年10月3日:	下午2:26:22
+ */
+@Getter
+@Setter
+@ToString
+@ApiModel(description = "字典值创建请求参数")
+public class DictCreateVO<T> extends BaseVO {
+
+	@ApiModelProperty(value = "工作历ID", required = true)
+	private String calendarId; // 工作历ID
+	
+	@NotBlank(message = "字典类型不可为空")
+	@ApiModelProperty(value = "字典类型", required = true)
+	private String dictType; // 字典类型
+	
+	@Valid
+	@NotEmpty(message = "字典类型不可为空")
+	@ApiModelProperty(value = "字典类型", required = true)
+	private List<T> codes;
+	
+}

+ 37 - 0
src/main/java/com/persagy/calendar/pojo/vo/DictQueryVO.java

@@ -0,0 +1,37 @@
+package com.persagy.calendar.pojo.vo;
+
+import javax.validation.constraints.NotBlank;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Getter;
+import lombok.Setter;
+import lombok.ToString;
+
+/**
+ * @version 
+ * @description 
+ * @company persagy
+ * @author zhangqiankun
+ * @since 2020年10月3日:	下午2:26:22
+ */
+@Getter
+@Setter
+@ToString
+@ApiModel(description = "字典值查询请求参数")
+public class DictQueryVO {
+
+	@NotBlank(message = "用户ID不可为空")
+	@ApiModelProperty(value = "用户ID", required = true)
+	private String userId;
+	
+	@ApiModelProperty(value = "集团编码", required = true)
+	private String groupCode;
+	
+	@ApiModelProperty(value = "字典类型", required = true)
+	private String dictType; // 字典类型
+	
+	@ApiModelProperty(value = "工作历ID", required = true)
+	private String calendarId; // 工作历ID
+	
+}

+ 55 - 0
src/main/java/com/persagy/calendar/pojo/vo/RwdObjectQueryVO.java

@@ -0,0 +1,55 @@
+package com.persagy.calendar.pojo.vo;
+
+import java.util.Set;
+
+import javax.validation.constraints.NotBlank;
+
+import com.google.common.collect.Sets;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Getter;
+import lombok.Setter;
+import lombok.ToString;
+
+/**
+ * @version 
+ * @description 
+ * @company persagy
+ * @author zhangqiankun
+ * @since 2021年3月2日:	下午3:21:57
+ */
+@Getter
+@Setter
+@ApiModel
+@ToString(callSuper = true)
+public class RwdObjectQueryVO {
+	
+	@NotBlank(message = "userId不可为空")
+	@ApiModelProperty(value = "用户ID", required = true)
+	private String userId;
+	
+	@NotBlank(message = "groupCode不可为空")
+	@ApiModelProperty(value = "集团编码", required = true)
+	private String groupCode;
+	
+	//@NotBlank(message = "项目ID不可为空")
+	@ApiModelProperty(value = "项目ID")
+	private String projectId;
+	
+	@ApiModelProperty(value = "应用ID")
+	private String appId;
+	
+	@ApiModelProperty(value = "主键ID", example = "Sp44030700030006cf1d00c2462499a292faf9411993")
+	private String id;
+	
+	@ApiModelProperty(value = "类型编码", example = "project")
+	private String classCode;
+	
+	@ApiModelProperty(value = "是否可用, 1-可用,0-不可用", example = "1")
+	private Integer valid = 1;
+	
+	@ApiModelProperty(value = "对象类型,默认space, floor, building, project", example = "[space, floor]")
+	private Set<String> objType = Sets.newHashSet("space", "floor", "building", "project");
+	
+}

+ 44 - 0
src/main/java/com/persagy/calendar/pojo/vo/WorkCalendarDateCreateVO.java

@@ -0,0 +1,44 @@
+package com.persagy.calendar.pojo.vo;
+
+import javax.validation.constraints.NotBlank;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Getter;
+import lombok.Setter;
+import lombok.ToString;
+
+/**
+ * @version 
+ * @description 
+ * @company persagy
+ * @author zhangqiankun
+ * @since 2020年10月3日:	下午2:26:22
+ */
+@Getter
+@Setter
+@ToString
+@ApiModel(description = "自定义作息时间请求参数")
+public class WorkCalendarDateCreateVO {
+	
+	@NotBlank(message = "工作历ID,不可为空")
+	@ApiModelProperty(value = "工作历ID", required = true)
+	private String calendarId; // 工作历ID
+	
+	@NotBlank(message = "字典类型,不可为空")
+	@ApiModelProperty(value = "字典类型", required = true)
+	private String dictType; // 字典类型
+
+	@NotBlank(message = "字典数据code,不可为空")
+	@ApiModelProperty(value = "字典数据code", required = true)
+	private String dictCode; // 字典数据code
+	
+	@NotBlank(message = "作息日期,不可为空")
+	@ApiModelProperty(value = "作息时间点[YYYYMMDD]", required = true)
+	private String workDate; // 具体执行日期,新接口YYYYMMDD
+
+	@NotBlank(message = "作息时间点,不可为空")
+	@ApiModelProperty(value = "作息时间点[HHMMSS]", required = true)
+	private String workTime; // 具体时间段
+	
+}

+ 45 - 0
src/main/java/com/persagy/calendar/pojo/vo/WorkCalendarDateDeleteVO.java

@@ -0,0 +1,45 @@
+package com.persagy.calendar.pojo.vo;
+
+import java.util.Set;
+
+import javax.validation.constraints.NotBlank;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Getter;
+import lombok.Setter;
+import lombok.ToString;
+
+/**
+ * @version 
+ * @description 
+ * @company persagy
+ * @author zhangqiankun
+ * @since 2020年10月3日:	下午2:26:22
+ */
+@Getter
+@Setter
+@ToString
+@ApiModel(description = "删除自定义作息时间请求参数")
+public class WorkCalendarDateDeleteVO extends BaseQueryVO {
+
+	@NotBlank(message = "字典类型,不可为空")
+	@ApiModelProperty(value = "字典类型", required = true)
+	private String dictType; // 字典类型
+
+	//@NotEmpty(message = "字典数据code,不可为空")
+	@ApiModelProperty(value = "字典数据code", required = true)
+	private Set<String> dictCode; // 字典数据code
+	
+	@ApiModelProperty(value = "作息时间点[YYYYMMDD]", required = true)
+	private String workDate; // 具体执行日期,新接口YYYYMMDD
+	
+	@NotBlank(message = "workDateStart不可为空[YYYYMMDD]")
+	@ApiModelProperty(value = "查询从此日开始的作息详情 [YYYYMMDD]")
+	private String workDateStart; // 具体执行日期 YYYYMMDD
+	
+	@NotBlank(message = "workDateEnd不可为空[YYYYMMDD]")
+	@ApiModelProperty(value = "查询从此日结束的作息详情 [YYYYMMDD]")
+	private String workDateEnd; // 具体执行日期 YYYYMMDD
+	
+}

+ 65 - 0
src/main/java/com/persagy/calendar/pojo/vo/WorkCalendarDateQueryVO.java

@@ -0,0 +1,65 @@
+package com.persagy.calendar.pojo.vo;
+
+import java.util.Set;
+
+import javax.validation.constraints.NotBlank;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Getter;
+import lombok.Setter;
+import lombok.ToString;
+
+/**
+ * @version 
+ * @description 
+ * @company persagy
+ * @author zhangqiankun
+ * @since 2020年10月3日:	下午2:26:22
+ */
+@Getter
+@Setter
+@ToString
+@ApiModel
+public class WorkCalendarDateQueryVO {
+	
+	@NotBlank(message = "用户ID不可为空")
+	@ApiModelProperty(value = "用户ID", required = true)
+	private String userId;
+	
+	@ApiModelProperty(name = "ID", value = "主键ID,更新时不可为空")
+	private String id;
+	
+	@ApiModelProperty(value = "项目ID", required = true)
+	private String projectId;  // 项目
+	
+	@ApiModelProperty(value = "规则ID")
+	private String ruleId; 		// 规则ID
+	
+	@ApiModelProperty(value = "工作历ID")
+	private String calendarId; // 工作历ID
+
+	@ApiModelProperty(value = "工作历名称")
+	private String calendarName; // 工作历名称
+
+	@ApiModelProperty(value = "字典类型")
+	private String dictType; // 字典类型
+	
+	@ApiModelProperty(value = "字典类型")
+	private Set<String> dictTypes; // 字典类型
+
+	@ApiModelProperty(value = "字典数据code")
+	private Set<String> dictCode; // 字典数据code
+
+	@NotBlank(message = "workDateStart不可为空[YYYYMMDD]")
+	@ApiModelProperty(value = "查询从此日开始的作息详情 [YYYYMMDD]")
+	private String workDateStart; // 具体执行日期 YYYYMMDD
+	
+	@NotBlank(message = "workDateEnd不可为空[YYYYMMDD]")
+	@ApiModelProperty(value = "查询从此日结束的作息详情 [YYYYMMDD]")
+	private String workDateEnd; // 具体执行日期 YYYYMMDD
+	
+	@ApiModelProperty(value = "对象ID")
+	private String objId; 		// 对象D 
+
+}

+ 39 - 0
src/main/java/com/persagy/calendar/pojo/vo/WorkCalendarDateResultVO.java

@@ -0,0 +1,39 @@
+package com.persagy.calendar.pojo.vo;
+
+import lombok.Getter;
+import lombok.Setter;
+import lombok.ToString;
+
+/**
+ * @version 
+ * @description 
+ * @company persagy
+ * @author zhangqiankun
+ * @since 2020年10月3日:	下午2:26:22
+ */
+@Getter
+@Setter
+@ToString
+public class WorkCalendarDateResultVO extends BaseQueryVO {
+
+	private String ruleId; 		// 规则ID
+
+	private String calendarId; // 工作历ID
+
+	private String projectId; 	// PROJECT_ID
+
+	private String calendarName; // 工作历名称
+
+	private String calendarDesc; // 工作历描述
+
+	private String dictType; // 字典类型
+
+	private String dictCode; // 字典数据的code
+
+	private String workDate; // 具体执行日期,新接口YYYYMMDD
+
+	private String workTime; // 具体时间段
+
+	private String customFlag; // 0-非自定义;1-自定义
+	
+}

+ 48 - 0
src/main/java/com/persagy/calendar/pojo/vo/WorkCalendarDateUpdateVO.java

@@ -0,0 +1,48 @@
+package com.persagy.calendar.pojo.vo;
+
+import javax.validation.constraints.NotBlank;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Getter;
+import lombok.Setter;
+import lombok.ToString;
+
+/**
+ * @version 
+ * @description 
+ * @company persagy
+ * @author zhangqiankun
+ * @since 2020年10月3日:	下午2:26:22
+ */
+@Getter
+@Setter
+@ToString
+@ApiModel(description = "自定义作息时间请求参数")
+public class WorkCalendarDateUpdateVO {
+	
+	@NotBlank(message = "作息时间ID,不可为空")
+	@ApiModelProperty(value = "作息时间ID", required = true)
+	private String id; // 作息时间ID
+	
+	@NotBlank(message = "工作历ID,不可为空")
+	@ApiModelProperty(value = "工作历ID", required = true)
+	private String calendarId; // 工作历ID
+	
+	@NotBlank(message = "字典类型,不可为空")
+	@ApiModelProperty(value = "字典类型", required = true)
+	private String dictType; // 字典类型
+
+	@NotBlank(message = "字典数据code,不可为空")
+	@ApiModelProperty(value = "字典数据code", required = true)
+	private String dictCode; // 字典数据code
+	
+	@NotBlank(message = "作息日期,不可为空")
+	@ApiModelProperty(value = "作息时间点[YYYYMMDD]", required = true)
+	private String workDate; // 具体执行日期,新接口YYYYMMDD
+
+	@NotBlank(message = "作息时间点,不可为空")
+	@ApiModelProperty(value = "作息时间点[HHMMSS]", required = true)
+	private String workTime; // 具体时间段
+	
+}

+ 60 - 0
src/main/java/com/persagy/calendar/pojo/vo/WorkCalendarLabelQueryVO.java

@@ -0,0 +1,60 @@
+package com.persagy.calendar.pojo.vo;
+
+import javax.validation.constraints.NotBlank;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Getter;
+import lombok.Setter;
+import lombok.ToString;
+
+/**
+ * @version 
+ * @description 
+ * @company persagy
+ * @author zhangqiankun
+ * @since 2021年3月3日:	下午5:51:26
+ */
+@Getter
+@Setter
+@ToString
+@ApiModel
+public class WorkCalendarLabelQueryVO {
+	
+	@NotBlank(message = "用户ID不可为空")
+	@ApiModelProperty(value = "用户ID", required = true)
+	private String userId;
+	
+	@NotBlank(message = "集团编码不可为空")
+	@ApiModelProperty(value = "集团编码")
+	private String groupCode;
+	
+	//@NotBlank(message = "项目ID不可为空")
+	@ApiModelProperty(value = "项目ID")
+	private String projectId; 		// 项目
+	
+	@ApiModelProperty(value = "工作历ID")
+	private String calendarId; 			// 工作历ID
+	
+	@ApiModelProperty(value = "对象ID")
+	private String objId;	//对象ID
+	
+	@ApiModelProperty(value = "标签所属开始日期[yyyyMMdd]")
+	private String labelDateStart; 		// 标签所属开始日期
+	
+	@ApiModelProperty(value = "标签所属结束日期[yyyyMMdd]")
+	private String labelDateEnd; 		// 标签所属结束日期
+	
+	@ApiModelProperty(value = "字典类型")
+	private String dictType;
+	
+	@ApiModelProperty(value = "字典编码")
+	private String dictCode;
+	
+	@ApiModelProperty(value = "是否自定义,0-非自定义,1-自定义")
+	private String diyLabel;
+	
+	@ApiModelProperty(value = "分组条件,传列名:不传默认为DICT_TYPE, DICT_CODE")
+	private String groupBy = "DICT_TYPE, DICT_CODE";
+	
+}

+ 58 - 0
src/main/java/com/persagy/calendar/pojo/vo/WorkCalendarLabelUpdateVO.java

@@ -0,0 +1,58 @@
+package com.persagy.calendar.pojo.vo;
+
+import java.util.Set;
+
+import javax.validation.constraints.NotBlank;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Getter;
+import lombok.Setter;
+import lombok.ToString;
+
+/**
+ * @version 
+ * @description 
+ * @company persagy
+ * @author zhangqiankun
+ * @since 2021年3月3日:	下午5:51:26
+ */
+@Getter
+@Setter
+@ToString
+@ApiModel
+public class WorkCalendarLabelUpdateVO extends BaseVO {
+	
+	@ApiModelProperty(value = "是否在创建或更新之前,优先删除此段日期下已存在的标签属性,默认true")
+	private Boolean isUpdate = true;
+	
+	@ApiModelProperty(value = "是否仅删除此段日期下已存在的标签属性,默认false")
+	private Boolean isDelete;
+	
+	@NotBlank(message = "工作历ID,不可为空")
+	@ApiModelProperty(value = "工作历ID", required = true)
+	private String calendarId; 			// 工作历ID
+	
+	@NotBlank(message = "标签所属开始日期,不可为空")
+	@ApiModelProperty(value = "标签所属开始日期[yyyyMMdd]", required = true)
+	private String labelDateStart; 		// 标签所属开始日期
+	
+	@NotBlank(message = "标签所属结束日期,不可为空")
+	@ApiModelProperty(value = "标签所属结束日期[yyyyMMdd]", required = true)
+	private String labelDateEnd; 		// 标签所属结束日期
+	
+	//@NotBlank(message = "标签编码,不可为空")
+	@ApiModelProperty(value = "字典类型,非自定义时,必填")
+	private String dictType;
+	
+	@ApiModelProperty(value = "字典编码,非自定义时,必填")
+	private String dictCode;
+	
+	@NotBlank(message = "是否自定义,不可为空")
+	@ApiModelProperty(value = "是否自定义,0-非自定义,1-自定义", required = true)
+	private String diyLabel;
+	
+	@ApiModelProperty(value = "字典编码,自定义时,必填")
+	private Set<String> diyValue;
+	
+}

+ 57 - 0
src/main/java/com/persagy/calendar/pojo/vo/WorkCalendarMoreDateCreateVO.java

@@ -0,0 +1,57 @@
+package com.persagy.calendar.pojo.vo;
+
+import java.util.Set;
+
+import javax.validation.constraints.NotBlank;
+
+import com.persagy.calendar.constant.WorkCalendarConstant;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Getter;
+import lombok.Setter;
+import lombok.ToString;
+
+/**
+ * @version 
+ * @description 
+ * @company persagy
+ * @author zhangqiankun
+ * @since 2020年10月3日:	下午2:26:22
+ */
+@Getter
+@Setter
+@ToString
+@ApiModel(description = "自定义作息时间请求参数")
+public class WorkCalendarMoreDateCreateVO extends BaseVO {
+	
+	@ApiModelProperty(value = "是否只删除此段日期下已存在的作息时间属性,重新添加,默认false")
+	private Boolean isDelete;
+	
+	@NotBlank(message = "工作历ID,不可为空")
+	@ApiModelProperty(value = "工作历ID", required = true)
+	private String calendarId; // 工作历ID
+	
+	@NotBlank(message = "字典类型,不可为空")
+	@ApiModelProperty(value = "字典类型", required = true)
+	private String dictType; // 字典类型
+
+	@ApiModelProperty(value = "字典数据code")
+	private String dictCode; // 字典数据code
+	
+	@NotBlank(message = "开始作息时间,不可为空")
+	@ApiModelProperty(value = "开始作息时间[YYYYMMDD]", required = true)
+	private String workDateStart;
+
+	@NotBlank(message = "结束作息时间,不可为空")
+	@ApiModelProperty(value = "结束作息时间[YYYYMMDD]", required = true)
+	private String workDateEnd;
+
+	//@NotEmpty(message = "作息时间点集合timetable,不可为空")
+	@ApiModelProperty(value = "作息时间点集合[HH:mm-HH:mm]", required = true)
+	private Set<String> timetable;
+	
+	@ApiModelProperty(value = "0-非自定义作息时间,1-自定义作息时间")
+	private String customFlag = WorkCalendarConstant.CUSTOM_CALENDAR_DATE_YES; 	//默认自定义
+	
+}

+ 46 - 0
src/main/java/com/persagy/calendar/pojo/vo/WorkCalendarObjectUpdateVO.java

@@ -0,0 +1,46 @@
+package com.persagy.calendar.pojo.vo;
+
+import java.util.Set;
+
+import javax.validation.constraints.NotBlank;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Getter;
+import lombok.Setter;
+import lombok.ToString;
+
+/**
+ * @version 
+ * @description 
+ * @company persagy
+ * @author zhangqiankun
+ * @since 2021年3月8日:	下午8:09:04
+ */
+@Getter
+@Setter
+@ApiModel
+@ToString
+public class WorkCalendarObjectUpdateVO {
+
+	@NotBlank(message = "用户ID,不可为空")
+	@ApiModelProperty(value = "用户ID", required = true)
+	private String userId;
+	
+	@ApiModelProperty(value = "集团编码", required = true)
+	private String groupCode;
+	
+	//@NotBlank(message = "项目ID,不可为空")
+	@ApiModelProperty(value = "项目ID", required = true)
+	private String projectId; 		// 项目
+	
+	@ApiModelProperty(value = "工作历ID", required = true)
+	private String calendarId; 	// 工作历ID
+	
+	@ApiModelProperty(value = "对象ID集合,空间、建筑、楼层、项目", example = "Sp4403070003f55c8b33cf1f45e5bfc699caaba4eedc")
+	private Set<String> objIds;
+	
+	@ApiModelProperty(value = "对象ID集合,空间、建筑、楼层、项目", example = "Sp4403070003f55c8b33cf1f45e5bfc699caaba4eedc")
+	private String objId;
+	
+}

+ 44 - 0
src/main/java/com/persagy/calendar/pojo/vo/WorkCalendarQueryVO.java

@@ -0,0 +1,44 @@
+package com.persagy.calendar.pojo.vo;
+
+import javax.validation.constraints.NotBlank;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Getter;
+import lombok.Setter;
+import lombok.ToString;
+
+/**
+ * @version 
+ * @description 
+ * @company persagy
+ * @author zhangqiankun
+ * @since 2020年10月2日:	下午4:50:41
+ */
+@Getter
+@Setter
+@ToString
+@ApiModel
+public class WorkCalendarQueryVO {
+
+	@NotBlank(message = "用户ID不可为空")
+	@ApiModelProperty(value = "用户ID", required = true)
+	private String userId;
+	
+	@ApiModelProperty(value = "集团编码", required = true)
+	private String groupCode;
+	
+	//@NotBlank(message = "项目ID不可为空")
+	@ApiModelProperty(value = "项目ID", required = true)
+	private String projectId; 		// 项目
+	
+	@ApiModelProperty(name = "ID", value = "主键ID,更新时不可为空")
+	private String id;
+	
+	@ApiModelProperty(value = "工作历名称[支持模糊查询]")
+	private String calendarName;	// 同一GROUP_ID下唯一,代码判断
+	
+	@ApiModelProperty(value = "对象ID")
+	private String objId;
+
+}

+ 61 - 0
src/main/java/com/persagy/calendar/pojo/vo/WorkCalendarRuleCreateVO.java

@@ -0,0 +1,61 @@
+package com.persagy.calendar.pojo.vo;
+
+import java.util.Set;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.Pattern;
+
+import com.persagy.calendar.constant.WorkCalendarConstant;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Getter;
+import lombok.Setter;
+import lombok.ToString;
+
+/**
+ * @version 
+ * @description 
+ * @company persagy
+ * @author zhangqiankun
+ * @since 2020年10月2日:	下午7:00:31
+ */
+@Getter
+@Setter
+@ToString
+@ApiModel
+public class WorkCalendarRuleCreateVO {
+	
+	@NotBlank(message = "工作历ID不可为空")
+	@ApiModelProperty(value = "工作历ID", required = true)
+	private String calendarId; 	// 工作历ID
+	
+	@NotBlank(message = "dictType不可为空")
+	@ApiModelProperty(value = "字典类型", required = true)
+	private String dictType; 	// 字典类型
+
+	//@NotBlank(message = "dictCode不可为空")
+	@ApiModelProperty(value = "字典数据code", required = true)
+	private String dictCode; 	// 字典数据code
+
+	@NotBlank(message = "ruleDateStart不可为空")
+	@ApiModelProperty(value = "开始日期[YYYYMMDD]", required = true)
+	@Pattern(regexp = WorkCalendarConstant.DATE_REG_YYYYMMDD, message = "时间格式必须是YYYYMMDD")
+	private String ruleDateStart; // 规则生效的开始日期YYYYMMDD
+
+	@NotBlank(message = "ruleDateEnd不可为空")
+	@ApiModelProperty(value = "结束日期[YYYYMMDD]", required = true)
+	@Pattern(regexp = WorkCalendarConstant.DATE_REG_YYYYMMDD, message = "时间格式必须是YYYYMMDD")
+	private String ruleDateEnd; // 规则生效的结束日期YYYYMMDD
+
+	@ApiModelProperty(value = "规则生效时间点[HHMMSS]")
+	@Pattern(regexp = WorkCalendarConstant.DATE_REG_HHMMSS, message = "时间格式必须是HHMMSS")
+	private String ruleTime; 	// HHMMSS
+
+	@ApiModelProperty(value = "规则生效时间")
+	private Set<String> value; 	// 非严格开始结束日期的类型下,结合dictCode填写此值,后台不解析,实时解析查询
+	
+	@ApiModelProperty(hidden = true)
+	private String ruleFlag = WorkCalendarConstant.WORK_CALENDAR_RULE_FLAG_NEW; // 0-解析规则;1-不解析规则,方便后续解析
+	
+}

+ 25 - 0
src/main/java/com/persagy/calendar/pojo/vo/WorkCalendarRuleDeleteVO.java

@@ -0,0 +1,25 @@
+package com.persagy.calendar.pojo.vo;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Getter;
+import lombok.Setter;
+import lombok.ToString;
+
+/**
+ * @version 
+ * @description 
+ * @company persagy
+ * @author zhangqiankun
+ * @since 2020年10月2日:	下午7:00:31
+ */
+@Getter
+@Setter
+@ToString
+@ApiModel
+public class WorkCalendarRuleDeleteVO extends BaseQueryVO {
+	
+	@ApiModelProperty(value = "工作历ID", required = true)
+	private String calendarId; 	// 工作历ID
+	
+}

+ 38 - 0
src/main/java/com/persagy/calendar/pojo/vo/WorkCalendarRuleQueryVO.java

@@ -0,0 +1,38 @@
+package com.persagy.calendar.pojo.vo;
+
+import java.util.Set;
+
+import com.persagy.calendar.constant.WorkCalendarConstant;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Getter;
+import lombok.Setter;
+import lombok.ToString;
+
+/**
+ * @version 
+ * @description 
+ * @company persagy
+ * @author zhangqiankun
+ * @since 2020年10月2日:	下午7:00:31
+ */
+@Getter
+@Setter
+@ToString
+@ApiModel
+public class WorkCalendarRuleQueryVO extends BaseQueryVO {
+	
+	@ApiModelProperty(value = "工作历ID")
+	private String calendarId; 	// 工作历ID
+	
+	@ApiModelProperty(value = "字典类型")
+	private String dictType; 	// 字典类型
+
+	@ApiModelProperty(value = "字典数据code")
+	private Set<String> dictCode; 	// 字典数据code
+	
+	@ApiModelProperty(hidden = true)
+	private String ruleFlag = WorkCalendarConstant.WORK_CALENDAR_RULE_FLAG_NEW; // 0-解析规则;1-不解析规则,方便后续解析
+	
+}

+ 65 - 0
src/main/java/com/persagy/calendar/pojo/vo/WorkCalendarRuleUpdateVO.java

@@ -0,0 +1,65 @@
+package com.persagy.calendar.pojo.vo;
+
+import java.util.Set;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.Pattern;
+
+import com.persagy.calendar.constant.WorkCalendarConstant;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Getter;
+import lombok.Setter;
+import lombok.ToString;
+
+/**
+ * @version 
+ * @description 
+ * @company persagy
+ * @author zhangqiankun
+ * @since 2020年10月2日:	下午7:00:31
+ */
+@Getter
+@Setter
+@ToString
+@ApiModel
+public class WorkCalendarRuleUpdateVO {
+	
+	@NotBlank(message = "规则ID不可为空")
+	@ApiModelProperty(value = "规则ID", required = true)
+	private String id;
+	
+	@NotBlank(message = "工作历ID不可为空")
+	@ApiModelProperty(value = "工作历ID", required = true)
+	private String calendarId; 	// 工作历ID
+	
+	@NotBlank(message = "dictType不可为空")
+	@ApiModelProperty(value = "字典类型", required = true)
+	private String dictType; 	// 字典类型
+
+	@NotBlank(message = "dictCode不可为空")
+	@ApiModelProperty(value = "字典数据code", required = true)
+	private String dictCode; 	// 字典数据code
+
+	@NotBlank(message = "ruleDateStart不可为空")
+	@ApiModelProperty(value = "开始日期[YYYYMMDD]", required = true)
+	@Pattern(regexp = WorkCalendarConstant.DATE_REG_YYYYMMDD, message = "时间格式必须是YYYYMMDD")
+	private String ruleDateStart; // 规则生效的开始日期YYYYMMDD
+
+	@NotBlank(message = "ruleDateEnd不可为空")
+	@ApiModelProperty(value = "结束日期[YYYYMMDD]", required = true)
+	@Pattern(regexp = WorkCalendarConstant.DATE_REG_YYYYMMDD, message = "时间格式必须是YYYYMMDD")
+	private String ruleDateEnd; // 规则生效的结束日期YYYYMMDD
+
+	@ApiModelProperty(value = "规则生效时间点[HHMMSS]")
+	@Pattern(regexp = WorkCalendarConstant.DATE_REG_HHMMSS, message = "时间格式必须是HHMMSS")
+	private String ruleTime; 	// HHMMSS
+
+	@ApiModelProperty(value = "规则生效时间")
+	private Set<String> value; 	// 非严格开始结束日期的类型下,结合dictCode填写此值,后台不解析,实时解析查询
+	
+	@ApiModelProperty(hidden = true)
+	private String ruleFlag = WorkCalendarConstant.WORK_CALENDAR_RULE_FLAG_NEW; // 0-解析规则;1-不解析规则,方便后续解析
+	
+}

+ 39 - 0
src/main/java/com/persagy/calendar/pojo/vo/WorkCalendarUpdateVO.java

@@ -0,0 +1,39 @@
+package com.persagy.calendar.pojo.vo;
+
+import java.util.Set;
+
+import javax.validation.constraints.NotBlank;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Getter;
+import lombok.Setter;
+import lombok.ToString;
+
+/**
+ * @version 
+ * @description 
+ * @company persagy
+ * @author zhangqiankun
+ * @since 2020年10月2日:	下午12:22:08
+ */
+
+@Getter
+@Setter
+@ToString
+@ApiModel
+public class WorkCalendarUpdateVO extends BaseQueryVO {
+	
+	@NotBlank(message = "工作历名称不可为空")
+	@ApiModelProperty(value = "工作历名称", required = true)
+	private String calendarName;	// 同一GROUP_ID下唯一,代码判断
+
+	@ApiModelProperty(value = "工作历描述")
+	private String calendarDesc; 	// 工作历描述
+
+	@ApiModelProperty(value = "工作历来源ID,当模板创建时,不可为空")
+	private String fromId;
+	
+	@ApiModelProperty(value = "对象ID集合,空间、建筑、楼层、项目", example = "Sp4403070003f55c8b33cf1f45e5bfc699caaba4eedc")
+	private Set<String> objIds;
+}

+ 39 - 0
src/main/java/com/persagy/calendar/pojo/vo/WorkLabelBatchUpdateVO.java

@@ -0,0 +1,39 @@
+package com.persagy.calendar.pojo.vo;
+
+import java.util.List;
+
+import javax.validation.Valid;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Getter;
+import lombok.Setter;
+import lombok.ToString;
+
+/**
+ * @version 
+ * @description 
+ * @company persagy
+ * @author zhangqiankun
+ * @since 2021年3月4日:	下午7:02:46
+ */
+@Getter
+@Setter
+@ToString
+@ApiModel
+public class WorkLabelBatchUpdateVO {
+	
+	@ApiModelProperty(value = "集团编码", required = true)
+	private String groupCode;
+	
+	@Valid
+	//@NotEmpty(message = "日期标签属性不可为空")
+	@ApiModelProperty(value = "日期标签属性", required = true)
+	private List<WorkCalendarLabelUpdateVO> labels;
+	
+	@Valid
+	//@NotEmpty(message = "日期作息时间属性不可为空")
+	@ApiModelProperty(value = "日期作息时间属性", required = true)
+	private List<WorkCalendarMoreDateCreateVO> times;
+	
+}

+ 49 - 0
src/main/java/com/persagy/calendar/service/IWorkCalendarDateService.java

@@ -0,0 +1,49 @@
+package com.persagy.calendar.service;
+
+import java.util.List;
+
+import com.persagy.calendar.pojo.dto.WorkCalendarDate;
+import com.persagy.db.service.ISuperService;
+
+/**
+ * 工作历作息时间表
+ * 
+ * @version 1.0.0
+ * @company persagy 
+ * @author zhangqiankun
+ * @date 2020-10-03 13:54:22
+ */
+public interface IWorkCalendarDateService extends ISuperService<WorkCalendarDate> {
+	
+	WorkCalendarDate getById(String id, String projectId);
+	
+	boolean createWorkCalendarDate(WorkCalendarDate workCalendarDate);
+	
+	boolean updateWorkCalendarDate(WorkCalendarDate workCalendarDate);
+	
+	boolean deleteWorkCalendarDate(WorkCalendarDate workCalendarDate);
+	
+	boolean deleteWorkCalendarDate(String id);
+	
+	/**
+	 * 同项目下,同天、同类型+code只允许存在一条自定义信息
+	 * @param calendarDate 将本身已存在的作息时间ID赋值给了此对象,方便使用
+	 */
+	boolean checkWorkDateValid(WorkCalendarDate calendarDate);
+
+	/**
+	 * 不存在新增,存在更新
+	 * @param calendarDate
+	 * @return
+	 */
+	boolean replaceIntoCalendarDate(WorkCalendarDate calendarDate);
+
+	/**
+	 * 批量创建自定义作息时间信息
+	 * @param datas
+	 * @return
+	 */
+	boolean batchCreateCalendarDate(List<WorkCalendarDate> datas);
+	
+}
+

+ 43 - 0
src/main/java/com/persagy/calendar/service/IWorkCalendarDictService.java

@@ -0,0 +1,43 @@
+package com.persagy.calendar.service;
+
+import java.util.List;
+import java.util.Set;
+
+import com.persagy.calendar.pojo.dto.WorkCalendarDict;
+import com.persagy.calendar.pojo.vo.DictCodeCreate;
+import com.persagy.db.service.ISuperService;
+
+/**
+ * @version 
+ * @description 
+ * @company persagy
+ * @author zhangqiankun
+ * @since 2021年3月4日:	上午9:48:23
+ */
+public interface IWorkCalendarDictService extends ISuperService<WorkCalendarDict> {
+
+	/**
+	 * 批量创建字典类型
+	 * 
+	 * @param calendarDict
+	 * @param diyValue
+	 */
+	boolean batchCreateOrUpdateDictType(WorkCalendarDict calendarDict, Set<String> diyValues);
+
+	/**
+	 * 批量创建字典类型
+	 * 
+	 * @param calendarDict
+	 * @param codes
+	 * @return
+	 */
+	boolean batchCreateOrUpdateDict(WorkCalendarDict calendarDict, List<DictCodeCreate> codes);
+
+	/**
+	 * 批量创建字典类型
+	 * @param calendarDicts
+	 * @return
+	 */
+	boolean batchCreateCalendarDict(List<WorkCalendarDict> calendarDicts);
+
+}

+ 23 - 0
src/main/java/com/persagy/calendar/service/IWorkCalendarLabelService.java

@@ -0,0 +1,23 @@
+package com.persagy.calendar.service;
+
+import java.util.List;
+
+import com.persagy.calendar.pojo.dto.WorkCalendarLabel;
+import com.persagy.db.service.ISuperService;
+
+/**
+ * @version 
+ * @description 
+ * @company persagy
+ * @author zhangqiankun
+ * @since 2021年3月3日:	下午5:44:34
+ */
+public interface IWorkCalendarLabelService extends ISuperService<WorkCalendarLabel> {
+
+	/**
+	 * 批量创建标签属性
+	 * @param calendarLabels
+	 */
+	boolean batchCreateCalendarLabel(List<WorkCalendarLabel> calendarLabels);
+
+}

+ 33 - 0
src/main/java/com/persagy/calendar/service/IWorkCalendarObjectService.java

@@ -0,0 +1,33 @@
+package com.persagy.calendar.service;
+
+import java.util.Set;
+
+import com.persagy.calendar.pojo.dto.WorkCalendarObject;
+import com.persagy.db.service.ISuperService;
+
+/**
+ * @version 
+ * @description 
+ * @company persagy
+ * @author zhangqiankun
+ * @since 2021年3月2日:	下午5:02:08
+ */
+public interface IWorkCalendarObjectService extends ISuperService<WorkCalendarObject> {
+
+	/**
+	 * 创建工作历关联的对象信息
+	 * 
+	 * @param object
+	 * @param objIds
+	 */
+	void batchInsertObjects(WorkCalendarObject object, Set<String> objIds);
+
+	/**
+	 * 对象变更所属工作历
+	 * @param calendarObject
+	 * @param objIds 
+	 * @return
+	 */
+	boolean replaceCalendarObject(WorkCalendarObject calendarObject, Set<String> objIds);
+
+}

+ 69 - 0
src/main/java/com/persagy/calendar/service/IWorkCalendarRuleService.java

@@ -0,0 +1,69 @@
+package com.persagy.calendar.service;
+
+import java.util.List;
+
+import com.persagy.calendar.pojo.dto.WorkCalendarRule;
+import com.persagy.db.service.ISuperService;
+
+/**
+ * 工作历规则表
+ * 
+ * @version 1.0.0
+ * @company persagy 
+ * @author zhangqiankun
+ * @date 2020-10-02 18:26:14
+ */
+public interface IWorkCalendarRuleService extends ISuperService<WorkCalendarRule> {
+	
+	/**
+	 * 根据工作历ID查询规则信息
+	 * @param calendarId
+	 * @param projectId 项目ID
+	 * @return
+	 */
+	List<WorkCalendarRule> queryRuleByCalendarId(String calendarId, String projectId);
+	
+	/**
+	 * 查询出与value相同的工作历规则ID,目前IBMS专用,其余方法不要调用
+	 * @param workCalendarRule
+	 * @return 
+	 */
+	String getCalendarRule(WorkCalendarRule workCalendarRule);
+	
+	/**
+	 * @param id 规则ID
+	 * @param projectId 项目ID
+	 * @return
+	 */
+	WorkCalendarRule getById(String id, String projectId);
+	
+	boolean createWorkCalendarRule(WorkCalendarRule workCalendarRule);
+	
+	boolean updateWorkCalendarRule(WorkCalendarRule workCalendarRule);
+	
+	/**
+	 * 当规则ID不为空时,主键删除;当工作历ID不为空时,根据工作历ID删除;同时存在,主键删除,逻辑删除
+	 * @param workCalendarRule
+	 * @return
+	 */
+	boolean deleteWorkCalendarRule(WorkCalendarRule workCalendarRule);
+	/**
+	 * 当规则ID不为空时,主键删除;当工作历ID不为空时,根据工作历ID删除;同时存在,主键删除,物理删除
+	 * @param workCalendarRule
+	 * @return
+	 */
+	boolean removeWorkCalendarRule(String id, String calendarId, String dictType);
+
+	/**
+	 * 同工作历类型下,dictType+dictCode 唯一
+	 * 
+	 * @param projectId
+	 * @param dictType
+	 * @param dictCode
+	 * @param id 存在为修改,修改略过自身
+	 * @return
+	 */
+	boolean checkDictRuleValid(String projectId, String calendarId, String dictType, String dictCode, String id);
+
+}
+

+ 50 - 0
src/main/java/com/persagy/calendar/service/IWorkCalendarService.java

@@ -0,0 +1,50 @@
+package com.persagy.calendar.service;
+
+import java.util.List;
+import java.util.Set;
+
+import com.persagy.calendar.pojo.dto.WorkCalendar;
+import com.persagy.db.service.ISuperService;
+
+/**
+ * 工作历主表
+ * 
+ * @version 1.0.0
+ * @company persagy 
+ * @author zhangqiankun
+ * @date 2020-10-02 11:33:00
+ */
+public interface IWorkCalendarService extends ISuperService<WorkCalendar> {
+	
+	/**
+	 * 查询工作历类型列表,包含所对应的对象
+	 * @param calendar
+	 * @return
+	 */
+	List<WorkCalendar> queryCalendarObjectList(WorkCalendar calendar);
+	
+	/**
+	 * @param id
+	 * @param projectId 允许为空
+	 * @return
+	 */
+	WorkCalendar getById(String id, String projectId);
+	
+	/**
+	 * 判断对应的groupId和calendarName,是否可以被插入或更新
+	 * @param id,更新时,需要传入,原ID
+	 * @param projectId
+	 * @param groupCode 集团编码
+	 * @param calendarName
+	 * @return true-可以,false-不可以
+	 */
+	boolean checkProjetcIdAndName(String id, String projectId, String groupCode, String calendarName);
+	
+	boolean createWorkCalendar(WorkCalendar workCalendar, Set<String> objIds);
+	
+	boolean updateWorkCalendar(WorkCalendar workCalendar);
+	
+	boolean deleteWorkCalendar(String id, String updateUser);
+
+}
+

+ 98 - 0
src/main/java/com/persagy/calendar/service/OldWorkCalendarDateService.java

@@ -0,0 +1,98 @@
+package com.persagy.calendar.service;
+
+import java.util.List;
+
+import com.persagy.calendar.pojo.dto.OldWorkCalendar;
+import com.persagy.calendar.pojo.old.OldCalendarIntervalCreateVO;
+import com.persagy.calendar.pojo.old.OldCalendarIntervalDeleteVO;
+import com.persagy.calendar.pojo.old.OldCalendarIntervalsByTag;
+import com.persagy.calendar.pojo.old.OldCalendarRuleCreateVO;
+import com.persagy.calendar.pojo.old.OldCalendarRuleDeleteVO;
+import com.persagy.calendar.pojo.old.OldCalendarRuleVO;
+import com.persagy.calendar.pojo.old.OldCalendarTagVO;
+
+/**
+ * 老版服务接口
+ * 
+ * @version 1.0.0
+ * @company persagy 
+ * @author zhangqiankun
+ * @date 2020-10-03 13:54:22
+ */
+public interface OldWorkCalendarDateService {
+	
+	/**
+	 * 查询工作历详情
+	 * @param oldWorkCalendar
+	 * @return
+	 */
+	List<OldWorkCalendar> queryOldCalendarList(OldWorkCalendar oldWorkCalendar);
+
+	/**
+	 * 创建老版规则信息
+	 * @param requestData
+	 * @return
+	 */
+	boolean createOldCalendarRule(OldCalendarRuleVO<OldCalendarRuleCreateVO> requestData);
+
+	/**
+	 * 删除老版规则信息
+	 * @param requestData
+	 * @return
+	 */
+	boolean deleteOldCalendarRule(OldCalendarRuleVO<OldCalendarRuleDeleteVO> requestData);
+
+	/**
+	 * 修改老版规则信息
+	 * @param requestData
+	 * @return
+	 */
+	boolean updateOldCalendarRule(OldCalendarRuleCreateVO requestData);
+	
+	/**
+	 * 查询规则信息
+	 * @param requestData
+	 */
+	List<OldWorkCalendar> queryOldCalendarRuleList(String id, String tag, String groupId);
+	
+	/**
+	 * 设置作息日期
+	 * @param id 工作历ID
+	 * @param tags
+	 * @return
+	 */
+	boolean setTags(String id, List<OldCalendarTagVO> tags);
+
+	/**
+	 * 删除作息日期
+	 * @param id 工作历ID
+	 * @param tags
+	 * @return
+	 */
+	boolean unsetTags(String id, List<OldCalendarTagVO> tags);
+
+	/**
+	 * 设置作息时段 from - to 和 已录入的作息日期相同
+	 * @param id 工作历ID
+	 * @param intervals
+	 * @return
+	 */
+	boolean setIntervals(String id, List<OldCalendarIntervalCreateVO> intervals);
+	
+	/**
+	 * 删除作息时间段
+	 * @param id 工作历ID
+	 * @param intervals
+	 * @return
+	 */
+	boolean unsetIntervals(String id, List<OldCalendarIntervalDeleteVO> intervals);
+	
+	/**
+	 * 根据Tag设置作息时间段
+	 * @param requestData
+	 * @return
+	 */
+	boolean setIntervalsByTag(OldCalendarIntervalsByTag requestData);
+	
+}
+

+ 24 - 0
src/main/java/com/persagy/calendar/service/RwdObjectService.java

@@ -0,0 +1,24 @@
+package com.persagy.calendar.service;
+
+import com.persagy.calendar.client.model.BaseModel;
+import com.persagy.calendar.client.model.RwdObjectModel;
+import com.persagy.common.utils.ResponseResult;
+
+/**
+ * @version 
+ * @description 
+ * @company persagy
+ * @author zhangqiankun
+ * @since 2021年3月2日:	下午3:15:44
+ */
+public interface RwdObjectService {
+
+	/**
+	 * 查询物理世界对象信息
+	 * @param baseModel
+	 * @param objectModel 
+	 * @return
+	 */
+	ResponseResult queryRwdObjects(BaseModel baseModel, RwdObjectModel objectModel);
+
+}

+ 294 - 0
src/main/java/com/persagy/calendar/service/impl/OldWorkCalendarDateServiceImpl.java

@@ -0,0 +1,294 @@
+package com.persagy.calendar.service.impl;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
+import com.baomidou.mybatisplus.extension.toolkit.SqlHelper;
+import com.persagy.calendar.constant.WorkCalendarConstant;
+import com.persagy.calendar.mapper.OldWorkCalendarMapper;
+import com.persagy.calendar.mapper.WorkCalendarDateMapper;
+import com.persagy.calendar.mapper.WorkCalendarMapper;
+import com.persagy.calendar.mapper.WorkCalendarRuleMapper;
+import com.persagy.calendar.pojo.dto.OldWorkCalendar;
+import com.persagy.calendar.pojo.dto.WorkCalendar;
+import com.persagy.calendar.pojo.dto.WorkCalendarDate;
+import com.persagy.calendar.pojo.dto.WorkCalendarRule;
+import com.persagy.calendar.pojo.dto.WorkCalendarRule.Builder;
+import com.persagy.calendar.pojo.old.DataRangeVO;
+import com.persagy.calendar.pojo.old.OldCalendarIntervalCreateVO;
+import com.persagy.calendar.pojo.old.OldCalendarIntervalDeleteVO;
+import com.persagy.calendar.pojo.old.OldCalendarIntervalsByTag;
+import com.persagy.calendar.pojo.old.OldCalendarRuleCreateVO;
+import com.persagy.calendar.pojo.old.OldCalendarRuleDeleteVO;
+import com.persagy.calendar.pojo.old.OldCalendarRuleVO;
+import com.persagy.calendar.pojo.old.OldCalendarSetIntervalVO;
+import com.persagy.calendar.pojo.old.OldCalendarTagQueryVO;
+import com.persagy.calendar.pojo.old.OldCalendarTagVO;
+import com.persagy.calendar.service.OldWorkCalendarDateService;
+import com.persagy.common.enums.ResponseCode;
+import com.persagy.common.exception.BusinessException;
+
+/**
+ * @version 
+ * @description 老版服务接口
+ * @company persagy
+ * @author zhangqiankun
+ * @since 2020年10月3日:	下午4:18:48
+ */
+@Service
+public class OldWorkCalendarDateServiceImpl implements OldWorkCalendarDateService {
+	
+	@Autowired
+	private OldWorkCalendarMapper oldWorkCalendarMapper;
+	
+	@Autowired
+	private WorkCalendarMapper workCalendarMapper;
+	
+	@Autowired
+	private WorkCalendarRuleMapper workCalendarRuleMapper;
+	
+	@Autowired
+	private WorkCalendarDateMapper workCalendarDateMapper;
+	
+	@Override
+	public List<OldWorkCalendar> queryOldCalendarList(OldWorkCalendar oldWorkCalendar) {
+		oldWorkCalendar.setDelFlag(WorkCalendarConstant.WORK_CALENDAR_DEL_FLAG_NOR);
+		return oldWorkCalendarMapper.queryOldCalendarList(oldWorkCalendar);
+	}
+	
+	
+	@Override
+	@Transactional
+	public boolean createOldCalendarRule(OldCalendarRuleVO<OldCalendarRuleCreateVO> requestData) {
+		List<OldCalendarRuleCreateVO> rules = requestData.getRules();
+		Integer result = null;
+		Long selectCount = null;
+		WorkCalendarRule calendarRule = null;
+		QueryWrapper<WorkCalendarRule> queryWrapper = null;
+		WorkCalendar calendar = null;
+		for (OldCalendarRuleCreateVO rule : rules) {
+			// 判断工作历信息是否存在
+			calendar = this.workCalendarMapper.selectById(rule.getId());
+			if (calendar == null) {
+				throw new BusinessException(ResponseCode.C0320.getCode(), rule.getId() + "的工作历信息不存在");
+			}
+			// 判断id tag 的唯一性
+	    	queryWrapper = new WorkCalendarRule.Builder().createQueryWrapper()
+	    			.calendarIdEq(rule.getId()).dictTypeEq(rule.getTag()).projectIdEq(rule.getProjectId())
+	    			.delFlagEq(WorkCalendarConstant.WORK_CALENDAR_DEL_FLAG_NOR).builderQueryWrapper();
+	    	selectCount = workCalendarRuleMapper.selectCount(queryWrapper);
+			if (selectCount == null || selectCount < 1) {
+				calendarRule = new WorkCalendarRule();
+				calendarRule.setCalendarId(rule.getId());
+				calendarRule.setDictType(rule.getTag());
+				calendarRule.setDictCode(rule.getType());
+				calendarRule.setValue(rule.getValue());
+				calendarRule.setProjectId(rule.getProjectId());
+				calendarRule.setRuleFlag(rule.getRuleFlag());
+				result = workCalendarRuleMapper.insert(calendarRule);
+				if (result == null || result < 1) {
+					throw new BusinessException(ResponseCode.B0001.getCode(), "创建规则信息失败");
+				}
+			} else {
+				throw new BusinessException(ResponseCode.C0341.getCode(), rule.getId() + "-" + rule.getTag() + "的数据已存在");
+			}
+		}
+		return SqlHelper.retBool(result);
+	}
+
+	@Override
+	@Transactional
+	public boolean deleteOldCalendarRule(OldCalendarRuleVO<OldCalendarRuleDeleteVO> requestData) {
+		List<OldCalendarRuleDeleteVO> rules = requestData.getRules();
+		Integer result = null;
+		Builder builder = new WorkCalendarRule.Builder();
+		UpdateWrapper<WorkCalendarRule> updateWrapper = null;
+		
+		// 要更新的字段值
+		WorkCalendarRule calendarRule = new WorkCalendarRule();
+		calendarRule.setDelFlag(WorkCalendarConstant.WORK_CALENDAR_DEL_FLAG_DEL);
+		
+		for (OldCalendarRuleDeleteVO rule : rules) {
+			// where 条件
+			builder = new WorkCalendarRule.Builder().createUpdateWrapper();
+			updateWrapper = builder.calendarIdEq(rule.getId())
+					.projectIdEq(rule.getProjectId()).dictTypeEq(rule.getTag())
+					.delFlagEq(WorkCalendarConstant.WORK_CALENDAR_DEL_FLAG_NOR)
+					.ruleFlagEq(rule.getRuleFlag()).builderUpdateWrapper();
+			result = this.workCalendarRuleMapper.update(calendarRule, updateWrapper);
+			if (result == null || result < 1) {
+				throw new BusinessException(ResponseCode.B0001.getCode(), "删除规则信息失败");
+			}
+		}
+		return SqlHelper.retBool(result);
+	}
+
+
+	@Override
+	@Transactional
+	public boolean updateOldCalendarRule(OldCalendarRuleCreateVO requestData) {
+		WorkCalendarRule calendarRule = new WorkCalendarRule();
+		calendarRule.setCalendarId(requestData.getId());
+		calendarRule.setDictType(requestData.getTag());
+		calendarRule.setDictCode(requestData.getType());
+		calendarRule.setValue(requestData.getValue());
+		calendarRule.setProjectId(requestData.getProjectId());
+		calendarRule.setRuleFlag(requestData.getRuleFlag());
+		
+		// where条件
+		UpdateWrapper<WorkCalendarRule> updateWrapper = new WorkCalendarRule.Builder().createUpdateWrapper()
+				.calendarIdEq(requestData.getId()).dictTypeEq(requestData.getTag())
+				.projectIdEq(requestData.getProjectId()).ruleFlagEq(requestData.getRuleFlag())
+    			.delFlagEq(WorkCalendarConstant.WORK_CALENDAR_DEL_FLAG_NOR).builderUpdateWrapper();
+		Integer result = workCalendarRuleMapper.update(calendarRule, updateWrapper);
+		return SqlHelper.retBool(result);
+	}
+
+	@Override
+	public List<OldWorkCalendar> queryOldCalendarRuleList(String id, String tag, String groupId) {
+		return this.oldWorkCalendarMapper.queryOldCalendarRuleList(id, tag, groupId,  
+				WorkCalendarConstant.WORK_CALENDAR_DEL_FLAG_NOR,
+				WorkCalendarConstant.WORK_CALENDAR_RULE_FLAG_OLD);
+	}
+
+
+	@Override
+	@Transactional
+	public boolean setTags(String id, List<OldCalendarTagVO> tags) {
+		Integer result = null;
+		WorkCalendarDate calendarDate = null;
+		for (OldCalendarTagVO tag : tags) {
+			calendarDate = new WorkCalendarDate();
+			calendarDate.setCalendarId(id);
+			calendarDate.setDictType(tag.getTag());
+			calendarDate.setProjectId(tag.getProjectId());
+			
+			List<DataRangeVO> dates = tag.getDates();
+			for (DataRangeVO date : dates) {
+				calendarDate.setWorkDateStart(date.getFrom());
+				calendarDate.setWorkDateEnd(date.getTo());
+				// 逐条插入
+				result = workCalendarDateMapper.insert(calendarDate);
+				if (result == null || result < 1) {
+					throw new BusinessException(ResponseCode.B0001.getCode(), "设置作息日期失败");
+				}
+			}
+		}
+		
+		return SqlHelper.retBool(result);
+	}
+
+
+	@Override
+	@Transactional
+	public boolean unsetTags(String id, List<OldCalendarTagVO> tags) {
+		Integer result = null;
+		QueryWrapper<WorkCalendarDate> queryWrapper = null;
+		for (OldCalendarTagVO tag : tags) {
+			List<DataRangeVO> dates = tag.getDates();
+			for (DataRangeVO date : dates) {
+				// 组装where条件语句
+				queryWrapper = new WorkCalendarDate.Builder().createQueryWrapper()
+						.calendarIdEq(id).dictTypeEq(tag.getTag())
+						.projectIdEq(tag.getProjectId())
+						.workDateStartEq(date.getFrom()).workDateEndEq(date.getTo())
+		    			.builderQueryWrapper();
+				// 更新
+				result = workCalendarDateMapper.delete(queryWrapper);
+				if (result == null || result < 1) {
+					throw new BusinessException(ResponseCode.B0001.getCode(), "删除作息日期失败");
+				}
+			}
+		}
+		
+		return SqlHelper.retBool(result);
+	}
+
+
+	@Override
+	@Transactional
+	public boolean setIntervals(String id, List<OldCalendarIntervalCreateVO> intervals) {
+		Integer result = null;
+		WorkCalendarDate calendarDate = null;
+		
+		UpdateWrapper<WorkCalendarDate> updateWrapper = null;
+		
+		for (OldCalendarIntervalCreateVO interval : intervals) {
+			// 组装要更新的字段值
+			calendarDate = new WorkCalendarDate();
+			calendarDate.setDictCode(interval.getCode());
+			calendarDate.setWorkTime(interval.getTime().stream().collect(Collectors.joining(",")));
+			
+			List<DataRangeVO> dates = interval.getDates();
+			for (DataRangeVO date : dates) {
+				// 组装where条件语句
+				updateWrapper = new WorkCalendarDate.Builder().createUpdateWrapper()
+						.calendarIdEq(id).projectIdEq(interval.getProjectId())
+						.workDateStartEq(date.getFrom()).workDateEndEq(date.getTo())
+		    			.builderUpdateWrapper();
+				// 更新
+				result = workCalendarDateMapper.update(calendarDate, updateWrapper);
+				if (result == null || result < 1) {
+					throw new BusinessException(ResponseCode.B0001.getCode(), "设置作息时间段失败");
+				}
+			}
+		}
+		
+		return SqlHelper.retBool(result);
+	}
+
+
+	@Override
+	@Transactional
+	public boolean unsetIntervals(String id, List<OldCalendarIntervalDeleteVO> intervals) {
+		Integer result = null;
+		// 需要更新的字段
+		QueryWrapper<WorkCalendarDate> queryWrapper = null;
+		for (OldCalendarIntervalDeleteVO interval : intervals) {
+			List<DataRangeVO> dates = interval.getDates();
+			for (DataRangeVO date : dates) {
+				// 组装where条件语句
+				queryWrapper = new WorkCalendarDate.Builder().createQueryWrapper()
+						.calendarIdEq(id).dictTypeEq(interval.getCode())
+						.projectIdEq(interval.getProjectId())
+						.workDateStartEq(date.getFrom()).workDateEndEq(date.getTo())
+		    			.builderQueryWrapper();
+				// 更新
+				result = workCalendarDateMapper.delete(queryWrapper);
+				if (result == null || result < 1) {
+					throw new BusinessException(ResponseCode.B0001.getCode(), "删除作息时间段失败");
+				}
+			}
+		}
+		
+		return SqlHelper.retBool(result);
+	}
+
+	
+	@Override
+	@Transactional
+	public boolean setIntervalsByTag(OldCalendarIntervalsByTag requestData) {
+		OldCalendarTagQueryVO query = requestData.getQuery();
+		OldCalendarSetIntervalVO interval = requestData.getSet_interval();
+		// 组装where条件语句
+		UpdateWrapper<WorkCalendarDate> updateWrapper = new WorkCalendarDate.Builder().createUpdateWrapper()
+				.calendarIdEq(requestData.getId())
+				.projectIdEq(requestData.getProjectId()).dictTypeEq(query.getTag())
+				.workDateStartEq(query.getDates().getFrom()).workDateEndEq(query.getDates().getTo())
+    			.builderUpdateWrapper();
+		// 组装 要更新的字段值
+		WorkCalendarDate calendarDate = new WorkCalendarDate();
+		calendarDate.setDictCode(interval.getCode());
+		calendarDate.setWorkTime(interval.getTime().stream().collect(Collectors.joining(",")));
+		// 更新
+		Integer result = workCalendarDateMapper.update(calendarDate, updateWrapper);
+		return SqlHelper.retBool(result);
+	}
+
+}

+ 122 - 0
src/main/java/com/persagy/calendar/service/impl/RwdObjectServiceImpl.java

@@ -0,0 +1,122 @@
+package com.persagy.calendar.service.impl;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.google.common.collect.Lists;
+import com.persagy.calendar.client.RwdObjectClient;
+import com.persagy.calendar.client.model.BaseModel;
+import com.persagy.calendar.client.model.BaseQueryModel;
+import com.persagy.calendar.client.model.RwdObjectModel;
+import com.persagy.calendar.pojo.dto.WorkCalendar;
+import com.persagy.calendar.pojo.dto.WorkCalendarObject;
+import com.persagy.calendar.service.IWorkCalendarObjectService;
+import com.persagy.calendar.service.IWorkCalendarService;
+import com.persagy.calendar.service.RwdObjectService;
+import com.persagy.common.constant.DMPConstant;
+import com.persagy.common.enums.ResponseCode;
+import com.persagy.common.utils.ResponseResult;
+import com.persagy.common.utils.ResponseUtil;
+import com.persagy.common.utils.StringUtil;
+
+import cn.hutool.core.collection.CollectionUtil;
+
+/**
+ * @version 
+ * @description 
+ * @company persagy
+ * @author zhangqiankun
+ * @since 2021年3月2日:	下午3:15:57
+ */
+@Service
+public class RwdObjectServiceImpl implements RwdObjectService {
+
+	@Autowired
+	private RwdObjectClient rwdObjectClient;
+
+	@Autowired
+	private IWorkCalendarService workCalendarService;
+	
+	@Autowired
+	private IWorkCalendarObjectService workCalendarObjectService;
+	
+	@Override
+	public ResponseResult queryRwdObjects(BaseModel baseModel, RwdObjectModel objectModel) {
+		BaseQueryModel<RwdObjectModel> object = new BaseQueryModel<RwdObjectModel>();
+		object.setCriteria(objectModel);
+		String objects = this.rwdObjectClient.queryProjectObjects(baseModel, object);
+		return this.parseDMPResult(objects, baseModel.getGroupCode());
+	}
+	
+	/**
+	 * 解析数据中台响应数据
+	 * 
+	 * @param dmpResult
+	 * @return
+	 */
+	public ResponseResult parseDMPResult(String dmpResult, String groupCode) {
+		if (StringUtil.isBlank(dmpResult) || dmpResult.indexOf(DMPConstant.DMP_RESULT_KEY) < 0) {
+			return ResponseUtil.errorResult(ResponseCode.C0110.getCode(), "DMP服务响应异常");
+		}
+		JSONObject result = JSONObject.parseObject(dmpResult);
+		if (StringUtil.isNotBlank(result.getString(DMPConstant.DMP_FAIL_MSG))) {
+			return ResponseUtil.errorResult(ResponseCode.C0110.getCode(), result.getString(DMPConstant.DMP_FAIL_MSG));
+		}
+		if (!DMPConstant.DMP_RESULT_VAL.equals(result.getString(DMPConstant.DMP_RESULT_KEY))) {
+			return ResponseUtil.errorResult(ResponseCode.C0110.getCode(), ResponseCode.C0110.getDesc());
+		}
+		JSONArray array = result.getJSONArray(DMPConstant.DMP_DATA_KEY);
+		if (array == null || array.size() == 0) {
+			return ResponseUtil.successResult(Lists.newArrayList(), 0L);
+		}
+		// 获取本地存储的对象关联信息
+		QueryWrapper<WorkCalendarObject> queryWrapper = new WorkCalendarObject.Builder().createQueryWrapper()
+				.groupCodeEq(groupCode).builderQueryWrapper();
+		List<WorkCalendarObject> objects = this.workCalendarObjectService.list(queryWrapper);
+		this.setCalendarId(array, groupCode, objects);
+		return ResponseUtil.successResult(array, (long)array.size());  
+	}
+	
+	/**
+	 * 添加是否具有工作历的标识
+	 * @param array
+	 * @return
+	 */
+	public void setCalendarId(JSONArray array, String groupCode, List<WorkCalendarObject> objects) {
+		// key-objId,value-calendarId
+		Map<String, String> objToCalendar = new HashMap<String, String>();
+		// key-calendarId,value-calendarName
+		Map<String, String> calendarName = new HashMap<String, String>();
+		if (CollectionUtil.isNotEmpty(objects)) {
+			for (WorkCalendarObject object : objects) {
+				objToCalendar.put(object.getObjectId(), object.getCalendarId());
+				if (!calendarName.containsKey(object.getCalendarId())) {
+					WorkCalendar calendar = this.workCalendarService.getById(object.getCalendarId());
+					if (calendar != null) {
+						calendarName.put(object.getCalendarId(), calendar.getCalendarName());
+					}
+				}
+			}
+		}
+		int size = array.size();
+		for(int i = 0; i < size; i++) {
+			JSONObject jsonObject = array.getJSONObject(i);
+			String calendarId = objToCalendar.get(jsonObject.getString("id"));
+			if (StringUtil.isBlank(calendarId)) {
+				jsonObject.put("isRelated", false);	//是否存在有工作历
+			} else {
+				jsonObject.put("calendarId", calendarId);
+				jsonObject.put("calendarName", calendarName.get(calendarId));
+				jsonObject.put("isRelated", true);
+			}
+		}
+	}
+	
+}

+ 100 - 0
src/main/java/com/persagy/calendar/service/impl/WorkCalendarDateServiceImpl.java

@@ -0,0 +1,100 @@
+package com.persagy.calendar.service.impl;
+
+import java.util.List;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.toolkit.SqlHelper;
+import com.persagy.calendar.mapper.WorkCalendarDateMapper;
+import com.persagy.calendar.pojo.dto.WorkCalendarDate;
+import com.persagy.calendar.service.IWorkCalendarDateService;
+import com.persagy.common.utils.StringUtil;
+import com.persagy.db.service.impl.SuperServiceImpl;
+
+/**
+ * 工作历作息时间表
+ * 
+ * @version 1.0.0
+ * @company persagy 
+ * @author zhangqiankun
+ * @date 2020-10-03 13:54:22
+ */
+@Service
+public class WorkCalendarDateServiceImpl extends SuperServiceImpl<WorkCalendarDateMapper, WorkCalendarDate> implements IWorkCalendarDateService {
+	
+	@Autowired
+	private WorkCalendarDateMapper workCalendarDateMapper;
+ 	
+ 	@Override
+	public WorkCalendarDate getById(String id, String projectId) {
+    	QueryWrapper<WorkCalendarDate> queryWrapper = new WorkCalendarDate.Builder().createQueryWrapper()
+    			.idEq(id).projectIdEq(projectId).builderQueryWrapper();
+		return workCalendarDateMapper.selectOne(queryWrapper);
+	}
+ 	
+	@Override
+	@Transactional
+	public boolean createWorkCalendarDate(WorkCalendarDate workCalendarDate) {
+		Integer result = workCalendarDateMapper.insert(workCalendarDate);
+		return SqlHelper.retBool(result);
+	}
+	
+	@Override
+	@Transactional
+	public boolean updateWorkCalendarDate(WorkCalendarDate workCalendarDate) {
+		Integer result = workCalendarDateMapper.updateById(workCalendarDate);
+		return SqlHelper.retBool(result);
+	}
+
+	@Override
+	@Transactional
+	public boolean deleteWorkCalendarDate(WorkCalendarDate workCalendarDate) {
+		QueryWrapper<WorkCalendarDate> queryWrapper = new WorkCalendarDate.Builder().createQueryWrapper()
+				.projectIdEq(workCalendarDate.getProjectId()).idEq(workCalendarDate.getId())
+				.dictTypeEq(workCalendarDate.getDictType()).dictCodeEq(workCalendarDate.getDictCode())
+				.customFlagEq(workCalendarDate.getCustomFlag()).builderQueryWrapper();
+		Integer result = workCalendarDateMapper.delete(queryWrapper);
+		return SqlHelper.retBool(result);
+	}
+
+	@Override
+	@Transactional
+	public boolean deleteWorkCalendarDate(String id) {
+		Integer result = workCalendarDateMapper.deleteById(id);
+		return SqlHelper.retBool(result);
+	}
+
+	@Override
+	public boolean checkWorkDateValid(WorkCalendarDate calendarDate) {
+		QueryWrapper<WorkCalendarDate> queryWrapper = new WorkCalendarDate.Builder().createQueryWrapper()
+				.groupCodeEq(calendarDate.getGroupCode()).projectIdEq(calendarDate.getProjectId())
+				.workDateEq(calendarDate.getWorkDate()).dictCodeEq(calendarDate.getDictCode())
+				.dictTypeEq(calendarDate.getDictType()).customFlagEq(calendarDate.getCustomFlag())
+				.builderQueryWrapper();
+		WorkCalendarDate date = this.workCalendarDateMapper.selectOne(queryWrapper);
+		if (date == null) {
+			return true;
+		}
+		if (StringUtil.isNotBlank(calendarDate.getId()) && calendarDate.getId().equals(date.getId())) {
+			return true;
+		}
+		return false;
+	}
+
+	@Override
+	public boolean replaceIntoCalendarDate(WorkCalendarDate calendarDate) {
+		Integer result = this.workCalendarDateMapper.replaceIntoCalendarDate(calendarDate);
+		return SqlHelper.retBool(result);
+	}
+
+	@Override
+	@Transactional
+	public boolean batchCreateCalendarDate(List<WorkCalendarDate> datas) {
+		Integer result = this.workCalendarDateMapper.batchCreateCalendarDate(datas);
+		return SqlHelper.retBool(result);
+	}
+	
+}

+ 43 - 0
src/main/java/com/persagy/calendar/service/impl/WorkCalendarDictServiceImpl.java

@@ -0,0 +1,43 @@
+package com.persagy.calendar.service.impl;
+
+import java.util.List;
+import java.util.Set;
+
+import org.springframework.stereotype.Service;
+
+import com.baomidou.mybatisplus.extension.toolkit.SqlHelper;
+import com.persagy.calendar.mapper.WorkCalendarDictMapper;
+import com.persagy.calendar.pojo.dto.WorkCalendarDict;
+import com.persagy.calendar.pojo.vo.DictCodeCreate;
+import com.persagy.calendar.service.IWorkCalendarDictService;
+import com.persagy.db.service.impl.SuperServiceImpl;
+
+/**
+ * @version 
+ * @description 
+ * @company persagy
+ * @author zhangqiankun
+ * @since 2021年3月4日:	上午9:48:36
+ */
+@Service
+public class WorkCalendarDictServiceImpl extends SuperServiceImpl<WorkCalendarDictMapper, WorkCalendarDict> implements IWorkCalendarDictService {
+
+	@Override
+	public boolean batchCreateOrUpdateDictType(WorkCalendarDict calendarDict, Set<String> diyValues) {
+		Integer result = this.baseMapper.batchCreateOrUpdateDictType(calendarDict, diyValues);
+		return SqlHelper.retBool(result);
+	}
+
+	@Override
+	public boolean batchCreateOrUpdateDict(WorkCalendarDict calendarDict, List<DictCodeCreate> codes) {
+		Integer result = this.baseMapper.batchCreateOrUpdateDict(calendarDict, codes);
+		return SqlHelper.retBool(result);
+	}
+	
+	@Override
+	public boolean batchCreateCalendarDict(List<WorkCalendarDict> calendarDicts) {
+		Integer result = this.baseMapper.batchCreateCalendarDict(calendarDicts);
+		return SqlHelper.retBool(result);
+	}
+
+}

+ 29 - 0
src/main/java/com/persagy/calendar/service/impl/WorkCalendarLabelServiceImpl.java

@@ -0,0 +1,29 @@
+package com.persagy.calendar.service.impl;
+
+import java.util.List;
+
+import org.springframework.stereotype.Service;
+
+import com.baomidou.mybatisplus.extension.toolkit.SqlHelper;
+import com.persagy.calendar.mapper.WorkCalendarLabelMapper;
+import com.persagy.calendar.pojo.dto.WorkCalendarLabel;
+import com.persagy.calendar.service.IWorkCalendarLabelService;
+import com.persagy.db.service.impl.SuperServiceImpl;
+
+/**
+ * @version 
+ * @description 
+ * @company persagy
+ * @author zhangqiankun
+ * @since 2021年3月3日:	下午5:45:25
+ */
+@Service
+public class WorkCalendarLabelServiceImpl extends SuperServiceImpl<WorkCalendarLabelMapper, WorkCalendarLabel> implements IWorkCalendarLabelService {
+
+	@Override
+	public boolean batchCreateCalendarLabel(List<WorkCalendarLabel> calendarLabels) {
+		Integer result = this.baseMapper.batchCreateCalendarLabel(calendarLabels);
+		return SqlHelper.retBool(result);
+	}
+
+}

+ 34 - 0
src/main/java/com/persagy/calendar/service/impl/WorkCalendarObjectServiceImpl.java

@@ -0,0 +1,34 @@
+package com.persagy.calendar.service.impl;
+
+import java.util.Set;
+
+import org.springframework.stereotype.Service;
+
+import com.baomidou.mybatisplus.extension.toolkit.SqlHelper;
+import com.persagy.calendar.mapper.WorkCalendarObjectMapper;
+import com.persagy.calendar.pojo.dto.WorkCalendarObject;
+import com.persagy.calendar.service.IWorkCalendarObjectService;
+import com.persagy.db.service.impl.SuperServiceImpl;
+
+/**
+ * @version 
+ * @description 
+ * @company persagy
+ * @author zhangqiankun
+ * @since 2021年3月2日:	下午5:02:35
+ */
+@Service
+public class WorkCalendarObjectServiceImpl extends SuperServiceImpl<WorkCalendarObjectMapper, WorkCalendarObject> implements IWorkCalendarObjectService {
+
+	@Override
+	public void batchInsertObjects(WorkCalendarObject object, Set<String> objIds) {
+		this.baseMapper.batchInsertObjects(object, objIds);
+	}
+
+	@Override
+	public boolean replaceCalendarObject(WorkCalendarObject calendarObject, Set<String> objIds) {
+		Integer result = this.baseMapper.replaceCalendarObject(calendarObject, objIds);
+		return SqlHelper.retBool(result);
+	}
+
+}

+ 134 - 0
src/main/java/com/persagy/calendar/service/impl/WorkCalendarRuleServiceImpl.java

@@ -0,0 +1,134 @@
+package com.persagy.calendar.service.impl;
+
+import java.util.List;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
+import com.baomidou.mybatisplus.extension.toolkit.SqlHelper;
+import com.persagy.calendar.constant.WorkCalendarConstant;
+import com.persagy.calendar.mapper.WorkCalendarRuleMapper;
+import com.persagy.calendar.pojo.dto.WorkCalendarRule;
+import com.persagy.calendar.pojo.dto.WorkCalendarRule.Builder;
+import com.persagy.calendar.service.IWorkCalendarRuleService;
+import com.persagy.common.utils.StringUtil;
+import com.persagy.db.service.impl.SuperServiceImpl;
+
+import cn.hutool.core.collection.CollectionUtil;
+
+/**
+ * 工作历规则表
+ * 
+ * @version 1.0.0
+ * @company persagy 
+ * @author zhangqiankun
+ * @date 2020-10-02 18:26:14
+ */
+@Service
+public class WorkCalendarRuleServiceImpl extends SuperServiceImpl<WorkCalendarRuleMapper, WorkCalendarRule> implements IWorkCalendarRuleService {
+	
+	@Autowired
+	private WorkCalendarRuleMapper workCalendarRuleMapper;
+ 	
+	@Override
+	public List<WorkCalendarRule> queryRuleByCalendarId(String calendarId, String projectId) {
+    	QueryWrapper<WorkCalendarRule> queryWrapper = new WorkCalendarRule.Builder().createQueryWrapper()
+    			.calendarIdEq(calendarId).projectIdEq(projectId)
+    			.delFlagEq(WorkCalendarConstant.WORK_CALENDAR_DEL_FLAG_NOR).builderQueryWrapper();
+		return workCalendarRuleMapper.selectList(queryWrapper);
+	}
+	
+	@Override
+	public String getCalendarRule(WorkCalendarRule workCalendarRule) {
+		QueryWrapper<WorkCalendarRule> queryWrapper = new WorkCalendarRule.Builder().createQueryWrapper()
+    			.projectIdEq(workCalendarRule.getProjectId()).dictTypeEq(workCalendarRule.getDictType())
+    			.dictCodeEq(workCalendarRule.getDictCode()).delFlagEq(WorkCalendarConstant.WORK_CALENDAR_DEL_FLAG_NOR)
+    			.builderQueryWrapper();
+		List<WorkCalendarRule> selectList = workCalendarRuleMapper.selectList(queryWrapper);
+		if (CollectionUtil.isEmpty(selectList)) {
+			return null;
+		}
+		for (WorkCalendarRule rule : selectList) {
+			if (workCalendarRule.getValue().equals(rule.getValue())) {
+				return rule.getId();
+			}
+		}
+		return null;
+	}
+	
+	@Override
+	public WorkCalendarRule getById(String id, String projectId) {
+    	QueryWrapper<WorkCalendarRule> queryWrapper = new WorkCalendarRule.Builder().createQueryWrapper()
+    			.idEq(id).projectIdEq(projectId)
+    			.delFlagEq(WorkCalendarConstant.WORK_CALENDAR_DEL_FLAG_NOR).builderQueryWrapper();
+		return workCalendarRuleMapper.selectOne(queryWrapper);
+	}
+	
+	@Override
+	@Transactional
+	public boolean createWorkCalendarRule(WorkCalendarRule workCalendarRule) {
+		Integer result = workCalendarRuleMapper.insert(workCalendarRule);
+		return SqlHelper.retBool(result);
+	}
+	
+	@Override
+	@Transactional
+	public boolean updateWorkCalendarRule(WorkCalendarRule workCalendarRule) {
+		Integer result = workCalendarRuleMapper.updateById(workCalendarRule);
+		return SqlHelper.retBool(result);
+	}
+	
+	@Override
+	@Transactional
+	public boolean deleteWorkCalendarRule(WorkCalendarRule workCalendarRule) {
+		workCalendarRule.setDelFlag(WorkCalendarConstant.WORK_CALENDAR_DEL_FLAG_DEL);
+		Integer result = null;
+		if (StringUtil.isNotBlank(workCalendarRule.getId())) {
+			result = workCalendarRuleMapper.updateById(workCalendarRule);
+		} else {
+			Builder builder = new WorkCalendarRule.Builder().createUpdateWrapper();
+	    	UpdateWrapper<WorkCalendarRule> updateWrapper = builder
+	    			.calendarIdEq(workCalendarRule.getCalendarId())
+	    			.delFlagEq(WorkCalendarConstant.WORK_CALENDAR_DEL_FLAG_NOR).builderUpdateWrapper();
+			result = workCalendarRuleMapper.update(workCalendarRule, updateWrapper);
+		}
+		return SqlHelper.retBool(result);
+	}
+	
+	@Override
+	@Transactional
+	public boolean removeWorkCalendarRule(String id, String calendarId, String dictType) {
+		Integer result = null;
+		UpdateWrapper<WorkCalendarRule> updateWrapper = null;
+		Builder builder = new WorkCalendarRule.Builder().createUpdateWrapper();
+		if (StringUtil.isNotBlank(id)) {
+			updateWrapper = builder.idEq(id).delFlagEq(WorkCalendarConstant.WORK_CALENDAR_DEL_FLAG_NOR)
+					.builderUpdateWrapper();
+			result = workCalendarRuleMapper.delete(updateWrapper);
+		} else {
+	    	updateWrapper = builder.calendarIdEq(calendarId).dictTypeEq(dictType)
+	    			.delFlagEq(WorkCalendarConstant.WORK_CALENDAR_DEL_FLAG_NOR).builderUpdateWrapper();
+			result = workCalendarRuleMapper.delete(updateWrapper);
+		}
+		return SqlHelper.retBool(result);
+	}
+
+	@Override
+	public boolean checkDictRuleValid(String projectId, String calendarId, String dictType, String dictCode, String id) {
+		QueryWrapper<WorkCalendarRule> queryWrapper = new WorkCalendarRule.Builder().createQueryWrapper()
+    			.projectIdEq(projectId).calendarIdEq(calendarId).dictTypeEq(dictType).dictCodeEq(dictCode)
+    			.delFlagEq(WorkCalendarConstant.WORK_CALENDAR_DEL_FLAG_NOR).builderQueryWrapper();
+		WorkCalendarRule calendarRule = this.workCalendarRuleMapper.selectOne(queryWrapper);
+		if (calendarRule == null) {
+			return true;
+		}
+		if (StringUtil.isNotBlank(id) && id.equals(calendarRule.getId())) {
+			return true;
+		}
+		return false;
+	}
+
+}

+ 129 - 0
src/main/java/com/persagy/calendar/service/impl/WorkCalendarServiceImpl.java

@@ -0,0 +1,129 @@
+package com.persagy.calendar.service.impl;
+
+import java.util.List;
+import java.util.Set;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
+import com.baomidou.mybatisplus.extension.toolkit.SqlHelper;
+import com.persagy.calendar.constant.WorkCalendarConstant;
+import com.persagy.calendar.mapper.WorkCalendarDateMapper;
+import com.persagy.calendar.mapper.WorkCalendarMapper;
+import com.persagy.calendar.mapper.WorkCalendarObjectMapper;
+import com.persagy.calendar.pojo.dto.WorkCalendar;
+import com.persagy.calendar.pojo.dto.WorkCalendar.Builder;
+import com.persagy.calendar.pojo.dto.WorkCalendarDate;
+import com.persagy.calendar.pojo.dto.WorkCalendarObject;
+import com.persagy.calendar.service.IWorkCalendarService;
+import com.persagy.common.utils.StringUtil;
+import com.persagy.db.service.impl.SuperServiceImpl;
+
+import cn.hutool.core.collection.CollectionUtil;
+
+/**
+ * 工作历主表
+ * 
+ * @version 1.0.0
+ * @company persagy 
+ * @author zhangqiankun
+ * @date 2020-10-02 11:33:00
+ */
+@Service
+public class WorkCalendarServiceImpl extends SuperServiceImpl<WorkCalendarMapper, WorkCalendar> implements IWorkCalendarService {
+	
+	@Autowired
+	private WorkCalendarMapper workCalendarMapper;
+	
+	@Autowired
+	private WorkCalendarDateMapper workCalendarDateMapper;
+	
+	@Autowired
+	private WorkCalendarObjectMapper workCalendarObjectMapper;
+	
+	@Override
+	public List<WorkCalendar> queryCalendarObjectList(WorkCalendar calendar) {
+		return this.workCalendarMapper.queryCalendarObjectList(calendar);
+	}
+	
+	@Override
+	public WorkCalendar getById(String id, String projectId) {
+		Builder builder = new WorkCalendar.Builder().createQueryWrapper();
+    	QueryWrapper<WorkCalendar> queryWrapper = builder.idEq(id).projectIdEq(projectId)
+    			.delFlagEq(WorkCalendarConstant.WORK_CALENDAR_DEL_FLAG_NOR).builderQueryWrapper();
+		return workCalendarMapper.selectOne(queryWrapper);
+	}
+	
+	@Override
+	public boolean checkProjetcIdAndName(String id, String projectId, String groupCode, String calendarName) {
+		Builder builder = new WorkCalendar.Builder().createQueryWrapper();
+		QueryWrapper<WorkCalendar> queryWrapper = builder.groupCodeEq(groupCode)
+				.projectIdEq(projectId).calendarNameEq(calendarName)
+				.delFlagEq(WorkCalendarConstant.WORK_CALENDAR_DEL_FLAG_NOR)
+				.builderQueryWrapper();
+		WorkCalendar workCalendar = workCalendarMapper.selectOne(queryWrapper);
+		// 数据不存在允许,允许被插入或更新
+		if (workCalendar == null) {
+			return true;
+		}
+		
+		// 数据存在,且是更新情况时
+		if (StringUtil.isNotBlank(id) && workCalendar != null) {
+			if (id.equals(workCalendar.getId())) {
+				return true;
+			}
+		}
+		return false;
+	}
+	
+	@Override
+	@Transactional
+	public boolean createWorkCalendar(WorkCalendar workCalendar, Set<String> objIds) {
+		Integer result = workCalendarMapper.insert(workCalendar);
+		boolean retBool = SqlHelper.retBool(result);
+		if (retBool && CollectionUtil.isNotEmpty(objIds)) {
+			// 插入对象与工作历的关联表中
+			WorkCalendarObject object = new WorkCalendarObject();
+			object.setGroupCode(workCalendar.getGroupCode());
+			object.setCalendarId(workCalendar.getId());
+			object.setCreateTime(workCalendar.getCreateTime());
+			object.setUpdateUser(workCalendar.getUpdateUser());
+			object.setProjectId(workCalendar.getProjectId());
+			this.workCalendarObjectMapper.batchInsertObjects(object, objIds);
+		}
+		return retBool;
+	}
+	
+	@Override
+	@Transactional
+	public boolean updateWorkCalendar(WorkCalendar workCalendar) {
+		Integer result = workCalendarMapper.updateById(workCalendar);
+		boolean retBool = SqlHelper.retBool(result);
+		if (retBool) {
+			// 修改date表中的name和desc属性
+			WorkCalendarDate calendarDate = new WorkCalendarDate();
+			calendarDate.setCalendarName(workCalendar.getCalendarName());
+			calendarDate.setCalendarDesc(workCalendar.getCalendarDesc());
+			calendarDate.setUpdateTime(workCalendar.getUpdateTime());
+			UpdateWrapper<WorkCalendarDate> updateWrapper = new WorkCalendarDate.Builder().createUpdateWrapper()
+					.calendarIdEq(workCalendar.getId()).projectIdEq(workCalendar.getProjectId()).builderUpdateWrapper();
+			this.workCalendarDateMapper.update(calendarDate, updateWrapper);
+		}
+		return SqlHelper.retBool(result);
+	}
+	
+	@Override
+	@Transactional
+	public boolean deleteWorkCalendar(String id, String updateUser) {
+		WorkCalendar workCalendar = new WorkCalendar();
+		workCalendar.setId(id);
+		workCalendar.setUpdateUser(updateUser);
+		workCalendar.setDelFlag(WorkCalendarConstant.WORK_CALENDAR_DEL_FLAG_DEL);
+		Integer result = workCalendarMapper.updateById(workCalendar);
+		return SqlHelper.retBool(result);
+	}
+
+}

+ 42 - 0
src/main/java/com/persagy/calendar/utils/ApplicationContextUtil.java

@@ -0,0 +1,42 @@
+package com.persagy.calendar.utils;
+
+import org.springframework.beans.BeansException;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.stereotype.Component;
+
+/**
+ * @version 
+ * @description 
+ * @company persagy
+ * @author zhangqiankun
+ * @since 2020年8月24日:	上午10:57:25
+ */
+
+@Component
+public class ApplicationContextUtil implements ApplicationContextAware {
+
+	private static ApplicationContext applicationContext;
+	
+	@Override
+	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
+		ApplicationContextUtil.applicationContext = applicationContext;
+	}
+
+	public static ApplicationContext getApplicationContext(){
+		return applicationContext;
+	}
+	
+	public static Object getBean(String beanName){
+		return applicationContext.getBean(beanName);
+	}
+	
+	public static <T> T getBean(Class<T> beanType){
+		return applicationContext.getBean(beanType);
+	}
+	
+	public static <T> T getBean(String beanName, Class<T> beanType){
+		return applicationContext.getBean(beanName, beanType);
+	}
+
+}

+ 78 - 0
src/main/java/com/persagy/calendar/utils/NTPClientUtil.java

@@ -0,0 +1,78 @@
+package com.persagy.calendar.utils;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+import org.apache.commons.net.ntp.NTPUDPClient;
+import org.apache.commons.net.ntp.TimeInfo;
+import org.apache.commons.net.ntp.TimeStamp;
+
+import com.persagy.common.utils.DateUtil;
+
+/**
+ * @version
+ * @description
+ * @company persagy
+ * @author zhangqiankun
+ * @since 2020年9月7日: 下午3:32:07
+ */
+public class NTPClientUtil {
+
+	private static NTPUDPClient ntpudpClient = null;
+	private static InetAddress inetAddress = null;
+	private static List<String> hostList = new ArrayList<String>();
+	
+	static {
+		hostList.add("ntp1.aliyun.com");
+		hostList.add("ntp2.aliyun.com");
+		hostList.add("ntp3.aliyun.com");
+		hostList.add("ntp4.aliyun.com");
+		hostList.add("ntp5.aliyun.com");
+		hostList.add("ntp6.aliyun.com");
+		hostList.add("ntp7.aliyun.com");
+	}
+	
+	public static void main(String[] args) {
+		NTPClientUtil.initNTPClient("ntp1.aliyun.com", 5000);
+		String ntpServerTime = getNTPServerTime();
+		System.out.println(ntpServerTime);
+		stopNTPClient();
+	}
+	
+	public static synchronized String getNTPServerTime() {
+		for (String host : hostList) {
+			try {
+				initNTPClient(host, 5000);
+				
+				TimeInfo timeInfo = ntpudpClient.getTime(inetAddress);
+				TimeStamp timeStamp = timeInfo.getMessage().getTransmitTimeStamp();
+				Date date = timeStamp.getDate();
+				return DateUtil.format(date, DateUtil.FORMAT_DATE_YYYYMMDDHHMMSS);
+			} catch (Exception e) {
+				stopNTPClient();
+			}
+		}
+		return null;
+	}
+	
+	private static synchronized void initNTPClient(String host, int timeout) {
+		ntpudpClient = new NTPUDPClient();
+		// 设置连接超时时间
+		ntpudpClient.setDefaultTimeout(timeout);
+		try {
+			inetAddress = InetAddress.getByName(host);
+		} catch (UnknownHostException e) {
+			e.printStackTrace();
+		}
+	}
+
+	private static synchronized void stopNTPClient() {
+        if (null != ntpudpClient) {
+        	ntpudpClient.close();
+        }
+    }
+
+}

+ 65 - 0
src/main/java/com/persagy/calendar/utils/ResponseOldResult.java

@@ -0,0 +1,65 @@
+package com.persagy.calendar.utils;
+
+import java.io.Serializable;
+
+import com.alibaba.fastjson.annotation.JSONField;
+
+import lombok.Data;
+
+/**
+ * @description 
+ * @author zhangqiankun
+ * @since 2020年8月26日:	下午5:17:08
+ */
+@Data
+public class ResponseOldResult implements Serializable {
+	private static final long serialVersionUID = -5995466093934581697L;
+
+	@JSONField(name = "id")				// 响应ID
+	private String id;
+	
+	@JSONField(name = "Result")
+	private String result;				// 响应结果 success failure
+	
+	@JSONField(name = "ResultMsg")
+	private String respMsg;				// 响应描述
+
+	@JSONField(name = "Content")
+	private Object content; 			// 响应数据,实际可以是请求体,也可以是响应体,随意
+	
+	@JSONField(name = "Count")
+	private Integer count;				// 响应数据总记录数
+	
+	public ResponseOldResult() {
+		
+	}
+
+	public ResponseOldResult(String respMsg) {
+		super();
+		this.respMsg = respMsg;
+	}
+	
+	public ResponseOldResult(String result, String respMsg) {
+		super();
+		this.result = result;
+		this.respMsg = respMsg;
+	}
+
+	public ResponseOldResult(String result, String respMsg, Object content, Integer count) {
+		super();
+		this.result = result;
+		this.respMsg = respMsg;
+		this.content = content;
+		this.count = count;
+	}
+	
+	public ResponseOldResult(String id, String result, String respMsg, Object content, Integer count) {
+		super();
+		this.id = id;
+		this.result = result;
+		this.respMsg = respMsg;
+		this.content = content;
+		this.count = count;
+	}
+	
+}

+ 99 - 0
src/main/java/com/persagy/calendar/utils/ResponseOldResultUtil.java

@@ -0,0 +1,99 @@
+package com.persagy.calendar.utils;
+
+import com.alibaba.fastjson.JSONObject;
+
+/**
+ * @version 
+ * @description 
+ * @company persagy
+ * @author zhangqiankun
+ * @since 2020年9月1日:	下午2:21:25
+ */
+public class ResponseOldResultUtil {
+	
+	public static final String RESULT_SUCCESS = "success";
+	
+	public static final String RESULT_FAILURE = "failure";
+	
+	public static final String RESULT_EMPTY = "";
+	
+	public static ResponseOldResult successResult() {
+		ResponseOldResult result = new ResponseOldResult();
+		result.setResult(RESULT_SUCCESS);
+		result.setRespMsg(RESULT_EMPTY);
+		return result;
+	}
+	
+	/**
+	 * 此项目不建议再直接返回json数据,多一步转换,若为json数据,建议controller层直接返回string类型
+	 * @param jsonData Content数据,必须为json格式数据
+	 */
+	public static ResponseOldResult successResultContent(String jsonData) {
+		ResponseOldResult result = new ResponseOldResult();
+		result.setResult(RESULT_SUCCESS);
+		// 此处不转换,实际数据会被加上反斜杠
+		result.setContent(JSONObject.parseObject(jsonData));
+		return result;
+	}
+	
+	/**
+	 * @param data	Content数据,不允许为json格式数据,可以是普通string字符串
+	 */
+	public static ResponseOldResult successResultContent(Object data) {
+		ResponseOldResult result = new ResponseOldResult();
+		result.setResult(RESULT_SUCCESS);
+		result.setContent(data);
+		return result;
+	}
+	
+	public static ResponseOldResult successResultId(String id) {
+		ResponseOldResult result = new ResponseOldResult();
+		result.setResult(RESULT_SUCCESS);
+		result.setRespMsg(RESULT_EMPTY);
+		result.setId(id);
+		return result;
+	}
+	
+	public static ResponseOldResult successResultContent(Object data, Integer totalCount) {
+		ResponseOldResult result = new ResponseOldResult();
+		result.setResult(RESULT_SUCCESS);
+		result.setContent(data);
+		result.setCount(totalCount);
+		return result;
+	}
+
+	public static ResponseOldResult errorResultMsg(String respMsg) {
+		ResponseOldResult result = new ResponseOldResult();
+		result.setResult(RESULT_FAILURE);
+		result.setRespMsg(respMsg);
+		return result;
+	}
+
+	/**
+	 * 此项目不建议再直接返回json数据,多一步转换,若为json数据,建议controller层直接返回string类型
+	 * @param jsonData Content数据,必须为json格式数据
+	 */
+	public static ResponseOldResult errorResultMsg(String respCode, String respMsg, String jsonData) {
+		ResponseOldResult result = new ResponseOldResult();
+		result.setResult(RESULT_FAILURE);
+		result.setRespMsg(respMsg);
+		// 此处不转换,实际数据会被加上反斜杠
+		result.setContent(JSONObject.parseObject(jsonData));
+		return result;
+	}
+	
+	/**
+	 * @param respCode
+	 * @param respMsg
+	 * @param content Content数据,不允许为json格式数据,可以是普通string字符串
+	 * @return
+	 */
+	public static ResponseOldResult errorResultMsg(String respCode, String respMsg, Object content) {
+		ResponseOldResult result = new ResponseOldResult();
+		result.setResult(RESULT_FAILURE);
+		result.setRespMsg(respMsg);
+		result.setContent(content);
+		return result;
+	}
+
+}

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

@@ -0,0 +1,11 @@
+mybatis-plus: 
+  mapper-locations: classpath:/mapper/*.xml
+  typeAliasesPackage: com.persagy.calendar.pojo.dto
+      
+integrated: 
+  swagger: 
+    enabled: true
+    title: 工作历中心
+    description: 工作历中心接口文档
+    version: 1.0
+    base-package: com.persagy.calendar.controller

+ 0 - 0
src/main/resources/bootstrap.yml


Certains fichiers n'ont pas été affichés car il y a eu trop de fichiers modifiés dans ce diff