帝品仕外出和差旅同步

This commit is contained in:
Aria 2024-12-06 17:08:57 +08:00
parent 15d941b70f
commit 16f5cdb9e3
39 changed files with 1160 additions and 782 deletions

View File

@ -4,20 +4,43 @@
<option name="autoReloadType" value="SELECTIVE" /> <option name="autoReloadType" value="SELECTIVE" />
</component> </component>
<component name="ChangeListManager"> <component name="ChangeListManager">
<list default="true" id="10c8cb4d-8c7e-48ec-a4d5-cffb95288459" name="Changes" comment=""> <list default="true" id="10c8cb4d-8c7e-48ec-a4d5-cffb95288459" name="Changes" comment="帝品仕外出和差旅同步">
<change afterPath="$PROJECT_DIR$/.gitignore" afterDir="false" /> <change afterPath="$PROJECT_DIR$/fin-filing-admin/src/main/java/cn/jiutqy/finfiling/HelloController.java" afterDir="false" />
<change afterPath="$PROJECT_DIR$/.idea/misc.xml" afterDir="false" /> <change afterPath="$PROJECT_DIR$/fin-filing-admin/src/main/java/cn/jiutqy/finfiling/controller/VerifyWeChatController.java" afterDir="false" />
<change afterPath="$PROJECT_DIR$/.idea/vcs.xml" afterDir="false" /> <change afterPath="$PROJECT_DIR$/fin-filing-admin/src/main/java/cn/jiutqy/finfiling/dto/ReceiveMessage.java" afterDir="false" />
<change afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" /> <change afterPath="$PROJECT_DIR$/fin-filing-common/src/main/java/cn/jiutqy/finfiling/dipinshi/AbstractDiPinShiBaseService.java" afterDir="false" />
<change afterPath="$PROJECT_DIR$/fin-filing-quartz/src/main/java/cn/jiutqy/finfiling/quartz/dipinshi/DiPinShiAccessTokenService.java" afterDir="false" /> <change afterPath="$PROJECT_DIR$/fin-filing-common/src/main/java/cn/jiutqy/finfiling/dipinshi/constants/BusinessTypeEnum.java" afterDir="false" />
<change afterPath="$PROJECT_DIR$/fin-filing-quartz/src/main/java/cn/jiutqy/finfiling/quartz/dipinshi/DiPinShiFinFilingService.java" afterDir="false" /> <change afterPath="$PROJECT_DIR$/fin-filing-quartz/src/main/java/cn/jiutqy/finfiling/quartz/dipinshi/DiPinShiGoOutMapping.java" afterDir="false" />
<change afterPath="$PROJECT_DIR$/fin-filing-quartz/src/main/java/cn/jiutqy/finfiling/quartz/dipinshi/IDiPinShiFinFilingService.java" afterDir="false" /> <change afterPath="$PROJECT_DIR$/fin-filing-quartz/src/main/java/cn/jiutqy/finfiling/quartz/dipinshi/DiPinShiMapping.java" afterDir="false" />
<change afterPath="$PROJECT_DIR$/fin-filing-quartz/src/main/java/cn/jiutqy/finfiling/quartz/dipinshi/attendance/DiPinShiAttendanceService.java" afterDir="false" /> <change afterPath="$PROJECT_DIR$/fin-filing-quartz/src/main/java/cn/jiutqy/finfiling/quartz/dipinshi/DiPinShiTravelInMapping.java" afterDir="false" />
<change afterPath="$PROJECT_DIR$/fin-filing-quartz/src/main/java/cn/jiutqy/finfiling/quartz/dipinshi/attendance/IDiPinShiAttendanceService.java" afterDir="false" /> <change afterPath="$PROJECT_DIR$/fin-filing-quartz/src/main/java/cn/jiutqy/finfiling/quartz/dipinshi/DiPinShiTravelNoUSAMapping.java" afterDir="false" />
<change afterPath="$PROJECT_DIR$/fin-filing-quartz/src/main/java/cn/jiutqy/finfiling/quartz/dipinshi/attendance/vo/DiPinShiAttendanceReqVO.java" afterDir="false" /> <change afterPath="$PROJECT_DIR$/fin-filing-quartz/src/main/java/cn/jiutqy/finfiling/quartz/dipinshi/DiPinShiTravelOutMapping.java" afterDir="false" />
<change afterPath="$PROJECT_DIR$/fin-filing-quartz/src/main/java/cn/jiutqy/finfiling/quartz/dipinshi/attendance/vo/DiPinShiAttendanceRespVO.java" afterDir="false" /> <change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
<change afterPath="$PROJECT_DIR$/fin-filing-quartz/src/main/java/cn/jiutqy/finfiling/quartz/dipinshi/dto/DiPinShiAccessToken.java" afterDir="false" /> <change beforePath="$PROJECT_DIR$/fin-filing-admin/src/main/resources/application-dev.yml" beforeDir="false" afterPath="$PROJECT_DIR$/fin-filing-admin/src/main/resources/application-dev.yml" afterDir="false" />
<change afterPath="$PROJECT_DIR$/pom.xml" afterDir="false" /> <change beforePath="$PROJECT_DIR$/fin-filing-admin/src/test/java/cn/jiutqy/finfiling/TestEmailSend.java" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/fin-filing-admin/src/test/java/cn/jiutqy/finfiling/TestHuiLianYiFinFilingService.java" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/fin-filing-admin/src/test/java/cn/jiutqy/finfiling/TestU9CFinFilingService.java" beforeDir="false" afterPath="$PROJECT_DIR$/fin-filing-admin/src/test/java/cn/jiutqy/finfiling/TestU9CFinFilingService.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/fin-filing-common/src/main/java/cn/jiutqy/finfiling/common/config/properties/FinFilingMappingFormRelationProperties.java" beforeDir="false" afterPath="$PROJECT_DIR$/fin-filing-common/src/main/java/cn/jiutqy/finfiling/common/config/properties/FinFilingMappingFormRelationProperties.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/fin-filing-common/src/main/java/cn/jiutqy/finfiling/common/enums/FormEnum.java" beforeDir="false" afterPath="$PROJECT_DIR$/fin-filing-common/src/main/java/cn/jiutqy/finfiling/common/enums/FormEnum.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/fin-filing-common/src/main/java/cn/jiutqy/finfiling/common/service/AbstractFinFilingService.java" beforeDir="false" afterPath="$PROJECT_DIR$/fin-filing-common/src/main/java/cn/jiutqy/finfiling/common/service/AbstractFinFilingService.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/fin-filing-common/src/main/java/cn/jiutqy/finfiling/common/service/DefaultFormAtFinFilingService.java" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/fin-filing-common/src/main/java/cn/jiutqy/finfiling/common/service/DefaultFormFinFilingService.java" beforeDir="false" afterPath="$PROJECT_DIR$/fin-filing-common/src/main/java/cn/jiutqy/finfiling/common/service/DefaultFormFinFilingService.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/fin-filing-common/src/main/java/cn/jiutqy/finfiling/common/service/IFinFilingMapping.java" beforeDir="false" afterPath="$PROJECT_DIR$/fin-filing-common/src/main/java/cn/jiutqy/finfiling/common/service/IFinFilingMapping.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/fin-filing-quartz/src/main/java/cn/jiutqy/finfiling/quartz/dipinshi/DiPinShiAccessTokenService.java" beforeDir="false" afterPath="$PROJECT_DIR$/fin-filing-quartz/src/main/java/cn/jiutqy/finfiling/quartz/dipinshi/DiPinShiAccessTokenService.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/fin-filing-quartz/src/main/java/cn/jiutqy/finfiling/quartz/dipinshi/DiPinShiFinFilingService.java" beforeDir="false" afterPath="$PROJECT_DIR$/fin-filing-common/src/main/java/cn/jiutqy/finfiling/dipinshi/DiPinShiFinFilingService.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/fin-filing-quartz/src/main/java/cn/jiutqy/finfiling/quartz/dipinshi/IDiPinShiFinFilingService.java" beforeDir="false" afterPath="$PROJECT_DIR$/fin-filing-common/src/main/java/cn/jiutqy/finfiling/dipinshi/IDiPinShiFinFilingService.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/fin-filing-quartz/src/main/java/cn/jiutqy/finfiling/quartz/dipinshi/attendance/vo/req/DiPinShiAttendanceGoOutReqVO.java" beforeDir="false" afterPath="$PROJECT_DIR$/fin-filing-common/src/main/java/cn/jiutqy/finfiling/dipinshi/vo/req/DiPinShiAttendanceGoOutReqVO.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/fin-filing-quartz/src/main/java/cn/jiutqy/finfiling/quartz/dipinshi/attendance/vo/req/DiPinShiAttendanceReqVO.java" beforeDir="false" afterPath="$PROJECT_DIR$/fin-filing-common/src/main/java/cn/jiutqy/finfiling/dipinshi/vo/req/DiPinShiAttendanceReqVO.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/fin-filing-quartz/src/main/java/cn/jiutqy/finfiling/quartz/dipinshi/attendance/vo/req/DiPinShiAttendanceTravelInReqVO.java" beforeDir="false" afterPath="$PROJECT_DIR$/fin-filing-common/src/main/java/cn/jiutqy/finfiling/dipinshi/vo/req/DiPinShiAttendanceTravelInReqVO.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/fin-filing-quartz/src/main/java/cn/jiutqy/finfiling/quartz/dipinshi/attendance/vo/req/DiPinShiAttendanceTravelOutNotUSAReqVO.java" beforeDir="false" afterPath="$PROJECT_DIR$/fin-filing-common/src/main/java/cn/jiutqy/finfiling/dipinshi/vo/req/DiPinShiAttendanceTravelOutNotUSAReqVO.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/fin-filing-quartz/src/main/java/cn/jiutqy/finfiling/quartz/dipinshi/attendance/vo/req/DiPinShiAttendanceTravelOutReqVO.java" beforeDir="false" afterPath="$PROJECT_DIR$/fin-filing-common/src/main/java/cn/jiutqy/finfiling/dipinshi/vo/req/DiPinShiAttendanceTravelOutReqVO.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/fin-filing-quartz/src/main/java/cn/jiutqy/finfiling/quartz/dipinshi/attendance/vo/resp/DiPinShiAttendanceRespVO.java" beforeDir="false" afterPath="$PROJECT_DIR$/fin-filing-common/src/main/java/cn/jiutqy/finfiling/dipinshi/vo/resp/DiPinShiAttendanceRespVO.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/fin-filing-quartz/src/main/java/cn/jiutqy/finfiling/quartz/enums/GeYuanOutboundTypeEnum.java" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/fin-filing-quartz/src/main/java/cn/jiutqy/finfiling/quartz/enums/U9cMappingHoseEntityIdEnum.java" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/fin-filing-quartz/src/main/java/cn/jiutqy/finfiling/quartz/sync/IOutboundSyncDiPinShiService.java" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/fin-filing-quartz/src/main/java/cn/jiutqy/finfiling/quartz/sync/OutboundSyncDiPinShiService.java" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/fin-filing-quartz/src/main/java/cn/jiutqy/finfiling/quartz/task/DiPinShiSyncDataTask.java" beforeDir="false" afterPath="$PROJECT_DIR$/fin-filing-quartz/src/main/java/cn/jiutqy/finfiling/quartz/task/DiPinShiSyncDataTask.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/pom.xml" beforeDir="false" afterPath="$PROJECT_DIR$/pom.xml" afterDir="false" />
</list> </list>
<option name="SHOW_DIALOG" value="false" /> <option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" /> <option name="HIGHLIGHT_CONFLICTS" value="true" />
@ -27,8 +50,9 @@
<component name="FileTemplateManagerImpl"> <component name="FileTemplateManagerImpl">
<option name="RECENT_TEMPLATES"> <option name="RECENT_TEMPLATES">
<list> <list>
<option value="Class" />
<option value="Interface" /> <option value="Interface" />
<option value="Enum" />
<option value="Class" />
</list> </list>
</option> </option>
</component> </component>
@ -44,27 +68,79 @@
</option> </option>
</component> </component>
<component name="ProjectId" id="2p37Aad3GONiU3QEtonY8ISsKbo" /> <component name="ProjectId" id="2p37Aad3GONiU3QEtonY8ISsKbo" />
<component name="ProjectLevelVcsManager" settingsEditedManually="true" /> <component name="ProjectLevelVcsManager" settingsEditedManually="true">
<ConfirmationsSetting value="2" id="Add" />
</component>
<component name="ProjectViewState"> <component name="ProjectViewState">
<option name="hideEmptyMiddlePackages" value="true" /> <option name="hideEmptyMiddlePackages" value="true" />
<option name="showLibraryContents" value="true" /> <option name="showLibraryContents" value="true" />
</component> </component>
<component name="PropertiesComponent"><![CDATA[{ <component name="PropertiesComponent">{
"keyToString": { &quot;keyToString&quot;: {
"RunOnceActivity.OpenProjectViewOnStart": "true", &quot;RequestMappingsPanelOrder0&quot;: &quot;0&quot;,
"RunOnceActivity.ShowReadmeOnStart": "true", &quot;RequestMappingsPanelOrder1&quot;: &quot;1&quot;,
"WebServerToolWindowFactoryState": "false", &quot;RequestMappingsPanelWidth0&quot;: &quot;75&quot;,
"last_opened_file_path": "D:/worksplace/dipinshi-hesi", &quot;RequestMappingsPanelWidth1&quot;: &quot;75&quot;,
"node.js.detected.package.eslint": "true", &quot;RunOnceActivity.OpenProjectViewOnStart&quot;: &quot;true&quot;,
"node.js.detected.package.tslint": "true", &quot;RunOnceActivity.ShowReadmeOnStart&quot;: &quot;true&quot;,
"node.js.selected.package.eslint": "(autodetect)", &quot;WebServerToolWindowFactoryState&quot;: &quot;false&quot;,
"node.js.selected.package.tslint": "(autodetect)", &quot;last_opened_file_path&quot;: &quot;D:/worksplace/dipinshi-hesi/fin-filing-common/src/main/java/cn/jiutqy/finfiling/dipinshi&quot;,
"nodejs_package_manager_path": "npm", &quot;node.js.detected.package.eslint&quot;: &quot;true&quot;,
"settings.editor.selected.configurable": "reference.projectsettings.compiler.javacompiler", &quot;node.js.detected.package.tslint&quot;: &quot;true&quot;,
"vue.rearranger.settings.migration": "true" &quot;node.js.selected.package.eslint&quot;: &quot;(autodetect)&quot;,
&quot;node.js.selected.package.tslint&quot;: &quot;(autodetect)&quot;,
&quot;nodejs_package_manager_path&quot;: &quot;npm&quot;,
&quot;settings.editor.selected.configurable&quot;: &quot;reference.projectsettings.compiler.javacompiler&quot;,
&quot;spring.configuration.checksum&quot;: &quot;b46d2d04d263a2ac42116bf89528daed&quot;,
&quot;vue.rearranger.settings.migration&quot;: &quot;true&quot;
} }
}]]></component> }</component>
<component name="RunManager"> <component name="RecentsManager">
<key name="CopyFile.RECENT_KEYS">
<recent name="D:\worksplace\dipinshi-hesi\fin-filing-common\src\main\java\cn\jiutqy\finfiling\dipinshi" />
<recent name="D:\worksplace\dipinshi-hesi\fin-filing-common\src\main\java\cn\jiutqy\finfiling\common\vo" />
</key>
<key name="CopyClassDialog.RECENTS_KEY">
<recent name="cn.jiutqy.finfiling.common.enums" />
<recent name="cn.jiutqy.finfiling.dipinshi" />
<recent name="cn.jiutqy.finfiling.common.vo.resp" />
<recent name="cn.jiutqy.finfiling" />
<recent name="cn.jiutqy.finfiling.quartz" />
</key>
</component>
<component name="RunManager" selected="JUnit.TestU9CFinFilingService.test">
<configuration name="TestU9CFinFilingService.test" type="JUnit" factoryName="JUnit" temporary="true" nameIsGenerated="true">
<module name="fin-filing-admin" />
<extension name="coverage">
<pattern>
<option name="PATTERN" value="cn.jiutqy.finfiling.*" />
<option name="ENABLED" value="true" />
</pattern>
</extension>
<option name="PACKAGE_NAME" value="cn.jiutqy.finfiling" />
<option name="MAIN_CLASS_NAME" value="cn.jiutqy.finfiling.TestU9CFinFilingService" />
<option name="METHOD_NAME" value="test" />
<option name="TEST_OBJECT" value="method" />
<method v="2">
<option name="Make" enabled="true" />
</method>
</configuration>
<configuration name="TestU9CFinFilingService.testSyncExpense2" type="JUnit" factoryName="JUnit" temporary="true" nameIsGenerated="true">
<module name="fin-filing-admin" />
<extension name="coverage">
<pattern>
<option name="PATTERN" value="cn.jiutqy.finfiling.*" />
<option name="ENABLED" value="true" />
</pattern>
</extension>
<option name="PACKAGE_NAME" value="cn.jiutqy.finfiling" />
<option name="MAIN_CLASS_NAME" value="cn.jiutqy.finfiling.TestU9CFinFilingService" />
<option name="METHOD_NAME" value="testSyncExpense2" />
<option name="TEST_OBJECT" value="method" />
<method v="2">
<option name="Make" enabled="true" />
</method>
</configuration>
<configuration name="AdminApplication" type="SpringBootApplicationConfigurationType" factoryName="Spring Boot" nameIsGenerated="true"> <configuration name="AdminApplication" type="SpringBootApplicationConfigurationType" factoryName="Spring Boot" nameIsGenerated="true">
<module name="fin-filing-admin" /> <module name="fin-filing-admin" />
<option name="SPRING_BOOT_MAIN_CLASS" value="cn.jiutqy.finfiling.AdminApplication" /> <option name="SPRING_BOOT_MAIN_CLASS" value="cn.jiutqy.finfiling.AdminApplication" />
@ -72,6 +148,12 @@
<option name="Make" enabled="true" /> <option name="Make" enabled="true" />
</method> </method>
</configuration> </configuration>
<recent_temporary>
<list>
<item itemvalue="JUnit.TestU9CFinFilingService.test" />
<item itemvalue="JUnit.TestU9CFinFilingService.testSyncExpense2" />
</list>
</recent_temporary>
</component> </component>
<component name="SpellCheckerSettings" RuntimeDictionaries="0" Folders="0" CustomDictionaries="0" DefaultDictionary="application-level" UseSingleDictionary="true" transferred="true" /> <component name="SpellCheckerSettings" RuntimeDictionaries="0" Folders="0" CustomDictionaries="0" DefaultDictionary="application-level" UseSingleDictionary="true" transferred="true" />
<component name="TaskManager"> <component name="TaskManager">
@ -83,7 +165,32 @@
<updated>1731982764438</updated> <updated>1731982764438</updated>
<workItem from="1731982765514" duration="3000" /> <workItem from="1731982765514" duration="3000" />
<workItem from="1731982886946" duration="6741000" /> <workItem from="1731982886946" duration="6741000" />
<workItem from="1731995008221" duration="56811000" />
<workItem from="1732496792136" duration="60272000" />
<workItem from="1733197864468" duration="596000" />
</task> </task>
<task id="LOCAL-00001" summary="init">
<created>1732084433359</created>
<option name="number" value="00001" />
<option name="presentableId" value="LOCAL-00001" />
<option name="project" value="LOCAL" />
<updated>1732084433359</updated>
</task>
<task id="LOCAL-00002" summary="init">
<created>1732085139319</created>
<option name="number" value="00002" />
<option name="presentableId" value="LOCAL-00002" />
<option name="project" value="LOCAL" />
<updated>1732085139319</updated>
</task>
<task id="LOCAL-00003" summary="帝品仕外出和差旅同步">
<created>1732527712083</created>
<option name="number" value="00003" />
<option name="presentableId" value="LOCAL-00003" />
<option name="project" value="LOCAL" />
<updated>1732527712083</updated>
</task>
<option name="localTasksCounter" value="4" />
<servers /> <servers />
</component> </component>
<component name="TypeScriptGeneratedFilesManager"> <component name="TypeScriptGeneratedFilesManager">
@ -100,4 +207,50 @@
</map> </map>
</option> </option>
</component> </component>
<component name="VcsManagerConfiguration">
<MESSAGE value="init" />
<MESSAGE value="帝品仕外出和差旅同步" />
<option name="LAST_COMMIT_MESSAGE" value="帝品仕外出和差旅同步" />
</component>
<component name="XDebuggerManager">
<breakpoint-manager>
<breakpoints>
<line-breakpoint enabled="true" type="java-line">
<url>file://$PROJECT_DIR$/fin-filing-quartz/src/main/java/cn/jiutqy/finfiling/quartz/hosecloud/organize/HoseCloudTemplateService.java</url>
<line>33</line>
<option name="timeStamp" value="1" />
</line-breakpoint>
<line-breakpoint enabled="true" type="java-line">
<url>file://$PROJECT_DIR$/fin-filing-common/src/main/java/cn/jiutqy/finfiling/common/service/AbstractFinFilingService.java</url>
<line>132</line>
<option name="timeStamp" value="2" />
</line-breakpoint>
<line-breakpoint enabled="true" type="java-line">
<url>file://$PROJECT_DIR$/fin-filing-common/src/main/java/cn/jiutqy/finfiling/common/service/AbstractFinFilingService.java</url>
<line>370</line>
<option name="timeStamp" value="3" />
</line-breakpoint>
<line-breakpoint enabled="true" type="java-line">
<url>file://$PROJECT_DIR$/fin-filing-common/src/main/java/cn/jiutqy/finfiling/common/service/AbstractFinFilingService.java</url>
<line>386</line>
<option name="timeStamp" value="4" />
</line-breakpoint>
<line-breakpoint enabled="true" type="java-line">
<url>file://$PROJECT_DIR$/fin-filing-common/src/main/java/cn/jiutqy/finfiling/common/service/DefaultFormFinFilingService.java</url>
<line>35</line>
<option name="timeStamp" value="5" />
</line-breakpoint>
<line-breakpoint enabled="true" type="java-line">
<url>file://$PROJECT_DIR$/fin-filing-common/src/main/java/cn/jiutqy/finfiling/common/service/AbstractFinFilingService.java</url>
<line>328</line>
<option name="timeStamp" value="6" />
</line-breakpoint>
<line-breakpoint enabled="true" type="java-line">
<url>file://$PROJECT_DIR$/fin-filing-common/src/main/java/cn/jiutqy/finfiling/dipinshi/DiPinShiFinFilingService.java</url>
<line>54</line>
<option name="timeStamp" value="10" />
</line-breakpoint>
</breakpoints>
</breakpoint-manager>
</component>
</project> </project>

