This commit is contained in:
Aria 2024-11-20 14:45:13 +08:00
parent fb24ea058b
commit 05f6e112c8
88 changed files with 3957 additions and 0 deletions

41
.gitignore vendored Normal file
View File

@ -0,0 +1,41 @@
# Java class files
*.class
#package file
*.war
*.ear
#kdiff3 ignore
*.orig
#maven ignore
target/
#eclipse ignore
.settings/
.project
.classpath
#idea
.idea/
/idea/
/out/
*.ipr
*.iml
*.iws
#temp file
*.log
*.cache
*.diff
*.patch
*.tmp
*.log.gz
# system ignore
.DS_Store
Thumbs.db
.apt_generated/
.factorypath
rebel.xml
generator/dist/

14
.idea/misc.xml Normal file
View File

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="MavenProjectsManager">
<option name="originalFiles">
<list>
<option value="$PROJECT_DIR$/pom.xml" />
</list>
</option>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" />
</component>
</project>

6
.idea/vcs.xml Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
</component>
</project>

103
.idea/workspace.xml Normal file
View File

@ -0,0 +1,103 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="AutoImportSettings">
<option name="autoReloadType" value="SELECTIVE" />
</component>
<component name="ChangeListManager">
<list default="true" id="10c8cb4d-8c7e-48ec-a4d5-cffb95288459" name="Changes" comment="">
<change afterPath="$PROJECT_DIR$/.gitignore" afterDir="false" />
<change afterPath="$PROJECT_DIR$/.idea/misc.xml" afterDir="false" />
<change afterPath="$PROJECT_DIR$/.idea/vcs.xml" afterDir="false" />
<change afterPath="$PROJECT_DIR$/.idea/workspace.xml" 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-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/IDiPinShiFinFilingService.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/attendance/IDiPinShiAttendanceService.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/attendance/vo/DiPinShiAttendanceRespVO.java" afterDir="false" />
<change afterPath="$PROJECT_DIR$/fin-filing-quartz/src/main/java/cn/jiutqy/finfiling/quartz/dipinshi/dto/DiPinShiAccessToken.java" afterDir="false" />
<change afterPath="$PROJECT_DIR$/pom.xml" afterDir="false" />
</list>
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
<option name="LAST_RESOLUTION" value="IGNORE" />
</component>
<component name="FileTemplateManagerImpl">
<option name="RECENT_TEMPLATES">
<list>
<option value="Class" />
<option value="Interface" />
</list>
</option>
</component>
<component name="Git.Settings">
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
</component>
<component name="MavenImportPreferences">
<option name="generalSettings">
<MavenGeneralSettings>
<option name="localRepository" value="D:\developSoftware\apache-maven-3.6.3\repository" />
<option name="userSettingsFile" value="D:\developSoftware\apache-maven-3.6.3\conf\settings.xml" />
</MavenGeneralSettings>
</option>
</component>
<component name="ProjectId" id="2p37Aad3GONiU3QEtonY8ISsKbo" />
<component name="ProjectLevelVcsManager" settingsEditedManually="true" />
<component name="ProjectViewState">
<option name="hideEmptyMiddlePackages" value="true" />
<option name="showLibraryContents" value="true" />
</component>
<component name="PropertiesComponent"><![CDATA[{
"keyToString": {
"RunOnceActivity.OpenProjectViewOnStart": "true",
"RunOnceActivity.ShowReadmeOnStart": "true",
"WebServerToolWindowFactoryState": "false",
"last_opened_file_path": "D:/worksplace/dipinshi-hesi",
"node.js.detected.package.eslint": "true",
"node.js.detected.package.tslint": "true",
"node.js.selected.package.eslint": "(autodetect)",
"node.js.selected.package.tslint": "(autodetect)",
"nodejs_package_manager_path": "npm",
"settings.editor.selected.configurable": "reference.projectsettings.compiler.javacompiler",
"vue.rearranger.settings.migration": "true"
}
}]]></component>
<component name="RunManager">
<configuration name="AdminApplication" type="SpringBootApplicationConfigurationType" factoryName="Spring Boot" nameIsGenerated="true">
<module name="fin-filing-admin" />
<option name="SPRING_BOOT_MAIN_CLASS" value="cn.jiutqy.finfiling.AdminApplication" />
<method v="2">
<option name="Make" enabled="true" />
</method>
</configuration>
</component>
<component name="SpellCheckerSettings" RuntimeDictionaries="0" Folders="0" CustomDictionaries="0" DefaultDictionary="application-level" UseSingleDictionary="true" transferred="true" />
<component name="TaskManager">
<task active="true" id="Default" summary="Default task">
<changelist id="10c8cb4d-8c7e-48ec-a4d5-cffb95288459" name="Changes" comment="" />
<created>1731982764438</created>
<option name="number" value="Default" />
<option name="presentableId" value="Default" />
<updated>1731982764438</updated>
<workItem from="1731982765514" duration="3000" />
<workItem from="1731982886946" duration="6741000" />
</task>
<servers />
</component>
<component name="TypeScriptGeneratedFilesManager">
<option name="version" value="3" />
</component>
<component name="Vcs.Log.Tabs.Properties">
<option name="TAB_STATES">
<map>
<entry key="MAIN">
<value>
<State />
</value>
</entry>
</map>
</option>
</component>
</project>

74
deploy/bin/spring-boot.sh Normal file
View File