View File

@ -0,0 +1,13 @@
package cn.jiutqy.finfiling;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
//@RestController
public class HelloController {
@GetMapping("/")
public String hello() {
return "Hello World";
}
}

View File

@ -0,0 +1,127 @@
package cn.jiutqy.finfiling.controller;
import cn.jiutqy.finfiling.dto.ReceiveMessage;
import org.apache.commons.codec.binary.Base64;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.Map;
import java.util.stream.Collectors;
@RestController
public class VerifyWeChatController {
@GetMapping("/hook")
public String handleWeChatVerify(@RequestParam Map<String, String> allParams) {
//通过参数msg_signature对请求进行校验
if (!verifySignature(allParams)) {
return "Invalid signature";
}
//解密echostr参数得到消息内容
String msg = decryptEchostr(allParams.get("echostr"));
if (msg == null) {
return "Failed to decrypt message";
}
// 在1秒内原样返回明文消息内容
return msg;
}
@PostMapping("/hook")
public ResponseEntity<String> receiveMessage(@RequestBody ReceiveMessage message,
@RequestParam("msg_signature") String msgSignature,
@RequestParam("timestamp") String timestamp,
@RequestParam("nonce") String nonce) throws NoSuchAlgorithmException {
/*String token = "";
// 按照字母字典排序并拼接字符串
String sortedStr = Arrays.asList("token", token, "timestamp", timestamp, "nonce", nonce)
.stream().sorted().collect(Collectors.joining(""));
// 使用SHA1计算签名
MessageDigest md = MessageDigest.getInstance("SHA-1");
byte[] digest = md.digest(sortedStr.getBytes(StandardCharsets.UTF_8));
StringBuilder hexStr = new StringBuilder();
for (byte b : digest) {
hexStr.append(String.format("%02x", b & 0xFF));
}*/
return new ResponseEntity<>("", HttpStatus.OK);
}
private boolean verifySignature(Map<String, String> params) {
String msgSignature = params.get("msg_signature");
String timestamp = params.get("timestamp");
String nonce = params.get("nonce");
String echostr = params.get("echostr");
String token = "";
try {
// 按照字母字典排序并拼接字符串
String sortedStr = Arrays.asList("token", token, "timestamp", timestamp, "nonce", nonce, "echostr", echostr)
.stream().sorted().collect(Collectors.joining(""));
// 使用SHA1计算签名
MessageDigest md = MessageDigest.getInstance("SHA-1");
byte[] digest = md.digest(sortedStr.getBytes(StandardCharsets.UTF_8));
StringBuilder hexStr = new StringBuilder();
for (byte b : digest) {
hexStr.append(String.format("%02x", b & 0xFF));
}
return hexStr.toString().equals(msgSignature);
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
private String decryptEchostr(String encryptedStr) {
try {
byte[] aesKey = "".getBytes(StandardCharsets.UTF_8);
SecretKeySpec keySpec = new SecretKeySpec(aesKey, "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
cipher.init(Cipher.DECRYPT_MODE, keySpec);
// Base64解码
byte[] aesMsg = Base64.decodeBase64(encryptedStr);
byte[] decrypted = cipher.doFinal(aesMsg);
// 去掉头部的随机字节和长度字节截取消息部分
int randomByteLength = 16;
int msgLenByteLength = 4;
// 跳过随机字节和长度字节
byte[] rawBytes = new byte[decrypted.length - randomByteLength - msgLenByteLength];
System.arraycopy(decrypted, randomByteLength + msgLenByteLength, rawBytes, 0, rawBytes.length);
// 提取msg
int msgLen = bytesToInt(Arrays.copyOfRange(rawBytes, 0, msgLenByteLength));
byte[] msgBytes = Arrays.copyOfRange(rawBytes, msgLenByteLength, msgLenByteLength + msgLen);
return new String(msgBytes, StandardCharsets.UTF_8);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
private int bytesToInt(byte[] bytes) {
return (bytes[0] & 0xFF) << 24 |
(bytes[1] & 0xFF) << 16 |
(bytes[2] & 0xFF) << 8 |
(bytes[3] & 0xFF);
}
}

View File

@ -0,0 +1,22 @@
package cn.jiutqy.finfiling.dto;
import lombok.Data;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement(name = "xml")
@XmlAccessorType(XmlAccessType.FIELD)
@Data
public class ReceiveMessage {
@XmlElement(name = "ToUserName")
private String toUserName;
@XmlElement(name = "AgentID")
private String agentId;
@XmlElement(name = "Encrypt")
private String encrypt;
}

View File

@ -17,7 +17,7 @@ jiutqy:
# 开发环境配置 # 开发环境配置
server: server:
# 服务器的HTTP端口默认为8080 # 服务器的HTTP端口默认为8080
port: 8080 port: 8081
servlet: servlet:
# 应用的访问路径 # 应用的访问路径
context-path: / context-path: /
@ -99,9 +99,56 @@ finfiling:
dipinshi: dipinshi:
host: https://qyapi.weixin.qq.com host: https://qyapi.weixin.qq.com
oauth: oauth:
reqUrl: https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid={corpid}}&corpsecret={corpsecret} reqUrl: https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid={corpid}&corpsecret={corpsecret}
appId: appId: ww501bfd45644052f2
appSecret: appSecret: nXt0bPsSF1frA3NPnKkvn9vic3VTuEWM1fu8J2tiSZk
forms:
goOut:
reqUrl: https://qyapi.weixin.qq.com/cgi-bin/oa/getapprovalinfo?access_token={accessToken}
reqMethod: POST
travel:
reqUrl: https://qyapi.weixin.qq.com/cgi-bin/oa/getapprovalinfo?access_token={accessToken}
reqMethod: POST
mapping:
relation:
#外出
- channelRelation:
inputChannelId: dipinshi
outputChannelId: hosecloud
formRelation:
inputFormId: goOut
inputGroupId: goOut
outputFormId: create
#国内出差
- channelRelation:
inputChannelId: dipinshi
outputChannelId: hosecloud
formRelation:
inputFormId: travel
inputGroupId: travelIn
outputFormId: create
#国外出差
- channelRelation:
inputChannelId: dipinshi
outputChannelId: hosecloud
formRelation:
inputFormId: travel
inputGroupId: travelOut
outputFormId: create
#国外出差 非美国
- channelRelation:
inputChannelId: dipinshi
outputChannelId: hosecloud
formRelation:
inputFormId: travel
inputGroupId: travelOutNoUSA
outputFormId: create
output: output:
channel: channel:
@ -109,7 +156,11 @@ finfiling:
host: https://app.ekuaibao.com host: https://app.ekuaibao.com
oauth: oauth:
reqUrl: https://app.ekuaibao.com/api/openapi/v1/auth/getAccessToken reqUrl: https://app.ekuaibao.com/api/openapi/v1/auth/getAccessToken
appId: 0ed9a207-c594-460c-9245-91dee9260a9c appId: 7f913942-01b9-49eb-a751-053062c01ab1
appSecret: fc559d05-bc67-4d34-9c15-e2953fe97bb8 appSecret: 98f95ef9-a586-4546-b1e6-66e811313544
forms:
create:
reqUrl: https://app.ekuaibao.com/api/openapi/v2.2/flow/data?accessToken={accessToken}
reqMethod: POST

View File

@ -1,25 +0,0 @@
package cn.jiutqy.finfiling;
import cn.jiutqy.archives.common.utils.email.EmailSendUtil;
import cn.jiutqy.finfiling.common.dto.FinFilingAccessToken;
import cn.jiutqy.finfiling.common.enums.ChannelEnum;
import com.alibaba.fastjson.JSONObject;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.TestPropertySource;
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
@TestPropertySource(properties = "server.port=8080")
public class TestEmailSend {
@Autowired
private EmailSendUtil emailSendUtil;
@Test
public void testEmailSend(){
emailSendUtil.sendEmail("pengzhihao@jiutqy.com", "测试邮件", "测试邮件内容");
System.out.println("发送结束");
}
}

View File

@ -1,101 +0,0 @@
package cn.jiutqy.finfiling;
import cn.jiutqy.finfiling.common.service.DefaultFormAtFinFilingService;
import cn.jiutqy.finfiling.common.service.DefaultFormFinFilingService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.TestPropertySource;
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
@TestPropertySource(properties = "server.port=8080")
public class TestHuiLianYiFinFilingService {
@Autowired
private DefaultFormFinFilingService defaultFormFinFilingService;
@Autowired
private DefaultFormAtFinFilingService defaultFormAtFinFilingService;
// 测试汇联易附件上传
@Test
public void testSyncAt(){
defaultFormAtFinFilingService.syncData("huilianyi","at");
}
//测试报销单
@Test
public void testSyncExpense(){
String startCursor = "2024-09-26 00:00:00";
String endCursor = "2024-09-26 23:59:59";
String channelId = "huilianyi";
String formId = "expenseReport";
defaultFormFinFilingService.syncData(startCursor, endCursor, channelId, formId);
}
//测试报销单
@Test
public void testSyncExpense2(){
String channelId = "huilianyi";
String formId = "expenseReport";
defaultFormFinFilingService.syncData(channelId, formId);
}
//测试出差申请单
@Test
public void testSyncTravelApplication(){
String startCursor = "2024-09-26 00:00:00";
String endCursor = "2024-09-26 23:59:59";
String channelId = "huilianyi";
String formId = "travelApplication";
defaultFormFinFilingService.syncData(startCursor, endCursor, channelId, formId);
}
@Test
public void testSyncTravelApplication2(){
String channelId = "huilianyi";
String formId = "travelApplication";
defaultFormFinFilingService.syncData(channelId, formId);
}
//测试招待单
@Test
public void testSyncReceptionApplication(){
String startCursor = "2024-09-26 00:00:00";
String endCursor = "2024-09-27 23:59:59";
String channelId = "huilianyi";
String formId = "receptionApplication";
defaultFormFinFilingService.syncData(startCursor, endCursor, channelId, formId);
}
//测试借款单
@Test
public void testLoanBill(){
String startCursor = "2024-09-25 00:00:00";
String endCursor = "2024-09-28 23:59:59";
String channelId = "huilianyi";
String formId = "loanBill";
defaultFormFinFilingService.syncData(startCursor, endCursor, channelId, formId);
}
//对公报销 + 对公借款
@Test
public void testForCorporateExpense(){
String startCursor = "2024-09-25 00:00:00";
String endCursor = "2024-09-29 23:59:59";
String channelId = "huilianyi";
String formId = "corExpenseReport";
defaultFormFinFilingService.syncData(startCursor, endCursor, channelId, formId);
}
@Test
public void testInvoice(){
String startCursor = "2024-09-25 00:00:00";
String endCursor = "2024-09-29 23:59:59";
String channelId = "huilianyi";
String formId = "invoice";
defaultFormFinFilingService.syncData(startCursor, endCursor, channelId, formId);
}
}

View File

@ -1,34 +1,29 @@
package cn.jiutqy.finfiling; package cn.jiutqy.finfiling;
import cn.jiutqy.finfiling.common.service.DefaultFormAtFinFilingService;
import cn.jiutqy.finfiling.common.service.DefaultFormFinFilingService; import cn.jiutqy.finfiling.common.service.DefaultFormFinFilingService;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.TestPropertySource; import org.springframework.test.context.TestPropertySource;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT) @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
@TestPropertySource(properties = "server.port=8080") @TestPropertySource(properties = "server.port=8080")
public class TestU9CFinFilingService { public class TestService {
@Autowired @Autowired
private DefaultFormFinFilingService defaultFormFinFilingService; private DefaultFormFinFilingService defaultFormFinFilingService;
@Autowired
private DefaultFormAtFinFilingService defaultFormAtFinFilingService;
// 测试U9C附件上传
@Test @Test
public void testSyncAt(){ public void test() throws ParseException {
defaultFormAtFinFilingService.syncData("u9c","at");
} defaultFormFinFilingService.syncData("2024-12-01 00:00:00","2024-12-02 23:59:59","dipinshi","goOut");
//测试报销单
@Test
public void testSyncExpense2(){
String channelId = "u9c";
String formId = "UFData9002021";
defaultFormFinFilingService.syncData(channelId, formId);
} }
} }

View File

@ -14,13 +14,20 @@ public class FinFilingChannelProperties {
private Integer pageNum = 1; private Integer pageNum = 1;
private Integer pageSize = 5; private Integer pageSize = 10;
/** /**
* 首次同步过去多长时间的数据格式为1d 1h 1min 1sec默认为1d * 首次同步过去多长时间的数据格式为1d 1h 1min 1sec默认为1d
*/ */
private String firstPassTime = "30d"; private String firstPassTime = "30d";
/**
* 缓冲时间
*/
private String bufferTime = "0d";
private Integer sleepMS = 100;
private String cursorFormat = DateUtils.YYYY_MM_DD_HH_MM_SS; private String cursorFormat = DateUtils.YYYY_MM_DD_HH_MM_SS;
private Map<String, String> reqHeader; private Map<String, String> reqHeader;
@ -29,6 +36,5 @@ public class FinFilingChannelProperties {
private Map<String, FinFilingFormProperties> forms; private Map<String, FinFilingFormProperties> forms;
private String key;
} }

View File

@ -9,8 +9,8 @@ public class FinFilingMappingFormRelationProperties {
private String inputFormId; private String inputFormId;
private String inputGroupId;
private String outputFormId; private String outputFormId;
private String outputAtFormId;
} }

View File

@ -8,25 +8,23 @@ import java.util.Map;
public enum FormEnum implements IFinFilingFormService { public enum FormEnum implements IFinFilingFormService {
UF_DATA_9002021("UFData9002021"),
UF_DATA_3012018("UFData3012018"), GO_OUT("goOut"),
UF_DATA_3022018("UFData3022018"),
UF_DATA_3112021("UFData3112021"), TRAVEL("tarvel")
UF_DATA_5012021("UFData5012021"),
UF_DATA_5022023("UFData5022023"),
UF_DATA_5032024("UFData5032024"),
UF_DATA_5042024("UFData5042024"),
UF_DATA_5052024("UFData5052024"),
; ;
private static final Map<String, FormEnum> FORM_ID_MAPPINGS = new HashMap<>(); private static final Map<String, FormEnum> FORMID_MAPPINGS = new HashMap<>();
static static
{ {
for (FormEnum formEnum : values()) for (FormEnum formEnum : values())
{ {
FORM_ID_MAPPINGS.put(formEnum.getFormId(), formEnum); FORMID_MAPPINGS.put(formEnum.getFormId(), formEnum);
} }
} }
@ -36,7 +34,7 @@ public enum FormEnum implements IFinFilingFormService {
FormEnum(String formId) { FormEnum(String formId) {
this.formId = formId; this.formId = formId;
this.channelService = ChannelEnum.U9C; this.channelService = ChannelEnum.DI_PIN_SHI;
} }
@ -52,6 +50,6 @@ public enum FormEnum implements IFinFilingFormService {
@Override @Override
public IFinFilingFormService resolveFormId(String formId) { public IFinFilingFormService resolveFormId(String formId) {
return (formId != null ? FORM_ID_MAPPINGS.get(formId) : null); return (formId != null ? FORMID_MAPPINGS.get(formId) : null);
} }
} }

View File

@ -4,9 +4,13 @@ import cn.jiutqy.archives.common.enums.HttpMethod;
import cn.jiutqy.archives.common.utils.DateUtils; import cn.jiutqy.archives.common.utils.DateUtils;
import cn.jiutqy.archives.common.utils.ExceptionUtil; import cn.jiutqy.archives.common.utils.ExceptionUtil;
import cn.jiutqy.archives.common.utils.http.OkHttpClientUtil; import cn.jiutqy.archives.common.utils.http.OkHttpClientUtil;
import cn.jiutqy.finfiling.common.enums.ChannelEnum;
import cn.jiutqy.finfiling.dipinshi.IDiPinShiFinFilingService;
import cn.jiutqy.finfiling.dipinshi.constants.BusinessTypeEnum;
import cn.jiutqy.finfiling.dipinshi.vo.req.*;
import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject; import com.alibaba.fastjson2.JSONObject;
import com.alibaba.fastjson2.JSONPath;
import com.github.pagehelper.PageInfo; import com.github.pagehelper.PageInfo;
import cn.jiutqy.finfiling.common.config.FinFilingConfig; import cn.jiutqy.finfiling.common.config.FinFilingConfig;
import cn.jiutqy.finfiling.common.config.properties.FinFilingChannelProperties; import cn.jiutqy.finfiling.common.config.properties.FinFilingChannelProperties;
@ -43,36 +47,27 @@ public abstract class AbstractFinFilingService implements IFinFilingService {
@Autowired @Autowired
private FinFilingConfig finFilingConfig; private FinFilingConfig finFilingConfig;
public AbstractFinFilingService(){} @Autowired
private IDiPinShiFinFilingService diPinShiFinFilingService;
public AbstractFinFilingService() {
}
@Override @Override
public void syncData(String channelId, String formId) { public void syncData(String channelId, String formId) {
FinFilingChannelProperties channelProperties = finFilingConfig.getInput().getChannel().get(channelId); FinFilingChannelProperties channelProperties = finFilingConfig.getInput().getChannel().get(channelId);
FinFilingFormProperties formProperties = channelProperties.getForms().get(formId);
Integer pageNum = formProperties.getPageNum(); //第一次是30天可修改之前30天前到现在往后都是从现在开始20分钟一次同步
if(null == pageNum){ Integer pageNum = channelProperties.getPageNum();
pageNum = channelProperties.getPageNum(); Integer pageSize = channelProperties.getPageSize();
}
Integer pageSize = formProperties.getPageSize(); String firstPassTime = channelProperties.getFirstPassTime();
if(null == pageSize){ String cursorFormat = channelProperties.getCursorFormat();
pageSize = channelProperties.getPageSize();
}
String firstPassTime = formProperties.getFirstPassTime();
if(null == firstPassTime){
firstPassTime = channelProperties.getFirstPassTime();
}
String cursorFormat = formProperties.getCursorFormat();
if(null == cursorFormat){
cursorFormat = channelProperties.getCursorFormat();
}
Date now = new Date(); Date now = new Date();
String endCursor = DateUtils.parseDateToStr(cursorFormat, now); //结束时间
String endCursor = DateUtils.parseDateToStr(cursorFormat, now);
//开始时间
String startCursor; String startCursor;
FinFilingSyncCursor finFilingSyncCursor = finFilingSyncCursorService.findByChannelIdAndFormId(channelId, formId); FinFilingSyncCursor finFilingSyncCursor = finFilingSyncCursorService.findByChannelIdAndFormId(channelId, formId);
if(null == finFilingSyncCursor){ if(null == finFilingSyncCursor){
@ -81,6 +76,7 @@ public abstract class AbstractFinFilingService implements IFinFilingService {
startCursor = DateUtils.parseDateToStr(cursorFormat, finFilingSyncCursor.getEndCursor()); startCursor = DateUtils.parseDateToStr(cursorFormat, finFilingSyncCursor.getEndCursor());
} }
log.info("[{}]-[{}]执行同步开始时间[{}]-结束时间[{}]", channelId, formId, startCursor, endCursor);
Integer totalCount = syncData(startCursor,endCursor,channelId, formId, pageNum, pageSize, 0); Integer totalCount = syncData(startCursor,endCursor,channelId, formId, pageNum, pageSize, 0);
finFilingSyncCursor = new FinFilingSyncCursor(); finFilingSyncCursor = new FinFilingSyncCursor();
@ -101,100 +97,122 @@ public abstract class AbstractFinFilingService implements IFinFilingService {
FinFilingFormProperties formProperties = channelProperties.getForms().get(formId); FinFilingFormProperties formProperties = channelProperties.getForms().get(formId);
Integer pageNum = formProperties.getPageNum(); Integer pageNum = formProperties.getPageNum();
if(null == pageNum){ if (null == pageNum) {
pageNum = channelProperties.getPageNum(); pageNum = channelProperties.getPageNum();
} }
Integer pageSize = formProperties.getPageSize(); Integer pageSize = formProperties.getPageSize();
if(null == pageSize){ if (null == pageSize) {
pageSize = channelProperties.getPageSize(); pageSize = channelProperties.getPageSize();
} }
syncData(startCursor,endCursor,channelId, formId, pageNum, pageSize, 0); syncData(startCursor, endCursor, channelId, formId, pageNum, pageSize, 0);
} }
private int syncData(String startCursor, String endCursor,String channelId, String formId,Integer pageNum,Integer pageSize,Integer totalCount) { private int syncData(String startCursor, String endCursor, String channelId, String formId, Integer pageNum, Integer pageSize, Integer totalCount) {
// 调用渠道客户系统的接口获取数据 // 调用渠道客户系统的接口获取数据
PageInfo<JSONObject> pageInfo = this.inputData(new FinFilingContext(startCursor, endCursor, channelId, formId,pageNum,pageSize),finFilingConfig); PageInfo<String> pageInfo = this.inputData(new FinFilingContext(startCursor, endCursor, channelId, formId, pageNum, pageSize), finFilingConfig);
totalCount = totalCount + pageInfo.getList().size(); totalCount = totalCount + pageInfo.getList().size();
// 对输入数据进行分组key为分组字段的值 List<String> approvalNos = pageInfo.getList();
Map<String, List<FinFilingData>> dataMap = this.groupByInputData(channelId, formId, pageInfo.getList());
List<DiPinShiAttendanceReqVO> documents = new ArrayList<>();
//根据单号查询详情 取出有效数据x
for (String approvalNo : approvalNos) {
String detail = diPinShiFinFilingService.getApprovalNoDetail(approvalNo);
//根据类型判断外出国内出差国际出差国际出差非美国
JSONObject jsonObjectDetail = JSONObject.parseObject(detail).getJSONObject("info");
//取出出差类型根据类型分别映射到不同VO --类型是外出和出差出差需要再进行一次分类
String type = jsonObjectDetail.getString("sp_name");
if (BusinessTypeEnum.TRAVEL_IN.getName().equals(type)) {
DiPinShiAttendanceTravelInReqVO travelIn = takeTravelInData(jsonObjectDetail);
documents.add(travelIn);
} else if (BusinessTypeEnum.TRAVEL_OUT.getName().equals(type)) {
DiPinShiAttendanceTravelOutReqVO travelOut = takeTravelOutData(jsonObjectDetail);
documents.add(travelOut);
} else if (BusinessTypeEnum.TRAVEL_OUT_NOT_USA.getName().equals(type)) {
DiPinShiAttendanceTravelOutNotUSAReqVO travelOutNotUSA = takeTravelOutNoSUAData(jsonObjectDetail);
documents.add(travelOutNotUSA);
} else if (BusinessTypeEnum.GO_OUT.getName().equals(type)) {
DiPinShiAttendanceGoOutReqVO goOut = takeGoOutData(jsonObjectDetail);
documents.add(goOut);
}
}
// 将获取到的数据进行转换 // 将获取到的数据进行转换
for (String groupId : dataMap.keySet()) { for (DiPinShiAttendanceReqVO document : documents) {
List<FinFilingData> dataList = dataMap.get(groupId); //groupId为goOut travelIn travelOut travelNoUSA
String groupId = document.getType();
// 根据分组后的字段获取mapping实现类 // 根据分组后的字段获取mapping实现类
IFinFilingMapping mappingService = getFinFilingMappingService(channelId, formId, groupId); IFinFilingMapping mappingService = getFinFilingMappingService(channelId, formId, groupId);
if(null == mappingService){ if (null == mappingService) {
log.error("映射实现类找不到请检查对应实现类是否配置或者重写afterPropertiesSet方法是否设置了正确的formId值channelId={},formId={}",channelId,groupId); log.error("映射实现类找不到请检查对应实现类是否配置或者重写afterPropertiesSet方法是否设置了正确的formId值channelId={},formId={}", channelId, groupId);
continue; continue;
} }
// 获取映射配置 // 获取映射配置
FinFilingMappingRelationProperties mappingRelationProperties = getMappingRelationProperties(channelId,formId, groupId); FinFilingMappingRelationProperties mappingRelationProperties = getMappingRelationProperties(channelId, formId, groupId);
if(null == mappingRelationProperties){ if (null == mappingRelationProperties) {
log.warn("mapping配置不正确当前渠道或表单未配置映射关系channelId={},formId={}",channelId,groupId); log.warn("mapping配置不正确当前渠道或表单未配置映射关系channelId={},formId={}", channelId, groupId);
continue; continue;
} }
// 初始化上下文对象 // 初始化上下文对象
FinFilingContext context = new FinFilingContext(startCursor,endCursor,mappingRelationProperties); FinFilingContext context = new FinFilingContext(startCursor, endCursor, mappingRelationProperties);
// 字段映射 // 字段映射
mappingService.mapping(dataList, context, mappingRelationProperties, finFilingConfig); FinFilingData sendData = mappingService.mapping(document, context, mappingRelationProperties, finFilingConfig);
if (sendData == null) {
continue;
}
// 调用渠道客户系统的接口推送数据 // 调用渠道客户系统的接口推送数据
for (FinFilingData data : dataList) {
if (data.getOutputData().isEmpty()){
continue;
}
FinFilingChannelProperties channelProperties = finFilingConfig.getOutput().getChannel().get(context.getOutputChannelId());
channelProperties.setChannelId(context.getOutputChannelId());
FinFilingFormProperties formProperties = channelProperties.getForms().get(context.getOutputFormId());
// 记录同步结果数据同步状态 FinFilingChannelProperties channelProperties = finFilingConfig.getOutput().getChannel().get(context.getOutputChannelId());
FinFilingSyncLog finFilingSyncLog = null; channelProperties.setChannelId(context.getOutputChannelId());
try { FinFilingFormProperties formProperties = channelProperties.getForms().get(context.getOutputFormId());
finFilingSyncLog = this.saveSyncLog(data,context);
} catch (Exception e) {
log.error("写入同步日志失败:{}",JSON.toJSONString(data));
continue;
}
try { // 记录同步结果数据同步状态
// 将转换之后的数据同步到合思 FinFilingSyncLog finFilingSyncLog = null;
this.outputData(data,context,finFilingConfig); try {
finFilingSyncLog.setInputDataId(data.getInputDataId()); finFilingSyncLog = this.saveSyncLog(sendData, context);
finFilingSyncLog.setSyncState(SyncStateEnum.SUCCESSED.value()); } catch (Exception e) {
finFilingSyncLog.setOutputDataId(data.getOutputDataId()); log.error("写入同步日志失败:{}", JSON.toJSONString(sendData));
log.info("输出成功:{}", JSON.toJSONString(finFilingSyncLog)); continue;
} catch (Exception e) { }
log.error("输出异常",e);
// 异常状态才记录输入JSON报文,异常信息
finFilingSyncLog.setSyncState(SyncStateEnum.FAILED.value());
finFilingSyncLog.setErrorMsg(ExceptionUtil.getExceptionMessage(e));
log.error("输出失败:{}", JSON.toJSONString(finFilingSyncLog));
}
try { try {
updateSyncLog(finFilingSyncLog,context); // 将转换之后的数据同步到合思
} catch (Exception e) { this.outputData(sendData, context, finFilingConfig);
log.error("修改同步日志失败",e); finFilingSyncLog.setSyncState(SyncStateEnum.SUCCESSED.value());
continue; finFilingSyncLog.setOutputDataId(sendData.getOutputDataId());
} log.info("输出成功:{}", JSON.toJSONString(finFilingSyncLog));
} catch (Exception e) {
log.error("输出异常", e);
// 异常状态才记录输入JSON报文,异常信息
finFilingSyncLog.setSyncState(SyncStateEnum.FAILED.value());
finFilingSyncLog.setErrorMsg(ExceptionUtil.getExceptionMessage(e));
log.error("输出失败:{}", JSON.toJSONString(finFilingSyncLog));
}
try { try {
Thread.sleep(formProperties.getSleepMS()); updateSyncLog(finFilingSyncLog, context);
} catch (InterruptedException e) { } catch (Exception e) {
log.error("等待异常", e); log.error("修改同步日志失败", e);
//continue; continue;
} }
try {
Thread.sleep(formProperties.getSleepMS());
} catch (InterruptedException e) {
log.error("等待异常", e);
//continue;
} }
} }
if (pageInfo.isHasNextPage()) { if (pageInfo.isHasNextPage()) {
syncData(startCursor, endCursor, channelId, formId, pageInfo.getNextPage(), pageSize, totalCount); syncData(startCursor, endCursor, channelId, formId, pageInfo.getNextPage(), pageSize, totalCount);
} }
@ -202,18 +220,66 @@ public abstract class AbstractFinFilingService implements IFinFilingService {
return totalCount; return totalCount;
} }
private IFinFilingMapping getFinFilingMappingService(String channelId, String formId, String groupId) { private DiPinShiAttendanceTravelInReqVO takeTravelInData(JSONObject jsonObjectDetail) {
FinFilingChannelProperties channelProperties = finFilingConfig.getInput().getChannel().get(channelId); DiPinShiAttendanceTravelInReqVO travelIn = new DiPinShiAttendanceTravelInReqVO();
FinFilingFormProperties formProperties = channelProperties.getForms().get(formId);
if (StringUtils.isNotBlank(formProperties.getGroupByField())) { return travelIn;
return FinFilingMappingFactory.getContainer(channelId, formId, groupId); }
}else{
return FinFilingMappingFactory.getContainer(channelId, formId); private DiPinShiAttendanceTravelOutReqVO takeTravelOutData(JSONObject jsonObjectDetail) {
DiPinShiAttendanceTravelOutReqVO travelOut = new DiPinShiAttendanceTravelOutReqVO();
return travelOut;
}
private DiPinShiAttendanceTravelOutNotUSAReqVO takeTravelOutNoSUAData(JSONObject jsonObjectDetail) {
DiPinShiAttendanceTravelOutNotUSAReqVO travelOutNotUSA = new DiPinShiAttendanceTravelOutNotUSAReqVO();
return travelOutNotUSA;
}
private DiPinShiAttendanceGoOutReqVO takeGoOutData(JSONObject jsonObjectDetail) {
DiPinShiAttendanceGoOutReqVO goOutReqVO = new DiPinShiAttendanceGoOutReqVO();
goOutReqVO.setData(jsonObjectDetail.toJSONString());
String userId = jsonObjectDetail.getJSONObject("applyer").getString("userid");
goOutReqVO.setApplicant(userId);
//TODO 根据userId查询手机号 或者邮箱也可以
goOutReqVO.setPhone("");
goOutReqVO.setApplicationType(jsonObjectDetail.getString("sp_name"));
goOutReqVO.setApprovalNo(jsonObjectDetail.getString("sp_no"));
JSONArray contents = jsonObjectDetail.getJSONObject("apply_data").getJSONArray("contents");
for (int i = 0; i < contents.size(); i++) {
JSONObject content = contents.getJSONObject(i);
if (content.getString("control").equals("Attendance")){
JSONObject attendance = content.getJSONObject("value").getJSONObject("attendance").getJSONObject("attendance");
String start = attendance.getLong("new_begin").toString();
String end = attendance.getLong("new_end").toString();
//装入的是小时
String hours = String.valueOf(attendance.getLong("new_duration") / 3600.0);
goOutReqVO.setStartTime(start);
goOutReqVO.setEndTime(end);
goOutReqVO.setGoOutHours(hours);
}
JSONArray title = content.getJSONArray("title");
for (int j = 0; j < title.size(); j++) {
String text = title.getJSONObject(j).getString("text");
if (text.equals("外出事由")){
String reason = content.getJSONObject("value").getString("text");
goOutReqVO.setGoOutReason(reason);
}
//TODO 办公类型
}
} }
return goOutReqVO;
}
private IFinFilingMapping getFinFilingMappingService(String channelId, String formId, String groupId) {
return FinFilingMappingFactory.getContainer(channelId, formId, groupId);
} }
private Map<String, List<FinFilingData>> groupByInputData(String channelId, String formId, List<JSONObject> jsonList) { private Map<String, List<FinFilingData>> groupByInputData(String channelId, String formId, List<JSONObject> jsonList) {
Map<String,List<FinFilingData>> dataMap = new HashMap<>(); Map<String, List<FinFilingData>> dataMap = new HashMap<>();
FinFilingChannelProperties channelProperties = finFilingConfig.getInput().getChannel().get(channelId); FinFilingChannelProperties channelProperties = finFilingConfig.getInput().getChannel().get(channelId);
FinFilingFormProperties formProperties = channelProperties.getForms().get(formId); FinFilingFormProperties formProperties = channelProperties.getForms().get(formId);
String groupByField = formProperties.getGroupByField(); String groupByField = formProperties.getGroupByField();
@ -222,16 +288,16 @@ public abstract class AbstractFinFilingService implements IFinFilingService {
.collect(Collectors.groupingBy(json -> json.getString(groupByField))); .collect(Collectors.groupingBy(json -> json.getString(groupByField)));
for (String inputFormId : groupByData.keySet()) { for (String inputFormId : groupByData.keySet()) {
List<FinFilingData> dataList = toFinFilingDataList(groupByData.get(inputFormId)); List<FinFilingData> dataList = toFinFilingDataList(groupByData.get(inputFormId));
dataMap.put(inputFormId,dataList); dataMap.put(inputFormId, dataList);
} }
}else{ } else {
List<FinFilingData> dataList = toFinFilingDataList(jsonList); List<FinFilingData> dataList = toFinFilingDataList(jsonList);
dataMap.put(formId,dataList); dataMap.put(formId, dataList);
} }
return dataMap; return dataMap;
} }
private List<FinFilingData> toFinFilingDataList(List<JSONObject> jsonList){ private List<FinFilingData> toFinFilingDataList(List<JSONObject> jsonList) {
List<FinFilingData> dataList = new ArrayList<>(); List<FinFilingData> dataList = new ArrayList<>();
for (JSONObject inputData : jsonList) { for (JSONObject inputData : jsonList) {
FinFilingData data = new FinFilingData(); FinFilingData data = new FinFilingData();
@ -244,24 +310,14 @@ public abstract class AbstractFinFilingService implements IFinFilingService {
} }
private FinFilingMappingRelationProperties getMappingRelationProperties(String channelId, String formId, String groupId) { private FinFilingMappingRelationProperties getMappingRelationProperties(String channelId, String formId, String groupId) {
FinFilingChannelProperties channelProperties = finFilingConfig.getInput().getChannel().get(channelId);
FinFilingFormProperties formProperties = channelProperties.getForms().get(formId);
List<FinFilingMappingRelationProperties> relationProperties = finFilingConfig.getMapping().getRelation(); List<FinFilingMappingRelationProperties> relationProperties = finFilingConfig.getMapping().getRelation();
FinFilingMappingRelationProperties matchedRelationProperty = null; FinFilingMappingRelationProperties matchedRelationProperty = null;
for (FinFilingMappingRelationProperties relationProperty : relationProperties) { for (FinFilingMappingRelationProperties relationProperty : relationProperties) {
String inputChannelId = relationProperty.getChannelRelation().getInputChannelId(); String inputChannelId = relationProperty.getChannelRelation().getInputChannelId();
String inputFormId = relationProperty.getFormRelation().getInputFormId(); String inputFormId = relationProperty.getFormRelation().getInputFormId();
String inputGroupId = relationProperty.getFormRelation().getInputGroupId();
String sourceKey; if (channelId.equals(inputChannelId) && formId.equals(inputFormId) && inputGroupId.equals(groupId)) {
if (StringUtils.isNotBlank(formProperties.getGroupByField())) {
sourceKey = FinFilingMappingFactory.buildContainerKey(channelId,formId,groupId);
}else{
sourceKey = FinFilingMappingFactory.buildContainerKey(channelId,formId);
}
String targetKey = FinFilingMappingFactory.buildContainerKey(inputChannelId,inputFormId);
if (StringUtils.equalsIgnoreCase(sourceKey, targetKey)) {
matchedRelationProperty = relationProperty; matchedRelationProperty = relationProperty;
break; break;
} }
@ -269,14 +325,14 @@ public abstract class AbstractFinFilingService implements IFinFilingService {
return matchedRelationProperty; return matchedRelationProperty;
} }
protected FinFilingSyncLog saveSyncLog(FinFilingData data, FinFilingContext context){ protected FinFilingSyncLog saveSyncLog(FinFilingData data, FinFilingContext context) {
FinFilingSyncLog finFilingSyncLog = buildSyncLog(data,context); FinFilingSyncLog finFilingSyncLog = buildSyncLog(data, context);
finFilingSyncLogService.save(finFilingSyncLog); finFilingSyncLogService.save(finFilingSyncLog);
return finFilingSyncLog; return finFilingSyncLog;
} }
protected void updateSyncLog(FinFilingSyncLog finFilingSyncLog,FinFilingContext context) { protected void updateSyncLog(FinFilingSyncLog finFilingSyncLog, FinFilingContext context) {
finFilingSyncLog.setUpdateTime(new Date()); finFilingSyncLog.setUpdateTime(new Date());
finFilingSyncLogService.updateById(finFilingSyncLog); finFilingSyncLogService.updateById(finFilingSyncLog);
} }
@ -305,10 +361,11 @@ public abstract class AbstractFinFilingService implements IFinFilingService {
return finFilingSyncLog; return finFilingSyncLog;
} }
protected Object callData(FinFilingChannelProperties channelProperties, FinFilingFormProperties formProperties,String reqBody, FinFilingContext context){ protected List<String> callData(FinFilingChannelProperties channelProperties, FinFilingFormProperties formProperties, String reqBody, FinFilingContext context) {
String result = null; String result = null;
String reqUrl = formProperties.getReqUrl(); String reqUrl = formProperties.getReqUrl();
if(!(StringUtils.startsWithIgnoreCase(reqUrl,"http://") || StringUtils.startsWithIgnoreCase(reqUrl,"https://"))){ List<String> spNoList = new ArrayList<>();
if (!(StringUtils.startsWithIgnoreCase(reqUrl, "http://") || StringUtils.startsWithIgnoreCase(reqUrl, "https://"))) {
String host = channelProperties.getHost(); String host = channelProperties.getHost();
reqUrl = host + reqUrl; reqUrl = host + reqUrl;
} }
@ -317,9 +374,9 @@ public abstract class AbstractFinFilingService implements IFinFilingService {
Map<String, String> reqHeader = replaceVariable(channelProperties.getReqHeader(), context, channelProperties); Map<String, String> reqHeader = replaceVariable(channelProperties.getReqHeader(), context, channelProperties);
String reqMethod = formProperties.getReqMethod(); String reqMethod = formProperties.getReqMethod();
if(HttpMethod.GET.name().equalsIgnoreCase(reqMethod)){ if (HttpMethod.GET.name().equalsIgnoreCase(reqMethod)) {
Map<String, String> reqParam = replaceVariable(formProperties.getReqParam(), context, channelProperties); Map<String, String> reqParam = replaceVariable(formProperties.getReqParam(), context, channelProperties);
if(!CollectionUtils.isEmpty(formProperties.getReqHeader())) { if (!CollectionUtils.isEmpty(formProperties.getReqHeader())) {
if (!CollectionUtils.isEmpty(reqHeader)) { if (!CollectionUtils.isEmpty(reqHeader)) {
reqHeader.putAll(replaceVariable(formProperties.getReqHeader(), context, channelProperties)); reqHeader.putAll(replaceVariable(formProperties.getReqHeader(), context, channelProperties));
} else { } else {
@ -327,34 +384,51 @@ public abstract class AbstractFinFilingService implements IFinFilingService {
} }
} }
result = OkHttpClientUtil.doGet(reqUrl, reqParam, reqHeader); result = OkHttpClientUtil.doGet(reqUrl, reqParam, reqHeader);
}else if(HttpMethod.POST.name().equalsIgnoreCase(reqMethod)){ } else if (HttpMethod.POST.name().equalsIgnoreCase(reqMethod)) {
if(StringUtils.isBlank(reqBody)){ if (StringUtils.isBlank(reqBody)) {
reqBody = replaceVariable(formProperties.getReqBody(), context, channelProperties); reqBody = replaceVariable(formProperties.getReqBody(), context, channelProperties);
} }
if(!CollectionUtils.isEmpty(formProperties.getReqHeader())) { if (!CollectionUtils.isEmpty(formProperties.getReqHeader())) {
if (!CollectionUtils.isEmpty(reqHeader)) { if (!CollectionUtils.isEmpty(reqHeader)) {
reqHeader.putAll(replaceVariable(formProperties.getReqHeader(), context, channelProperties)); reqHeader.putAll(replaceVariable(formProperties.getReqHeader(), context, channelProperties));
} else { } else {
reqHeader = replaceVariable(formProperties.getReqHeader(), context, channelProperties); reqHeader = replaceVariable(formProperties.getReqHeader(), context, channelProperties);
} }
} }
result = OkHttpClientUtil.doPostJson(reqUrl, reqBody, reqHeader);
}else{ if (ChannelEnum.HOSECLOUD.getChannelId().equals(channelProperties.getChannelId())) {
throw new RuntimeException("暂不支持的请求方式:"+reqMethod); result = OkHttpClientUtil.doPostJson(reqUrl, reqBody, reqHeader);
JSONObject res = JSONObject.parseObject(JSONObject.toJSONString(result));
String id = res.getJSONObject("flow").getString("id");
spNoList.add(id);
} else {
String newNextCursor = "";
do {
result = OkHttpClientUtil.doPostJson(reqUrl, reqBody, reqHeader);
JSONObject res = JSONObject.parseObject(result);
JSONArray jsonArray = res.getJSONArray("sp_no_list");
spNoList.addAll(jsonArray.toJavaList(String.class));
newNextCursor = res.getString("new_next_cursor");
} while (StringUtils.isNotBlank(newNextCursor));
}
} else {
throw new RuntimeException("暂不支持的请求方式:" + reqMethod);
} }
if(StringUtils.isBlank(result)){ if (StringUtils.isBlank(result)) {
throw new RuntimeException("接口返回报文为空:"+context); throw new RuntimeException("接口返回报文为空:" + context);
} }
String resDataRootNode = formProperties.getResDataRootNode();
return JSONPath.eval(result, resDataRootNode); return spNoList;
} }
private Map<String, String> replaceVariable(Map<String, String> param,FinFilingContext context,FinFilingChannelProperties channelProperties) { private Map<String, String> replaceVariable(Map<String, String> param, FinFilingContext context, FinFilingChannelProperties channelProperties) {
if (!CollectionUtils.isEmpty(param)) { if (!CollectionUtils.isEmpty(param)) {
param = param.entrySet().stream() param = param.entrySet().stream()
.map(entry -> { .map(entry -> {
String value = entry.getValue(); String value = entry.getValue();
value = replaceVariable(value,context,channelProperties); value = replaceVariable(value, context, channelProperties);
return new AbstractMap.SimpleEntry<>(entry.getKey(), value); return new AbstractMap.SimpleEntry<>(entry.getKey(), value);
}).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); }).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
@ -364,41 +438,41 @@ public abstract class AbstractFinFilingService implements IFinFilingService {
private String replaceVariable(String param, FinFilingContext context) { private String replaceVariable(String param, FinFilingContext context) {
if (StringUtils.isNotBlank(param)) { if (StringUtils.isNotBlank(param)) {
if(StringUtils.contains(param,"{startCursor}")){ if (StringUtils.contains(param, "{startCursor}")) {
param = StringUtils.replace(param, "{startCursor}", context.getStartCursor()); param = StringUtils.replace(param, "{startCursor}", context.getStartCursor());
} }
if(StringUtils.contains(param,"{endCursor}")){ if (StringUtils.contains(param, "{endCursor}")) {
param = StringUtils.replace(param, "{endCursor}", context.getEndCursor()); param = StringUtils.replace(param, "{endCursor}", context.getEndCursor());
} }
if(StringUtils.contains(param,"{pageNum}")){ if (StringUtils.contains(param, "{pageNum}")) {
param = StringUtils.replace(param, "{pageNum}", context.getPageNum().toString()); param = StringUtils.replace(param, "{pageNum}", context.getPageNum().toString());
} }
if(StringUtils.contains(param,"{pageSize}")){ if (StringUtils.contains(param, "{pageSize}")) {
param = StringUtils.replace(param, "{pageSize}", context.getPageSize().toString()); param = StringUtils.replace(param, "{pageSize}", context.getPageSize().toString());
} }
if(StringUtils.contains(param,"{inputChannelId}")){ if (StringUtils.contains(param, "{inputChannelId}")) {
param = StringUtils.replace(param, "{inputChannelId}", context.getInputChannelId()); param = StringUtils.replace(param, "{inputChannelId}", context.getInputChannelId());
} }
if(StringUtils.contains(param,"{inputFormId}")){ if (StringUtils.contains(param, "{inputFormId}")) {
param = StringUtils.replace(param, "{inputFormId}", context.getInputFormId()); param = StringUtils.replace(param, "{inputFormId}", context.getInputFormId());
} }
if(StringUtils.contains(param,"{outputChannelId}")){ if (StringUtils.contains(param, "{outputChannelId}")) {
param = StringUtils.replace(param, "{outputChannelId}", context.getOutputChannelId()); param = StringUtils.replace(param, "{outputChannelId}", context.getOutputChannelId());
} }
if(StringUtils.contains(param,"{outputFormId}")){ if (StringUtils.contains(param, "{outputFormId}")) {
param = StringUtils.replace(param, "{outputFormId}", context.getOutputFormId()); param = StringUtils.replace(param, "{outputFormId}", context.getOutputFormId());
} }
if(StringUtils.contains(param,"{outputDataId}")){ if (StringUtils.contains(param, "{outputDataId}")) {
param = StringUtils.replace(param, "{outputDataId}", context.getOutputDataId()); param = StringUtils.replace(param, "{outputDataId}", context.getOutputDataId());
} }
} }
return param; return param;
} }
private String replaceVariable(String param, FinFilingContext context,FinFilingChannelProperties channelProperties) { private String replaceVariable(String param, FinFilingContext context, FinFilingChannelProperties channelProperties) {
param = replaceVariable(param, context); param = replaceVariable(param, context);
if (StringUtils.isNotBlank(param)) { if (StringUtils.isNotBlank(param)) {
if(StringUtils.contains(param,"{accessToken}")){ if (StringUtils.contains(param, "{accessToken}")) {
IFinFilingAccessTokenService accessTokenService = getAccessTokenService(channelProperties.getChannelId()); IFinFilingAccessTokenService accessTokenService = getAccessTokenService(channelProperties.getChannelId());
String accessToken = accessTokenService.getAccessToken(channelProperties).getAccessToken(); String accessToken = accessTokenService.getAccessToken(channelProperties).getAccessToken();
param = StringUtils.replace(param, "{accessToken}", accessToken); param = StringUtils.replace(param, "{accessToken}", accessToken);
@ -407,14 +481,13 @@ public abstract class AbstractFinFilingService implements IFinFilingService {
return param; return param;
} }
protected IFinFilingAccessTokenService getAccessTokenService(String channelId){ protected IFinFilingAccessTokenService getAccessTokenService(String channelId) {
return FinFilingAccessTokenFactory.getContainer(channelId); return FinFilingAccessTokenFactory.getContainer(channelId);
} }
protected abstract PageInfo<JSONObject> inputData(FinFilingContext context, FinFilingConfig finFilingConfig); protected abstract PageInfo<String> inputData(FinFilingContext context, FinFilingConfig finFilingConfig);
protected abstract void outputData(FinFilingData data, FinFilingContext context, FinFilingConfig finFilingConfig); protected abstract void outputData(FinFilingData data, FinFilingContext context, FinFilingConfig finFilingConfig);
} }

View File

@ -1,84 +0,0 @@
package cn.jiutqy.finfiling.common.service;
import cn.jiutqy.archives.common.exception.ServiceException;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.alibaba.fastjson2.JSONPath;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.pagehelper.PageInfo;
import cn.jiutqy.finfiling.common.config.FinFilingConfig;
import cn.jiutqy.finfiling.common.config.properties.FinFilingChannelProperties;
import cn.jiutqy.finfiling.common.config.properties.FinFilingFormProperties;
import cn.jiutqy.finfiling.common.domain.FinFilingSyncLog;
import cn.jiutqy.finfiling.common.dto.FinFilingData;
import cn.jiutqy.finfiling.common.enums.SyncStateEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Date;
import java.util.List;
@Slf4j
@Component
public class DefaultFormAtFinFilingService extends AbstractFinFilingService{
@Autowired
private IFinFilingSyncLogService finFilingSyncLogService;
@Override
protected PageInfo<JSONObject> inputData(FinFilingContext context, FinFilingConfig finFilingConfig) {
LambdaQueryWrapper<FinFilingSyncLog> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(FinFilingSyncLog::getInputChannelId,context.getInputChannelId());
//queryWrapper.likeRight(FinFilingSyncLog::getInputFormId,context.getInputFormId());
queryWrapper.eq(FinFilingSyncLog::getSyncState, SyncStateEnum.SUCCESSED.value());
queryWrapper.ne(FinFilingSyncLog::getAtSyncState, SyncStateEnum.SUCCESSED.value());
Page<FinFilingSyncLog> page = new Page<>(context.getPageNum(),context.getPageSize());
page = finFilingSyncLogService.page(page,queryWrapper);
List<JSONObject> jsonList = (List<JSONObject>) JSON.toJSON(page.getRecords());
PageInfo<JSONObject> pageInfo = new PageInfo<>(jsonList);
pageInfo.setHasNextPage(page.hasNext());
pageInfo.setNextPage(context.getPageNum() + 1);
return pageInfo;
}
@Override
protected void outputData(FinFilingData data, FinFilingContext context, FinFilingConfig finFilingConfig){
FinFilingChannelProperties channelProperties = finFilingConfig.getOutput().getChannel().get(context.getOutputChannelId());
channelProperties.setChannelId(context.getOutputChannelId());
FinFilingFormProperties formProperties = channelProperties.getForms().get(context.getOutputFormId());
Object result = callData(channelProperties,formProperties,String.valueOf(data.getOutputData()),context);
String outputDataId = null;
try {
outputDataId = (String) JSONPath.eval(result, formProperties.getResDataIdNode());
} catch (Exception e) {
throw new ServiceException("无法解析resDataIdNode返回报文"+result);
}
context.addOutputDataId(outputDataId);
}
@Override
protected FinFilingSyncLog saveSyncLog(FinFilingData data, FinFilingContext context) {
FinFilingSyncLog finFilingSyncLog = data.getInputData().toJavaObject(FinFilingSyncLog.class);
return finFilingSyncLog;
}
@Override
protected void updateSyncLog(FinFilingSyncLog finFilingSyncLog, FinFilingContext context) {
FinFilingSyncLog entity = new FinFilingSyncLog();
entity.setLogId(finFilingSyncLog.getLogId());
entity.setAtSyncState(finFilingSyncLog.getSyncState());
entity.setAtErrorMsg(finFilingSyncLog.getErrorMsg());
entity.setUpdateTime(new Date());
finFilingSyncLogService.updateById(entity);
}
}

View File

@ -1,66 +1,93 @@
package cn.jiutqy.finfiling.common.service; package cn.jiutqy.finfiling.common.service;
import cn.jiutqy.archives.common.exception.ServiceException;
import com.alibaba.fastjson2.JSONArray; import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject; import com.alibaba.fastjson2.JSONObject;
import com.alibaba.fastjson2.JSONPath;
import com.github.pagehelper.PageInfo; import com.github.pagehelper.PageInfo;
import cn.jiutqy.finfiling.common.config.FinFilingConfig; import cn.jiutqy.finfiling.common.config.FinFilingConfig;
import cn.jiutqy.finfiling.common.config.properties.FinFilingChannelProperties; import cn.jiutqy.finfiling.common.config.properties.FinFilingChannelProperties;
import cn.jiutqy.finfiling.common.config.properties.FinFilingFormProperties; import cn.jiutqy.finfiling.common.config.properties.FinFilingFormProperties;
import cn.jiutqy.finfiling.common.dto.FinFilingData; import cn.jiutqy.finfiling.common.dto.FinFilingData;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List; import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
@Slf4j @Slf4j
@Component @Component
public class DefaultFormFinFilingService extends AbstractFinFilingService{ public class DefaultFormFinFilingService extends AbstractFinFilingService {
private static final String APPLICATION_TEM_ID = "";
private static final String TRAVEL = "3";
private static final String GO_OUT = "4";
@Override @Override
protected PageInfo<JSONObject> inputData(FinFilingContext context, FinFilingConfig finFilingConfig){ protected PageInfo<String> inputData(FinFilingContext context, FinFilingConfig finFilingConfig) {
FinFilingChannelProperties channelProperties = finFilingConfig.getInput().getChannel().get(context.getInputChannelId()); FinFilingChannelProperties channelProperties = finFilingConfig.getInput().getChannel().get(context.getInputChannelId());
channelProperties.setChannelId(context.getInputChannelId()); channelProperties.setChannelId(context.getInputChannelId());
FinFilingFormProperties formProperties = channelProperties.getForms().get(context.getInputFormId()); FinFilingFormProperties formProperties = channelProperties.getForms().get(context.getInputFormId());
JSONArray jsonArray = (JSONArray)callData(channelProperties, formProperties, null, context); //构建请求体
JSONObject reqBody = new JSONObject();
reqBody.put("starttime", convert(context.getStartCursor()));
reqBody.put("endtime", convert(context.getEndCursor()));
reqBody.put("new_cursor", "");
reqBody.put("size", 100);
JSONArray filters = new JSONArray();
JSONObject type = new JSONObject();
if ("goOut".equals(context.getInputFormId())) {
type.put("key", "record_type");
type.put("value", GO_OUT);
} else {
type.put("key", "record_type");
type.put("value", TRAVEL);
}
filters.add(type);
reqBody.put("filters", filters);
List<JSONObject> jsonList = IntStream.range(0, jsonArray.size()) List<String> result = callData(channelProperties, formProperties, reqBody.toJSONString(), context);
.mapToObj(jsonArray::getJSONObject)
.collect(Collectors.toList());
PageInfo<JSONObject> pageInfo = new PageInfo<>(jsonList); PageInfo<String> pageInfo = new PageInfo<>(result);
pageInfo.setHasNextPage(jsonList.size() == context.getPageSize()); pageInfo.setHasNextPage(result.size() == context.getPageSize());
pageInfo.setNextPage(context.getPageNum() + 1); pageInfo.setNextPage(context.getPageNum() + 1);
return pageInfo; return pageInfo;
} }
//将日期转成时间戳 xxxx-xx-xx xx:xx:xx
public long convert(String dateStr) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
// 要转换的时间
Date date = null;
try {
date = sdf.parse(dateStr);
} catch (ParseException e) {
log.error("转换时间失败");
}
return date.getTime() / 1000;
}
@Override @Override
protected void outputData(FinFilingData data, FinFilingContext context, FinFilingConfig finFilingConfig){ protected void outputData(FinFilingData data, FinFilingContext context, FinFilingConfig finFilingConfig) {
FinFilingChannelProperties channelProperties = finFilingConfig.getOutput().getChannel().get(context.getOutputChannelId()); FinFilingChannelProperties channelProperties = finFilingConfig.getOutput().getChannel().get(context.getOutputChannelId());
channelProperties.setChannelId(context.getOutputChannelId()); channelProperties.setChannelId(context.getOutputChannelId());
FinFilingFormProperties formProperties = channelProperties.getForms().get(context.getOutputFormId()); FinFilingFormProperties formProperties = channelProperties.getForms().get(context.getOutputFormId());
Object result = callData(channelProperties,formProperties,String.valueOf(data.getOutputData()),context); List<String> result = callData(channelProperties, formProperties, String.valueOf(data.getOutputData()), context);
log.info("输出报文:{}",result);
String outputDataId = null;
try {
outputDataId = (String) JSONPath.eval(result, formProperties.getResDataIdNode());
} catch (Exception e) {
throw new ServiceException("无法解析resDataIdNode返回报文"+result+" 上下文:"+context);
}
if(StringUtils.isBlank(outputDataId)){ String documentId = result.get(1);
throw new ServiceException("无法解析resDataIdNode返回报文 "+ result+" 上下文:"+context); log.info("同步到合思成功单据id为{}", documentId);
}
data.setOutputDataId(outputDataId); data.setOutputDataId(documentId);
} }
} }

View File

@ -4,19 +4,21 @@ import cn.jiutqy.finfiling.common.config.FinFilingConfig;
import cn.jiutqy.finfiling.common.config.properties.FinFilingMappingRelationProperties; import cn.jiutqy.finfiling.common.config.properties.FinFilingMappingRelationProperties;
import cn.jiutqy.finfiling.common.dto.FinFilingData; import cn.jiutqy.finfiling.common.dto.FinFilingData;
import cn.jiutqy.finfiling.common.factory.FinFilingMappingFactory; import cn.jiutqy.finfiling.common.factory.FinFilingMappingFactory;
import cn.jiutqy.finfiling.dipinshi.vo.req.DiPinShiAttendanceReqVO;
import java.util.List; import java.util.List;
import java.util.Map;
public interface IFinFilingMapping { public interface IFinFilingMapping {
default void mapping(List<FinFilingData> dataList, FinFilingContext context, FinFilingMappingRelationProperties mappingRelationProperties, FinFilingConfig finFilingConfig){ /*default void mapping(List<FinFilingData> dataList, FinFilingContext context, FinFilingMappingRelationProperties mappingRelationProperties, FinFilingConfig finFilingConfig){
for (FinFilingData data : dataList) { for (FinFilingData data : dataList) {
mapping(data,context,mappingRelationProperties,finFilingConfig); mapping(data,context,mappingRelationProperties,finFilingConfig);
} }
} }*/
//void mapping(List<FinFilingData> dataList, FinFilingContext context, FinFilingMappingRelationProperties mappingRelationProperties, FinFilingConfig finFilingConfig); //void mapping(List<FinFilingData> dataList, FinFilingContext context, FinFilingMappingRelationProperties mappingRelationProperties, FinFilingConfig finFilingConfig);
void mapping(FinFilingData data, FinFilingContext context, FinFilingMappingRelationProperties mappingRelationProperties, FinFilingConfig finFilingConfig); FinFilingData mapping(DiPinShiAttendanceReqVO reqVO, FinFilingContext context, FinFilingMappingRelationProperties mappingRelationProperties, FinFilingConfig finFilingConfig);
default void registerSelf(IFinFilingFormService form, IFinFilingMapping mappingService){ default void registerSelf(IFinFilingFormService form, IFinFilingMapping mappingService){
FinFilingMappingFactory.addContainer(form.getChannelId(),form.getFormId(),mappingService); FinFilingMappingFactory.addContainer(form.getChannelId(),form.getFormId(),mappingService);

View File

@ -0,0 +1,18 @@
package cn.jiutqy.finfiling.dipinshi;
import cn.jiutqy.finfiling.common.enums.ChannelTypeEnum;
import cn.jiutqy.finfiling.common.factory.FinFilingAccessTokenFactory;
import cn.jiutqy.finfiling.common.service.IFinFilingAccessTokenService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
@Component
public abstract class AbstractDiPinShiBaseService {
protected String getAccessToken(String url, String channelId, ChannelTypeEnum channelTypeEnum){
IFinFilingAccessTokenService accessTokenService = FinFilingAccessTokenFactory.getContainer(channelId);
String accessToken = accessTokenService.getAccessToken(channelId, channelTypeEnum).getAccessToken();
return StringUtils.replace(url,"{accessToken}",accessToken);
}
}

View File

@ -1,4 +1,4 @@
package cn.jiutqy.finfiling.quartz.dipinshi; package cn.jiutqy.finfiling.dipinshi;
import cn.jiutqy.archives.common.utils.StringUtils; import cn.jiutqy.archives.common.utils.StringUtils;
import cn.jiutqy.archives.common.utils.http.OkHttpClientUtil; import cn.jiutqy.archives.common.utils.http.OkHttpClientUtil;

View File

@ -1,4 +1,4 @@
package cn.jiutqy.finfiling.quartz.dipinshi; package cn.jiutqy.finfiling.dipinshi;
import java.util.List; import java.util.List;

View File

@ -0,0 +1,23 @@
package cn.jiutqy.finfiling.dipinshi.constants;
import lombok.Getter;
@Getter
public enum BusinessTypeEnum {
GO_OUT("ID01ErfUV64viD", "外出"),
TRAVEL_IN("ID01DLQ36ToAB9", "国内出差"),
TRAVEL_OUT("ID01DLQ21tIZeD", "国际出差"),
TRAVEL_OUT_NOT_USA("ID01ErfRpaaLYH", "国际出差非美国");
private final String name;
private final String code;
BusinessTypeEnum(String code, String name) {
this.code = code;
this.name = name;
}
}

View File

@ -0,0 +1,13 @@
package cn.jiutqy.finfiling.dipinshi.constants;
public class WeChatTitleConstants {
public static final String goOutReason = "外出事由";
//文本
public static final String goOutLocation = "外出地点";
//假期
public static final String ATTENDANCE = "Attendance";
}

View File

@ -1,4 +1,4 @@
package cn.jiutqy.finfiling.quartz.dipinshi.attendance.vo.req; package cn.jiutqy.finfiling.dipinshi.vo.req;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;

View File

@ -1,4 +1,4 @@
package cn.jiutqy.finfiling.quartz.dipinshi.attendance.vo.req; package cn.jiutqy.finfiling.dipinshi.vo.req;
import lombok.Data; import lombok.Data;
@ -10,6 +10,11 @@ public class DiPinShiAttendanceReqVO {
*/ */
private String applicant; private String applicant;
/**
* 手机号
*/
private String phone;
/** /**
* 申请类型 * 申请类型
*/ */
@ -38,6 +43,6 @@ public class DiPinShiAttendanceReqVO {
/** /**
* 出差类型 * 出差类型
*/ */
private String travelType; private String type;
} }

View File

@ -1,4 +1,4 @@
package cn.jiutqy.finfiling.quartz.dipinshi.attendance.vo.req; package cn.jiutqy.finfiling.dipinshi.vo.req;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;

View File

@ -1,4 +1,4 @@
package cn.jiutqy.finfiling.quartz.dipinshi.attendance.vo.req; package cn.jiutqy.finfiling.dipinshi.vo.req;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;

View File

@ -1,4 +1,4 @@
package cn.jiutqy.finfiling.quartz.dipinshi.attendance.vo.req; package cn.jiutqy.finfiling.dipinshi.vo.req;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;

View File

@ -0,0 +1,33 @@
package cn.jiutqy.finfiling.dipinshi.vo.req;
import lombok.Data;
@Data
public class TravelDetail {
/**
* 拜访日期
*/
private String visitDate;
/**
* 国家地区
*/
private String address;
/**
* 供应商名称
*/
private String vendorName;
/**
* 供应商类型
*/
private String vendorType;
/**
* 出差目的
*/
private String travelPurpose;
}

View File

@ -1,4 +1,4 @@
package cn.jiutqy.finfiling.quartz.dipinshi.attendance.vo.resp; package cn.jiutqy.finfiling.dipinshi.vo.resp;
import lombok.Data; import lombok.Data;

View File

@ -10,7 +10,9 @@ import cn.jiutqy.finfiling.quartz.dipinshi.dto.DiPinShiAccessToken;
import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSON;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Component;
@Component
public class DiPinShiAccessTokenService extends AbstractFinFilingAccessTokenService implements IFinFilingAccessTokenService, InitializingBean { public class DiPinShiAccessTokenService extends AbstractFinFilingAccessTokenService implements IFinFilingAccessTokenService, InitializingBean {
@Override @Override
protected FinFilingAccessToken getAccessToken(FinFilingOauthProperties oauthProperties) { protected FinFilingAccessToken getAccessToken(FinFilingOauthProperties oauthProperties) {

View File

@ -0,0 +1,37 @@
package cn.jiutqy.finfiling.quartz.dipinshi;
import cn.jiutqy.finfiling.common.config.FinFilingConfig;
import cn.jiutqy.finfiling.common.config.properties.FinFilingMappingRelationProperties;
import cn.jiutqy.finfiling.common.dto.FinFilingData;
import cn.jiutqy.finfiling.common.enums.ChannelEnum;
import cn.jiutqy.finfiling.common.enums.FormEnum;
import cn.jiutqy.finfiling.common.service.FinFilingContext;
import cn.jiutqy.finfiling.dipinshi.vo.req.DiPinShiAttendanceGoOutReqVO;
import cn.jiutqy.finfiling.dipinshi.vo.req.DiPinShiAttendanceReqVO;
import java.util.Map;
public class DiPinShiGoOutMapping extends DiPinShiMapping {
@Override
public FinFilingData mapping(DiPinShiAttendanceReqVO reqVO, FinFilingContext context, FinFilingMappingRelationProperties mappingRelationProperties, FinFilingConfig finFilingConfig) {
DiPinShiAttendanceGoOutReqVO travelInRep = (DiPinShiAttendanceGoOutReqVO) reqVO;
//将企微的数据 转成保存到合思同步时需要的数据,一个一个取出来塞进map里
//将travelOutRep里的数据取出来放入一个map中
Map<String, String> data = null;
//取数据
//构建请求体
return mappingSendData(data, travelInRep);
}
@Override
public void afterPropertiesSet() throws Exception {
super.registerSelf(FormEnum.GO_OUT,"goOut",this);
}
}

View File

@ -0,0 +1,214 @@
package cn.jiutqy.finfiling.quartz.dipinshi;
import cn.jiutqy.finfiling.common.domain.FinFilingSyncLog;
import cn.jiutqy.finfiling.common.dto.FinFilingData;
import cn.jiutqy.finfiling.common.service.IFinFilingMapping;
import cn.jiutqy.finfiling.common.service.IFinFilingSyncLogService;
import cn.jiutqy.finfiling.dipinshi.vo.req.DiPinShiAttendanceReqVO;
import cn.jiutqy.finfiling.quartz.constants.*;
import cn.jiutqy.finfiling.quartz.hosecloud.organize.IHoseCloudPersonnelService;
import cn.jiutqy.finfiling.quartz.hosecloud.organize.vo.HoseCloudPersonnelVO;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
@Slf4j
@Component
public abstract class DiPinShiMapping implements IFinFilingMapping , InitializingBean {
private static final String LEGAL_ENTITY_ID = "ID01Dnd2qUASmj";
@Resource
private IFinFilingSyncLogService finFilingSyncLogService;
@Resource
private IHoseCloudPersonnelService personnelService;
protected FinFilingData mappingSendData(Map<String, String> data, DiPinShiAttendanceReqVO reqVO) {
FinFilingData finFilingData = new FinFilingData();
//填充审批单号
FinFilingSyncLog finFilingSyncLog = finFilingSyncLogService.getFinFilingSyncLogByInputDataId("审批单号");
if (finFilingSyncLog != null) {
log.info("输入数据[{}]已同步", "审批单号");
return null;
}
JSONObject form = new JSONObject();
form.put("specificationId", TemplateAndCostConstants.TEMPLATE_DETAIL_ID);
//先填充公用的数据
//需要调用接口查询员工id
List<String> strings = new ArrayList<>();
HoseCloudPersonnelVO personnelVO = personnelService.queryUser(strings);
form.put("submitterId", personnelVO.getId());
//申请日期需要转成时间戳 --看是什么样子的时间然后转成时间戳
form.put("requisitionDate", "申请日期");
//法人实体不确定填写中文还是公司id
form.put("法人实体", LEGAL_ENTITY_ID);
//需要调用接口查询员工部门
form.put("expenseDepartment", personnelVO.getDefaultDepartment());
//需要转成时间戳
form.put("u_开始时间", "u_开始时间");
form.put("u_结束时间", "u_结束时间");
//根据类型填充详情
if (BusinessTypeEnum.GO_OUT.getName().equals(data.get("applicationType"))) {
hoseGoOutMapping(data, form);
} else if (BusinessTypeEnum.TRAVEL_IN.getName().equals(data.get("travelType"))) {
hoseTravelInMapping(data, form);
} else if (BusinessTypeEnum.TRAVEL_OUT.getName().equals(data.get("travelType"))) {
hoseTravelOutMapping(data, form);
} else if (BusinessTypeEnum.TRAVEL_OUT_NOT_USA.getName().equals(data.get("travelType"))) {
hoseTravelOutNotUSAMapping(data, form);
}
finFilingData.setInputData(JSONObject.parseObject(JSONObject.toJSONString(reqVO.getData())));
finFilingData.setInputDataId(reqVO.getApprovalNo());
finFilingData.setOutputData(form);
return finFilingData;
}
private void hoseGoOutMapping(Map<String,String> data, JSONObject form) {
form.put("u_出差类型", BusinessTypeEnum.GO_OUT.getCode());
String officeType = data.get("officeType");
form.put("u_办公类型",officeType.equals("居家办公") ? OfficeTypeCodeConstants.HOME_OFFICE : OfficeTypeCodeConstants.OUTSIDE_OFFICE);
//要么直接有时间要么需要算时间
form.put("公出时长","");
//可能会有多个详情 需要遍历填充数据
JSONArray details = new JSONArray();
JSONObject detail = new JSONObject();
detail.put("feeTypeId",TemplateAndCostConstants.FEE_TYPE_ID);
detail.put("specificationId",TemplateAndCostConstants.FEE_TYPE_DETAIL_ID);
JSONObject feeTypeForm = new JSONObject();
//填充公出事由
feeTypeForm.put("u_公出事由","");
detail.put("feeTypeForm",feeTypeForm);
details.add(detail);
form.put("details",details);
}
private void hoseTravelInMapping(Map<String,String> data, JSONObject form) {
form.put("u_出差类型",BusinessTypeEnum.TRAVEL_IN.getCode());
//要么直接有时间要么需要算时间
form.put("出差天数","");
//可能会有多个详情 需要遍历填充数据
JSONArray details = new JSONArray();
JSONObject detail = new JSONObject();
detail.put("feeTypeId",TemplateAndCostConstants.FEE_TYPE_ID);
detail.put("specificationId",TemplateAndCostConstants.FEE_TYPE_DETAIL_ID);
JSONObject feeTypeForm = new JSONObject();
//填充数据
feeTypeForm.put("u_拜访日期","");
feeTypeForm.put("u_VendorName","");
if (VendorTypeEnum.EXISTING_VENDOR_WITH_SHIPMENT.getName().equals(data.get("供应商类型"))){
feeTypeForm.put("u_供应商类型",VendorTypeEnum.EXISTING_VENDOR_WITH_SHIPMENT.getCode());
}else if (VendorTypeEnum.KNOWN_VENDOR_WITHOUT_SHIPMENT.getName().equals(data.get("供应商类型"))){
feeTypeForm.put("u_供应商类型",VendorTypeEnum.KNOWN_VENDOR_WITHOUT_SHIPMENT.getCode());
}else if (VendorTypeEnum.NEW_VENDOR.getName().equals(data.get("供应商类型"))){
feeTypeForm.put("u_供应商类型",VendorTypeEnum.NEW_VENDOR.getCode());
}
//取出data里的出差目的data里的出差目前有多个用分号隔开
feeTypeForm.put("u_出差",assemblePurpose(data));
detail.put("feeTypeForm",feeTypeForm);
details.add(detail);
form.put("details",details);
}
private void hoseTravelOutMapping(Map<String,String> data, JSONObject form) {
form.put("u_出差类型",BusinessTypeEnum.TRAVEL_OUT.getCode());
//要么直接有时间要么需要算时间
form.put("出差天数","");
//可能会有多个详情 需要遍历填充数据
JSONArray details = new JSONArray();
JSONObject detail = new JSONObject();
detail.put("feeTypeId",TemplateAndCostConstants.FEE_TYPE_ID);
detail.put("specificationId",TemplateAndCostConstants.FEE_TYPE_DETAIL_ID);
JSONObject feeTypeForm = new JSONObject();
//填充数据
feeTypeForm.put("u_出差",assemblePurpose(data));
detail.put("feeTypeForm",feeTypeForm);
details.add(detail);
form.put("details",details);
}
private void hoseTravelOutNotUSAMapping(Map<String,String> data, JSONObject form) {
form.put("u_出差类型",BusinessTypeEnum.TRAVEL_OUT_NOT_USA.getCode());
//要么直接有时间要么需要算时间
form.put("出差天数","");
//可能会有多个详情 需要遍历填充数据
JSONArray details = new JSONArray();
JSONObject detail = new JSONObject();
detail.put("feeTypeId",TemplateAndCostConstants.FEE_TYPE_ID);
detail.put("specificationId",TemplateAndCostConstants.FEE_TYPE_DETAIL_ID);
JSONObject feeTypeForm = new JSONObject();
//填充数据
feeTypeForm.put("u_拜访日期","");
feeTypeForm.put("u_出差目的地","");
feeTypeForm.put("u_VendorName","");
if (VendorTypeEnum.EXISTING_VENDOR_WITH_SHIPMENT.getName().equals(data.get("供应商类型"))){
feeTypeForm.put("u_供应商类型",VendorTypeEnum.EXISTING_VENDOR_WITH_SHIPMENT.getCode());
}else if (VendorTypeEnum.KNOWN_VENDOR_WITHOUT_SHIPMENT.getName().equals(data.get("供应商类型"))){
feeTypeForm.put("u_供应商类型",VendorTypeEnum.KNOWN_VENDOR_WITHOUT_SHIPMENT.getCode());
}else if (VendorTypeEnum.NEW_VENDOR.getName().equals(data.get("供应商类型"))){
feeTypeForm.put("u_供应商类型",VendorTypeEnum.NEW_VENDOR.getCode());
}
feeTypeForm.put("u_供应商类型","");
feeTypeForm.put("u_出差",assemblePurpose(data));
detail.put("feeTypeForm",feeTypeForm);
details.add(detail);
form.put("details",details);
}
//填充出差目的
private List<String> assemblePurpose(Map<String,String> data){
String purpose = data.get("出差目的");
List<String> purposes = Arrays.asList(purpose.split(";"));
return covertPurposesToCodes(purposes);
}
private List<String> covertPurposesToCodes(List<String> purposes) {
List<String> codes = new ArrayList<>();
for (String purpose : purposes) {
String code = TravelPurposeEnum.getCodeByName(purpose);
if (code != null) {
codes.add(code);
} else {
log.warn("未找到对应的出差目的: {}", purpose);
}
}
return codes;
}
}

View File

@ -0,0 +1,31 @@
package cn.jiutqy.finfiling.quartz.dipinshi;
import cn.jiutqy.finfiling.common.config.FinFilingConfig;
import cn.jiutqy.finfiling.common.config.properties.FinFilingMappingRelationProperties;
import cn.jiutqy.finfiling.common.dto.FinFilingData;
import cn.jiutqy.finfiling.common.enums.FormEnum;
import cn.jiutqy.finfiling.common.service.FinFilingContext;
import cn.jiutqy.finfiling.dipinshi.vo.req.DiPinShiAttendanceReqVO;
import cn.jiutqy.finfiling.dipinshi.vo.req.DiPinShiAttendanceTravelInReqVO;
import java.util.Map;
public class DiPinShiTravelInMapping extends DiPinShiMapping {
@Override
public FinFilingData mapping(DiPinShiAttendanceReqVO reqVO, FinFilingContext context, FinFilingMappingRelationProperties mappingRelationProperties, FinFilingConfig finFilingConfig) {
DiPinShiAttendanceTravelInReqVO travelInRep = (DiPinShiAttendanceTravelInReqVO) reqVO;
//将travelOutRep里的数据取出来放入一个map中
Map<String, String> data = null;
//取数据
//构建请求体
return mappingSendData(data, travelInRep);
}
@Override
public void afterPropertiesSet() throws Exception {
super.registerSelf(FormEnum.TRAVEL,"travelIn",this);
}
}

View File

@ -0,0 +1,30 @@
package cn.jiutqy.finfiling.quartz.dipinshi;
import cn.jiutqy.finfiling.common.config.FinFilingConfig;
import cn.jiutqy.finfiling.common.config.properties.FinFilingMappingRelationProperties;
import cn.jiutqy.finfiling.common.dto.FinFilingData;
import cn.jiutqy.finfiling.common.enums.FormEnum;
import cn.jiutqy.finfiling.common.service.FinFilingContext;
import cn.jiutqy.finfiling.dipinshi.vo.req.DiPinShiAttendanceReqVO;
import cn.jiutqy.finfiling.dipinshi.vo.req.DiPinShiAttendanceTravelOutNotUSAReqVO;
import java.util.Map;
public class DiPinShiTravelNoUSAMapping extends DiPinShiMapping {
@Override
public FinFilingData mapping(DiPinShiAttendanceReqVO reqVO, FinFilingContext context, FinFilingMappingRelationProperties mappingRelationProperties, FinFilingConfig finFilingConfig) {
DiPinShiAttendanceTravelOutNotUSAReqVO travelOutNotUSARep = (DiPinShiAttendanceTravelOutNotUSAReqVO) reqVO;
//将travelOutNotUSARep里的数据取出来放入一个map中
Map<String, String> data = null;
//取数据
//构建请求体
return mappingSendData(data, travelOutNotUSARep);
}
@Override
public void afterPropertiesSet() throws Exception {
super.registerSelf(FormEnum.TRAVEL,"travelOutNoUSA",this);
}
}

View File

@ -0,0 +1,31 @@
package cn.jiutqy.finfiling.quartz.dipinshi;
import cn.jiutqy.finfiling.common.config.FinFilingConfig;
import cn.jiutqy.finfiling.common.config.properties.FinFilingMappingRelationProperties;
import cn.jiutqy.finfiling.common.dto.FinFilingData;
import cn.jiutqy.finfiling.common.enums.FormEnum;
import cn.jiutqy.finfiling.common.service.FinFilingContext;
import cn.jiutqy.finfiling.dipinshi.vo.req.DiPinShiAttendanceReqVO;
import cn.jiutqy.finfiling.dipinshi.vo.req.DiPinShiAttendanceTravelOutReqVO;
import java.util.Map;
public class DiPinShiTravelOutMapping extends DiPinShiMapping {
@Override
public FinFilingData mapping(DiPinShiAttendanceReqVO reqVO, FinFilingContext context, FinFilingMappingRelationProperties mappingRelationProperties, FinFilingConfig finFilingConfig) {
DiPinShiAttendanceTravelOutReqVO travelOutRep = (DiPinShiAttendanceTravelOutReqVO) reqVO;
//将travelOutRep里的数据取出来放入一个map中
Map<String,String> data = null;
//取数据
//构建请求体
return mappingSendData(data,travelOutRep);
}
@Override
public void afterPropertiesSet() throws Exception {
super.registerSelf(FormEnum.TRAVEL,"travelOut",this);
}
}

View File

@ -1,28 +0,0 @@
package cn.jiutqy.finfiling.quartz.enums;
import lombok.Getter;
@Getter
public enum GeYuanOutboundTypeEnum {
GY_ADD("gy_add"),
GY_UPDATE("gy_update"),
GY_DELETE("gy_delete"),
GY_GET("gy_get")
;
private final String type;
GeYuanOutboundTypeEnum(String type){
this.type = type;
}
public static GeYuanOutboundTypeEnum getByType(String type){
for(GeYuanOutboundTypeEnum typeEnum : GeYuanOutboundTypeEnum.values()){
if(typeEnum.getType().equals(type)){
return typeEnum;
}
}
return null;
}
}

View File

@ -1,30 +0,0 @@
package cn.jiutqy.finfiling.quartz.enums;
import lombok.Getter;
@Getter
public enum U9cMappingHoseEntityIdEnum {
//测试
UF_DATA_900_2021("UFData9002021", "上海玮驰仪器有限公司", "ID01C0qw92g4rB"),
//正式
UF_DATA_301_2018("UFData3012018", "上海玮驰仪器有限公司", "ID01C0qw92g4rB"),
UF_DATA_302_2018("UFData3022018", "上海修睿科学仪器有限公司", "ID01C0qwdSvb9Z"),
UF_DATA_311_2021("UFData3112021", "上海看咔科技有限公司", "ID01C0qycSdGnJ"),
UF_DATA_501_2021("UFData5012021", "上海逐典生物科技有限公司", "ID01C0qD5FxL7V"),
UF_DATA_502_2023("UFData5022023", "上海晴筝科技有限公司", "ID01C0qEk2fic7"),
UF_DATA_503_2024("UFData5032024", "上海普纳生物技术有限公司", "ID01C0qJnGX39d"),
UF_DATA_504_2024("UFData5042024", "上海阜金生物科技有限公司", "ID01C2KOZrONaf"),
UF_DATA_505_2024("UFData5052024", "上海雏田生物技术有限公司", "ID01C0qzCCbwF9");
private final String database;
private final String name;
private final String id;
U9cMappingHoseEntityIdEnum(String database, String name, String id){
this.database = database;
this.name = name;
this.id = id;
}
}

View File

@ -1,15 +0,0 @@
package cn.jiutqy.finfiling.quartz.sync;
import cn.jiutqy.finfiling.quartz.enums.GeYuanOutboundTypeEnum;
import java.util.Date;
import java.util.Map;
public interface IOutboundSyncDiPinShiService {
void updateSyncTravel(String start, String end);
void updateSyncGoOut(String start, String end);
void retry(Date beforeTime);
}

View File

@ -1,249 +0,0 @@
package cn.jiutqy.finfiling.quartz.sync;
import cn.hutool.core.collection.CollectionUtil;
import cn.jiutqy.archives.common.utils.ExceptionUtil;
import cn.jiutqy.finfiling.common.domain.FinFilingSyncLog;
import cn.jiutqy.finfiling.common.enums.ChannelEnum;
import cn.jiutqy.finfiling.common.enums.SyncStateEnum;
import cn.jiutqy.finfiling.common.service.IFinFilingSyncLogService;
import cn.jiutqy.finfiling.quartz.constants.BusinessTypeEnum;
import cn.jiutqy.finfiling.quartz.dipinshi.IDiPinShiFinFilingService;
import cn.jiutqy.finfiling.quartz.hosecloud.IDiPinShiAttendanceService;
import cn.jiutqy.finfiling.quartz.dipinshi.attendance.vo.req.*;
import cn.jiutqy.finfiling.quartz.enums.GeYuanOutboundTypeEnum;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.text.SimpleDateFormat;
import java.util.*;
@Slf4j
@Component
public class OutboundSyncDiPinShiService implements IOutboundSyncDiPinShiService{
@Autowired
private IFinFilingSyncLogService finFilingSyncLogService;
@Autowired
private IDiPinShiFinFilingService diPinShiFinFilingService;
@Autowired
private IDiPinShiAttendanceService attendanceService;
@Override
public void updateSyncTravel(String start, String end) {
//批量获取数据单号
List<String> approvalNos = diPinShiFinFilingService.getBatchApprovalNoTravel(start, end , "TRAVEL");
List<DiPinShiAttendanceReqVO> travelReps = new ArrayList<>();
//根据单号查询详情 取出有效数据x
for (String approvalNo : approvalNos) {
String detail = diPinShiFinFilingService.getApprovalNoDetail(approvalNo);
//根据类型判断外出国内出差国际出差国际出差非美国
JSONObject jsonObject = JSONObject.parseObject(JSONObject.toJSONString(detail));
//取出出差类型根据类型分别映射到不同VO --这里的类型应该没这么好取
String type = jsonObject.getString("type");
if (BusinessTypeEnum.TRAVEL_IN.getName().equals(type)){
//如果层级结构太多就手动取值然后塞进里
DiPinShiAttendanceTravelInReqVO travelIn = JSONObject.parseObject(detail, DiPinShiAttendanceTravelInReqVO.class);
travelReps.add(travelIn);
}else if (BusinessTypeEnum.TRAVEL_OUT.getName().equals(type)){
DiPinShiAttendanceTravelOutReqVO travelOut = JSONObject.parseObject(detail, DiPinShiAttendanceTravelOutReqVO.class);
travelReps.add(travelOut);
}else if (BusinessTypeEnum.TRAVEL_OUT_NOT_USA.getName().equals(type)){
DiPinShiAttendanceTravelOutNotUSAReqVO travelOutNotUSA = JSONObject.parseObject(detail, DiPinShiAttendanceTravelOutNotUSAReqVO.class);
travelReps.add(travelOutNotUSA);
}
}
FinFilingSyncLog finFilingSyncLog;
if (CollectionUtil.isNotEmpty(travelReps)) {
for (DiPinShiAttendanceReqVO travelRep : travelReps) {
// 区分出差类型
String tripType = travelRep.getTravelType();
try {
// 记录同步日志
finFilingSyncLog = finFilingSyncLogService.getFinFilingSyncLogByInputChannelAndInputDataId(ChannelEnum.DI_PIN_SHI_TRAVEL.getChannelId(), travelRep.getApprovalNo());
if (finFilingSyncLog == null){
finFilingSyncLog = new FinFilingSyncLog();
finFilingSyncLog.setInputChannelId(ChannelEnum.DI_PIN_SHI_TRAVEL.getChannelId());
finFilingSyncLog.setInputDataId(travelRep.getApprovalNo());
finFilingSyncLog.setInputData(JSON.toJSONString(travelRep.getData()));
finFilingSyncLog.setSyncState(SyncStateEnum.INIT.value());
finFilingSyncLog.setCreateTime(new Date());
finFilingSyncLogService.save(finFilingSyncLog);
}
} catch (Exception e) {
log.error("写入同步日志失败:{}-{}", ChannelEnum.DI_PIN_SHI_TRAVEL.getChannelId() , JSON.toJSONString(travelRep));
return;
}
// 根据出差类型组装数据
Map<String,String> dataToSend = assembleTravelData(travelRep, tripType);
try {
//数据同步到合思,更改同步状态
attendanceService.attendanceTravel(dataToSend);
finFilingSyncLog.setOutputChannelId(ChannelEnum.HOSECLOUD.getChannelId());
finFilingSyncLog.setOutputDataId(travelRep.getApprovalNo());
finFilingSyncLog.setSyncState(SyncStateEnum.SUCCESSED.value());
log.info("输出成功:{}", JSON.toJSONString(finFilingSyncLog));
} catch (Exception e) {
log.error("输出异常",e);
finFilingSyncLog.setSyncState(SyncStateEnum.FAILED.value());
finFilingSyncLog.setErrorMsg(ExceptionUtil.getExceptionMessage(e));
log.error("输出失败:{}", JSON.toJSONString(finFilingSyncLog));
}
try {
finFilingSyncLog.setUpdateTime(new Date());
finFilingSyncLogService.updateById(finFilingSyncLog);
} catch (Exception e) {
log.error("修改同步日志失败",e);
}
}
}
}
@Override
public void updateSyncGoOut(String start, String end) {
//批量获取数据单号
List<String> approvalNos = diPinShiFinFilingService.getBatchApprovalNoTravel(start, end , "GoOut");
List<DiPinShiAttendanceGoOutReqVO> goOuts = new ArrayList<>();
//根据单号查询单号详情
for (String approvalNo : approvalNos) {
String detail = diPinShiFinFilingService.getApprovalNoDetail(approvalNo);
DiPinShiAttendanceGoOutReqVO goOut = JSONObject.parseObject(detail, DiPinShiAttendanceGoOutReqVO.class);
goOuts.add(goOut);
}
FinFilingSyncLog finFilingSyncLog;
if (CollectionUtil.isNotEmpty(goOuts)){
for (DiPinShiAttendanceGoOutReqVO goOut : goOuts) {
//记录同步日志
try {
finFilingSyncLog = finFilingSyncLogService.getFinFilingSyncLogByInputChannelAndInputDataId(ChannelEnum.DI_PIN_SHI_GO_OUT.getChannelId(), goOut.getApprovalNo());
if (finFilingSyncLog == null){
finFilingSyncLog = new FinFilingSyncLog();
finFilingSyncLog.setInputChannelId(ChannelEnum.DI_PIN_SHI_GO_OUT.getChannelId());
finFilingSyncLog.setInputDataId(goOut.getApprovalNo());
finFilingSyncLog.setInputData(JSON.toJSONString(goOut.getData()));
finFilingSyncLog.setSyncState(SyncStateEnum.INIT.value());
finFilingSyncLog.setCreateTime(new Date());
finFilingSyncLogService.save(finFilingSyncLog);
}
} catch (Exception e) {
log.error("写入同步日志失败:{}-{}", ChannelEnum.DI_PIN_SHI_GO_OUT.getChannelId() , JSON.toJSONString(goOut));
return;
}
//字段映射
Map<String,String> dataToSend = goOutMapping(goOut);
try {
//数据同步到合思,更改同步状态
attendanceService.attendanceGoOut(dataToSend);
finFilingSyncLog.setOutputChannelId(ChannelEnum.HOSECLOUD.getChannelId());
finFilingSyncLog.setOutputDataId(goOut.getApprovalNo());
finFilingSyncLog.setSyncState(SyncStateEnum.SUCCESSED.value());
log.info("输出成功:{}", JSON.toJSONString(finFilingSyncLog));
} catch (Exception e) {
log.error("输出异常",e);
finFilingSyncLog.setSyncState(SyncStateEnum.FAILED.value());
finFilingSyncLog.setErrorMsg(ExceptionUtil.getExceptionMessage(e));
log.error("输出失败:{}", JSON.toJSONString(finFilingSyncLog));
}
try {
finFilingSyncLog.setUpdateTime(new Date());
finFilingSyncLogService.updateById(finFilingSyncLog);
} catch (Exception e) {
log.error("修改同步日志失败",e);
}
}
}
}
private Map<String,String> goOutMapping(DiPinShiAttendanceGoOutReqVO goOut) {
//字段映射
return null;
}
private Map<String,String> assembleTravelData(DiPinShiAttendanceReqVO travelRep, String tripType) {
Map<String,String> sendData = null;
if (BusinessTypeEnum.TRAVEL_IN.getName().equals(tripType)){
if (travelRep instanceof DiPinShiAttendanceTravelInReqVO){
DiPinShiAttendanceTravelInReqVO travelInRep = (DiPinShiAttendanceTravelInReqVO) travelRep;
sendData = travelInMapping(travelInRep);
}
}else if (BusinessTypeEnum.TRAVEL_OUT.getName().equals(tripType)){
if (travelRep instanceof DiPinShiAttendanceTravelOutReqVO){
DiPinShiAttendanceTravelOutReqVO travelOutRep = (DiPinShiAttendanceTravelOutReqVO) travelRep;
sendData = travelOutMapping(travelOutRep);
}
}else if (BusinessTypeEnum.TRAVEL_OUT_NOT_USA.getName().equals(tripType)){
if (travelRep instanceof DiPinShiAttendanceTravelOutNotUSAReqVO){
DiPinShiAttendanceTravelOutNotUSAReqVO travelOutNotUSARep = (DiPinShiAttendanceTravelOutNotUSAReqVO) travelRep;
sendData = travelOutNotUSAMapping(travelOutNotUSARep);
}
}
return sendData;
}
private Map<String,String> travelInMapping(DiPinShiAttendanceTravelInReqVO travelInRep) {
//将企微的数据 转成保存到合思同步时需要的数据,一个一个取出来塞进map里
return null;
}
private Map<String,String> travelOutMapping(DiPinShiAttendanceTravelOutReqVO travelOutRep) {
return null;
}
private Map<String,String> travelOutNotUSAMapping(DiPinShiAttendanceTravelOutNotUSAReqVO travelOutNotUSARep) {
return null;
}
@Override
public void retry(Date beforeTime) {
List<FinFilingSyncLog> list = finFilingSyncLogService.listFailFinFiling(beforeTime);
list.forEach(item -> {
GeYuanOutboundTypeEnum typeEnum = GeYuanOutboundTypeEnum.getByType(item.getInputChannelId());
if (typeEnum == null){
return;
}
Map<String, Object> map = JSON.parseObject(item.getInputData());
});
}
//转成日期格式yyyy-mm-dd mm:ss
public String convertDateFormat(String stamp){
long timestamp = Long.parseLong(stamp);
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
sdf.setTimeZone(TimeZone.getTimeZone("GMT+08:00"));
Date date = new Date(timestamp);
return sdf.format(date);
}
}

View File

@ -1,22 +1,22 @@
package cn.jiutqy.finfiling.quartz.task; package cn.jiutqy.finfiling.quartz.task;
import cn.jiutqy.finfiling.common.service.DefaultFormAtFinFilingService;
import cn.jiutqy.finfiling.common.service.DefaultFormFinFilingService; import cn.jiutqy.finfiling.common.service.DefaultFormFinFilingService;
import cn.jiutqy.finfiling.common.service.IFinFilingSyncCursorService;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.Date;
@Slf4j @Slf4j
@Component("diPinShiSyncDataTask") @Component("diPinShiSyncDataTask")
public class DiPinShiSyncDataTask { public class DiPinShiSyncDataTask {
@Autowired @Autowired
private DefaultFormFinFilingService defaultFormFinFilingService; private DefaultFormFinFilingService defaultFormFinFilingService;
@Autowired @Autowired
private DefaultFormAtFinFilingService defaultFormAtFinFilingService; private IFinFilingSyncCursorService finFilingSyncCursorService;
public void syncData(String channelId,String formId){ public void syncData(String channelId,String formId){
long startTime = System.currentTimeMillis(); long startTime = System.currentTimeMillis();

View File

@ -106,6 +106,12 @@
<artifactId>logging-interceptor</artifactId> <artifactId>logging-interceptor</artifactId>
<version>4.9.3</version> <version>4.9.3</version>
</dependency> </dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
</dependency>
</dependencies> </dependencies>
<build> <build>