@ -0,0 +1,74 @@
#!/bin/bash
SpringBoot=$2
if [ "$1" = "" ];
then
echo -e "\033[0;31m 未输入操作名 \033[0m \033[0;34m {start|stop|restart|status} \033[0m"
exit 1
fi
if [ "$SpringBoot" = "" ];
then
echo -e "\033[0;31m 未输入应用名 \033[0m"
exit 1
fi
function start()
{
count=`ps -ef |grep java|grep $SpringBoot|grep -v grep|wc -l`
if [ $count != 0 ];then
echo "$SpringBoot is running..."
else
echo "Start $SpringBoot success..."
nohup java -jar $SpringBoot > /dev/null 2>&1 &
fi
}
function stop()
{
echo "Stop $SpringBoot"
boot_id=`ps -ef |grep java|grep $SpringBoot|grep -v grep|awk '{print $2}'`
count=`ps -ef |grep java|grep $SpringBoot|grep -v grep|wc -l`
if [ $count != 0 ];then
kill $boot_id
count=`ps -ef |grep java|grep $SpringBoot|grep -v grep|wc -l`
boot_id=`ps -ef |grep java|grep $SpringBoot|grep -v grep|awk '{print $2}'`
kill -9 $boot_id
fi
}
function restart()
{
stop
sleep 2
start
}
function status()
{
count=`ps -ef |grep java|grep $SpringBoot|grep -v grep|wc -l`
if [ $count != 0 ];then
echo "$SpringBoot is running..."
else
echo "$SpringBoot is not running..."
fi
}
case $1 in
start)
start;;
stop)
stop;;
restart)
restart;;
status)
status;;
*)
echo -e "\033[0;31m Usage: \033[0m \033[0;34m sh $0 {start|stop|restart|status} {SpringBootJarName} \033[0m
\033[0;31m Example: \033[0m
\033[0;33m sh $0 start esmart-test.jar \033[0m"
esac

469
doc/sql/geyuan-hesi.sql Normal file
View File

@ -0,0 +1,469 @@
/*
Navicat MySQL Data Transfer
Source Server : 119.23.149.63
Source Server Version : 80019
Source Host : 119.23.149.63:3306
Source Database : geyuan-hesi
Target Server Type : MYSQL
Target Server Version : 80019
File Encoding : 65001
Date: 2024-10-16 11:48:16
*/
SET FOREIGN_KEY_CHECKS=0;
-- ----------------------------
-- Table structure for `fin_filing_sync_cursor`
-- ----------------------------
DROP TABLE IF EXISTS `fin_filing_sync_cursor`;
CREATE TABLE `fin_filing_sync_cursor` (
`cursor_id` bigint NOT NULL AUTO_INCREMENT COMMENT '游标ID',
`channel_id` varchar(64) DEFAULT '' COMMENT '输入渠道',
`form_id` varchar(128) DEFAULT '' COMMENT '输入表单ID',
`start_cursor` datetime DEFAULT NULL COMMENT '开始游标',
`end_cursor` datetime DEFAULT NULL COMMENT '结束游标',
`sync_num` int DEFAULT '0' COMMENT '同步数量',
`trace_id` varchar(64) DEFAULT '' COMMENT '日志跟踪ID',
`create_by` varchar(64) DEFAULT '' COMMENT '创建者',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
`update_by` varchar(64) DEFAULT '' COMMENT '更新者',
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
`remark` varchar(4096) DEFAULT NULL COMMENT '备注',
PRIMARY KEY (`cursor_id`),
KEY `index_channel_id_form_id` (`channel_id`,`form_id`)
) ENGINE=InnoDB AUTO_INCREMENT=63 DEFAULT CHARSET=utf8 COMMENT='财务归档同步游标表';
-- ----------------------------
-- Records of fin_filing_sync_cursor
-- ----------------------------
-- ----------------------------
-- Table structure for `fin_filing_sync_log`
-- ----------------------------
DROP TABLE IF EXISTS `fin_filing_sync_log`;
CREATE TABLE `fin_filing_sync_log` (
`log_id` bigint NOT NULL AUTO_INCREMENT COMMENT '日志ID',
`input_channel_id` varchar(64) DEFAULT '' COMMENT '输入渠道ID',
`input_form_id` varchar(128) DEFAULT '' COMMENT '输入表单ID',
`input_data_id` varchar(64) DEFAULT '' COMMENT '输入渠道返回的数据唯一标示',
`input_data` text COMMENT '输入数据原始JSON记录起来同步失败时方便定位问题及补刀',
`input_data_at_json` json DEFAULT NULL COMMENT '输入数据包含的附件地址',
`output_channel_id` varchar(64) DEFAULT '' COMMENT '输出渠道ID',
`output_form_id` varchar(128) DEFAULT '' COMMENT '输出表单ID',
`output_data_id` varchar(64) DEFAULT '' COMMENT '输出渠道返回的数据唯一标示',
`sync_state` int DEFAULT '0' COMMENT '同步状态0-初始化1-成功2-失败',
`error_msg` text COMMENT '错误原因',
`at_sync_state` int DEFAULT '0' COMMENT '附件同步状态0-初始化1-成功2-失败',
`at_error_msg` text COMMENT '错误原因',
`trace_id` varchar(64) DEFAULT '' COMMENT '日志跟踪ID',
`create_by` varchar(64) DEFAULT '' COMMENT '创建者',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
`update_by` varchar(64) DEFAULT '' COMMENT '更新者',
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
`remark` varchar(4096) DEFAULT NULL COMMENT '备注',
PRIMARY KEY (`log_id`)
) ENGINE=InnoDB AUTO_INCREMENT=56 DEFAULT CHARSET=utf8 COMMENT='财务归档同步日志表';
-- ----------------------------
-- Records of fin_filing_sync_log
-- ----------------------------
-- ----------------------------
-- Table structure for `QRTZ_BLOB_TRIGGERS`
-- ----------------------------
DROP TABLE IF EXISTS `QRTZ_BLOB_TRIGGERS`;
CREATE TABLE `QRTZ_BLOB_TRIGGERS` (
`sched_name` varchar(120) COLLATE utf8mb4_general_ci NOT NULL COMMENT '调度名称',
`trigger_name` varchar(200) COLLATE utf8mb4_general_ci NOT NULL COMMENT 'qrtz_triggers表trigger_name的外键',
`trigger_group` varchar(200) COLLATE utf8mb4_general_ci NOT NULL COMMENT 'qrtz_triggers表trigger_group的外键',
`blob_data` blob COMMENT '存放持久化Trigger对象',
PRIMARY KEY (`sched_name`,`trigger_name`,`trigger_group`),
CONSTRAINT `QRTZ_BLOB_TRIGGERS_ibfk_1` FOREIGN KEY (`sched_name`, `trigger_name`, `trigger_group`) REFERENCES `QRTZ_TRIGGERS` (`sched_name`, `trigger_name`, `trigger_group`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='Blob类型的触发器表';
-- ----------------------------
-- Records of QRTZ_BLOB_TRIGGERS
-- ----------------------------
-- ----------------------------
-- Table structure for `QRTZ_CALENDARS`
-- ----------------------------
DROP TABLE IF EXISTS `QRTZ_CALENDARS`;
CREATE TABLE `QRTZ_CALENDARS` (
`sched_name` varchar(120) COLLATE utf8mb4_general_ci NOT NULL COMMENT '调度名称',
`calendar_name` varchar(200) COLLATE utf8mb4_general_ci NOT NULL COMMENT '日历名称',
`calendar` blob NOT NULL COMMENT '存放持久化calendar对象',
PRIMARY KEY (`sched_name`,`calendar_name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='日历信息表';
-- ----------------------------
-- Records of QRTZ_CALENDARS
-- ----------------------------
-- ----------------------------
-- Table structure for `QRTZ_CRON_TRIGGERS`
-- ----------------------------
DROP TABLE IF EXISTS `QRTZ_CRON_TRIGGERS`;
CREATE TABLE `QRTZ_CRON_TRIGGERS` (
`sched_name` varchar(120) COLLATE utf8mb4_general_ci NOT NULL COMMENT '调度名称',
`trigger_name` varchar(200) COLLATE utf8mb4_general_ci NOT NULL COMMENT 'qrtz_triggers表trigger_name的外键',
`trigger_group` varchar(200) COLLATE utf8mb4_general_ci NOT NULL COMMENT 'qrtz_triggers表trigger_group的外键',
`cron_expression` varchar(200) COLLATE utf8mb4_general_ci NOT NULL COMMENT 'cron表达式',
`time_zone_id` varchar(80) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '时区',
PRIMARY KEY (`sched_name`,`trigger_name`,`trigger_group`),
CONSTRAINT `QRTZ_CRON_TRIGGERS_ibfk_1` FOREIGN KEY (`sched_name`, `trigger_name`, `trigger_group`) REFERENCES `QRTZ_TRIGGERS` (`sched_name`, `trigger_name`, `trigger_group`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='Cron类型的触发器表';
-- ----------------------------
-- Records of QRTZ_CRON_TRIGGERS
-- ----------------------------
-- ----------------------------
-- Table structure for `QRTZ_FIRED_TRIGGERS`
-- ----------------------------
DROP TABLE IF EXISTS `QRTZ_FIRED_TRIGGERS`;
CREATE TABLE `QRTZ_FIRED_TRIGGERS` (
`sched_name` varchar(120) COLLATE utf8mb4_general_ci NOT NULL COMMENT '调度名称',
`entry_id` varchar(95) COLLATE utf8mb4_general_ci NOT NULL COMMENT '调度器实例id',
`trigger_name` varchar(200) COLLATE utf8mb4_general_ci NOT NULL COMMENT 'qrtz_triggers表trigger_name的外键',
`trigger_group` varchar(200) COLLATE utf8mb4_general_ci NOT NULL COMMENT 'qrtz_triggers表trigger_group的外键',
`instance_name` varchar(200) COLLATE utf8mb4_general_ci NOT NULL COMMENT '调度器实例名',
`fired_time` bigint NOT NULL COMMENT '触发的时间',
`sched_time` bigint NOT NULL COMMENT '定时器制定的时间',
`priority` int NOT NULL COMMENT '优先级',
`state` varchar(16) COLLATE utf8mb4_general_ci NOT NULL COMMENT '状态',
`job_name` varchar(200) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '任务名称',
`job_group` varchar(200) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '任务组名',
`is_nonconcurrent` varchar(1) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '是否并发',
`requests_recovery` varchar(1) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '是否接受恢复执行',
PRIMARY KEY (`sched_name`,`entry_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='已触发的触发器表';
-- ----------------------------
-- Records of QRTZ_FIRED_TRIGGERS
-- ----------------------------
-- ----------------------------
-- Table structure for `QRTZ_JOB_DETAILS`
-- ----------------------------
DROP TABLE IF EXISTS `QRTZ_JOB_DETAILS`;
CREATE TABLE `QRTZ_JOB_DETAILS` (
`sched_name` varchar(120) COLLATE utf8mb4_general_ci NOT NULL COMMENT '调度名称',
`job_name` varchar(200) COLLATE utf8mb4_general_ci NOT NULL COMMENT '任务名称',
`job_group` varchar(200) COLLATE utf8mb4_general_ci NOT NULL COMMENT '任务组名',
`description` varchar(250) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '相关介绍',
`job_class_name` varchar(250) COLLATE utf8mb4_general_ci NOT NULL COMMENT '执行任务类名称',
`is_durable` varchar(1) COLLATE utf8mb4_general_ci NOT NULL COMMENT '是否持久化',
`is_nonconcurrent` varchar(1) COLLATE utf8mb4_general_ci NOT NULL COMMENT '是否并发',
`is_update_data` varchar(1) COLLATE utf8mb4_general_ci NOT NULL COMMENT '是否更新数据',
`requests_recovery` varchar(1) COLLATE utf8mb4_general_ci NOT NULL COMMENT '是否接受恢复执行',
`job_data` blob COMMENT '存放持久化job对象',
PRIMARY KEY (`sched_name`,`job_name`,`job_group`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='任务详细信息表';
-- ----------------------------
-- Records of QRTZ_JOB_DETAILS
-- ----------------------------
-- ----------------------------
-- Table structure for `QRTZ_LOCKS`
-- ----------------------------
DROP TABLE IF EXISTS `QRTZ_LOCKS`;
CREATE TABLE `QRTZ_LOCKS` (
`sched_name` varchar(120) COLLATE utf8mb4_general_ci NOT NULL COMMENT '调度名称',
`lock_name` varchar(40) COLLATE utf8mb4_general_ci NOT NULL COMMENT '悲观锁名称',
PRIMARY KEY (`sched_name`,`lock_name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='存储的悲观锁信息表';
-- ----------------------------
-- Records of QRTZ_LOCKS
-- ----------------------------
-- ----------------------------
-- Table structure for `QRTZ_PAUSED_TRIGGER_GRPS`
-- ----------------------------
DROP TABLE IF EXISTS `QRTZ_PAUSED_TRIGGER_GRPS`;
CREATE TABLE `QRTZ_PAUSED_TRIGGER_GRPS` (
`sched_name` varchar(120) COLLATE utf8mb4_general_ci NOT NULL COMMENT '调度名称',
`trigger_group` varchar(200) COLLATE utf8mb4_general_ci NOT NULL COMMENT 'qrtz_triggers表trigger_group的外键',
PRIMARY KEY (`sched_name`,`trigger_group`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='暂停的触发器表';
-- ----------------------------
-- Records of QRTZ_PAUSED_TRIGGER_GRPS
-- ----------------------------
-- ----------------------------
-- Table structure for `QRTZ_SCHEDULER_STATE`
-- ----------------------------
DROP TABLE IF EXISTS `QRTZ_SCHEDULER_STATE`;
CREATE TABLE `QRTZ_SCHEDULER_STATE` (
`sched_name` varchar(120) COLLATE utf8mb4_general_ci NOT NULL COMMENT '调度名称',
`instance_name` varchar(200) COLLATE utf8mb4_general_ci NOT NULL COMMENT '实例名称',
`last_checkin_time` bigint NOT NULL COMMENT '上次检查时间',
`checkin_interval` bigint NOT NULL COMMENT '检查间隔时间',
PRIMARY KEY (`sched_name`,`instance_name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='调度器状态表';
-- ----------------------------
-- Records of QRTZ_SCHEDULER_STATE
-- ----------------------------
-- ----------------------------
-- Table structure for `QRTZ_SIMPLE_TRIGGERS`
-- ----------------------------
DROP TABLE IF EXISTS `QRTZ_SIMPLE_TRIGGERS`;
CREATE TABLE `QRTZ_SIMPLE_TRIGGERS` (
`sched_name` varchar(120) COLLATE utf8mb4_general_ci NOT NULL COMMENT '调度名称',
`trigger_name` varchar(200) COLLATE utf8mb4_general_ci NOT NULL COMMENT 'qrtz_triggers表trigger_name的外键',
`trigger_group` varchar(200) COLLATE utf8mb4_general_ci NOT NULL COMMENT 'qrtz_triggers表trigger_group的外键',
`repeat_count` bigint NOT NULL COMMENT '重复的次数统计',
`repeat_interval` bigint NOT NULL COMMENT '重复的间隔时间',
`times_triggered` bigint NOT NULL COMMENT '已经触发的次数',
PRIMARY KEY (`sched_name`,`trigger_name`,`trigger_group`),
CONSTRAINT `QRTZ_SIMPLE_TRIGGERS_ibfk_1` FOREIGN KEY (`sched_name`, `trigger_name`, `trigger_group`) REFERENCES `QRTZ_TRIGGERS` (`sched_name`, `trigger_name`, `trigger_group`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='简单触发器的信息表';
-- ----------------------------
-- Records of QRTZ_SIMPLE_TRIGGERS
-- ----------------------------
-- ----------------------------
-- Table structure for `QRTZ_SIMPROP_TRIGGERS`
-- ----------------------------
DROP TABLE IF EXISTS `QRTZ_SIMPROP_TRIGGERS`;
CREATE TABLE `QRTZ_SIMPROP_TRIGGERS` (
`sched_name` varchar(120) COLLATE utf8mb4_general_ci NOT NULL COMMENT '调度名称',
`trigger_name` varchar(200) COLLATE utf8mb4_general_ci NOT NULL COMMENT 'qrtz_triggers表trigger_name的外键',
`trigger_group` varchar(200) COLLATE utf8mb4_general_ci NOT NULL COMMENT 'qrtz_triggers表trigger_group的外键',
`str_prop_1` varchar(512) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT 'String类型的trigger的第一个参数',
`str_prop_2` varchar(512) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT 'String类型的trigger的第二个参数',
`str_prop_3` varchar(512) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT 'String类型的trigger的第三个参数',
`int_prop_1` int DEFAULT NULL COMMENT 'int类型的trigger的第一个参数',
`int_prop_2` int DEFAULT NULL COMMENT 'int类型的trigger的第二个参数',
`long_prop_1` bigint DEFAULT NULL COMMENT 'long类型的trigger的第一个参数',
`long_prop_2` bigint DEFAULT NULL COMMENT 'long类型的trigger的第二个参数',
`dec_prop_1` decimal(13,4) DEFAULT NULL COMMENT 'decimal类型的trigger的第一个参数',
`dec_prop_2` decimal(13,4) DEFAULT NULL COMMENT 'decimal类型的trigger的第二个参数',
`bool_prop_1` varchar(1) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT 'Boolean类型的trigger的第一个参数',
`bool_prop_2` varchar(1) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT 'Boolean类型的trigger的第二个参数',
PRIMARY KEY (`sched_name`,`trigger_name`,`trigger_group`),
CONSTRAINT `QRTZ_SIMPROP_TRIGGERS_ibfk_1` FOREIGN KEY (`sched_name`, `trigger_name`, `trigger_group`) REFERENCES `QRTZ_TRIGGERS` (`sched_name`, `trigger_name`, `trigger_group`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='同步机制的行锁表';
-- ----------------------------
-- Records of QRTZ_SIMPROP_TRIGGERS
-- ----------------------------
-- ----------------------------
-- Table structure for `QRTZ_TRIGGERS`
-- ----------------------------
DROP TABLE IF EXISTS `QRTZ_TRIGGERS`;
CREATE TABLE `QRTZ_TRIGGERS` (
`sched_name` varchar(120) COLLATE utf8mb4_general_ci NOT NULL COMMENT '调度名称',
`trigger_name` varchar(200) COLLATE utf8mb4_general_ci NOT NULL COMMENT '触发器的名字',
`trigger_group` varchar(200) COLLATE utf8mb4_general_ci NOT NULL COMMENT '触发器所属组的名字',
`job_name` varchar(200) COLLATE utf8mb4_general_ci NOT NULL COMMENT 'qrtz_job_details表job_name的外键',
`job_group` varchar(200) COLLATE utf8mb4_general_ci NOT NULL COMMENT 'qrtz_job_details表job_group的外键',
`description` varchar(250) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '相关介绍',
`next_fire_time` bigint DEFAULT NULL COMMENT '上一次触发时间(毫秒)',
`prev_fire_time` bigint DEFAULT NULL COMMENT '下一次触发时间(默认为-1表示不触发',
`priority` int DEFAULT NULL COMMENT '优先级',
`trigger_state` varchar(16) COLLATE utf8mb4_general_ci NOT NULL COMMENT '触发器状态',
`trigger_type` varchar(8) COLLATE utf8mb4_general_ci NOT NULL COMMENT '触发器的类型',
`start_time` bigint NOT NULL COMMENT '开始时间',
`end_time` bigint DEFAULT NULL COMMENT '结束时间',
`calendar_name` varchar(200) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '日程表名称',
`misfire_instr` smallint DEFAULT NULL COMMENT '补偿执行的策略',
`job_data` blob COMMENT '存放持久化job对象',
PRIMARY KEY (`sched_name`,`trigger_name`,`trigger_group`),
KEY `sched_name` (`sched_name`,`job_name`,`job_group`),
CONSTRAINT `QRTZ_TRIGGERS_ibfk_1` FOREIGN KEY (`sched_name`, `job_name`, `job_group`) REFERENCES `QRTZ_JOB_DETAILS` (`sched_name`, `job_name`, `job_group`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='触发器详细信息表';
-- ----------------------------
-- Records of QRTZ_TRIGGERS
-- ----------------------------
-- ----------------------------
-- Table structure for `sys_config`
-- ----------------------------
DROP TABLE IF EXISTS `sys_config`;
CREATE TABLE `sys_config` (
`config_id` int NOT NULL AUTO_INCREMENT COMMENT '参数主键',
`config_name` varchar(100) COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '参数名称',
`config_key` varchar(100) COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '参数键名',
`config_value` varchar(500) COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '参数键值',
`config_type` char(1) COLLATE utf8mb4_general_ci DEFAULT 'N' COMMENT '系统内置Y是 N否',
`create_by` varchar(64) COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '创建者',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
`update_by` varchar(64) COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '更新者',
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
`remark` varchar(500) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '备注',
PRIMARY KEY (`config_id`)
) ENGINE=InnoDB AUTO_INCREMENT=100 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='参数配置表';
-- ----------------------------
-- Records of sys_config
-- ----------------------------
INSERT INTO `sys_config` VALUES ('1', '主框架页-默认皮肤样式名称', 'sys.index.skinName', 'skin-blue', 'Y', 'admin', '2024-10-11 15:32:44', '', null, '蓝色 skin-blue、绿色 skin-green、紫色 skin-purple、红色 skin-red、黄色 skin-yellow');
INSERT INTO `sys_config` VALUES ('2', '用户管理-账号初始密码', 'sys.user.initPassword', '123456', 'Y', 'admin', '2024-10-11 15:32:44', '', null, '初始化密码 123456');
INSERT INTO `sys_config` VALUES ('3', '主框架页-侧边栏主题', 'sys.index.sideTheme', 'theme-dark', 'Y', 'admin', '2024-10-11 15:32:44', '', null, '深色主题theme-dark浅色主题theme-light');
INSERT INTO `sys_config` VALUES ('4', '账号自助-验证码开关', 'sys.account.captchaEnabled', 'true', 'Y', 'admin', '2024-10-11 15:32:44', '', null, '是否开启验证码功能true开启false关闭');
INSERT INTO `sys_config` VALUES ('5', '账号自助-是否开启用户注册功能', 'sys.account.registerUser', 'false', 'Y', 'admin', '2024-10-11 15:32:44', '', null, '是否开启注册用户功能true开启false关闭');
INSERT INTO `sys_config` VALUES ('6', '用户登录-黑名单列表', 'sys.login.blackIPList', '', 'Y', 'admin', '2024-10-11 15:32:44', '', null, '设置登录IP黑名单限制多个匹配项以;分隔,支持匹配(*通配、网段)');
-- ----------------------------
-- Table structure for `sys_dict_data`
-- ----------------------------
DROP TABLE IF EXISTS `sys_dict_data`;
CREATE TABLE `sys_dict_data` (
`dict_code` bigint NOT NULL AUTO_INCREMENT COMMENT '字典编码',
`dict_sort` int DEFAULT '0' COMMENT '字典排序',
`dict_label` varchar(100) COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '字典标签',
`dict_value` varchar(100) COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '字典键值',
`dict_type` varchar(100) COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '字典类型',
`css_class` varchar(100) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '样式属性(其他样式扩展)',
`list_class` varchar(100) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '表格回显样式',
`is_default` char(1) COLLATE utf8mb4_general_ci DEFAULT 'N' COMMENT '是否默认Y是 N否',
`status` char(1) COLLATE utf8mb4_general_ci DEFAULT '0' COMMENT '状态0正常 1停用',
`create_by` varchar(64) COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '创建者',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
`update_by` varchar(64) COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '更新者',
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
`remark` varchar(500) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '备注',
PRIMARY KEY (`dict_code`)
) ENGINE=InnoDB AUTO_INCREMENT=100 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='字典数据表';
-- ----------------------------
-- Records of sys_dict_data
-- ----------------------------
-- ----------------------------
-- Table structure for `sys_dict_type`
-- ----------------------------
DROP TABLE IF EXISTS `sys_dict_type`;
CREATE TABLE `sys_dict_type` (
`dict_id` bigint NOT NULL AUTO_INCREMENT COMMENT '字典主键',
`dict_name` varchar(100) COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '字典名称',
`dict_type` varchar(100) COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '字典类型',
`status` char(1) COLLATE utf8mb4_general_ci DEFAULT '0' COMMENT '状态0正常 1停用',
`create_by` varchar(64) COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '创建者',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
`update_by` varchar(64) COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '更新者',
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
`remark` varchar(500) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '备注',
PRIMARY KEY (`dict_id`),
UNIQUE KEY `dict_type` (`dict_type`)
) ENGINE=InnoDB AUTO_INCREMENT=100 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='字典类型表';
-- ----------------------------
-- Records of sys_dict_type
-- ----------------------------
-- ----------------------------
-- Table structure for `sys_job`
-- ----------------------------
DROP TABLE IF EXISTS `sys_job`;
CREATE TABLE `sys_job` (
`job_id` bigint NOT NULL AUTO_INCREMENT COMMENT '任务ID',
`job_name` varchar(64) NOT NULL DEFAULT '' COMMENT '任务名称',
`job_group` varchar(64) NOT NULL DEFAULT 'DEFAULT' COMMENT '任务组名',
`invoke_target` varchar(500) NOT NULL COMMENT '调用目标字符串',
`cron_expression` varchar(255) DEFAULT '' COMMENT 'cron执行表达式',
`misfire_policy` varchar(20) DEFAULT '3' COMMENT '计划执行错误策略1立即执行 2执行一次 3放弃执行',
`concurrent` char(1) DEFAULT '1' COMMENT '是否并发执行0允许 1禁止',
`status` char(1) DEFAULT '0' COMMENT '状态0正常 1暂停',
`create_by` varchar(64) DEFAULT '' COMMENT '创建者',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
`update_by` varchar(64) DEFAULT '' COMMENT '更新者',
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
`remark` varchar(500) DEFAULT '' COMMENT '备注信息',
PRIMARY KEY (`job_id`,`job_name`,`job_group`)
) ENGINE=InnoDB AUTO_INCREMENT=101 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='定时任务调度表';
-- ----------------------------
-- Records of sys_job
-- ----------------------------
INSERT INTO `sys_job` VALUES ('1', '系统默认(无参)', 'DEFAULT', 'ryTask.ryNoParams', '0/10 * * * * ?', '3', '1', '1', 'admin', '2024-10-14 05:24:40', '', null, '');
INSERT INTO `sys_job` VALUES ('2', '系统默认(有参)', 'DEFAULT', 'ryTask.ryParams(\'ry\')', '0/15 * * * * ?', '3', '1', '1', 'admin', '2024-10-14 05:24:40', '', null, '');
INSERT INTO `sys_job` VALUES ('3', '系统默认(多参)', 'DEFAULT', 'ryTask.ryMultipleParams(\'ry\', true, 2000L, 316.50D, 100)', '0/20 * * * * ?', '3', '1', '1', 'admin', '2024-10-14 05:24:40', '', null, '');
INSERT INTO `sys_job` VALUES ('100', '差旅和外出申请同步', 'DEFAULT', 'abnormalRetryTask.retry', '0 0/30 * * * ?', '3', '1', '0', 'admin', '2024-10-15 02:51:04', '', null, '');
-- ----------------------------
-- Table structure for `sys_job_log`
-- ----------------------------
DROP TABLE IF EXISTS `sys_job_log`;
CREATE TABLE `sys_job_log` (
`job_log_id` bigint NOT NULL AUTO_INCREMENT COMMENT '任务日志ID',
`job_name` varchar(64) NOT NULL COMMENT '任务名称',
`job_group` varchar(64) NOT NULL COMMENT '任务组名',
`invoke_target` varchar(500) NOT NULL COMMENT '调用目标字符串',
`job_message` varchar(500) DEFAULT NULL COMMENT '日志信息',
`status` char(1) DEFAULT '0' COMMENT '执行状态0正常 1失败',
`exception_info` varchar(2000) DEFAULT '' COMMENT '异常信息',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
PRIMARY KEY (`job_log_id`)
) ENGINE=InnoDB AUTO_INCREMENT=34 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='定时任务调度日志表';
-- ----------------------------
-- Records of sys_job_log
-- ----------------------------
-- ----------------------------
-- Table structure for `sys_logininfor`
-- ----------------------------
DROP TABLE IF EXISTS `sys_logininfor`;
CREATE TABLE `sys_logininfor` (
`info_id` bigint NOT NULL AUTO_INCREMENT COMMENT '访问ID',
`user_name` varchar(50) COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '用户账号',
`ipaddr` varchar(128) COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '登录IP地址',
`login_location` varchar(255) COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '登录地点',
`browser` varchar(50) COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '浏览器类型',
`os` varchar(50) COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '操作系统',
`status` char(1) COLLATE utf8mb4_general_ci DEFAULT '0' COMMENT '登录状态0成功 1失败',
`msg` varchar(255) COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '提示消息',
`login_time` datetime DEFAULT NULL COMMENT '访问时间',
PRIMARY KEY (`info_id`),
KEY `idx_sys_logininfor_s` (`status`),
KEY `idx_sys_logininfor_lt` (`login_time`)
) ENGINE=InnoDB AUTO_INCREMENT=100 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='系统访问记录';
-- ----------------------------
-- Records of sys_logininfor
-- ----------------------------
-- ----------------------------
-- Table structure for `sys_user`
-- ----------------------------
DROP TABLE IF EXISTS `sys_user`;
CREATE TABLE `sys_user` (
`user_id` bigint NOT NULL AUTO_INCREMENT COMMENT '用户ID',
`dept_id` bigint DEFAULT NULL COMMENT '部门ID',
`user_name` varchar(30) COLLATE utf8mb4_general_ci NOT NULL COMMENT '用户账号',
`nick_name` varchar(30) COLLATE utf8mb4_general_ci NOT NULL COMMENT '用户昵称',
`user_type` varchar(2) COLLATE utf8mb4_general_ci DEFAULT '00' COMMENT '用户类型00系统用户',
`email` varchar(50) COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '用户邮箱',
`phonenumber` varchar(11) COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '手机号码',
`sex` char(1) COLLATE utf8mb4_general_ci DEFAULT '0' COMMENT '用户性别0男 1女 2未知',
`avatar` varchar(100) COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '头像地址',
`password` varchar(100) COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '密码',
`status` char(1) COLLATE utf8mb4_general_ci DEFAULT '0' COMMENT '帐号状态0正常 1停用',
`del_flag` char(1) COLLATE utf8mb4_general_ci DEFAULT '0' COMMENT '删除标志0代表存在 2代表删除',
`login_ip` varchar(128) COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '最后登录IP',
`login_date` datetime DEFAULT NULL COMMENT '最后登录时间',
`create_by` varchar(64) COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '创建者',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
`update_by` varchar(64) COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '更新者',
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
`remark` varchar(500) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '备注',
PRIMARY KEY (`user_id`)
) ENGINE=InnoDB AUTO_INCREMENT=100 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='用户信息表';
-- ----------------------------
-- Records of sys_user
-- ----------------------------
INSERT INTO `sys_user` VALUES ('1', '103', 'admin', '玮驰', '00', null, null, '1', '', '$2a$10$7JB720yubVSZvUI0rEqK/.VqGOZTH.ulu33dHOiBE8ByOhJIrdAu2', '0', '0', null, '2024-10-11 15:32:36', 'admin', '2024-10-11 15:32:36', '', null, '管理员');

BIN
doc/框架说明文档.docx Normal file

Binary file not shown.

68
fin-filing-admin/pom.xml Normal file
View File

@ -0,0 +1,68 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>dipinshi-hesi</artifactId>
<groupId>cn.jiutqy</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>fin-filing-admin</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>cn.jiutqy</groupId>
<artifactId>fin-filing-common</artifactId>
</dependency>
<dependency>
<groupId>cn.jiutqy</groupId>
<artifactId>fin-filing-quartz</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.5.15</version>
<configuration>
<fork>true</fork> <!-- 如果没有该配置devtools不会生效 -->
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>3.1.0</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
<warName>${project.artifactId}</warName>
</configuration>
</plugin>
</plugins>
<finalName>${project.artifactId}</finalName>
</build>
</project>

View File

@ -0,0 +1,22 @@
package cn.jiutqy.finfiling;
import lombok.extern.slf4j.Slf4j;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.ComponentScans;
@Slf4j
@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class })
@ComponentScans({@ComponentScan("cn.jiutqy")})
@MapperScan({"cn.jiutqy.**.mapper"})
public class AdminApplication {
public static void main(String[] args) {
SpringApplication.run(AdminApplication.class, args);
}
}

View File

@ -0,0 +1 @@
restart.include.json=/com.alibaba.fastjson2.*.jar

View File

@ -0,0 +1,115 @@
# 项目相关配置
jiutqy:
# 名称
name: 九天青云财务归档平台
# 版本
version: 3.8.8
# 版权年份
copyrightYear: 2024
# 文件路径 示例( Windows配置D:/jiutqy/uploadPathLinux配置 /home/jiutqy/uploadPath
profile: D:/jiutqy/uploadPath
# 获取ip地址开关
addressEnabled: false
# 验证码类型 math 数字计算 char 字符验证
captchaType: math
# 开发环境配置
server:
# 服务器的HTTP端口默认为8080
port: 8080
servlet:
# 应用的访问路径
context-path: /
tomcat:
# tomcat的URI编码
uri-encoding: UTF-8
# 连接数满后的排队数默认为100
accept-count: 1000
threads:
# tomcat最大线程数默认为200
max: 800
# Tomcat启动初始化的线程数默认值10
min-spare: 100
# 日志配置
logging:
level:
cn.jiutqy: debug
org.springframework: warn
# token配置
token:
# 令牌自定义标识
header: Authorization
# 令牌密钥
secret: abcdefghijklmnopqrstuvwxyz
# 令牌有效期默认30分钟
expireTime: 30
# Swagger配置
swagger:
# 是否开启swagger
enabled: true
# 请求前缀
pathMapping: /dev-api
# 数据源配置
spring:
datasource:
druid:
stat-view-servlet:
enabled: true
loginUsername: jiutqy
loginPassword: 123456
dynamic:
druid:
initial-size: 5
min-idle: 5
maxActive: 20
maxWait: 60000
connectTimeout: 30000
socketTimeout: 60000
timeBetweenEvictionRunsMillis: 60000
minEvictableIdleTimeMillis: 300000
validationQuery: SELECT 1 FROM DUAL
testWhileIdle: true
testOnBorrow: false
testOnReturn: false
poolPreparedStatements: true
maxPoolPreparedStatementPerConnectionSize: 20
filters: stat,slf4j
connectionProperties: druid.stat.mergeSql\=true;druid.stat.slowSqlMillis\=5000
datasource:
# 主库数据源
master:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/ry-vue?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
username: root
password:
finfiling:
storeType: yml
input:
channel:
dipinshi:
host: https://qyapi.weixin.qq.com
oauth:
reqUrl: https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid={corpid}}&corpsecret={corpsecret}
appId:
appSecret:
output:
channel:
hosecloud:
host: https://app.ekuaibao.com
oauth:
reqUrl: https://app.ekuaibao.com/api/openapi/v1/auth/getAccessToken
appId: 0ed9a207-c594-460c-9245-91dee9260a9c
appSecret: fc559d05-bc67-4d34-9c15-e2953fe97bb8

View File

@ -0,0 +1,68 @@
# 用户配置
user:
password:
# 密码最大错误次数
maxRetryCount: 5
# 密码锁定时间默认10分钟
lockTime: 10
# Spring配置
spring:
profiles:
active: dev
# 文件上传
servlet:
multipart:
# 单个文件大小
max-file-size: 10MB
# 设置总上传的文件大小
max-request-size: 20MB
# 服务模块
devtools:
restart:
# 热部署开关
enabled: true
# MyBatis Plus配置
mybatis-plus:
# 搜索指定包别名
typeAliasesPackage: cn.jiutqy.**.domain
# 配置mapper的扫描找到所有的mapper.xml映射文件
mapperLocations: classpath*:mapper/**/*Mapper.xml
# 加载全局的配置文件
configLocation: classpath:mybatis/mybatis-config.xml
global-config:
enable-sql-runner: true
# PageHelper分页插件
pagehelper:
helperDialect: mysql
supportMethodsArguments: true
params: count=countSql
# 防止XSS攻击
xss:
# 过滤开关
enabled: true
# 排除链接(多个用逗号分隔)
excludes: /system/notice
# 匹配链接
urlPatterns: /system/*,/monitor/*,/tool/*
ok:
http:
connect-timeout: 60
read-timeout: 60
write-timeout: 60
# 连接池中整体的空闲连接的最大数量
max-idle-connections: 200
# 连接空闲时间最多为 300 秒
keep-alive-duration: 300
tlog:
pattern: '$traceId'

View File

@ -0,0 +1,11 @@
( ( ( * ) ( )
( ( )\ ) )\ ) )\ ) ( ( ` ( ( ( /( )\ ) ( /(
)\ )\ (()/( (()/( (()/( )\ )\))( ( )\))( ')\()) (()/( )\())
(((_)((((_)( /(_)) /(_)) /(_))((((_)( ((_)()\ )\ ((_)()\ )((_)\ /(_))|((_)\
)\___ )\ _ )\ (_)) (_))_|(_)) )\ _ )\ (_()((_)((_) _(())\_)() ((_) (_)) |_ ((_)
((/ __|(_)_\(_)| _ \ | |_ | _ \ (_)_\(_)| \/ || __|\ \((_)/ // _ \ | _ \ | |/ /
| (__ / _ \ | _/ | __| | / / _ \ | |\/| || _| \ \/\/ /| (_) || / ' <
\___|/_/ \_\ |_| |_| |_|_\ /_/ \_\ |_| |_||___| \_/\_/ \___/ |_|_\ _|\_\
:: JIUTQY FRAMEWORK :: (v1.0.0.SNAPSHOT)

View File

@ -0,0 +1,96 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!-- 增加如下的TLog MDC Listener -->
<contextListener class="com.yomahub.tlog.core.enhance.logback.TLogLogbackTTLMdcListener"/>
<!-- 日志存放路径 -->
<property name="log.path" value="logs" />
<!-- 日志输出格式 -->
<property name="log.pattern" value="%d{HH:mm:ss.SSS} %X{tl} [%thread] %-5level %logger{50} - [%method,%line] - %msg%n" />
<!-- 控制台输出 -->
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="com.yomahub.tlog.core.enhance.logback.AspectLogbackEncoder">
<pattern>${log.pattern}</pattern>
</encoder>
</appender>
<!-- 系统日志输出 -->
<appender name="file_info" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.path}/sys-info.log</file>
<!-- 循环政策:基于时间创建日志文件 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 日志文件名格式 -->
<fileNamePattern>${log.path}/sys-info.%d{yyyy-MM-dd}.log</fileNamePattern>
<!-- 日志最大的历史 60天 -->
<maxHistory>60</maxHistory>
</rollingPolicy>
<encoder class="com.yomahub.tlog.core.enhance.logback.AspectLogbackEncoder">
<pattern>${log.pattern}</pattern>
</encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<!-- 过滤的级别 -->
<level>INFO</level>
<!-- 匹配时的操作:接收(记录) -->
<onMatch>ACCEPT</onMatch>
<!-- 不匹配时的操作:拒绝(不记录) -->
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<appender name="file_error" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.path}/sys-error.log</file>
<!-- 循环政策:基于时间创建日志文件 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 日志文件名格式 -->
<fileNamePattern>${log.path}/sys-error.%d{yyyy-MM-dd}.log</fileNamePattern>
<!-- 日志最大的历史 60天 -->
<maxHistory>60</maxHistory>
</rollingPolicy>
<encoder class="com.yomahub.tlog.core.enhance.logback.AspectLogbackEncoder">
<pattern>${log.pattern}</pattern>
</encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<!-- 过滤的级别 -->
<level>ERROR</level>
<!-- 匹配时的操作:接收(记录) -->
<onMatch>ACCEPT</onMatch>
<!-- 不匹配时的操作:拒绝(不记录) -->
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- 用户访问日志输出 -->
<appender name="sys-user" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.path}/sys-user.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 按天回滚 daily -->
<fileNamePattern>${log.path}/sys-user.%d{yyyy-MM-dd}.log</fileNamePattern>
<!-- 日志最大的历史 60天 -->
<maxHistory>60</maxHistory>
</rollingPolicy>
<encoder>
<pattern>${log.pattern}</pattern>
</encoder>
</appender>
<!-- 系统模块日志级别控制 -->
<logger name="cn.jiutqy" level="info" />
<!-- Spring日志级别控制 -->
<logger name="org.springframework" level="warn" />
<root level="info">
<appender-ref ref="console" />
</root>
<!--系统操作日志-->
<root level="info">
<appender-ref ref="file_info" />
<appender-ref ref="file_error" />
</root>
<!--系统用户操作日志-->
<logger name="sys-user" level="info">
<appender-ref ref="sys-user"/>
</logger>
</configuration>

View File

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!-- 全局参数 -->
<settings>
<!-- 使全局的映射器启用或禁用缓存 -->
<setting name="cacheEnabled" value="true" />
<!-- 允许JDBC 支持自动生成主键 -->
<setting name="useGeneratedKeys" value="true" />
<!-- 配置默认的执行器.SIMPLE就是普通执行器;REUSE执行器会重用预处理语句(prepared statements);BATCH执行器将重用语句并执行批量更新 -->
<setting name="defaultExecutorType" value="SIMPLE" />
<!-- 指定 MyBatis 所用日志的具体实现 -->
<setting name="logImpl" value="SLF4J" />
<!-- 使用驼峰命名法转换字段 -->
<!-- <setting name="mapUnderscoreToCamelCase" value="true"/> -->
</settings>
</configuration>

View File

@ -0,0 +1,25 @@
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

@ -0,0 +1,101 @@
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

@ -0,0 +1,34 @@
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 TestU9CFinFilingService {
@Autowired
private DefaultFormFinFilingService defaultFormFinFilingService;
@Autowired
private DefaultFormAtFinFilingService defaultFormAtFinFilingService;
// 测试U9C附件上传
@Test
public void testSyncAt(){
defaultFormAtFinFilingService.syncData("u9c","at");
}
//测试报销单
@Test
public void testSyncExpense2(){
String channelId = "u9c";
String formId = "UFData9002021";
defaultFormFinFilingService.syncData(channelId, formId);
}
}

20
fin-filing-common/pom.xml Normal file
View File

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>dipinshi-hesi</artifactId>
<groupId>cn.jiutqy</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>fin-filing-common</artifactId>
<packaging>jar</packaging>
<dependencies>
</dependencies>
</project>

View File

@ -0,0 +1,23 @@
package cn.jiutqy.finfiling.common.config;
import cn.jiutqy.finfiling.common.config.properties.FinFilingInputProperties;
import cn.jiutqy.finfiling.common.config.properties.FinFilingMappingProperties;
import cn.jiutqy.finfiling.common.config.properties.FinFilingOutputProperties;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@Data
@Component
@ConfigurationProperties(prefix = "finfiling")
public class FinFilingConfig {
private String storeType;
private FinFilingInputProperties input;
private FinFilingMappingProperties mapping;
private FinFilingOutputProperties output;
}

View File

@ -0,0 +1,34 @@
package cn.jiutqy.finfiling.common.config.properties;
import cn.jiutqy.archives.common.utils.DateUtils;
import lombok.Data;
import java.util.Map;
@Data
public class FinFilingChannelProperties {
private String channelId;
private String host;
private Integer pageNum = 1;
private Integer pageSize = 5;
/**
* 首次同步过去多长时间的数据格式为1d 1h 1min 1sec默认为1d
*/
private String firstPassTime = "30d";
private String cursorFormat = DateUtils.YYYY_MM_DD_HH_MM_SS;
private Map<String, String> reqHeader;
private FinFilingOauthProperties oauth;
private Map<String, FinFilingFormProperties> forms;
private String key;
}

View File

@ -0,0 +1,41 @@
package cn.jiutqy.finfiling.common.config.properties;
import lombok.Data;
import java.util.Map;
@Data
public class FinFilingFormProperties {
private String formId;
private Integer pageNum;
private Integer pageSize;
/**
* 同步过去多长时间的数据格式为1d 1h 1min 1sec默认为1d
*/
private String firstPassTime;
private String cursorFormat;
private String groupByField;
private String reqUrl;
private String reqMethod;
private Map<String, String> reqParam;
private Map<String, String> reqHeader;
private String reqBody;
private String resDataRootNode = "$";
private String resDataIdNode;
private Integer sleepMS = 100;
}

View File

@ -0,0 +1,13 @@
package cn.jiutqy.finfiling.common.config.properties;
import lombok.Data;
import java.util.Map;
@Data
public class FinFilingInputProperties {
private Map<String,FinFilingChannelProperties> channel;
}

View File

@ -0,0 +1,12 @@
package cn.jiutqy.finfiling.common.config.properties;
import lombok.Data;
@Data
public class FinFilingMappingChannelRelationProperties {
private String inputChannelId;
private String outputChannelId;
}

View File

@ -0,0 +1,12 @@
package cn.jiutqy.finfiling.common.config.properties;
import lombok.Data;
@Data
public class FinFilingMappingFieldRelationProperties {
private String inputField;
private String outputField;
}

View File

@ -0,0 +1,16 @@
package cn.jiutqy.finfiling.common.config.properties;
import lombok.Data;
import java.util.Map;
@Data
public class FinFilingMappingFormRelationProperties {
private String inputFormId;
private String outputFormId;
private String outputAtFormId;
}

View File

@ -0,0 +1,12 @@
package cn.jiutqy.finfiling.common.config.properties;
import lombok.Data;
import java.util.List;
@Data
public class FinFilingMappingProperties {
private List<FinFilingMappingRelationProperties> relation;
}

View File

@ -0,0 +1,18 @@
package cn.jiutqy.finfiling.common.config.properties;
import lombok.Data;
import java.util.List;
@Data
public class FinFilingMappingRelationProperties {
private FinFilingMappingChannelRelationProperties channelRelation;
private FinFilingMappingFormRelationProperties formRelation;
private List<FinFilingMappingFieldRelationProperties> fieldRelation;
}

View File

@ -0,0 +1,18 @@
package cn.jiutqy.finfiling.common.config.properties;
import lombok.Data;
@Data
public class FinFilingOauthProperties {
private String reqUrl;
private String reqMethod;
private String appId;
private String appSecret;
private String channelKey;
}

View File

@ -0,0 +1,12 @@
package cn.jiutqy.finfiling.common.config.properties;
import lombok.Data;
import java.util.Map;
@Data
public class FinFilingOutputProperties {
private Map<String,FinFilingChannelProperties> channel;
}

View File

@ -0,0 +1,49 @@
package cn.jiutqy.finfiling.common.domain;
import cn.jiutqy.archives.common.core.domain.BaseEntity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.util.Date;
@Data
@TableName("fin_filing_sync_cursor")
public class FinFilingSyncCursor extends BaseEntity {
@TableId(type = IdType.AUTO)
private Long cursorId;
/**
* 输入渠道ID
*/
private String channelId;
/**
* 输入表单ID
*/
private String formId;
/**
* 开始游标
*/
private Date startCursor;
/**
* 结束游标
*/
private Date endCursor;
/**
* 同步数量
*/
private Integer syncNum;
/**
* 日志跟踪ID
*/
private String traceId;
}

View File

@ -0,0 +1,83 @@
package cn.jiutqy.finfiling.common.domain;
import cn.jiutqy.archives.common.core.domain.BaseEntity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
@Data
@TableName("fin_filing_sync_log")
public class FinFilingSyncLog extends BaseEntity {
@TableId(type = IdType.AUTO)
private Long logId;
/**
* 输入渠道ID
*/
private String inputChannelId;
/**
* 输入表单ID
*/
private String inputFormId;
/**
* 输入渠道返回的数据唯一标示
*/
private String inputDataId;
/**
* 输入数据原始JSON记录起来同步失败时方便定位问题及补刀
*/
private String inputData;
/**
* 输入数据包含的附件地址
*/
private String inputDataAtJson;
/**
* 输出渠道ID
*/
private String outputChannelId;
/**
* 输出表单ID
*/
private String outputFormId;
/**
* 输出渠道返回的数据唯一标示
*/
private String outputDataId;
/**
* 同步状态0-初始化1-成功2-失败
*/
private Integer syncState;
/**
* 错误原因
*/
private String errorMsg;
/**
* 附件同步状态0-初始化1-成功2-失败
*/
private Integer atSyncState;
/**
* 错误原因
*/
private String atErrorMsg;
/**
* 日志跟踪ID
*/
private String traceId;
}

View File

@ -0,0 +1,16 @@
package cn.jiutqy.finfiling.common.dto;
import lombok.Data;
import lombok.NoArgsConstructor;
@NoArgsConstructor
@Data
public class FinFilingAccessToken {
private String accessToken;
private String refreshToken;
private Long expireTime;
}

View File

@ -0,0 +1,33 @@
package cn.jiutqy.finfiling.common.dto;
import com.alibaba.fastjson2.JSONObject;
import lombok.Data;
import org.springframework.util.CollectionUtils;
import java.util.List;
@Data
public class FinFilingData {
private String inputDataId;
private JSONObject inputData;
private FinFilingDataAtJson inputDataAtJson;
private String outputDataId;
private JSONObject outputData;
public void addFinFilingDataAtUploadUrls(List<FinFilingDataAtUploadUrl> uploadUrls){
if(CollectionUtils.isEmpty(uploadUrls)){
return;
}
if(null == inputDataAtJson){
inputDataAtJson = new FinFilingDataAtJson();
}
inputDataAtJson.setType("1");
inputDataAtJson.getUploadUrls().addAll(uploadUrls);
}
}

View File

@ -0,0 +1,20 @@
package cn.jiutqy.finfiling.common.dto;
import lombok.Data;
import java.util.ArrayList;
import java.util.List;
@Data
public class FinFilingDataAtJson {
/**
* 文件关联类型不能为空0-关联源文件1-关联附件2-关联电子凭证验签包
*/
private String type;
/**
* 上传文件信息数组
*/
private List<FinFilingDataAtUploadUrl> uploadUrls = new ArrayList<>();
}

View File

@ -0,0 +1,22 @@
package cn.jiutqy.finfiling.common.dto;
import lombok.Data;
@Data
public class FinFilingDataAtUploadUrl {
/**
* 文件唯一标识如果type = 0非必填如果type = 1 2必填
*/
private String fileKey;
/**
* 文件名称
*/
private String fileName;
/**
* 文件url
*/
private String url;
}

View File

@ -0,0 +1,8 @@
package cn.jiutqy.finfiling.common.dto;
import com.alibaba.fastjson2.JSONObject;
public class FinFilingJSONObject extends JSONObject {
}

View File

@ -0,0 +1,47 @@
package cn.jiutqy.finfiling.common.enums;
import cn.jiutqy.finfiling.common.service.IFinFilingChannelService;
import java.util.HashMap;
import java.util.Map;
public enum ChannelEnum implements IFinFilingChannelService {
U9C("u9c"),
GE_YUAN("geyuan"),
DI_PIN_SHI("dipinshi"),
HOSECLOUD("hosecloud");
private static final Map<String, ChannelEnum> CHANNEL_ID_MAPPINGS = new HashMap<>();
static
{
for (ChannelEnum channelEnum : values())
{
CHANNEL_ID_MAPPINGS.put(channelEnum.getChannelId(), channelEnum);
}
}
private final String channelId;
ChannelEnum(String channelId) {
this.channelId = channelId;
}
@Override
public String getChannelId() {
return channelId;
}
@Override
public IFinFilingChannelService resolveChannelId(String channelId) {
return (channelId != null ? CHANNEL_ID_MAPPINGS.get(channelId) : null);
}
}

View File

@ -0,0 +1,16 @@
package cn.jiutqy.finfiling.common.enums;
import lombok.Getter;
@Getter
public enum ChannelTypeEnum {
IN(1),
OUT(2);
private final Integer type;
ChannelTypeEnum(Integer type){
this.type = type;
}
}

View File

@ -0,0 +1,17 @@
package cn.jiutqy.finfiling.common.enums;
import lombok.Getter;
@Getter
public enum DatasourceEnum {
U9C_UF_SYSTEM("UFSystem");
private final String datasource;
DatasourceEnum(String datasource){
this.datasource = datasource;
}
}

View File

@ -0,0 +1,57 @@
package cn.jiutqy.finfiling.common.enums;
import cn.jiutqy.finfiling.common.service.IFinFilingChannelService;
import cn.jiutqy.finfiling.common.service.IFinFilingFormService;
import java.util.HashMap;
import java.util.Map;
public enum FormEnum implements IFinFilingFormService {
UF_DATA_9002021("UFData9002021"),
UF_DATA_3012018("UFData3012018"),
UF_DATA_3022018("UFData3022018"),
UF_DATA_3112021("UFData3112021"),
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<>();
static
{
for (FormEnum formEnum : values())
{
FORM_ID_MAPPINGS.put(formEnum.getFormId(), formEnum);
}
}
private IFinFilingChannelService channelService;
private String formId;
FormEnum(String formId) {
this.formId = formId;
this.channelService = ChannelEnum.U9C;
}
@Override
public String getChannelId() {
return channelService.getChannelId();
}
@Override
public String getFormId() {
return formId;
}
@Override
public IFinFilingFormService resolveFormId(String formId) {
return (formId != null ? FORM_ID_MAPPINGS.get(formId) : null);
}
}

View File

@ -0,0 +1,5 @@
package cn.jiutqy.finfiling.common.enums;
public enum StoreType {
yml,mysql,redis
}

View File

@ -0,0 +1,20 @@
package cn.jiutqy.finfiling.common.enums;
public enum SyncStateEnum {
INIT(0),
SUCCESSED(1),
FAILED(2);
private final int value;
SyncStateEnum(int value)
{
this.value = value;
}
public int value()
{
return this.value;
}
}

View File

@ -0,0 +1,20 @@
package cn.jiutqy.finfiling.common.factory;
import cn.jiutqy.finfiling.common.service.IFinFilingAccessTokenService;
import java.util.HashMap;
import java.util.Map;
public class FinFilingAccessTokenFactory {
private static Map<String, IFinFilingAccessTokenService> CONTAINER = new HashMap<>();
public static void addContainer(String channelId, IFinFilingAccessTokenService accessTokenService){
CONTAINER.put(channelId,accessTokenService);
}
public static IFinFilingAccessTokenService getContainer(String channelId){
return CONTAINER.get(channelId);
}
}

View File

@ -0,0 +1,36 @@
package cn.jiutqy.finfiling.common.factory;
import cn.jiutqy.finfiling.common.service.IFinFilingMapping;
import java.util.HashMap;
import java.util.Map;
public class FinFilingMappingFactory {
private static Map<String, IFinFilingMapping> CONTAINER = new HashMap<>();
public static void addContainer(String channelId, String formId, IFinFilingMapping mappingService){
CONTAINER.put(buildContainerKey(channelId,formId),mappingService);
}
public static void addContainer(String channelId, String formId, String groupId, IFinFilingMapping mappingService){
CONTAINER.put(buildContainerKey(channelId,formId,groupId),mappingService);
}
public static IFinFilingMapping getContainer(String channelId, String formId, String groupId){
return CONTAINER.get(buildContainerKey(channelId,formId,groupId));
}
public static IFinFilingMapping getContainer(String channelId, String formId){
return CONTAINER.get(buildContainerKey(channelId,formId));
}
public static String buildContainerKey(String channelId, String formId, String groupId){
return channelId + "/" + formId + "/" + groupId;
}
public static String buildContainerKey(String channelId, String formId){
return channelId + "/" + formId;
}
}

View File

@ -0,0 +1,12 @@
package cn.jiutqy.finfiling.common.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import cn.jiutqy.finfiling.common.domain.FinFilingSyncCursor;
public interface FinFilingSyncCursorMapper extends BaseMapper<FinFilingSyncCursor> {
}

View File

@ -0,0 +1,10 @@
package cn.jiutqy.finfiling.common.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import cn.jiutqy.finfiling.common.domain.FinFilingSyncLog;
public interface FinFilingSyncLogMapper extends BaseMapper<FinFilingSyncLog> {
}

View File

@ -0,0 +1,74 @@
package cn.jiutqy.finfiling.common.service;
import cn.jiutqy.archives.common.core.cache.LocalCache;
import cn.jiutqy.archives.common.exception.ServiceException;
import cn.jiutqy.finfiling.common.config.FinFilingConfig;
import cn.jiutqy.finfiling.common.enums.ChannelEnum;
import cn.jiutqy.finfiling.common.enums.ChannelTypeEnum;
import com.alibaba.fastjson2.JSON;
import cn.jiutqy.finfiling.common.config.properties.FinFilingChannelProperties;
import cn.jiutqy.finfiling.common.config.properties.FinFilingOauthProperties;
import cn.jiutqy.finfiling.common.dto.FinFilingAccessToken;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;
@Component
public abstract class AbstractFinFilingAccessTokenService implements IFinFilingAccessTokenService, InitializingBean {
private static final String FORMAT_REDISKEY = "finfiling:access_token:%s";
private static ReentrantLock lock = new ReentrantLock();
@Resource
private FinFilingConfig finFilingConfig;
public FinFilingAccessToken getAccessToken(String channelId, ChannelTypeEnum channelTypeEnum){
FinFilingChannelProperties channelProperties;
if (channelTypeEnum.equals(ChannelTypeEnum.IN)){
channelProperties = finFilingConfig.getInput().getChannel().get(channelId);
} else {
channelProperties = finFilingConfig.getOutput().getChannel().get(channelId);
}
channelProperties.setChannelId(channelId);
return getAccessToken(channelProperties);
}
@Override
public FinFilingAccessToken getAccessToken(FinFilingChannelProperties channelProperties) {
String cacheKey = buildCacheKey(channelProperties);
FinFilingAccessToken accessToken = null;
accessToken = JSON.parseObject((String) LocalCache.getCacheObject(cacheKey),FinFilingAccessToken.class);
if(null != accessToken){
return accessToken;
}
lock.lock();
try {
accessToken = getAccessToken(channelProperties.getOauth());
Long timeout = accessToken.getExpireTime() - System.currentTimeMillis();
if(timeout > 0){
LocalCache.setCacheObject(cacheKey, JSON.toJSONString(accessToken),timeout.intValue(), TimeUnit.MILLISECONDS);
}
} catch (Exception e){
ServiceException exception = new ServiceException("获取AccessToken失败" + JSON.toJSONString(channelProperties.getOauth()));
exception.setDetailMessage(e.getMessage());
throw exception;
} finally {
lock.unlock();
}
return accessToken;
}
protected abstract FinFilingAccessToken getAccessToken(FinFilingOauthProperties oauthProperties);
private String buildCacheKey(FinFilingChannelProperties channelProperties){
return String.format(FORMAT_REDISKEY, channelProperties.getChannelId());
}
}

View File

@ -0,0 +1,420 @@
package cn.jiutqy.finfiling.common.service;
import cn.jiutqy.archives.common.enums.HttpMethod;
import cn.jiutqy.archives.common.utils.DateUtils;
import cn.jiutqy.archives.common.utils.ExceptionUtil;
import cn.jiutqy.archives.common.utils.http.OkHttpClientUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.alibaba.fastjson2.JSONPath;
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.config.properties.FinFilingMappingRelationProperties;
import cn.jiutqy.finfiling.common.domain.FinFilingSyncCursor;
import cn.jiutqy.finfiling.common.domain.FinFilingSyncLog;
import cn.jiutqy.finfiling.common.dto.FinFilingData;
import cn.jiutqy.finfiling.common.dto.FinFilingDataAtJson;
import cn.jiutqy.finfiling.common.enums.SyncStateEnum;
import cn.jiutqy.finfiling.common.factory.FinFilingAccessTokenFactory;
import cn.jiutqy.finfiling.common.factory.FinFilingMappingFactory;
import cn.jiutqy.finfiling.common.utils.TimeParser;
import com.yomahub.tlog.context.TLogContext;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import java.util.*;
import java.util.stream.Collectors;
@Slf4j
@Component
public abstract class AbstractFinFilingService implements IFinFilingService {
@Autowired
private IFinFilingSyncLogService finFilingSyncLogService;
@Autowired
private IFinFilingSyncCursorService finFilingSyncCursorService;
@Autowired
private FinFilingConfig finFilingConfig;
public AbstractFinFilingService(){}
@Override
public void syncData(String channelId, String formId) {
FinFilingChannelProperties channelProperties = finFilingConfig.getInput().getChannel().get(channelId);
FinFilingFormProperties formProperties = channelProperties.getForms().get(formId);
Integer pageNum = formProperties.getPageNum();
if(null == pageNum){
pageNum = channelProperties.getPageNum();
}
Integer pageSize = formProperties.getPageSize();
if(null == pageSize){
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();
String endCursor = DateUtils.parseDateToStr(cursorFormat, now);
String startCursor;
FinFilingSyncCursor finFilingSyncCursor = finFilingSyncCursorService.findByChannelIdAndFormId(channelId, formId);
if(null == finFilingSyncCursor){
startCursor = DateUtils.parseDateToStr(cursorFormat, DateUtils.addSeconds(now, -TimeParser.parseTime(firstPassTime)));
}else{
startCursor = DateUtils.parseDateToStr(cursorFormat, finFilingSyncCursor.getEndCursor());
}
Integer totalCount = syncData(startCursor,endCursor,channelId, formId, pageNum, pageSize, 0);
finFilingSyncCursor = new FinFilingSyncCursor();
finFilingSyncCursor.setChannelId(channelId);
finFilingSyncCursor.setFormId(formId);
finFilingSyncCursor.setStartCursor(DateUtils.parseDate(startCursor));
finFilingSyncCursor.setEndCursor(DateUtils.parseDate(endCursor));
finFilingSyncCursor.setSyncNum(totalCount);
finFilingSyncCursor.setTraceId(TLogContext.getTraceId());
finFilingSyncCursor.setCreateTime(new Date());
finFilingSyncCursorService.save(finFilingSyncCursor);
}
@Override
public void syncData(String startCursor, String endCursor, String channelId, String formId) {
FinFilingChannelProperties channelProperties = finFilingConfig.getInput().getChannel().get(channelId);
FinFilingFormProperties formProperties = channelProperties.getForms().get(formId);
Integer pageNum = formProperties.getPageNum();
if(null == pageNum){
pageNum = channelProperties.getPageNum();
}
Integer pageSize = formProperties.getPageSize();
if(null == pageSize){
pageSize = channelProperties.getPageSize();
}
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) {
// 调用渠道客户系统的接口获取数据
PageInfo<JSONObject> pageInfo = this.inputData(new FinFilingContext(startCursor, endCursor, channelId, formId,pageNum,pageSize),finFilingConfig);
totalCount = totalCount + pageInfo.getList().size();
// 对输入数据进行分组key为分组字段的值
Map<String, List<FinFilingData>> dataMap = this.groupByInputData(channelId, formId, pageInfo.getList());
// 将获取到的数据进行转换
for (String groupId : dataMap.keySet()) {
List<FinFilingData> dataList = dataMap.get(groupId);
// 根据分组后的字段获取mapping实现类
IFinFilingMapping mappingService = getFinFilingMappingService(channelId, formId, groupId);
if(null == mappingService){
log.error("映射实现类找不到请检查对应实现类是否配置或者重写afterPropertiesSet方法是否设置了正确的formId值channelId={},formId={}",channelId,groupId);
continue;
}
// 获取映射配置
FinFilingMappingRelationProperties mappingRelationProperties = getMappingRelationProperties(channelId,formId, groupId);
if(null == mappingRelationProperties){
log.warn("mapping配置不正确当前渠道或表单未配置映射关系channelId={},formId={}",channelId,groupId);
continue;
}
// 初始化上下文对象
FinFilingContext context = new FinFilingContext(startCursor,endCursor,mappingRelationProperties);
// 字段映射
mappingService.mapping(dataList, context, mappingRelationProperties, finFilingConfig);
// 调用渠道客户系统的接口推送数据
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());
// 记录同步结果数据同步状态
FinFilingSyncLog finFilingSyncLog = null;
try {
finFilingSyncLog = this.saveSyncLog(data,context);
} catch (Exception e) {
log.error("写入同步日志失败:{}",JSON.toJSONString(data));
continue;
}
try {
// 将转换之后的数据同步到合思
this.outputData(data,context,finFilingConfig);
finFilingSyncLog.setInputDataId(data.getInputDataId());
finFilingSyncLog.setSyncState(SyncStateEnum.SUCCESSED.value());
finFilingSyncLog.setOutputDataId(data.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 {
updateSyncLog(finFilingSyncLog,context);
} catch (Exception e) {
log.error("修改同步日志失败",e);
continue;
}
try {
Thread.sleep(formProperties.getSleepMS());
} catch (InterruptedException e) {
log.error("等待异常", e);
//continue;
}
}
}
if (pageInfo.isHasNextPage()) {
syncData(startCursor, endCursor, channelId, formId, pageInfo.getNextPage(), pageSize, totalCount);
}
return totalCount;
}
private IFinFilingMapping getFinFilingMappingService(String channelId, String formId, String groupId) {
FinFilingChannelProperties channelProperties = finFilingConfig.getInput().getChannel().get(channelId);
FinFilingFormProperties formProperties = channelProperties.getForms().get(formId);
if (StringUtils.isNotBlank(formProperties.getGroupByField())) {
return FinFilingMappingFactory.getContainer(channelId, formId, groupId);
}else{
return FinFilingMappingFactory.getContainer(channelId, formId);
}
}
private Map<String, List<FinFilingData>> groupByInputData(String channelId, String formId, List<JSONObject> jsonList) {
Map<String,List<FinFilingData>> dataMap = new HashMap<>();
FinFilingChannelProperties channelProperties = finFilingConfig.getInput().getChannel().get(channelId);
FinFilingFormProperties formProperties = channelProperties.getForms().get(formId);
String groupByField = formProperties.getGroupByField();
if (StringUtils.isNotBlank(groupByField)) {
Map<String, List<JSONObject>> groupByData = jsonList.stream()
.collect(Collectors.groupingBy(json -> json.getString(groupByField)));
for (String inputFormId : groupByData.keySet()) {
List<FinFilingData> dataList = toFinFilingDataList(groupByData.get(inputFormId));
dataMap.put(inputFormId,dataList);
}
}else{
List<FinFilingData> dataList = toFinFilingDataList(jsonList);
dataMap.put(formId,dataList);
}
return dataMap;
}
private List<FinFilingData> toFinFilingDataList(List<JSONObject> jsonList){
List<FinFilingData> dataList = new ArrayList<>();
for (JSONObject inputData : jsonList) {
FinFilingData data = new FinFilingData();
data.setInputData(inputData);
// 这里初始化mapping方法中就不用初始化了直接赋值即可
data.setOutputData(new JSONObject());
dataList.add(data);
}
return dataList;
}
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();
FinFilingMappingRelationProperties matchedRelationProperty = null;
for (FinFilingMappingRelationProperties relationProperty : relationProperties) {
String inputChannelId = relationProperty.getChannelRelation().getInputChannelId();
String inputFormId = relationProperty.getFormRelation().getInputFormId();
String sourceKey;
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;
break;
}
}
return matchedRelationProperty;
}
protected FinFilingSyncLog saveSyncLog(FinFilingData data, FinFilingContext context){
FinFilingSyncLog finFilingSyncLog = buildSyncLog(data,context);
finFilingSyncLogService.save(finFilingSyncLog);
return finFilingSyncLog;
}
protected void updateSyncLog(FinFilingSyncLog finFilingSyncLog,FinFilingContext context) {
finFilingSyncLog.setUpdateTime(new Date());
finFilingSyncLogService.updateById(finFilingSyncLog);
}
protected FinFilingSyncLog buildSyncLog(FinFilingData data, FinFilingContext context) {
FinFilingSyncLog finFilingSyncLog = new FinFilingSyncLog();
finFilingSyncLog.setInputChannelId(context.getInputChannelId());
finFilingSyncLog.setInputFormId(context.getInputFormId());
finFilingSyncLog.setInputDataId((data.getInputDataId()));
finFilingSyncLog.setInputData(data.getInputData().toJSONString());
FinFilingDataAtJson inputDataAtJson = data.getInputDataAtJson();
if (null != inputDataAtJson) {
finFilingSyncLog.setInputDataAtJson(JSON.toJSONString(inputDataAtJson));
}
finFilingSyncLog.setOutputChannelId(context.getOutputChannelId());
finFilingSyncLog.setOutputFormId((context.getOutputFormId()));
finFilingSyncLog.setOutputDataId((data.getOutputDataId()));
finFilingSyncLog.setSyncState(SyncStateEnum.INIT.value());
finFilingSyncLog.setAtSyncState(SyncStateEnum.INIT.value());
finFilingSyncLog.setTraceId(TLogContext.getTraceId());
Date now = new Date();
finFilingSyncLog.setCreateTime(now);
finFilingSyncLog.setUpdateTime(now);
return finFilingSyncLog;
}
protected Object callData(FinFilingChannelProperties channelProperties, FinFilingFormProperties formProperties,String reqBody, FinFilingContext context){
String result = null;
String reqUrl = formProperties.getReqUrl();
if(!(StringUtils.startsWithIgnoreCase(reqUrl,"http://") || StringUtils.startsWithIgnoreCase(reqUrl,"https://"))){
String host = channelProperties.getHost();
reqUrl = host + reqUrl;
}
reqUrl = replaceVariable(reqUrl, context, channelProperties);
Map<String, String> reqHeader = replaceVariable(channelProperties.getReqHeader(), context, channelProperties);
String reqMethod = formProperties.getReqMethod();
if(HttpMethod.GET.name().equalsIgnoreCase(reqMethod)){
Map<String, String> reqParam = replaceVariable(formProperties.getReqParam(), context, channelProperties);
if(!CollectionUtils.isEmpty(formProperties.getReqHeader())) {
if (!CollectionUtils.isEmpty(reqHeader)) {
reqHeader.putAll(replaceVariable(formProperties.getReqHeader(), context, channelProperties));
} else {
reqHeader = replaceVariable(formProperties.getReqHeader(), context, channelProperties);
}
}
result = OkHttpClientUtil.doGet(reqUrl, reqParam, reqHeader);
}else if(HttpMethod.POST.name().equalsIgnoreCase(reqMethod)){
if(StringUtils.isBlank(reqBody)){
reqBody = replaceVariable(formProperties.getReqBody(), context, channelProperties);
}
if(!CollectionUtils.isEmpty(formProperties.getReqHeader())) {
if (!CollectionUtils.isEmpty(reqHeader)) {
reqHeader.putAll(replaceVariable(formProperties.getReqHeader(), context, channelProperties));
} else {
reqHeader = replaceVariable(formProperties.getReqHeader(), context, channelProperties);
}
}
result = OkHttpClientUtil.doPostJson(reqUrl, reqBody, reqHeader);
}else{
throw new RuntimeException("暂不支持的请求方式:"+reqMethod);
}
if(StringUtils.isBlank(result)){
throw new RuntimeException("接口返回报文为空:"+context);
}
String resDataRootNode = formProperties.getResDataRootNode();
return JSONPath.eval(result, resDataRootNode);
}
private Map<String, String> replaceVariable(Map<String, String> param,FinFilingContext context,FinFilingChannelProperties channelProperties) {
if (!CollectionUtils.isEmpty(param)) {
param = param.entrySet().stream()
.map(entry -> {
String value = entry.getValue();
value = replaceVariable(value,context,channelProperties);
return new AbstractMap.SimpleEntry<>(entry.getKey(), value);
}).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
}
return param;
}
private String replaceVariable(String param, FinFilingContext context) {
if (StringUtils.isNotBlank(param)) {
if(StringUtils.contains(param,"{startCursor}")){
param = StringUtils.replace(param, "{startCursor}", context.getStartCursor());
}
if(StringUtils.contains(param,"{endCursor}")){
param = StringUtils.replace(param, "{endCursor}", context.getEndCursor());
}
if(StringUtils.contains(param,"{pageNum}")){
param = StringUtils.replace(param, "{pageNum}", context.getPageNum().toString());
}
if(StringUtils.contains(param,"{pageSize}")){
param = StringUtils.replace(param, "{pageSize}", context.getPageSize().toString());
}
if(StringUtils.contains(param,"{inputChannelId}")){
param = StringUtils.replace(param, "{inputChannelId}", context.getInputChannelId());
}
if(StringUtils.contains(param,"{inputFormId}")){
param = StringUtils.replace(param, "{inputFormId}", context.getInputFormId());
}
if(StringUtils.contains(param,"{outputChannelId}")){
param = StringUtils.replace(param, "{outputChannelId}", context.getOutputChannelId());
}
if(StringUtils.contains(param,"{outputFormId}")){
param = StringUtils.replace(param, "{outputFormId}", context.getOutputFormId());
}
if(StringUtils.contains(param,"{outputDataId}")){
param = StringUtils.replace(param, "{outputDataId}", context.getOutputDataId());
}
}
return param;
}
private String replaceVariable(String param, FinFilingContext context,FinFilingChannelProperties channelProperties) {
param = replaceVariable(param, context);
if (StringUtils.isNotBlank(param)) {
if(StringUtils.contains(param,"{accessToken}")){
IFinFilingAccessTokenService accessTokenService = getAccessTokenService(channelProperties.getChannelId());
String accessToken = accessTokenService.getAccessToken(channelProperties).getAccessToken();
param = StringUtils.replace(param, "{accessToken}", accessToken);
}
}
return param;
}
protected IFinFilingAccessTokenService getAccessTokenService(String channelId){
return FinFilingAccessTokenFactory.getContainer(channelId);
}
protected abstract PageInfo<JSONObject> inputData(FinFilingContext context, FinFilingConfig finFilingConfig);
protected abstract void outputData(FinFilingData data, FinFilingContext context, FinFilingConfig finFilingConfig);
}

View File

@ -0,0 +1,84 @@
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

@ -0,0 +1,66 @@
package cn.jiutqy.finfiling.common.service;
import cn.jiutqy.archives.common.exception.ServiceException;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.alibaba.fastjson2.JSONPath;
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.dto.FinFilingData;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
@Slf4j
@Component
public class DefaultFormFinFilingService extends AbstractFinFilingService{
@Override
protected PageInfo<JSONObject> inputData(FinFilingContext context, FinFilingConfig finFilingConfig){
FinFilingChannelProperties channelProperties = finFilingConfig.getInput().getChannel().get(context.getInputChannelId());
channelProperties.setChannelId(context.getInputChannelId());
FinFilingFormProperties formProperties = channelProperties.getForms().get(context.getInputFormId());
JSONArray jsonArray = (JSONArray)callData(channelProperties, formProperties, null, context);
List<JSONObject> jsonList = IntStream.range(0, jsonArray.size())
.mapToObj(jsonArray::getJSONObject)
.collect(Collectors.toList());
PageInfo<JSONObject> pageInfo = new PageInfo<>(jsonList);
pageInfo.setHasNextPage(jsonList.size() == context.getPageSize());
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);
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)){
throw new ServiceException("无法解析resDataIdNode返回报文 "+ result+" 上下文:"+context);
}
data.setOutputDataId(outputDataId);
}
}

View File

@ -0,0 +1,157 @@
package cn.jiutqy.finfiling.common.service;
import cn.jiutqy.finfiling.common.config.properties.FinFilingMappingChannelRelationProperties;
import cn.jiutqy.finfiling.common.config.properties.FinFilingMappingFormRelationProperties;
import cn.jiutqy.finfiling.common.config.properties.FinFilingMappingRelationProperties;
import org.apache.commons.lang3.StringUtils;
import java.util.HashMap;
import java.util.Map;
public class FinFilingContext {
public static final String PARAM_STARTCURSOR = "startCursor";
public static final String PARAM_ENDCURSOR = "endCursor";
public static final String PARAM_PAGENUM = "pageNum";
public static final String PARAM_PAGESIZE = "pageSize";
public static final String PARAM_INPUTCHANNELID = "inputChannelId";
public static final String PARAM_OUTPUTCHANNELID = "outputChannelId";
public static final String PARAM_INPUTFORMID = "inputFormId";
public static final String PARAM_OUTPUTFORMID = "outputFormId";
public static final String PARAM_OUTPUTDATAID = "outputDataId";
private Map<String,Object> context;
public FinFilingContext() {
this(null,null,null,null,null,null);
}
public FinFilingContext(String startCursor,String endCursor,String inputChannelId,String inputFormId,Integer pageNum,Integer pageSize) {
this.context = new HashMap<>();
if (StringUtils.isNotBlank(startCursor)) {
this.context.put(PARAM_STARTCURSOR,startCursor);
}
if (StringUtils.isNotBlank(endCursor)) {
this.context.put(PARAM_ENDCURSOR,endCursor);
}
if (StringUtils.isNotBlank(inputChannelId)) {
this.context.put(PARAM_INPUTCHANNELID,inputChannelId);
}
if (StringUtils.isNotBlank(inputFormId)) {
this.context.put(PARAM_INPUTFORMID,inputFormId);
}
if (null != pageNum) {
this.context.put(PARAM_PAGENUM,pageNum);
}
if (null != pageSize) {
this.context.put(PARAM_PAGESIZE,pageSize);
}
}
public FinFilingContext(String startCursor, String endCursor, FinFilingMappingRelationProperties mappingRelationProperties) {
this.context = new HashMap<>();
if (StringUtils.isNotBlank(startCursor)) {
this.context.put(PARAM_STARTCURSOR,startCursor);
}
if (StringUtils.isNotBlank(endCursor)) {
this.context.put(PARAM_ENDCURSOR,endCursor);
}
FinFilingMappingChannelRelationProperties channelRelation = mappingRelationProperties.getChannelRelation();
if (StringUtils.isNotBlank(channelRelation.getInputChannelId())) {
this.context.put(PARAM_INPUTCHANNELID,channelRelation.getInputChannelId());
}
if (StringUtils.isNotBlank(channelRelation.getOutputChannelId())) {
this.context.put(PARAM_OUTPUTCHANNELID,channelRelation.getOutputChannelId());
}
FinFilingMappingFormRelationProperties formRelation = mappingRelationProperties.getFormRelation();
if (StringUtils.isNotBlank(formRelation.getInputFormId())) {
this.context.put(PARAM_INPUTFORMID,formRelation.getInputFormId());
}
if (StringUtils.isNotBlank(formRelation.getOutputFormId())) {
this.context.put(PARAM_OUTPUTFORMID,formRelation.getOutputFormId());
}
}
public FinFilingContext add(String key,Object value){
context.put(key,value);
return this;
}
public FinFilingContext addOutputFormId(Object value){
context.put(PARAM_OUTPUTFORMID,value);
return this;
}
public FinFilingContext addOutputChannelId(Object value){
context.put(PARAM_OUTPUTCHANNELID,value);
return this;
}
public Object get(String key){
return context.get(key);
}
public String getString(String key){
return String.valueOf(context.get(key));
}
public Integer getInteger(String key){
return (Integer) context.get(key);
}
public Long getLong(String key){
return (Long)context.get(key);
}
public Boolean isBoolean(String key){
return (Boolean)context.get(key);
}
public String getStartCursor(){
return String.valueOf(context.get(PARAM_STARTCURSOR));
}
public String getEndCursor(){
return String.valueOf(context.get(PARAM_ENDCURSOR));
}
public Integer getPageNum(){
return (Integer) context.get(PARAM_PAGENUM);
}
public Integer getPageSize(){
return (Integer) context.get(PARAM_PAGESIZE);
}
public String getInputChannelId(){
return String.valueOf(context.get(PARAM_INPUTCHANNELID));
}
public String getOutputChannelId(){
return String.valueOf(context.get(PARAM_OUTPUTCHANNELID));
}
public String getInputFormId(){
return String.valueOf(context.get(PARAM_INPUTFORMID));
}
public String getOutputFormId(){
return String.valueOf(context.get(PARAM_OUTPUTFORMID));
}
public String getOutputDataId(){
return String.valueOf(context.get(PARAM_OUTPUTDATAID));
}
public FinFilingContext addOutputDataId(String outputDataId){
context.put(PARAM_OUTPUTDATAID,outputDataId);
return this;
}
@Override
public String toString() {
return "FinFilingContext{" +
"context=" + context +
'}';
}
}

View File

@ -0,0 +1,33 @@
package cn.jiutqy.finfiling.common.service;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import cn.jiutqy.finfiling.common.domain.FinFilingSyncCursor;
import cn.jiutqy.finfiling.common.mapper.FinFilingSyncCursorMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import java.util.List;
@Service
public class FinFilingSyncCursorService extends ServiceImpl<FinFilingSyncCursorMapper, FinFilingSyncCursor> implements IFinFilingSyncCursorService {
@Autowired
private FinFilingSyncCursorMapper finFilingSyncCursorMapper;
@Override
public FinFilingSyncCursor findByChannelIdAndFormId(String channelId, String formId) {
LambdaQueryWrapper<FinFilingSyncCursor> queryWrapper = new LambdaQueryWrapper();
queryWrapper.eq(FinFilingSyncCursor::getChannelId,channelId);
queryWrapper.eq(FinFilingSyncCursor::getFormId,formId);
queryWrapper.orderByDesc(FinFilingSyncCursor::getEndCursor);
List<FinFilingSyncCursor> list = super.list(queryWrapper);
if(CollectionUtils.isEmpty(list)){
return null;
}
return list.get(0);
}
}

View File

@ -0,0 +1,39 @@
package cn.jiutqy.finfiling.common.service;
import cn.jiutqy.archives.common.utils.DateUtils;
import cn.jiutqy.finfiling.common.enums.SyncStateEnum;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import cn.jiutqy.finfiling.common.domain.FinFilingSyncLog;
import cn.jiutqy.finfiling.common.mapper.FinFilingSyncLogMapper;
import org.springframework.stereotype.Service;
import java.util.Date;
import java.util.List;
@Service
public class FinFilingSyncLogService extends ServiceImpl<FinFilingSyncLogMapper,FinFilingSyncLog> implements IFinFilingSyncLogService {
@Override
public FinFilingSyncLog getFinFilingSyncLogByInputDataId(String inputDataId) {
List<FinFilingSyncLog> list = this.list(new LambdaQueryWrapper<FinFilingSyncLog>()
.eq(FinFilingSyncLog::getInputDataId, inputDataId));
return list == null || list.isEmpty() ? null : list.get(0);
}
@Override
public FinFilingSyncLog getFinFilingSyncLogByInputChannelAndInputDataId(String inputChannelId, String inputDataId) {
List<FinFilingSyncLog> list = this.list(new LambdaQueryWrapper<FinFilingSyncLog>()
.eq(FinFilingSyncLog::getInputChannelId, inputChannelId)
.eq(FinFilingSyncLog::getInputDataId, inputDataId));
return list == null || list.isEmpty() ? null : list.get(0);
}
@Override
public List<FinFilingSyncLog> listFailFinFiling(Date beforeTime) {
return this.list((new LambdaQueryWrapper<FinFilingSyncLog>()
.eq(FinFilingSyncLog::getSyncState, SyncStateEnum.FAILED.value()))
.ge(FinFilingSyncLog::getCreateTime, beforeTime));
}
}

View File

@ -0,0 +1,18 @@
package cn.jiutqy.finfiling.common.service;
import cn.jiutqy.finfiling.common.config.properties.FinFilingChannelProperties;
import cn.jiutqy.finfiling.common.dto.FinFilingAccessToken;
import cn.jiutqy.finfiling.common.enums.ChannelTypeEnum;
import cn.jiutqy.finfiling.common.factory.FinFilingAccessTokenFactory;
public interface IFinFilingAccessTokenService {
FinFilingAccessToken getAccessToken(String channelId, ChannelTypeEnum channelTypeEnum);
FinFilingAccessToken getAccessToken(FinFilingChannelProperties channelProperties);
default void registerSelf(IFinFilingChannelService channel, IFinFilingAccessTokenService accessTokenService){
FinFilingAccessTokenFactory.addContainer(channel.getChannelId(),accessTokenService);
}
}

View File

@ -0,0 +1,7 @@
package cn.jiutqy.finfiling.common.service;
public interface IFinFilingApiService {
}

View File

@ -0,0 +1,10 @@
package cn.jiutqy.finfiling.common.service;
public interface IFinFilingChannelService {
String name();
String getChannelId();
public IFinFilingChannelService resolveChannelId(String channelId);
}

View File

@ -0,0 +1,13 @@
package cn.jiutqy.finfiling.common.service;
public interface IFinFilingFormService {
String name();
String getChannelId();
String getFormId();
IFinFilingFormService resolveFormId(String formId);
}

View File

@ -0,0 +1,30 @@
package cn.jiutqy.finfiling.common.service;
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.factory.FinFilingMappingFactory;
import java.util.List;
public interface IFinFilingMapping {
default void mapping(List<FinFilingData> dataList, FinFilingContext context, FinFilingMappingRelationProperties mappingRelationProperties, FinFilingConfig finFilingConfig){
for (FinFilingData data : dataList) {
mapping(data,context,mappingRelationProperties,finFilingConfig);
}
}
//void mapping(List<FinFilingData> dataList, FinFilingContext context, FinFilingMappingRelationProperties mappingRelationProperties, FinFilingConfig finFilingConfig);
void mapping(FinFilingData data, FinFilingContext context, FinFilingMappingRelationProperties mappingRelationProperties, FinFilingConfig finFilingConfig);
default void registerSelf(IFinFilingFormService form, IFinFilingMapping mappingService){
FinFilingMappingFactory.addContainer(form.getChannelId(),form.getFormId(),mappingService);
}
default void registerSelf(IFinFilingFormService form, String groupId, IFinFilingMapping mappingService){
FinFilingMappingFactory.addContainer(form.getChannelId(),form.getFormId(),groupId,mappingService);
}
}

View File

@ -0,0 +1,9 @@
package cn.jiutqy.finfiling.common.service;
public interface IFinFilingService {
void syncData(String channelId, String formId);
void syncData(String startCursor, String endCursor,String channelKey, String formKey);
}

View File

@ -0,0 +1,11 @@
package cn.jiutqy.finfiling.common.service;
import com.baomidou.mybatisplus.extension.service.IService;
import cn.jiutqy.finfiling.common.domain.FinFilingSyncCursor;
public interface IFinFilingSyncCursorService extends IService<FinFilingSyncCursor> {
FinFilingSyncCursor findByChannelIdAndFormId(String channelId,String formId);
}

View File

@ -0,0 +1,23 @@
package cn.jiutqy.finfiling.common.service;
import com.baomidou.mybatisplus.extension.service.IService;
import cn.jiutqy.finfiling.common.domain.FinFilingSyncLog;
import java.util.Date;
import java.util.List;
public interface IFinFilingSyncLogService extends IService<FinFilingSyncLog> {
FinFilingSyncLog getFinFilingSyncLogByInputDataId(String inputDataId);
FinFilingSyncLog getFinFilingSyncLogByInputChannelAndInputDataId(String inputChannelId, String inputDataId);
/**
* 查询同步失败的记录
* @return
*/
List<FinFilingSyncLog> listFailFinFiling(Date beforeTime);
}

View File

@ -0,0 +1,38 @@
package cn.jiutqy.finfiling.common.utils;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class TimeParser {
private static Pattern PATTERN = Pattern.compile("(\\d+)\\s*(d|h|min|sec)");
public static int parseTime(String timeStr) {
int seconds = 0;
Matcher matcher = PATTERN.matcher(timeStr);
while (matcher.find()) {
int amount = Integer.parseInt(matcher.group(1));
String unit = matcher.group(2);
switch (unit) {
case "d":
seconds += amount * 24 * 60 * 60;
break;
case "h":
seconds += amount * 60 * 60;
break;
case "min":
seconds += amount * 60;
break;
case "sec":
seconds += amount;
break;
default:
throw new IllegalArgumentException("Unknown time unit: " + unit);
}
}
return seconds;
}
}

28
fin-filing-quartz/pom.xml Normal file
View File

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>dipinshi-hesi</artifactId>
<groupId>cn.jiutqy</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>fin-filing-quartz</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>cn.jiutqy</groupId>
<artifactId>fin-filing-common</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,33 @@
package cn.jiutqy.finfiling.quartz.dipinshi;
import cn.jiutqy.archives.common.utils.http.OkHttpClientUtil;
import cn.jiutqy.finfiling.common.config.properties.FinFilingOauthProperties;
import cn.jiutqy.finfiling.common.dto.FinFilingAccessToken;
import cn.jiutqy.finfiling.common.enums.ChannelEnum;
import cn.jiutqy.finfiling.common.service.AbstractFinFilingAccessTokenService;
import cn.jiutqy.finfiling.common.service.IFinFilingAccessTokenService;
import cn.jiutqy.finfiling.quartz.dipinshi.dto.DiPinShiAccessToken;
import com.alibaba.fastjson2.JSON;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.InitializingBean;
public class DiPinShiAccessTokenService extends AbstractFinFilingAccessTokenService implements IFinFilingAccessTokenService, InitializingBean {
@Override
protected FinFilingAccessToken getAccessToken(FinFilingOauthProperties oauthProperties) {
String corpId = oauthProperties.getAppId();
String corpSecret = oauthProperties.getAppSecret();
String url = StringUtils.replace(oauthProperties.getReqUrl(), "{corpid}", corpId);
url = StringUtils.replace(url, "{corpsecret}", corpSecret);
String result = OkHttpClientUtil.doGet(url);
DiPinShiAccessToken diPinShiAccessToken = JSON.parseObject(result, DiPinShiAccessToken.class);
diPinShiAccessToken.setAccessToken(diPinShiAccessToken.getAccess_token());
diPinShiAccessToken.setRefreshToken(diPinShiAccessToken.getAccess_token());
diPinShiAccessToken.setExpireTime(Long.valueOf(diPinShiAccessToken.getExpires_in()));
return diPinShiAccessToken;
}
@Override
public void afterPropertiesSet() throws Exception {
super.registerSelf(ChannelEnum.DI_PIN_SHI,this);
}
}

View File

@ -0,0 +1,106 @@
package cn.jiutqy.finfiling.quartz.dipinshi;
import cn.jiutqy.archives.common.utils.StringUtils;
import cn.jiutqy.archives.common.utils.http.OkHttpClientUtil;
import cn.jiutqy.finfiling.common.enums.ChannelEnum;
import cn.jiutqy.finfiling.common.enums.ChannelTypeEnum;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
@Slf4j
@Component
public class DiPinShiFinFilingService extends AbstractDiPinShiBaseService implements IDiPinShiFinFilingService{
private static final String BATCH_APPROVAL_NO = "https://qyapi.weixin.qq.com/cgi-bin/oa/getapprovalinfo?access_token={accessToken}";
private static final String APPROVAL_NO_DETAIL = "https://qyapi.weixin.qq.com/cgi-bin/oa/getapprovaldetail?access_token={accessToken}";
private static final String APPLICATION_TEM_ID = "";
private static final String TRAVEL = "3";
private static final String GO_OUT = "4";
@Override
public List<String> getBatchApprovalNoTravel(String start,String end,String type) {
List<String> spNoList = new ArrayList<>();
//构建请求体
JSONObject reqBody = buildReqBody(start,end,type);
String url = getAccessToken(BATCH_APPROVAL_NO, ChannelEnum.DI_PIN_SHI.getChannelId(), ChannelTypeEnum.IN);
String result = OkHttpClientUtil.doPostJson(url, reqBody.toJSONString());
JSONObject res = JSONObject.parseObject(JSONObject.toJSONString(result));
JSONArray jsonArray = res.getJSONArray("sp_no_list");
for (Object spNo : jsonArray) {
spNoList.add((String) spNo);
}
//判断后面还有没有数据
String newNextCursor = res.getString("new_next_cursor");
while (StringUtils.isNotBlank(newNextCursor)){
result = OkHttpClientUtil.doPostJson(url, reqBody.toJSONString());
res = JSONObject.parseObject(JSONObject.toJSONString(result));
jsonArray = res.getJSONArray("sp_no_list");
for (Object spNo : jsonArray) {
spNoList.add((String) spNo);
}
newNextCursor = res.getString("new_next_cursor");
}
return spNoList;
}
@Override
public String getApprovalNoDetail(String approvalNo) {
//构建请求体
JSONObject reqBody = new JSONObject();
reqBody.put("sp_no",approvalNo);
String url = getAccessToken(APPROVAL_NO_DETAIL, ChannelEnum.DI_PIN_SHI.getChannelId(), ChannelTypeEnum.IN);
return OkHttpClientUtil.doPostJson(url, reqBody.toJSONString());
}
private JSONObject buildReqBody(String start,String end,String type){
JSONObject reqBody = new JSONObject();
reqBody.put("starttime", convert(start));
reqBody.put("endtime", convert(end));
reqBody.put("new_cursor","");
reqBody.put("size",100);
JSONArray filters = new JSONArray();
JSONObject template = new JSONObject();
template.put("key","template_id");
template.put("value",APPLICATION_TEM_ID);
JSONObject type1 = new JSONObject();
template.put("key","record_type");
if ("TRAVEL".equals(type)){
template.put("value",TRAVEL);
}else {
template.put("value",GO_OUT);
}
filters.add(template);
filters.add(type1);
reqBody.put("filters",filters);
return reqBody;
}
//将日期转成时间戳 xxxx-xx-xx
public long convert(String dateStr){
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
LocalDate date = LocalDate.parse(dateStr, formatter);
LocalDateTime dateTime = LocalDateTime.of(date, LocalTime.MIDNIGHT);
ZonedDateTime zonedDateTime = dateTime.atZone(ZoneOffset.UTC);
return zonedDateTime.toInstant().toEpochMilli();
}
}

View File

@ -0,0 +1,13 @@
package cn.jiutqy.finfiling.quartz.dipinshi;
import java.util.List;
public interface IDiPinShiFinFilingService {
// 获取批量审批号
List<String> getBatchApprovalNoTravel(String start, String end, String type);
// 获取审批单号详情
String getApprovalNoDetail(String approvalNo);
}

View File

@ -0,0 +1,29 @@
package cn.jiutqy.finfiling.quartz.dipinshi.attendance;
import cn.jiutqy.finfiling.quartz.dipinshi.attendance.vo.DiPinShiAttendanceGoOutReqVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.util.HashMap;
@Component
@Slf4j
public class DiPinShiAttendanceService implements IDiPinShiAttendanceService{
@Override
public void attendanceGoOut(DiPinShiAttendanceGoOutReqVO goOut) {
log.info("外出申请单号:{}", goOut.getApprovalNo());
//获取合思token
//构建请求体
//发送请求
}
@Override
public void attenancedTravel(HashMap<String, Object> map) {
}
}

View File

@ -0,0 +1,18 @@
package cn.jiutqy.finfiling.quartz.dipinshi.attendance;
import cn.jiutqy.finfiling.quartz.dipinshi.attendance.vo.DiPinShiAttendanceGoOutReqVO;
import java.util.HashMap;
public interface IDiPinShiAttendanceService {
/**
* 同步外出
*/
void attendanceGoOut(DiPinShiAttendanceGoOutReqVO goOut);
/**
* 同步出差
*/
void attenancedTravel(HashMap<String, Object> map);
}

View File

@ -0,0 +1,9 @@
package cn.jiutqy.finfiling.quartz.dipinshi.attendance.vo;
import lombok.Data;
import lombok.EqualsAndHashCode;
@EqualsAndHashCode(callSuper = true)
@Data
public class DiPinShiAttendanceGoOutReqVO extends DiPinShiAttendanceReqVO{
}

View File

@ -0,0 +1,38 @@
package cn.jiutqy.finfiling.quartz.dipinshi.attendance.vo;
import lombok.Data;
@Data
public class DiPinShiAttendanceReqVO {
/**
* 申请人
*/
private String applicant;
/**
* 申请类型
*/
private String applicationType;
/**
* 开始时间
*/
private String startTime;
/**
* 结束时间
*/
private String endTime;
/**
* 审批单号
*/
private String approvalNo;
/**
* 数据
*/
private String data;
}

View File

@ -0,0 +1,7 @@
package cn.jiutqy.finfiling.quartz.dipinshi.attendance.vo;
import lombok.Data;
@Data
public class DiPinShiAttendanceRespVO {
}

View File

@ -0,0 +1,9 @@
package cn.jiutqy.finfiling.quartz.dipinshi.attendance.vo;
import lombok.Data;
import lombok.EqualsAndHashCode;
@EqualsAndHashCode(callSuper = true)
@Data
public class DiPinShiAttendanceTravelInReqVO extends DiPinShiAttendanceReqVO{
}

View File

@ -0,0 +1,9 @@
package cn.jiutqy.finfiling.quartz.dipinshi.attendance.vo;
import lombok.Data;
import lombok.EqualsAndHashCode;
@EqualsAndHashCode(callSuper = true)
@Data
public class DiPinShiAttendanceTravelOutNotUSAReqVO extends DiPinShiAttendanceReqVO{
}

View File

@ -0,0 +1,9 @@
package cn.jiutqy.finfiling.quartz.dipinshi.attendance.vo;
import lombok.Data;
import lombok.EqualsAndHashCode;
@EqualsAndHashCode(callSuper = true)
@Data
public class DiPinShiAttendanceTravelOutReqVO extends DiPinShiAttendanceReqVO{
}

View File

@ -0,0 +1,16 @@
package cn.jiutqy.finfiling.quartz.dipinshi.dto;
import cn.jiutqy.finfiling.common.dto.FinFilingAccessToken;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
@EqualsAndHashCode(callSuper = true)
@NoArgsConstructor
@Data
public class DiPinShiAccessToken extends FinFilingAccessToken {
private String access_token;
private String expires_in;
}

View File

@ -0,0 +1,28 @@
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

@ -0,0 +1,30 @@
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

@ -0,0 +1,19 @@
package cn.jiutqy.finfiling.quartz.hosecloud;
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 AbstractHoseCloudBaseService {
protected final String BASE_URL = "https://app.ekuaibao.com";
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

@ -0,0 +1,13 @@
package cn.jiutqy.finfiling.quartz.hosecloud;
import cn.jiutqy.finfiling.common.dto.FinFilingAccessToken;
import lombok.Data;
import lombok.NoArgsConstructor;
@NoArgsConstructor
@Data
public class HoseCloudAccessToken extends FinFilingAccessToken {
private String corporationId;
}

View File

@ -0,0 +1,38 @@
package cn.jiutqy.finfiling.quartz.hosecloud;
import cn.jiutqy.archives.common.utils.http.OkHttpClientUtil;
import cn.jiutqy.finfiling.common.config.properties.FinFilingOauthProperties;
import cn.jiutqy.finfiling.common.dto.FinFilingAccessToken;
import cn.jiutqy.finfiling.common.enums.ChannelEnum;
import cn.jiutqy.finfiling.common.service.AbstractFinFilingAccessTokenService;
import cn.jiutqy.finfiling.common.service.IFinFilingAccessTokenService;
import com.alibaba.fastjson2.JSON;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.Map;
@Component
public class HoseCloudFinFilingAccessTokenService extends AbstractFinFilingAccessTokenService implements IFinFilingAccessTokenService,InitializingBean {
@Override
public FinFilingAccessToken getAccessToken(FinFilingOauthProperties oauthProperties) {
String appId = oauthProperties.getAppId();
String appSecret = oauthProperties.getAppSecret();
Map<String,String> body = new HashMap<>();
body.put("appKey",appId);
body.put("appSecurity",appSecret);
String result = OkHttpClientUtil.doPostJson(oauthProperties.getReqUrl(),JSON.toJSONString(body));
return JSON.parseObject(JSON.parseObject(result).getString("value"), HoseCloudAccessToken.class);
}
@Override
public void afterPropertiesSet() throws Exception {
super.registerSelf(ChannelEnum.HOSECLOUD,this);
}
}

View File

@ -0,0 +1,40 @@
package cn.jiutqy.finfiling.quartz.hosecloud;
import cn.jiutqy.archives.common.utils.StringUtils;
import cn.jiutqy.archives.common.utils.http.OkHttpClientUtil;
import cn.jiutqy.finfiling.common.enums.ChannelEnum;
import cn.jiutqy.finfiling.common.enums.ChannelTypeEnum;;
import cn.jiutqy.finfiling.quartz.hosecloud.vo.HoseCloudPersonnelVO;
import com.alibaba.fastjson2.JSON;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Component
public class HoseCloudPersonnelService extends AbstractHoseCloudBaseService implements IHoseCloudPersonnelService {
@Override
public List<HoseCloudPersonnelVO> queryUser(List<String> ids) {
Map<String, Object> body = new HashMap<>();
//STAFFID : 员工ID
//CODE : 工号
//CELLPHONE : 手机号
//MAIL : 邮箱
//USERID : 第三方ID
body.put("type","STAFFID");
body.put("conditionIds", ids);
//请求链接
String url = BASE_URL + "/api/openapi/v1/staffs/getStaffIds?accessToken={accessToken}";
String result = OkHttpClientUtil.doPostJson(getAccessToken(url, ChannelEnum.HOSECLOUD.getChannelId(), ChannelTypeEnum.OUT),
JSON.toJSONString(body));
List<HoseCloudPersonnelVO> list = new ArrayList<>();
if (StringUtils.isNotBlank(result)){
list = JSON.parseArray(JSON.parseObject(result).getString("items"), HoseCloudPersonnelVO.class);
}
return list.isEmpty() ? null : list;
}
}

View File

@ -0,0 +1,10 @@
package cn.jiutqy.finfiling.quartz.hosecloud;
import cn.jiutqy.finfiling.quartz.hosecloud.vo.HoseCloudPersonnelVO;
import java.util.List;
public interface IHoseCloudPersonnelService {
List<HoseCloudPersonnelVO> queryUser(List<String> ids);
}

View File

@ -0,0 +1,19 @@
package cn.jiutqy.finfiling.quartz.hosecloud.vo;
import lombok.Data;
@Data
public class HoseCloudPersonnelVO {
private String id;
private String name;
private String nickName;
private String code;
private String defaultDepartment;
//第三方平台人员ID
private String userId;
}

View File

@ -0,0 +1,15 @@
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

@ -0,0 +1,208 @@
package cn.jiutqy.finfiling.quartz.sync;
import cn.hutool.core.collection.CollectionUtil;
import cn.jiutqy.archives.common.utils.ExceptionUtil;
import cn.jiutqy.archives.common.utils.email.EmailSendUtil;
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.dipinshi.IDiPinShiFinFilingService;
import cn.jiutqy.finfiling.quartz.dipinshi.attendance.IDiPinShiAttendanceService;
import cn.jiutqy.finfiling.quartz.dipinshi.attendance.vo.*;
import cn.jiutqy.finfiling.quartz.enums.GeYuanOutboundTypeEnum;
import cn.jiutqy.finfiling.quartz.hosecloud.HoseCloudPersonnelService;
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 OutboundSyncGeYuanService implements IOutboundSyncDiPinShiService{
@Autowired
private IFinFilingSyncLogService finFilingSyncLogService;
@Autowired
private IDiPinShiFinFilingService diPinShiFinFilingService;
@Autowired
private IDiPinShiAttendanceService attendanceService;
private final static String TRAVEL_IN = "国内出差";
private final static String TRAVEL_OUT = "国际出差";
private final static String TRAVEL_OUT_NOT_USA = "国际出差非美国";
@Override
public void updateSyncTravel(String start, String end) {
//批量获取数据单号
List<String> approvalNos = diPinShiFinFilingService.getBatchApprovalNoTravel(start, end , "TRAVEL");
HashMap<String, Object> map = new HashMap<>();
List<DiPinShiAttendanceTravelInReqVO> travelIns = new ArrayList<>();
List<DiPinShiAttendanceTravelOutNotUSAReqVO> travelOutNotUSAs = new ArrayList<>();
List<DiPinShiAttendanceTravelOutReqVO> travelOuts = new ArrayList<>();
//根据单号查询详情 取出有效数据x
for (String approvalNo : approvalNos) {
String detail = diPinShiFinFilingService.getApprovalNoDetail(approvalNo);
//根据类型判断外出国内出差国际出差国际出差非美国
}
//记录同步结果
if (CollectionUtil.isNotEmpty(travelIns)){
travelIns.forEach(this::recordSyncData);
}
if (CollectionUtil.isNotEmpty(travelOutNotUSAs)){
travelOutNotUSAs.forEach(this::recordSyncData);
}
if (CollectionUtil.isNotEmpty(travelOuts)){
travelOuts.forEach(this::recordSyncData);
}
map.put(TRAVEL_IN,travelIns);
map.put(TRAVEL_OUT,travelOuts);
map.put(TRAVEL_OUT_NOT_USA,travelOutNotUSAs);
//数据的字段进行映射
HashMap<String, Object> reqBodys = travelMapping(map);
//数据同步到合思
attendanceService.attenancedTravel(reqBodys);
}
@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.getChannelId(), goOut.getApprovalNo());
if (finFilingSyncLog == null){
finFilingSyncLog = new FinFilingSyncLog();
finFilingSyncLog.setInputChannelId(ChannelEnum.DI_PIN_SHI.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.getChannelId() , JSON.toJSONString(goOut));
return;
}
try {
//数据同步到合思,更改同步状态
attendanceService.attendanceGoOut(goOut);
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 HashMap<String, Object> travelMapping(HashMap<String, Object> map) {
HashMap<String, Object> reqBodys = new HashMap<>();
List<String> travelInList = new ArrayList<>();
List<String> travelOutList = new ArrayList<>();
List<String> travelOutNotUSAList = new ArrayList<>();
//字段映射
reqBodys.put(TRAVEL_IN,travelInList);
reqBodys.put(TRAVEL_OUT,travelOutList);
reqBodys.put(TRAVEL_OUT_NOT_USA,travelOutNotUSAList);
return reqBodys;
}
//记录同步数据
private void recordSyncData(DiPinShiAttendanceReqVO reqVO){
FinFilingSyncLog finFilingSyncLog;
try {
finFilingSyncLog = finFilingSyncLogService.getFinFilingSyncLogByInputChannelAndInputDataId(ChannelEnum.DI_PIN_SHI.getChannelId(), "审批单号");
if (finFilingSyncLog == null){
finFilingSyncLog = new FinFilingSyncLog();
finFilingSyncLog.setInputChannelId(ChannelEnum.DI_PIN_SHI.getChannelId());
finFilingSyncLog.setInputDataId("审批单号");
finFilingSyncLog.setInputData(JSON.toJSONString("获取的数据"));
finFilingSyncLog.setSyncState(SyncStateEnum.INIT.value());
finFilingSyncLog.setCreateTime(new Date());
finFilingSyncLogService.save(finFilingSyncLog);
}
} catch (Exception e) {
log.error("写入同步日志失败:{}-{}", ChannelEnum.DI_PIN_SHI.getChannelId(), reqVO.getData());
}
}
@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

@ -0,0 +1,33 @@
package cn.jiutqy.finfiling.quartz.task;
import cn.jiutqy.finfiling.common.service.DefaultFormAtFinFilingService;
import cn.jiutqy.finfiling.common.service.DefaultFormFinFilingService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.Date;
@Slf4j
@Component("diPinShiSyncDataTask")
public class DiPinShiSyncDataTask {
@Autowired
private DefaultFormFinFilingService defaultFormFinFilingService;
@Autowired
private DefaultFormAtFinFilingService defaultFormAtFinFilingService;
public void syncData(String channelId,String formId){
long startTime = System.currentTimeMillis();
try {
log.info("同步({}/{})数据开始",channelId,formId);
defaultFormFinFilingService.syncData("2024-01-01 00:00:00","2024-01-31 23:59:59",channelId,formId);
long endTime = System.currentTimeMillis();
log.info("同步({}/{})数据结束,耗时:{}ms",channelId,formId,endTime-startTime);
} catch (Exception e) {
long endTime = System.currentTimeMillis();
log.error("同步({}/{})数据异常,耗时:{}ms",channelId,formId,endTime-startTime,e);
}
}
}

178
pom.xml Normal file
View File

@ -0,0 +1,178 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>cn.jiutqy</groupId>
<artifactId>dipinshi-hesi</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>
<name>dipinshi-hesi</name>
<url>http://www.jiutqy.com</url>
<properties>
<project.version>1.0.0-SNAPSHOT</project.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<lombok.version>1.18.26</lombok.version>
<spring-framework.version>5.3.33</spring-framework.version>
<jiutqy.version>3.8.8-SNAPSHOT</jiutqy.version>
</properties>
<modules>
<module>fin-filing-common</module>
<module>fin-filing-admin</module>
<module>fin-filing-quartz</module>
</modules>
<dependencyManagement>
<dependencies>
<!-- SpringFramework的依赖配置-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-framework-bom</artifactId>
<version>${spring-framework.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- SpringBoot的依赖配置-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.5.15</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>cn.jiutqy</groupId>
<artifactId>fin-filing-common</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>cn.jiutqy</groupId>
<artifactId>fin-filing-quartz</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>cn.jiutqy.archives</groupId>
<artifactId>jiutqy-admin</artifactId>
<version>${jiutqy.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<!-- SpringBoot Web容器 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- SpringBoot 拦截器 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>cn.jiutqy.archives</groupId>
<artifactId>jiutqy-admin</artifactId>
</dependency>
<!-- okhttp3 依赖 -->
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>4.9.3</version>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>logging-interceptor</artifactId>
<version>4.9.3</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<skip>true</skip>
<source>${java.version}</source>
<target>${java.version}</target>
<optimize>true</optimize>
<encoding>${project.build.sourceEncoding}</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<executions>
<execution>
<phase>verify</phase>
<goals>
<goal>jar-no-fork</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>public</id>
<name>aliyun nexus</name>
<url>https://maven.aliyun.com/repository/public</url>
<releases>
<enabled>true</enabled>
</releases>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>public</id>
<name>aliyun nexus</name>
<url>https://maven.aliyun.com/repository/public</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>
</project>