Commit 18a2cf91 by yxdubhe_bot

merge:feature-changeFlow-221110:operator:hzhuyuanyuan@corp.netease.com:auto_bran…

merge:feature-changeFlow-221110:operator:hzhuyuanyuan@corp.netease.com:auto_branch_merge_by_branchService_end
parents f005b819 8e009370
include: variables:
- project: tech/ci-operator SERVICE_CODE: 'yanxuan-qc-change-system'
file: /yanxuan-qc-change-system/gitlab-ci.yml TARGET_FILE_PATH: './build' #目标文件所在的目录; 根据实际情况修改
ref: master TARGET_FILE_NAME: 'yanxuan-qc-change-system.jar' #目标文件的文件名,根据实际情况修改
\ No newline at end of file ARTIFACT_NAME: 'yanxuan-qc-change-system.jar' #制品名, 主要是考虑目标文件和制品文件文件名不一致的情况;如果一致, 则和目标文件名一致
DEV_SETENV_FILE_PATH: './deploy/env/setenv-dev.sh' #开发环境setenv文件路径
TEST_SETENV_FILE_PATH: './deploy/env/setenv-test.sh' #测试环境setenv文件路径
ONLINE_SETENV_FILE_PATH: './deploy/env/setenv-online.sh' #线上环境setenv文件路径
stages:
- inspection
- unitTest
- package
- upload-bee
- upload
#inspection
#inspection-job:
# stage: inspection
# script:
# - ci_tools inspection $SERVICE_CODE $CI_COMMIT_REF_NAME $CI_PIPELINE_ID
# tags:
# - ci-backend
#unitTest-job:
# stage: unitTest
# script:
# - mvn clean org.jacoco:jacoco-maven-plugin:0.8.2:prepare-agent test org.jacoco:jacoco-maven-plugin:0.8.2:report -Dmaven.test.failure.ignore=true
# - ci_tools report_unit_test_result $TARGET_FILE_PATH/site/jacoco/jacoco.xml $SERVICE_CODE $CI_COMMIT_REF_NAME $CI_PIPELINE_ID
# tags:
# - ci-backend
################
# Test
################
test_package:
stage: package
script:
- mvn clean -U package -Ptest -Dmaven.test.skip=true -Dencoding=UTF-8
- mv $TARGET_FILE_PATH/$TARGET_FILE_NAME $ARTIFACT_NAME
- mv $TEST_SETENV_FILE_PATH ./setenv.sh
- zip $CI_PROJECT_NAME.zip ./setenv.sh $ARTIFACT_NAME
tags:
- ci-backend
artifacts:
paths:
- $CI_PROJECT_NAME.zip
- swagger/
expire_in: 1d
except:
- master
test_upload_bee:
stage: upload-bee
script:
- cd swagger
- beeUpload $SERVICE_CODE $CI_BUILD_REF_NAME $GITLAB_USER_NAME $GITLAB_USER_EMAIL
tags:
- ci-backend
except:
- master
dependencies:
- test_package
test_image_upload:
stage: upload
script:
- version_tools time && CURRENT_TIMESTAMP=$(version_tools result)
- version_tools version && PROJECT_VERSION=$(version_tools result)
- IMAGE_TAG="${PROJECT_VERSION}-${CI_COMMIT_REF_NAME##*/}-${CURRENT_TIMESTAMP}-${CI_PIPELINE_ID}"
- IMAGE_NAME="${HARBOR_URL}/${HARBOR_APP_DIRECTOR}/${SERVICE_CODE}:${IMAGE_TAG}"
- unzip -o -q $CI_PROJECT_NAME.zip -d .
- docker build --pull -t ${IMAGE_NAME} .
- eval opera docker $OPERA_ARGS --env=test --imageName=${IMAGE_NAME} --imageTag=${IMAGE_TAG} --autoDeploy=true --clusterId=44 --ldcCode=cluster1
tags:
- ci-backend
only:
- dev
- /^feature-.*$/
dependencies:
- test_package
################
# Online
################
online_package:
stage: package
script:
- mvn clean -U package -Ponline -Dmaven.test.skip=true -Dencoding=UTF-8
- mv $TARGET_FILE_PATH/$TARGET_FILE_NAME $ARTIFACT_NAME
- mv $ONLINE_SETENV_FILE_PATH ./setenv.sh
- zip $CI_PROJECT_NAME.zip ./setenv.sh $ARTIFACT_NAME
tags:
- ci-backend
artifacts:
paths:
- $CI_PROJECT_NAME.zip
- swagger/
expire_in: 1d
only:
- master
online_upload_bee:
stage: upload-bee
script:
- cd swagger
- beeUpload $SERVICE_CODE $CI_BUILD_REF_NAME $GITLAB_USER_NAME $GITLAB_USER_EMAIL
tags:
- ci-backend
only:
- master
dependencies:
- online_package
online_image_upload:
stage: upload
script:
- version_tools time && CURRENT_TIMESTAMP=$(version_tools result)
- version_tools version && PROJECT_VERSION=$(version_tools result)
- IMAGE_TAG="${PROJECT_VERSION}-${CI_COMMIT_REF_NAME##*/}-${CURRENT_TIMESTAMP}-${CI_PIPELINE_ID}"
- IMAGE_NAME="${HARBOR_URL}/${HARBOR_APP_DIRECTOR}/${SERVICE_CODE}:${IMAGE_TAG}"
- unzip -o -q $CI_PROJECT_NAME.zip -d .
- docker build -t ${IMAGE_NAME} .
- eval opera docker $OPERA_ARGS --env=online --imageName=${IMAGE_NAME} --imageTag=${IMAGE_TAG}
tags:
- ci-backend
only:
- master
dependencies:
- online_package
java_home=/home/petools/packages/jdk1.8.0_91
jvm_opts_property="-Dspring.profiles.active=online -Dserver.port=8080"
consul_service_port=8080
consul_service_tags=online
consul_health_url="/yanxuan-qc-change-system/i/health"
java_home=/home/petools/packages/jdk1.8.0_91
jvm_opts_property="-Dspring.profiles.active=test -Dserver.port=8080"
consul_service_port=8080
consul_service_tags=test
consul_health_url="/yanxuan-qc-change-system/i/health"
CREATE TABLE `TB_YX_QC_CHANGE_CONFIG`
(
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`change_subject` int(11) NOT NULL DEFAULT '0' COMMENT '变更主体',
`parent_change_class_id` int(11) NOT NULL DEFAULT '0' COMMENT '一级变更类型id',
`son_change_class_id` int(11) NOT NULL DEFAULT '0' COMMENT '二级变更类型id',
`change_level` int(11) NOT NULL DEFAULT '0' COMMENT '变更等级',
`change_department` varchar(20) NOT NULL DEFAULT '' COMMENT '变更负责部门名',
`participate_change_exec_department` varchar(255) NOT NULL DEFAULT '' COMMENT '变更行动部门列表',
`change_commander_type` int(11) NOT NULL DEFAULT '0' COMMENT '变更负责人类型',
`change_commander` varchar(50) NOT NULL DEFAULT '' COMMENT '变更负责人详情(不同类型存储不同内容)',
`need_file` int(11) NOT NULL DEFAULT '0' COMMENT '是否需要资料上传',
`create_time` bigint(20) NOT NULL DEFAULT '0' COMMENT '创建时间',
`update_time` bigint(20) NOT NULL DEFAULT '0' COMMENT '更新时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='变更类型配置表';
CREATE TABLE `TB_YX_QC_CHANGE_EXEC_CONFIG`
(
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`change_template_id` bigint(20) NOT NULL DEFAULT '0' COMMENT '变更类型配置记录id',
`change_exec_department` varchar(20) NOT NULL DEFAULT '' COMMENT '变更执行部门名',
`change_exec_user_type` int(11) NOT NULL DEFAULT '0' COMMENT '变更行动人类型',
`change_exec_user` varchar(20) NOT NULL DEFAULT '' COMMENT '变更行动人(不同类型存储不同内容)',
`change_risk_desc` varchar(550) NOT NULL DEFAULT '' COMMENT '变更风险描述',
`change_exec_project` varchar(550) NOT NULL DEFAULT '' COMMENT '行动项',
`change_checking` varchar(550) NOT NULL DEFAULT '' COMMENT '变更验证措施',
`create_time` bigint(20) NOT NULL DEFAULT '0' COMMENT '创建时间',
`update_time` bigint(20) NOT NULL DEFAULT '0' COMMENT '更新时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='变更类型配置行动方案配置表';
CREATE TABLE `TB_YX_QC_CHANGE_TYPE`
(
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`type_name` varchar(20) NOT NULL DEFAULT '' COMMENT '类型名',
`parent_id` bigint(20) NOT NULL DEFAULT '0' COMMENT '父类id',
`delete_type` int(11) NOT NULL DEFAULT '0' COMMENT '是否删除',
`create_time` bigint(20) NOT NULL DEFAULT '0' COMMENT '创建时间',
`update_time` bigint(20) NOT NULL DEFAULT '0' COMMENT '更新时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='变更类型表';
CREATE TABLE `TB_YX_QC_CHANGE_RECORD`
(
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`flow_id` bigint(20) NOT NULL DEFAULT '0' COMMENT '工单id',
`flow_node` varchar(20) NOT NULL DEFAULT '' COMMENT '工单当前节点',
`change_subject` int(11) NOT NULL DEFAULT '0' COMMENT '变更主体',
`parent_change_class_id` int(11) NOT NULL DEFAULT '0' COMMENT '一级变更类型id',
`son_change_class_id` int(11) NOT NULL DEFAULT '0' COMMENT '二级变更类型id',
`change_level` int(11) NOT NULL DEFAULT '0' COMMENT '变更等级',
`change_commander` varchar(70) NOT NULL DEFAULT '' COMMENT '变更负责人',
`change_department` varchar(20) NOT NULL DEFAULT '' COMMENT '变更负责部门名',
`participate_change_exec_department` varchar(255) NOT NULL DEFAULT '' COMMENT '变更行动部门列表,JSON格式',
`change_item` varchar(1020) NOT NULL DEFAULT '' COMMENT '变更商品(变更主体为商品时有效)',
`change_supplier` varchar(20) NOT NULL DEFAULT '' COMMENT '变更供应商(变更主体为供应商时有效)',
`change_reason` varchar(550) NOT NULL DEFAULT '' COMMENT '变更原因',
`change_content` varchar(550) NOT NULL DEFAULT '' COMMENT '变更内容',
`change_risk_desc` varchar(550) NOT NULL DEFAULT '' COMMENT '变更潜在风险描述',
`change_checking` varchar(550) NOT NULL DEFAULT '' COMMENT '变更验证措施',
`change_profit` int(11) NOT NULL DEFAULT '0' COMMENT '变更收益',
`change_profit_desc` varchar(550) NOT NULL DEFAULT '' COMMENT '变更收益说明',
`change_confirm_result_time` bigint(20) NOT NULL DEFAULT '0' COMMENT '变更结果确认时间',
`state` int(2) NOT NULL DEFAULT '0' COMMENT '工单状态,1进行中,2取消完结,3延期,4正常完结',
`cancel_reason` varchar(550) NOT NULL DEFAULT '' COMMENT '取消原因',
`change_result` int(2) NOT NULL DEFAULT '0' COMMENT '变更结论',
`create_source` int(2) NOT NULL DEFAULT '0' COMMENT '创建端(普通or同舟)',
`create_supplier` varchar(20) NOT NULL DEFAULT '' COMMENT '创建人所属供应商(同舟创建)',
`change_result_desc` varchar(550) NOT NULL DEFAULT '' COMMENT '结论说明',
`remark` varchar(550) NOT NULL DEFAULT '' COMMENT '备注',
`creator` varchar(50) NOT NULL DEFAULT '' COMMENT '创建人邮箱',
`auto_submit_email` int(2) NOT NULL DEFAULT '0' COMMENT '自动提交发送邮件',
`create_time` bigint(20) NOT NULL DEFAULT '0' COMMENT '创建时间',
`update_time` bigint(20) NOT NULL DEFAULT '0' COMMENT '更新时间',
PRIMARY KEY (`id`),
KEY `key_flow_id` (`flow_id`) USING BTREE COMMENT '变更工单id普通索引',
KEY `key_email` (`auto_submit_email`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='变更工单记录表'
CREATE TABLE `TB_YX_QC_CHANGE_FILE`
(
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`change_record_id` bigint(20) NOT NULL DEFAULT '0' COMMENT '变更记录id',
`file_type` int(2) NOT NULL DEFAULT '0' COMMENT '文件类型(基础信息图片/基础信息视频/基础信息资料/变更结果资料)',
`file_name` varchar(255) NOT NULL DEFAULT '' COMMENT '文件名称',
`file_url` varchar(255) NOT NULL DEFAULT '' COMMENT '文件地址',
`create_time` bigint(20) NOT NULL DEFAULT '0' COMMENT '创建时间',
`update_time` bigint(20) NOT NULL DEFAULT '0' COMMENT '更新时间',
PRIMARY KEY (`id`),
KEY `key_record_id` (`change_record_id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='附件表';
CREATE TABLE `TB_YX_QC_CHANGE_EXEC_RECORD`
(
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`change_record_id` bigint(20) NOT NULL DEFAULT '0' COMMENT '变更记录id',
`change_exec_department` varchar(50) NOT NULL DEFAULT '' COMMENT '变更执行部门名',
`change_exec_user_type` int(2) NOT NULL DEFAULT '0' COMMENT '变更行动人类型',
`change_exec_user` varchar(50) NOT NULL DEFAULT '' COMMENT '变更行动人(不同类型存储不同内容)',
`change_exec_user_email` varchar(60) NOT NULL DEFAULT '' COMMENT '变更行动人邮箱',
`change_risk_desc` varchar(550) NOT NULL DEFAULT '' COMMENT '变更风险描述',
`change_exec_project` varchar(550) NOT NULL DEFAULT '' COMMENT '行动项',
`change_checking` varchar(550) NOT NULL DEFAULT '' COMMENT '变更措施验证',
`change_exec_finish_time` bigint(20) NOT NULL DEFAULT '0' COMMENT '行动完成时间',
`change_exec_finish_desc` varchar(550) NOT NULL DEFAULT '' COMMENT '行动完成情况',
`create_time` bigint(20) NOT NULL DEFAULT '0' COMMENT '创建时间',
`update_time` bigint(20) NOT NULL DEFAULT '0' COMMENT ' 更新时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='变更类型行动方案记录表';
\ No newline at end of file
...@@ -39,6 +39,7 @@ ...@@ -39,6 +39,7 @@
<tracer.version>1.0.8-RELEASE</tracer.version> <tracer.version>1.0.8-RELEASE</tracer.version>
<shadow.version>1.0.6-RELEASE</shadow.version> <shadow.version>1.0.6-RELEASE</shadow.version>
<netease.ddb.version>4.6.0.4</netease.ddb.version> <netease.ddb.version>4.6.0.4</netease.ddb.version>
<user-info-client.version>1.0.2-RELEASE</user-info-client.version>
<!-- store-db --> <!-- store-db -->
<mysql.version>5.1.34</mysql.version> <mysql.version>5.1.34</mysql.version>
...@@ -59,7 +60,8 @@ ...@@ -59,7 +60,8 @@
<commonsio.version>2.4</commonsio.version> <commonsio.version>2.4</commonsio.version>
<commonscollection.version>4.1</commonscollection.version> <commonscollection.version>4.1</commonscollection.version>
<commons.lang.version>2.4</commons.lang.version> <commons.lang.version>2.4</commons.lang.version>
<des.version>1.0.2-SNAPSHOT</des.version>
<mapstruct.version>1.3.1.Final</mapstruct.version>
</properties> </properties>
<!-- 子模块可选依赖 --> <!-- 子模块可选依赖 -->
...@@ -126,12 +128,6 @@ ...@@ -126,12 +128,6 @@
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.netease.yanxuan.missa</groupId>
<artifactId>missa-client</artifactId>
<version>${missa.client.version}</version>
</dependency>
<dependency>
<groupId>com.netease.mail.yanxuan</groupId> <groupId>com.netease.mail.yanxuan</groupId>
<artifactId>eudemon-all</artifactId> <artifactId>eudemon-all</artifactId>
<version>${eudemon.version}</version> <version>${eudemon.version}</version>
...@@ -200,10 +196,17 @@ ...@@ -200,10 +196,17 @@
<artifactId>spring-data-redis</artifactId> <artifactId>spring-data-redis</artifactId>
<version>${spring.data.redis.version}</version> <version>${spring.data.redis.version}</version>
</dependency> </dependency>
<dependency>
<groupId>com.netease.yanxuan</groupId>
<artifactId>user-ula-sdk</artifactId>
<version>1.0.13-RELEASE</version>
</dependency>
<dependency> <dependency>
<groupId>netease.ddb</groupId> <groupId>com.netease.yanxuan</groupId>
<artifactId>db</artifactId> <artifactId>user-info-client</artifactId>
<version>${netease.ddb.version}</version> <version>${user-info-client.version}</version>
</dependency> </dependency>
</dependencies> </dependencies>
...@@ -233,10 +236,33 @@ ...@@ -233,10 +236,33 @@
<artifactId>apolloY-client</artifactId> <artifactId>apolloY-client</artifactId>
</dependency> </dependency>
<dependency>
<groupId>com.netease.yanxuan</groupId>
<artifactId>user-ula-sdk</artifactId>
</dependency>
<dependency>
<groupId>com.netease.yanxuan</groupId>
<artifactId>user-info-client</artifactId>
</dependency>
<!--默认引入missa--> <!--默认引入missa-->
<dependency> <dependency>
<groupId>com.netease.yanxuan.missa</groupId> <groupId>com.netease.yanxuan.missa</groupId>
<artifactId>missa-client</artifactId> <artifactId>missa-client</artifactId>
<version>${missa.client.version}</version>
</dependency>
<dependency>
<groupId>com.netease.mail</groupId>
<artifactId>yx-openid-login</artifactId>
<version>1.0.1-SNAPSHOT</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</exclusion>
</exclusions>
</dependency> </dependency>
<!--其他严选中间件依赖包按需添加--> <!--其他严选中间件依赖包按需添加-->
...@@ -349,6 +375,104 @@ ...@@ -349,6 +375,104 @@
<artifactId>guava</artifactId> <artifactId>guava</artifactId>
<version>${guava.version}</version> <version>${guava.version}</version>
</dependency> </dependency>
<dependency>
<groupId>tk.mybatis</groupId>
<artifactId>mapper-spring-boot-starter</artifactId>
<version>2.1.5</version>
</dependency>
<!--mybatis 分页插件-->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.3.0</version>
</dependency>
<dependency>
<groupId>com.netease.yanxuan.flowx</groupId>
<artifactId>yanxuan-flowx-sdk</artifactId>
<version>1.4</version>
<exclusions>
<exclusion>
<artifactId>logback-classic</artifactId>
<groupId>ch.qos.logback</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.netease.mail.yanxuan</groupId>
<artifactId>dschedule-boot-starter</artifactId>
<version>1.0.6-RELEASE</version>
<exclusions>
<exclusion>
<artifactId>fastjson</artifactId>
<groupId>com.alibaba</groupId>
</exclusion>
</exclusions>
</dependency>
<!-- <dependency>-->
<!-- <groupId>io.springfox</groupId>-->
<!-- <artifactId>springfox-swagger2</artifactId>-->
<!-- <version>2.7.0</version>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>io.springfox</groupId>-->
<!-- <artifactId>springfox-swagger-ui</artifactId>-->
<!-- <version>2.7.0</version>-->
<!-- </dependency>-->
<!--qc -->
<!--<dependency>-->
<!-- <groupId>com.netease.yanxuan</groupId>-->
<!-- <artifactId>yanxuan-qc-service-client</artifactId>-->
<!-- <version>2.0.0-SNAPSHOT</version>-->
<!--</dependency>-->
<!--<dependency>-->
<!-- <groupId>com.netease.yanxuan</groupId>-->
<!-- <artifactId>yanxuan-qc-business-lib</artifactId>-->
<!-- <version>2.0.0-SNAPSHOT</version>-->
<!--</dependency>-->
<!--<dependency>-->
<!-- <groupId>com.netease.yanxuan</groupId>-->
<!-- <artifactId>yanxuan-qc-parent</artifactId>-->
<!-- <version>2.0.0-SNAPSHOT</version>-->
<!--</dependency>-->
<!-- <dependency>-->
<!-- <groupId>com.netease.mail.yanxuan</groupId>-->
<!-- <artifactId>dschedule-boot-starter</artifactId>-->
<!-- <version>1.0.3-SNAPSHOT</version>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>com.netease.mailsaas</groupId>-->
<!-- <artifactId>saas-kit-java-bundle</artifactId>-->
<!-- <version>0.1.0-SNAPSHOT</version>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>org.assertj</groupId>-->
<!-- <artifactId>assertj-core</artifactId>-->
<!-- <version>3.18.1</version>-->
<!-- </dependency>-->
<!--easypoi-->
<dependency>
<groupId>cn.afterturn</groupId>
<artifactId>easypoi-base</artifactId>
<version>3.1.0</version>
</dependency>
<dependency>
<groupId>cn.afterturn</groupId>
<artifactId>easypoi-web</artifactId>
<version>3.1.0</version>
</dependency>
<dependency>
<groupId>cn.afterturn</groupId>
<artifactId>easypoi-annotation</artifactId>
<version>3.1.0</version>
</dependency>
<dependency>
<groupId>com.netease.mail.dp</groupId>
<artifactId>des-boot-starter</artifactId>
<version>${des.version}</version>
</dependency>
</dependencies> </dependencies>
<repositories> <repositories>
...@@ -437,5 +561,14 @@ ...@@ -437,5 +561,14 @@
</plugin> </plugin>
</plugins> </plugins>
<resources>
<resource>
<directory>src/main/resources</directory>
</resource>
<resource>
<directory>src/main/resources/config/${env}</directory>
</resource>
</resources>
</build> </build>
</project> </project>
\ No newline at end of file
...@@ -18,6 +18,53 @@ ...@@ -18,6 +18,53 @@
</dependency> </dependency>
</dependencies> </dependencies>
<!-- profiles -->
<profiles>
<profile>
<id>dev</id>
<properties>
<env>dev</env>
<profileActive>dev</profileActive>
<env.resource.directory>src/main/resources/config/dev</env.resource.directory>
</properties>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
</profile>
<profile>
<id>test</id>
<properties>
<env>test</env>
<profileActive>test</profileActive>
<env.resource.directory>src/main/resources/config/test</env.resource.directory>
</properties>
</profile>
<profile>
<id>regression</id>
<properties>
<env>regression</env>
<profileActive>regression</profileActive>
<env.resource.directory>src/main/resources/config/regression</env.resource.directory>
</properties>
</profile>
<profile>
<id>online</id>
<properties>
<env>online</env>
<profileActive>online</profileActive>
<env.resource.directory>src/main/resources/config/online</env.resource.directory>
</properties>
</profile>
<profile>
<id>release</id>
<properties>
<env>release</env>
<profileActive>online</profileActive>
<env.resource.directory>src/main/resources/config/release</env.resource.directory>
</properties>
</profile>
</profiles>
<build> <build>
<finalName>yanxuan-qc-change-system</finalName> <finalName>yanxuan-qc-change-system</finalName>
<directory>../build</directory> <directory>../build</directory>
......
package com.netease.mail.yanxuan.change.assembly; package com.netease.mail.yanxuan.change.assembly;
import com.ctrip.framework.apollo.spring.annotation.EnableApolloConfig;
import com.netease.yanxuan.missa.client.annotation.EnableMissaClients;
import org.springframework.boot.SpringApplication; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.ComponentScan;
import com.ctrip.framework.apollo.spring.annotation.EnableApolloConfig;
import com.netease.yanxuan.missa.client.annotation.EnableMissaClients;
import tk.mybatis.spring.annotation.MapperScan;
/** /**
* 项目启动类 * 项目启动类
*/ */
@ComponentScan(basePackages = "com.netease.mail.yanxuan.change") @ComponentScan(basePackages = {"com.netease.mail.yanxuan.change", "com.netease.yanxuan.user", "com.netease.mail.yanxuan.qc"})
@MapperScan("com.netease.mail.yanxuan.change.dal.mapper")
@EnableApolloConfig @EnableApolloConfig
@EnableMissaClients(basePackages = "com.netease.mail.yanxuan.change") @EnableMissaClients(basePackages = "com.netease.mail.yanxuan.change")
@SpringBootApplication @SpringBootApplication
......
dschedule.enable=true
dschedule.env=test
dschedule.app-id=yanxuan-sc-ehc
dschedule.job-group=235
dschedule.enable-auto-register=true
dschedule.executor-fail-strategy=fail_alarm
dschedule.alarm-email=wb.tanglongwei@mesg.corp.netease.com
dschedule.adminAddresses=http://127.0.0.1:8550/proxy/test.dschedule-admin.service.mailsaas/
spring.http.multipart.max-file-size=100MB
spring.http.multipart.max-request-size=100MB
# mysql
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/change_config?useUnicode=true&characterEncoding=UTF-8&autoReconnet=true
spring.datasource.username=root
spring.datasource.password=abc123
#tomcat
server.tomcat.max-threads=600
server.tomcat.uri-encoding=UTF-8
server.tomcat.basedir=/home/logs/access
server.tomcat.accesslog.enabled=true
server.tomcat.accesslog.pattern=%h %l %u %t "%r" %s %b %{X-Forwarded-For}i %D %{P_INFO}c %{Referer}i %{User-Agent}i %{Host}i
# mybatis
mybatis.mapper-locations=classpath:mybatis/mapper/*.xml
mybatis.configuration.cache-enabled=true
mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
# redis
spring.redis.pool.max-active=50
spring.redis.host=127.0.0.1
spring.redis.port=6379
spring.redis.password=
spring.redis.pool.max-wait=10000
spring.redis.pool.max-idle=20
spring.redis.timeout=20000
<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="true" scan="true" scanPeriod="60 seconds">
<contextName>yanxuan-sc-ehc</contextName>
<include resource="logback-missa.xml"/>
<!--定义日志文件的存储地址 勿在 LogBack 的配置中使用相对路径-->
<property name="log.productName" value="yanxuan-sc-ehc"/>
<property name="log.path" value="/home/logs"/>
<property name="log.path.holmes" value="/home/logs/holmes"/>
<property name="log.level" value="debug"/>
<property name="log.pattern"
value="{time=%d{yyyy-MM-dd HH:mm:ss.SSS}, traceId=%X{XTraceId}, level=%p} [%c{0}] %m%n"/>
<!-- custom coloring conversion -->
<conversionRule conversionWord="highlightex"
converterClass="com.netease.mail.yanxuan.qc.api.common.common.HighlightingCompositeConverterEx"/>
<!--appender-->
<!--输出到控制台-->
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>{time=%d{yyyy-MM-dd HH:mm:ss.SSS}, traceId=%X{XTraceId}, level=%p} [%c{0}] [%C{0}] [%L] [%M] %m%n
</pattern>
<charset>UTF-8</charset>
</encoder>
</appender>
<appender name="query-internal" class="ch.qos.logback.core.rolling.RollingFileAppender">
<encoder>
<pattern>${log.pattern}</pattern>
<charset>UTF-8</charset>
</encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${log.path}/${log.productName}/query.log.%d{yyyy-MM-dd}</fileNamePattern>
<maxHistory>90</maxHistory>
<!-- <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">-->
<!-- &lt;!&ndash; maxFileSize:这是活动文件的大小,默认值是10MB,本篇设置为1KB,只是为了演示 &ndash;&gt;-->
<!-- <maxFileSize>500MB</maxFileSize>-->
<!-- </timeBasedFileNamingAndTriggeringPolicy>-->
</rollingPolicy>
</appender>
<appender name="query" class="ch.qos.logback.classic.AsyncAppender">
<queueSize>512</queueSize>
<discardingThreshold>0</discardingThreshold>
<includeCallerData>true</includeCallerData>
<appender-ref ref="query-internal"/>
</appender>
<appender name="stdout-internal"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<encoder>
<pattern>${log.pattern}</pattern>
<charset>UTF-8</charset>
</encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${log.path}/${log.productName}/stdout.log.%d{yyyy-MM-dd}</fileNamePattern>
<maxHistory>14</maxHistory>
</rollingPolicy>
</appender>
<appender name="stdout" class="ch.qos.logback.classic.AsyncAppender">
<queueSize>512</queueSize>
<discardingThreshold>0</discardingThreshold>
<includeCallerData>true</includeCallerData>
<appender-ref ref="stdout-internal"/>
</appender>
<appender name="holmes-appender"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<encoder>
<pattern>%msg</pattern>
<charset>UTF-8</charset>
</encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${log.path.holmes}/${log.productName}/yanxuan.${log.productName}.%d{yyyy-MM-dd}.log
</fileNamePattern>
<maxHistory>7</maxHistory>
</rollingPolicy>
</appender>
<appender name="rpc" class="ch.qos.logback.core.rolling.RollingFileAppender">
<encoder>
<pattern>${log.pattern}</pattern>
<charset>UTF-8</charset>
</encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${log.path}/${log.productName}/rpc.log.%d{yyyy-MM-dd}</fileNamePattern>
<maxHistory>60</maxHistory>
</rollingPolicy>
</appender>
<appender name="task" class="ch.qos.logback.core.rolling.RollingFileAppender">
<encoder>
<pattern>${log.pattern}</pattern>
<charset>UTF-8</charset>
</encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${log.path}/${log.productName}/task.log.%d{yyyy-MM-dd}
</fileNamePattern>
</rollingPolicy>
</appender>
<!-- <appender name="admin" class="ch.qos.logback.core.rolling.RollingFileAppender">-->
<!-- <encoder>-->
<!-- <pattern>${log.pattern}</pattern>-->
<!-- <charset>UTF-8</charset>-->
<!-- </encoder>-->
<!-- <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">-->
<!-- <fileNamePattern>${log.path}/${log.productName}/admin.log.%d{yyyy-MM-dd}-->
<!-- </fileNamePattern>-->
<!-- </rollingPolicy>-->
<!-- </appender>-->
<!-- <appender name="core" class="ch.qos.logback.core.rolling.RollingFileAppender">-->
<!-- <encoder>-->
<!-- <pattern>${log.pattern}</pattern>-->
<!-- <charset>UTF-8</charset>-->
<!-- </encoder>-->
<!-- <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">-->
<!-- <fileNamePattern>${log.path}/${log.productName}/core.log.%d{yyyy-MM-dd}-->
<!-- </fileNamePattern>-->
<!-- </rollingPolicy>-->
<!-- </appender>-->
<appender name="stderr"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<encoder>
<pattern>${log.pattern}</pattern>
<charset>UTF-8</charset>
</encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${log.path}/${log.productName}/stderr.log.%d{yyyy-MM-dd}
</fileNamePattern>
</rollingPolicy>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>ERROR</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- <logger name="com.netease.mail.yanxuan.ehc.admin" additivity="false" level="${log.level}">-->
<!-- <appender-ref ref="admin"/>-->
<!-- </logger>-->
<!-- <logger name="com.netease.mail.yanxuan.ehc.core" additivity="false" level="${log.level}">-->
<!-- <appender-ref ref="core"/>-->
<!-- </logger>-->
<appender name="HELIOS-COMMON-APPENDER"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%p] [%c{0}] %m%n</pattern>
<charset>UTF-8</charset>
</encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${log.path}/${log.productName}/helios-common.log.%d{yyyy-MM-dd}.gz
</fileNamePattern>
</rollingPolicy>
</appender>
<appender name="HELIOS-STATS-APPENDER"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%p] [%c{0}] %m%n</pattern>
<charset>UTF-8</charset>
</encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${log.path}/${log.productName}/helios-stats.log.%d{yyyy-MM-dd}.gz
</fileNamePattern>
</rollingPolicy>
</appender>
<appender name="HELIOS-PROFILER-APPENDER"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%p] [%c{0}] %m%n</pattern>
<charset>UTF-8</charset>
</encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${log.path}/${log.productName}/helios-profile.log.%d{yyyy-MM-dd}.gz
</fileNamePattern>
</rollingPolicy>
</appender>
<appender name="HELIOS-SCHEDULE-JOB"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%p] [%t] [%c{0}] [%X{PtxId}] %m%n</pattern>
<charset>UTF-8</charset>
</encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!-- rollover daily -->
<fileNamePattern>${log.path}/${log.productName}/helios-schedule.log.%d{yyyy-MM-dd}-%i.gz
</fileNamePattern>
<!-- each file should be at most 30MB, keep 60 days worth of history, but at most 2GB -->
<maxFileSize>30MB</maxFileSize>
<maxHistory>60</maxHistory>
<totalSizeCap>2GB</totalSizeCap>
</rollingPolicy>
</appender>
<appender name="helios-biz-appender"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<encoder>
<charset>UTF-8</charset>
<pattern>%msg</pattern>
</encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${log.path}/${log.productName}/biz.helios.log.%d{yyyy-MM-dd}.gz
</fileNamePattern>
<cleanHistoryOnStart>true</cleanHistoryOnStart>
<maxHistory>21</maxHistory>
</rollingPolicy>
</appender>
<appender name="async-helios-biz-appender"
class="ch.qos.logback.classic.AsyncAppender">
<queueSize>1024</queueSize>
<appender-ref ref="helios-biz-appender"/>
</appender>
<logger name="helios-biz-logger" additivity="false" level="${log.level}">
<appender-ref ref="async-helios-biz-appender"/>
</logger>
<appender name="ASYNC-HELIOS-SCHEDULE-JOB"
class="ch.qos.logback.classic.AsyncAppender">
<!-- 更改默认的队列的深度,该值会影响性能.默认值为256 -->
<queueSize>512</queueSize>
<appender-ref ref="HELIOS-SCHEDULE-JOB"/>
</appender>
<logger name="HELIOS_SCHEDULE" additivity="false" level="info">
<appender-ref ref="ASYNC-HELIOS-SCHEDULE-JOB"/>
</logger>
<logger name="HELIOS_COMMON" level="${log.level}" additivity="false">
<appender-ref ref="HELIOS-COMMON-APPENDER"/>
</logger>
<logger name="HELIOS_STATS" level="${log.level}"
additivity="false">
<appender-ref ref="HELIOS-STATS-APPENDER"/>
</logger>
<logger name="HELIOS_PROFILER" level="${log.level}"
additivity="false">
<appender-ref ref="HELIOS-PROFILER-APPENDER"/>
</logger>
<logger name="net.sf.ehcache.pool.impl.DefaultSizeOfEngine" level="error"/>
<logger name="net.sf.ehcache.pool.sizeof.ObjectGraphWalker" level="error"/>
<logger name="com.netease.mail.yanxuan.ehc.core.meta.bean.rpc" additivity="false" level="info">
<appender-ref ref="rpc"/>
<appender-ref ref="stderr"/>
</logger>
<logger name="com.netease" additivity="false" level="${log.level}">
<appender-ref ref="query"/>
<appender-ref ref="stderr"/>
<appender-ref ref="console"/>
</logger>
<logger name="holmes-logger" level="info">
<appender-ref ref="holmes-appender"/>
</logger>
<!-- 日志输出级别 -->
<root level="${log.level}">
<appender-ref ref="stdout"/>
<appender-ref ref="stderr"/>
<appender-ref ref="console"/>
</root>
</configuration>
jvm_opts_base="-cp . -ea -Xms4096m -Xmx4096m"
jvm_opts_gc="-XX:+UseG1GC -XX:MaxGCPauseMillis=100 -XX:G1HeapRegionSize=16m -XX:G1ReservePercent=15 -XX:InitiatingHeapOccupancyPercent=45 -XX:MaxTenuringThreshold=7 -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=368m -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+UnlockExperimentalVMOptions -XX:G1LogLevel=finest -XX:+PrintHeapAtGC -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/home/logs/yanxuan-sc-ehc -XX:-OmitStackTraceInFastThrow -Xloggc:/home/logs/yanxuan-sc-ehc/gc-%t.log"
jvm_opts_property="-Dspring.profiles.active=test -Denv=test -Dserver.port=8080"
jvm_opts_ext="-javaagent:/home/caesar-agent/caesar-agent-router-1.0.0.jar -Dapp.id=yanxuan-sc-ehc"
consul_service_tags=test
consul_service_port=8080
consul_health_url="/i/health"
consul_service_name="yanxuan-sc-ehc"
env=online
dschedule.enable=true
dschedule.env=online
dschedule.app-id=yanxuan-sc-ehc
dschedule.job-group=375
dschedule.enable-auto-register=true
dschedule.executor-fail-strategy=fail_alarm
dschedule.alarm-email=wb.tanglongwei@mesg.corp.netease.com
dschedule.adminAddresses=http://10.200.169.73:8080,http://10.200.169.74:8080,http://10.200.169.75:8080,http://10.200.169.76:8080,http://10.200.169.77:8080
spring.http.multipart.max-file-size=100MB
spring.http.multipart.max-request-size=100MB
#mysql
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://10.130.72.182:4306/hd_qc_ecr?useUnicode=true&characterEncoding=UTF-8&autoReconnet=true
spring.datasource.username=hd_qc_ecr
spring.datasource.password=hd_qc_ecr
#tomcat
server.tomcat.max-threads=600
server.tomcat.uri-encoding=UTF-8
server.tomcat.basedir=/home/logs/access
server.tomcat.accesslog.enabled=true
server.tomcat.accesslog.pattern=%h %l %u %t "%r" %s %b %{X-Forwarded-For}i %D %{P_INFO}c %{Referer}i %{User-Agent}i %{Host}i
mapper.style=normal
mapper.enum-as-simple-type=true
# mybatis
mybatis.mapper-locations=classpath:mybatis/mapper/*.xml
mybatis.configuration.cache-enabled=true
mybatis.configuration.map-underscore-to-camel-case=true
# redis
spring.redis.password=BC6AYgWOXuJetuJG
spring.redis.timeout=20000
spring.redis.sentinel.master=paas-redis/yx-sc-ehc-onl
spring.redis.sentinel.nodes=yx-cust23-online.ncr.cn-east-p1.internal.:32427
spring.redis.pool.max-active=50
spring.redis.pool.max-idle=20
spring.redis.pool.max-wait=10000
spring.redis.host=yx-cust23-online.ncr.cn-east-p1.internal.
spring.redis.port=32427
# supplier
supplier.url=http://127.0.0.1:8550/proxy/test-v1.yanxuan-supplier-ms.service.mailsaas
### des\u914D\u7F6E
# \u5BFC\u51FA\u6587\u4EF6\u4E0A\u4F20\u5230\u54EA\u4E2A\u670D\u52A1\u5668\uFF0C\u6709test\u548Conline\u53EF\u9009
des.prop.env=online
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="true" scan="true" scanPeriod="60 seconds">
<contextName>yanxuan-sc-ehc</contextName>
<include resource="logback-missa.xml"/>
<!--定义日志文件的存储地址 勿在 LogBack 的配置中使用相对路径-->
<property name="log.productName" value="yanxuan-qc-change-system"/>
<property name="log.path" value="/home/logs"/>
<property name="log.path.holmes" value="/home/logs/holmes"/>
<property name="log.level" value="info"/>
<property name="log.pattern"
value="{time=%d{yyyy-MM-dd HH:mm:ss.SSS}, traceId=%X{XTraceId}, level=%p} [%c{0}] %m%n"/>
<!-- custom coloring conversion -->
<conversionRule conversionWord="highlightex"
converterClass="com.netease.mail.yanxuan.qc.api.common.common.HighlightingCompositeConverterEx"/>
<!--appender-->
<appender name="query-internal" class="ch.qos.logback.core.rolling.RollingFileAppender">
<encoder>
<pattern>${log.pattern}</pattern>
<charset>UTF-8</charset>
</encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${log.path}/${log.productName}/query.log.%d{yyyy-MM-dd}</fileNamePattern>
<maxHistory>90</maxHistory>
</rollingPolicy>
</appender>
<appender name="query" class="ch.qos.logback.classic.AsyncAppender">
<queueSize>512</queueSize>
<discardingThreshold>0</discardingThreshold>
<includeCallerData>true</includeCallerData>
<appender-ref ref="query-internal"/>
</appender>
<appender name="stdout-internal"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<encoder>
<pattern>${log.pattern}</pattern>
<charset>UTF-8</charset>
</encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${log.path}/${log.productName}/stdout.log.%d{yyyy-MM-dd}</fileNamePattern>
<maxHistory>14</maxHistory>
</rollingPolicy>
</appender>
<appender name="stdout" class="ch.qos.logback.classic.AsyncAppender">
<queueSize>512</queueSize>
<discardingThreshold>0</discardingThreshold>
<includeCallerData>true</includeCallerData>
<appender-ref ref="stdout-internal"/>
</appender>
<appender name="holmes-appender"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<encoder>
<pattern>%msg</pattern>
<charset>UTF-8</charset>
</encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${log.path.holmes}/${log.productName}/yanxuan.${log.productName}.%d{yyyy-MM-dd}.log
</fileNamePattern>
<maxHistory>7</maxHistory>
</rollingPolicy>
</appender>
<appender name="rpc" class="ch.qos.logback.core.rolling.RollingFileAppender">
<encoder>
<pattern>${log.pattern}</pattern>
<charset>UTF-8</charset>
</encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${log.path}/${log.productName}/rpc.log.%d{yyyy-MM-dd}</fileNamePattern>
<maxHistory>60</maxHistory>
</rollingPolicy>
</appender>
<appender name="stderr"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<encoder>
<pattern>${log.pattern}</pattern>
<charset>UTF-8</charset>
</encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${log.path}/${log.productName}/stderr.log.%d{yyyy-MM-dd}
</fileNamePattern>
</rollingPolicy>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>ERROR</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<appender name="HELIOS-COMMON-APPENDER"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%p] [%c{0}] %m%n</pattern>
<charset>UTF-8</charset>
</encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${log.path}/${log.productName}/helios-common.log.%d{yyyy-MM-dd}.gz
</fileNamePattern>
</rollingPolicy>
</appender>
<appender name="HELIOS-STATS-APPENDER"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%p] [%c{0}] %m%n</pattern>
<charset>UTF-8</charset>
</encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${log.path}/${log.productName}/helios-stats.log.%d{yyyy-MM-dd}.gz
</fileNamePattern>
</rollingPolicy>
</appender>
<appender name="HELIOS-PROFILER-APPENDER"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%p] [%c{0}] %m%n</pattern>
<charset>UTF-8</charset>
</encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${log.path}/${log.productName}/helios-profile.log.%d{yyyy-MM-dd}.gz
</fileNamePattern>
</rollingPolicy>
</appender>
<appender name="HELIOS-SCHEDULE-JOB"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%p] [%t] [%c{0}] [%X{PtxId}] %m%n</pattern>
<charset>UTF-8</charset>
</encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!-- rollover daily -->
<fileNamePattern>${log.path}/${log.productName}/helios-schedule.log.%d{yyyy-MM-dd}-%i.gz
</fileNamePattern>
<!-- each file should be at most 30MB, keep 60 days worth of history, but at most 2GB -->
<maxFileSize>30MB</maxFileSize>
<maxHistory>60</maxHistory>
<totalSizeCap>2GB</totalSizeCap>
</rollingPolicy>
</appender>
<appender name="helios-biz-appender"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<encoder>
<charset>UTF-8</charset>
<pattern>%msg</pattern>
</encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${log.path}/${log.productName}/biz.helios.log.%d{yyyy-MM-dd}.gz
</fileNamePattern>
<cleanHistoryOnStart>true</cleanHistoryOnStart>
<maxHistory>21</maxHistory>
</rollingPolicy>
</appender>
<appender name="async-helios-biz-appender"
class="ch.qos.logback.classic.AsyncAppender">
<queueSize>1024</queueSize>
<appender-ref ref="helios-biz-appender"/>
</appender>
<appender name="ASYNC-HELIOS-SCHEDULE-JOB"
class="ch.qos.logback.classic.AsyncAppender">
<!-- 更改默认的队列的深度,该值会影响性能.默认值为256 -->
<queueSize>512</queueSize>
<appender-ref ref="HELIOS-SCHEDULE-JOB"/>
</appender>
<logger name="HELIOS_SCHEDULE" additivity="false" level="info">
<appender-ref ref="ASYNC-HELIOS-SCHEDULE-JOB"/>
</logger>
<logger name="HELIOS_COMMON" level="${log.level}" additivity="false">
<appender-ref ref="HELIOS-COMMON-APPENDER"/>
</logger>
<logger name="HELIOS_STATS" level="${log.level}"
additivity="false">
<appender-ref ref="HELIOS-STATS-APPENDER"/>
</logger>
<logger name="HELIOS_PROFILER" level="${log.level}"
additivity="false">
<appender-ref ref="HELIOS-PROFILER-APPENDER"/>
</logger>
<logger name="net.sf.ehcache.pool.impl.DefaultSizeOfEngine" level="error"/>
<logger name="net.sf.ehcache.pool.sizeof.ObjectGraphWalker" level="error"/>
<logger name="com.netease.mail.yanxuan.ehc.core.meta.bean.rpc" additivity="false" level="info">
<appender-ref ref="rpc"/>
<appender-ref ref="stderr"/>
</logger>
<!--logger-->
<logger name="com.netease" additivity="false" level="${log.level}">
<appender-ref ref="query"/>
</logger>
<logger name="holmes-logger" level="info">
<appender-ref ref="holmes-appender"/>
</logger>
<!-- 日志输出级别 -->
<root level="info">
<appender-ref ref="stdout"/>
<appender-ref ref="stderr"/>
</root>
</configuration>
jvm_opts_base="-cp . -ea -Xms8192m -Xmx8192m"
jvm_opts_gc="-XX:+UseG1GC -XX:MaxGCPauseMillis=100 -XX:G1HeapRegionSize=16m -XX:G1ReservePercent=15 -XX:InitiatingHeapOccupancyPercent=45 -XX:MaxTenuringThreshold=7 -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=368m -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+UnlockExperimentalVMOptions -XX:G1LogLevel=finest -XX:+PrintHeapAtGC -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/home/logs/yanxuan-sc-ehc -XX:-OmitStackTraceInFastThrow -Xloggc:/home/logs/yanxuan-sc-ehc/gc-%t.log"
jvm_opts_property="-Dspring.profiles.active=online -Denv=online -Dserver.port=8080"
jvm_opts_ext="-javaagent:/home/caesar-agent/caesar-agent-router-1.0.0.jar -Dapp.id=yanxuan-sc-ehc"
consul_service_tags=online
consul_service_port=8080
consul_service_name="yanxuan-sc-ehc"
consul_health_url="/i/health"
env=test
dschedule.enable=true
dschedule.env=test
dschedule.app-id=yanxuan-qc-change-system
dschedule.job-group=736
dschedule.enable-auto-register=true
dschedule.executor-fail-strategy=fail_alarm
dschedule.alarm-email=wb.tanglongwei@mesg.corp.netease.com
dschedule.adminAddresses=http://127.0.0.1:8550/proxy/test.dschedule-admin.service.mailsaas/
spring.http.multipart.max-file-size=100MB
spring.http.multipart.max-request-size=100MB
# mysql
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://10.170.155.148:4306/qc_ecr_system?useUnicode=true&characterEncoding=UTF-8&autoReconnet=true
spring.datasource.username=qc_ecr_system
spring.datasource.password=qc_ecr_system
#tomcat
server.tomcat.max-threads=600
server.tomcat.uri-encoding=UTF-8
server.tomcat.basedir=/home/logs/access
server.tomcat.accesslog.enabled=true
server.tomcat.accesslog.pattern=%h %l %u %t "%r" %s %b %{X-Forwarded-For}i %D %{P_INFO}c %{Referer}i %{User-Agent}i %{Host}i
# mybatis
mybatis.mapper-locations=classpath:mybatis/mapper/*.xml
mybatis.configuration.cache-enabled=true
mybatis.configuration.map-underscore-to-camel-case=true
# redis
spring.redis.password=xc0CdqWMzMj6hBvpIY5HrciHX85txmftyXukMnyKdK8X
spring.redis.timeout=20000
spring.redis.sentinel.master=paas-redis/yx-common-repl-1-test
spring.redis.sentinel.nodes=yx-cust23-test.ncr.cn-east-p1.internal:31461
spring.redis.pool.max-active=50
spring.redis.pool.max-idle=20
spring.redis.pool.max-wait=10000
spring.redis.host=yx-cust23-test.ncr.cn-east-p1.internal
spring.redis.port=31461
# supplier
supplier.url=http://127.0.0.1:8550/proxy/test-v1.yanxuan-supplier-ms.service.mailsaas
### des\u914D\u7F6E
# \u5BFC\u51FA\u6587\u4EF6\u4E0A\u4F20\u5230\u54EA\u4E2A\u670D\u52A1\u5668\uFF0C\u6709test\u548Conline\u53EF\u9009
des.prop.env=test
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="true" scan="true" scanPeriod="60 seconds">
<contextName>yanxuan-sc-ehc</contextName>
<include resource="logback-missa.xml"/>
<!--定义日志文件的存储地址 勿在 LogBack 的配置中使用相对路径-->
<property name="log.productName" value="yanxuan-qc-change-system"/>
<property name="log.path" value="/home/logs"/>
<property name="log.path.holmes" value="/home/logs/holmes"/>
<property name="log.level" value="debug"/>
<property name="log.pattern"
value="{time=%d{yyyy-MM-dd HH:mm:ss.SSS}, traceId=%X{XTraceId}, level=%p} [%c{0}] %m%n"/>
<!-- custom coloring conversion -->
<conversionRule conversionWord="highlightex"
converterClass="com.netease.mail.yanxuan.qc.api.common.common.HighlightingCompositeConverterEx"/>
<!--appender-->
<appender name="query-internal" class="ch.qos.logback.core.rolling.RollingFileAppender">
<encoder>
<pattern>${log.pattern}</pattern>
<charset>UTF-8</charset>
</encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${log.path}/${log.productName}/query.log.%d{yyyy-MM-dd}</fileNamePattern>
<maxHistory>90</maxHistory>
<!-- <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">-->
<!-- &lt;!&ndash; maxFileSize:这是活动文件的大小,默认值是10MB,本篇设置为1KB,只是为了演示 &ndash;&gt;-->
<!-- <maxFileSize>500MB</maxFileSize>-->
<!-- </timeBasedFileNamingAndTriggeringPolicy>-->
</rollingPolicy>
</appender>
<appender name="query" class="ch.qos.logback.classic.AsyncAppender">
<queueSize>512</queueSize>
<discardingThreshold>0</discardingThreshold>
<includeCallerData>true</includeCallerData>
<appender-ref ref="query-internal"/>
</appender>
<appender name="stdout-internal"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<encoder>
<pattern>${log.pattern}</pattern>
<charset>UTF-8</charset>
</encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${log.path}/${log.productName}/stdout.log.%d{yyyy-MM-dd}</fileNamePattern>
<maxHistory>14</maxHistory>
</rollingPolicy>
</appender>
<appender name="stdout" class="ch.qos.logback.classic.AsyncAppender">
<queueSize>512</queueSize>
<discardingThreshold>0</discardingThreshold>
<includeCallerData>true</includeCallerData>
<appender-ref ref="stdout-internal"/>
</appender>
<appender name="holmes-appender"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<encoder>
<pattern>%msg</pattern>
<charset>UTF-8</charset>
</encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${log.path.holmes}/${log.productName}/yanxuan.${log.productName}.%d{yyyy-MM-dd}.log
</fileNamePattern>
<maxHistory>7</maxHistory>
</rollingPolicy>
</appender>
<appender name="rpc" class="ch.qos.logback.core.rolling.RollingFileAppender">
<encoder>
<pattern>${log.pattern}</pattern>
<charset>UTF-8</charset>
</encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${log.path}/${log.productName}/rpc.log.%d{yyyy-MM-dd}</fileNamePattern>
<maxHistory>60</maxHistory>
</rollingPolicy>
</appender>
<appender name="task" class="ch.qos.logback.core.rolling.RollingFileAppender">
<encoder>
<pattern>${log.pattern}</pattern>
<charset>UTF-8</charset>
</encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${log.path}/${log.productName}/task.log.%d{yyyy-MM-dd}
</fileNamePattern>
</rollingPolicy>
</appender>
<appender name="stderr"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<encoder>
<pattern>${log.pattern}</pattern>
<charset>UTF-8</charset>
</encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${log.path}/${log.productName}/stderr.log.%d{yyyy-MM-dd}
</fileNamePattern>
</rollingPolicy>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>ERROR</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- 定时任务 -->
<appender name="dschedule"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%p] [%c{0}] %m%n</pattern>
<charset>UTF-8</charset>
</encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${log.path}/dschedule.log.%d{yyyy-MM-dd}.gz
</fileNamePattern>
</rollingPolicy>
</appender>
<logger name="com.netease.mail.yanxuan.change.integration" additivity="false" level="${log.level}">
<appender-ref ref="rpc"/>
<appender-ref ref="stderr"/>
</logger>
<logger name="com.netease.mail.yanxuan.change" additivity="false" level="${log.level}">
<appender-ref ref="query"/>
<appender-ref ref="stderr"/>
</logger>
<!-- 日志输出级别 -->
<root level="${log.level}">
<appender-ref ref="stdout"/>
<appender-ref ref="stderr"/>
</root>
</configuration>
jvm_opts_base="-cp . -ea -Xms4096m -Xmx4096m"
jvm_opts_gc="-XX:+UseG1GC -XX:MaxGCPauseMillis=100 -XX:G1HeapRegionSize=16m -XX:G1ReservePercent=15 -XX:InitiatingHeapOccupancyPercent=45 -XX:MaxTenuringThreshold=7 -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=368m -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+UnlockExperimentalVMOptions -XX:G1LogLevel=finest -XX:+PrintHeapAtGC -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/home/logs/yanxuan-sc-ehc -XX:-OmitStackTraceInFastThrow -Xloggc:/home/logs/yanxuan-sc-ehc/gc-%t.log"
jvm_opts_property="-Dspring.profiles.active=test -Denv=test -Dserver.port=8080"
jvm_opts_ext="-javaagent:/home/caesar-agent/caesar-agent-router-1.0.0.jar -Dapp.id=yanxuan-sc-ehc"
consul_service_tags=test
consul_service_port=8080
consul_health_url="/i/health"
consul_service_name="yanxuan-sc-ehc"
/**
* @(#)ChangeFlowBiz.java, 2022/11/15.
* <p/>
* Copyright 2022 Netease, Inc. All rights reserved.
* NETEASE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
package com.netease.mail.yanxuan.change.biz.biz;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.UUID;
import java.util.stream.Collectors;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;
import com.alibaba.fastjson.JSON;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.netease.mail.yanxuan.change.biz.config.AppConfig;
import com.netease.mail.yanxuan.change.biz.meta.exception.ExceptionFactory;
import com.netease.mail.yanxuan.change.biz.service.ChangeFileService;
import com.netease.mail.yanxuan.change.biz.service.ChangeFlowExecService;
import com.netease.mail.yanxuan.change.biz.service.ChangeFlowService;
import com.netease.mail.yanxuan.change.biz.service.InteriorChangeConfigService;
import com.netease.mail.yanxuan.change.biz.service.change.ChangeConfigService;
import com.netease.mail.yanxuan.change.biz.service.change.ChangeTypeService;
import com.netease.mail.yanxuan.change.biz.service.rpc.FlowService;
import com.netease.mail.yanxuan.change.biz.service.rpc.ItemService;
import com.netease.mail.yanxuan.change.biz.service.rpc.IusService;
import com.netease.mail.yanxuan.change.biz.service.rpc.QCService;
import com.netease.mail.yanxuan.change.biz.service.rpc.SupplierSendService;
import com.netease.mail.yanxuan.change.biz.service.rpc.SupplierService;
import com.netease.mail.yanxuan.change.common.bean.CommonConstants;
import com.netease.mail.yanxuan.change.common.bean.RequestLocalBean;
import com.netease.mail.yanxuan.change.common.bean.ResponseCode;
import com.netease.mail.yanxuan.change.common.enums.ChangeFlowEnum;
import com.netease.mail.yanxuan.change.common.enums.ChangeResultEnum;
import com.netease.mail.yanxuan.change.common.enums.ChangeStatusEnum;
import com.netease.mail.yanxuan.change.common.enums.ChangeSubjectEnum;
import com.netease.mail.yanxuan.change.common.enums.CreateSourceEnum;
import com.netease.mail.yanxuan.change.common.enums.FileTypeEnum;
import com.netease.mail.yanxuan.change.common.enums.FlowOperationTypeEnum;
import com.netease.mail.yanxuan.change.common.enums.FlowxOperationEnum;
import com.netease.mail.yanxuan.change.common.enums.NeedFileEnum;
import com.netease.mail.yanxuan.change.common.util.DateUtils;
import com.netease.mail.yanxuan.change.dal.entity.ChangeConfig;
import com.netease.mail.yanxuan.change.dal.entity.ChangeExecRecord;
import com.netease.mail.yanxuan.change.dal.entity.ChangeFile;
import com.netease.mail.yanxuan.change.dal.entity.ChangeRecord;
import com.netease.mail.yanxuan.change.dal.entity.ChangeType;
import com.netease.mail.yanxuan.change.dal.mapper.ChangeRecordMapper;
import com.netease.mail.yanxuan.change.dal.meta.model.po.ChangeCommanderPO;
import com.netease.mail.yanxuan.change.dal.meta.model.po.ChangeConfigPo;
import com.netease.mail.yanxuan.change.dal.meta.model.po.ChangeGoodsPrincipalPO;
import com.netease.mail.yanxuan.change.dal.meta.model.req.ChangeExecConfigReq;
import com.netease.mail.yanxuan.change.dal.meta.model.req.ChangeFlowCancelReq;
import com.netease.mail.yanxuan.change.dal.meta.model.req.ChangeFlowCreateReq;
import com.netease.mail.yanxuan.change.dal.meta.model.req.ChangeFlowDeliverReq;
import com.netease.mail.yanxuan.change.dal.meta.model.req.ChangeFlowFile;
import com.netease.mail.yanxuan.change.dal.meta.model.req.ChangeFlowListQueryReq;
import com.netease.mail.yanxuan.change.dal.meta.model.req.ChangeFlowSubmitReq;
import com.netease.mail.yanxuan.change.dal.meta.model.rpc.GoodsResponseRpc;
import com.netease.mail.yanxuan.change.dal.meta.model.vo.BasicChangeFlowVO;
import com.netease.mail.yanxuan.change.dal.meta.model.vo.CategoryInfoVO;
import com.netease.mail.yanxuan.change.dal.meta.model.vo.ChangeFlowExecVO;
import com.netease.mail.yanxuan.change.dal.meta.model.vo.ChangeFlowListVO;
import com.netease.mail.yanxuan.change.dal.meta.model.vo.ChangeFlowVO;
import com.netease.mail.yanxuan.change.dal.meta.model.vo.ItemBasicInfoVO;
import com.netease.mail.yanxuan.change.dal.meta.model.vo.ItemVO;
import com.netease.mail.yanxuan.change.dal.meta.model.vo.PageVO;
import com.netease.mail.yanxuan.change.integration.email.enums.EmailTemplateEnum;
import com.netease.mail.yanxuan.change.integration.email.service.IEmailService;
import com.netease.mail.yanxuan.change.integration.excel.ChangeFlowExcelDTO;
import com.netease.mail.yanxuan.change.integration.flow.UserQueryDTO;
import com.netease.mail.yanxuan.change.integration.flow.ius.IusRpcService;
import com.netease.mail.yanxuan.change.integration.flow.ius.req.IusDepartmentReq;
import com.netease.mail.yanxuan.change.integration.flow.ius.rsp.IusUserInfoRsp;
import com.netease.mail.yanxuan.change.integration.flow.ius.rsp.SecondaryDepartments;
import com.netease.mail.yanxuan.change.integration.flow.ius.rsp.leaderChain;
import com.netease.mail.yanxuan.change.integration.flow.supplier.rsp.SupplierSimpleRsp;
import com.netease.mail.yanxuan.change.integration.item.SimplePhyCateGoryResultCo;
import com.netease.mail.yanxuan.change.integration.item.meta.SpuTO;
import com.netease.mail.yanxuan.change.integration.item.param.BatchQuerySpuInfoParam;
import com.netease.mail.yanxuan.change.integration.item.param.CommonIdsParamQuery;
import com.netease.mail.yanxuan.change.integration.qc.meta.QcCategoryVO;
import com.netease.mail.yanxuan.change.integration.todo.ChangeExecuteEmailDTO;
import com.netease.yanxuan.flowx.sdk.meta.controller.communal.AjaxResponse;
import com.netease.yanxuan.flowx.sdk.meta.dto.base.FlowDataDTO;
import com.netease.yanxuan.flowx.sdk.meta.dto.base.UserBaseDTO;
import com.netease.yanxuan.flowx.sdk.meta.dto.base.UserReachDTO;
import com.netease.yanxuan.flowx.sdk.meta.dto.exec.InterfaceInputDTO;
import com.netease.yanxuan.flowx.sdk.meta.dto.exec.UserBaseContainerDTO;
import com.netease.yanxuan.flowx.sdk.meta.dto.flow.FlowCreateReqDTO;
import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import lombok.extern.slf4j.Slf4j;
/**
* @Author zcwang
* @Date 2022/11/15
*/
@Component
@Slf4j
public class ChangeFlowBiz {
@Autowired
private ChangeConfigService changeConfigService;
@Autowired
private ChangeTypeService changeTypeService;
@Autowired
private ChangeFlowService changeFlowService;
@Autowired
private AppConfig appConfig;
@Autowired
private FlowService flowService;
@Autowired
private ChangeFileService changeFileService;
@Autowired
private ChangeFlowExecService changeFlowExecService;
@Autowired
private ChangeRecordMapper changeRecordMapper;
@Autowired
private ItemService itemService;
@Autowired
private InteriorChangeConfigService interiorChangeConfigService;
@Autowired
private IEmailService iEmailService;
@Autowired
private IusService iusService;
@Autowired
private IusRpcService iusRpcService;
@Autowired
private SupplierSendService sendSupplierEmail;
@Autowired
private SupplierService supplierService;
@Autowired
private QCService qcService;
public String createAndSubmit(ChangeFlowCreateReq changeFlowCreateReq) {
String uid = RequestLocalBean.getUid();
String name = RequestLocalBean.getName();
log.info("[create] createReq={}, uid:{}, name:{}", JSON.toJSONString(changeFlowCreateReq), uid, name);
// 校验变更主体
checkSubject(changeFlowCreateReq);
Long parentChangeClassId = changeFlowCreateReq.getParentChangeClassId();
Long sonChangeClassId = changeFlowCreateReq.getSonChangeClassId();
String changeItems = changeFlowCreateReq.getChangeItems();
List<Long> itemIds = null;
if (StringUtils.isNotBlank(changeItems)) {
List<ItemVO> itemVOS = JSON.parseArray(changeItems, ItemVO.class);
itemIds = itemVOS.stream().map(ItemVO::getItemId).collect(Collectors.toList());
}
// 工单负责人
String changeCommander = null;
// 获取工单负责人
GoodsResponseRpc goodsResponseRpc = null;
try {
goodsResponseRpc = interiorChangeConfigService
.queryCommanderInfo(ChangeCommanderPO.builder().parentChangeClassId(parentChangeClassId)
.sonChangeClassId(sonChangeClassId).changeSupplierId(changeFlowCreateReq.getChangeSupplier())
.goodsInfos(itemIds).flowCreator(uid).createSource(changeFlowCreateReq.getCreateSource())
.supplier(changeFlowCreateReq.getSupplier()).build());
changeCommander = goodsResponseRpc.getEmail();
} catch (Exception e) {
log.error("[op:queryCommanderInfo] error, goodsResponseRpc:{}, e:{}", JSON.toJSONString(goodsResponseRpc),e);
}
Assert.notNull(changeCommander, "未查询到负责人信息");
// 检验是否需要资料
ChangeConfig changeConfig = changeConfigService.getSonChange(sonChangeClassId);
Assert.notNull(changeConfig, "二级变更类型不存在");
Integer needFile = changeConfig.getNeedFile();
if (NeedFileEnum.NEED.getStatus().equals(needFile)) {
Assert.notEmpty(changeFlowCreateReq.getUploadFiles(), "必须上传资料");
}
changeFlowCreateReq.setChangeDepartment(changeConfig.getChangeDepartment());
// 变更行动项不可为空,最多20项
List<ChangeExecConfigReq> changeExecProject = changeFlowCreateReq.getChangeExecProject();
Assert.isTrue(changeExecProject.size() <= appConfig.getChangeExecLimit(),
"变更行动方案配置数超限");
// 结束时间不可晚于第二天定时任务执行时间
Long tomorrowSpecificTime = DateUtils.getTomorrowSpecificTime("00:00:00");
if (changeFlowCreateReq.getCreateSource() != 2) {
if (changeFlowCreateReq.getChangeConfirmResultTime() == null) {
throw ExceptionFactory.createBiz(ResponseCode.BAD_REQUEST, "变更结果确认时间不能为空");
}
Assert.isTrue(changeFlowCreateReq.getChangeConfirmResultTime() >= tomorrowSpecificTime, "时间不可晚于下次执行时间");
}
Map<String, Object> content = new HashMap<>(10);
content.put("createUserName", uid);
content.put("createUser", uid);
content.put("createTime", System.currentTimeMillis());
content.put("updateTime", System.currentTimeMillis());
content.put(CommonConstants.FLOW_OPERATION_KEY, FlowOperationTypeEnum.PASS.getValue());
// 变更类型, 一级变更类型>二级变更类型
ChangeConfigPo changeConfigPo = changeConfigService.queryInfoPo(parentChangeClassId, sonChangeClassId);
StringBuilder changeType = new StringBuilder();
try {
changeType.append(changeConfigPo.getChangeTypes().get(0).getTypeName());
changeType.append(changeConfigPo.getChangeTypes().get(1).getTypeName());
} catch (Exception e) {
log.error("queryInfoPo error:{}", JSON.toJSONString(changeConfigPo));
}
// 变更工单命名:变更主体+变更类型+变更商品(SPU+商品名称)/变更供应商(供应商ID+供应商名称)
String subject = ChangeSubjectEnum.getDescByType(changeFlowCreateReq.getChangeSubject());
String flowName = subject + changeType;
// 商品变更
if (ChangeSubjectEnum.PRODUCT.getType().equals(changeFlowCreateReq.getChangeSubject())) {
// 批量查询spu信息
List<SpuTO> spuTOS = itemService.batchQuerySpuInfo(BatchQuerySpuInfoParam.builder().ids(itemIds)
.commonProps(new ArrayList<>()).spuProps(new ArrayList<>()).build());
log.debug("[createAndSubmit] uid:{}, spuTOS:{}", uid, JSON.toJSONString(spuTOS));
String spuList = spuTOS.stream().map(spu -> "(" + spu.getId() + spu.getName() + ")")
.collect(Collectors.joining(","));
flowName += spuList;
}
if (ChangeSubjectEnum.SUPPLIER.getType().equals(changeFlowCreateReq.getChangeSubject())) {
List<SupplierSimpleRsp> supplierSimple = supplierService
.getSupplierName(changeFlowCreateReq.getChangeSupplier());
if (CollectionUtils.isNotEmpty(supplierSimple)) {
SupplierSimpleRsp supplier = supplierSimple.get(0);
flowName += supplier.getSupplierId() + supplier.getSupplierName();
}
}
// 组装工单创建数据
FlowCreateReqDTO flowCreateReqDTO = buildFlowCreateReqDTO(ChangeFlowEnum.CHANGE_FLOW_START.getTopoId(), uid,
JSON.toJSONString(content), FlowxOperationEnum.CREATE.getName(), name, flowName);
// 创建工单
String flowId = flowService.createFlow(flowCreateReqDTO);
// 查询工单详情
FlowDataDTO flowDataDTO = flowService.flowDetail(flowId);
String nodeId = flowDataDTO.getFlowMeta().getCurrNodeDataList().get(0).getNodeId();
// 保存工单数据
ChangeRecord changeRecord = buildChangeRecord(flowId, nodeId, changeFlowCreateReq, changeCommander, uid);
changeFlowService.saveRecord(changeRecord);
// 保存变更行动方案记录
List<ChangeExecRecord> changeExecRecords = buildChangeExecRecord(changeRecord.getId(), changeExecProject);
changeExecRecords.forEach(exec -> changeFlowExecService.saveRecord(exec));
List<ChangeFile> allFiles = new ArrayList<>();
// 变更前后图片/视频,非必填
List<ChangeFlowFile> changeFiles = changeFlowCreateReq.getChangeFiles();
if (CollectionUtils.isNotEmpty(changeFiles)) {
allFiles.addAll(buildChangeFileRecord(changeRecord.getId(), changeFiles, FileTypeEnum.CHANGE.getType()));
}
// 保存附件,根据配置看是否必传
List<ChangeFlowFile> uploadFiles = changeFlowCreateReq.getUploadFiles();
if (CollectionUtils.isNotEmpty(uploadFiles)) {
allFiles.addAll(buildChangeFileRecord(changeRecord.getId(), uploadFiles, FileTypeEnum.UPLOAD.getType()));
}
if (CollectionUtils.isNotEmpty(allFiles)) {
allFiles.forEach(file -> changeFileService.saveRecord(file));
}
// 如果发起人=变更负责人,直接提交到执行节点,发送邮件
if (changeCommander.equals(uid)) {
log.debug("[createAndSubmit] changeCommander:{}, uid:{}", changeCommander, uid);
String nextNodeId = flowService.submitFlow(flowId, flowDataDTO, uid,
ChangeFlowEnum.CHANGE_FLOW_SUBMIT.getTopoId(), JSON.toJSONString(content), true,
FlowxOperationEnum.SUBMIT.getName(), "提交工单",changeRecord.getCreateTime());
if (null == nextNodeId) {
throw ExceptionFactory.createBiz(ResponseCode.SUBMIT_FLOW_ERROR, "首次提交节点失败");
}
// 更新节点id
changeRecord.setFlowNode(ChangeFlowEnum.CHANGE_FLOW_EXE.getNodeId());
changeRecord.setState(ChangeStatusEnum.IN.getStatus());
changeRecord.setUpdateTime(DateUtils.getCurrentTime());
changeFlowService.updateRecord(changeRecord);
HashMap<String, Object> param = new HashMap<>();
param.put("changeId", changeRecord.getFlowId());
param.put("changeSubject", ChangeSubjectEnum.getChangeSubjectEnum(changeRecord.getChangeSubject()).getDesc());
param.put("changeContent", changeRecord.getChangeContent());
param.put("changeReason", changeRecord.getChangeReason());
AjaxResponse<IusUserInfoRsp> user = iusRpcService.queryUserInfo(changeRecord.getChangeCommander());
param.put("changeCommander", user.getData().getName());
param.put("changeCommanderEmail", changeRecord.getChangeCommander());
param.put("flowUrl", changeRecord.getFlowId());
List<ChangeExecuteEmailDTO> dataList = new ArrayList<>();
changeExecRecords.forEach(i -> {
ChangeExecuteEmailDTO changeExecuteEmailDTO = new ChangeExecuteEmailDTO();
changeExecuteEmailDTO.setChangeExecDepartment(i.getChangeExecDepartment());
changeExecuteEmailDTO.setChangeExecUser(i.getChangeExecUser());
changeExecuteEmailDTO.setChangeRiskDesc(i.getChangeRiskDesc());
changeExecuteEmailDTO.setChangeExecProject(i.getChangeExecProject());
changeExecuteEmailDTO.setChangeChecking(i.getChangeChecking());
dataList.add(changeExecuteEmailDTO);
});
param.put("dataList", dataList);
String subjectParam = ChangeSubjectEnum.getChangeSubjectEnum(changeRecord.getChangeSubject()).getDesc() + changeType
+ changeRecord.getFlowId().toString();
List<ChangeFlowExecVO> changeFlowExecRecord = changeFlowExecService
.getChangeFlowExecRecord(changeRecord.getId());
List<String> execUserEmailList = changeFlowExecRecord.stream().map(ChangeFlowExecVO::getChangeExecUserEmail)
.collect(Collectors.toList());
// 获取指定人的上级部门主管邮箱
List<String> ccList = getDepartmentInfo(execUserEmailList);
// 变更执行,抄送:所有变更行动人上一级LEADER,变更负责人、变更转交人(如有)
ccList.add(changeCommander);
// 变更执行,收件人:所有变更行动人+变更管理QM(cuiyixian@corp.netease.com)
execUserEmailList.add(appConfig.getChangeManageQM());
qcSendEmail(execUserEmailList, ccList, subjectParam, EmailTemplateEnum.YX_QC_CHANGE_EXECUTE, param);
// 如果是供应商,再次发送供应商邮件
if (changeFlowCreateReq.getCreateSource().equals(CreateSourceEnum.TONG_ZHOU.getType())) {
sendSupplierEmail.sendSupplierEmail(changeRecord.getCreateSupplier(), subjectParam,
EmailTemplateEnum.YX_QC_CHANGE_EXECUTE, param);
}
// 如果是其他端发起但是是供应商变更,再次发送供应商邮件
if (!changeFlowCreateReq.getCreateSource().equals(CreateSourceEnum.TONG_ZHOU.getType())
&& ChangeSubjectEnum.SUPPLIER.getType().equals(changeRecord.getChangeSubject())) {
sendSupplierEmail.sendSupplierEmail(changeRecord.getChangeSupplier(), subjectParam,
EmailTemplateEnum.YX_QC_CHANGE_EXECUTE, param);
}
return flowId;
}
// 如果发起人≠变更负责人,停留在变更申请提交节点,发送邮件
HashMap<String, Object> param = new HashMap<>();
param.put("changeId", changeRecord.getFlowId());
param.put("changeSubject", ChangeSubjectEnum.getChangeSubjectEnum(changeRecord.getChangeSubject()).getDesc());
param.put("changeType", changeType.toString());
param.put("flowUrl", changeRecord.getFlowId());
String subjectParam = changeRecord.getFlowId().toString();
// 发起变更,收件人:变更负责人
List<String> receiver = Collections.singletonList(changeCommander);
List<String> ccList = getDepartmentInfo(receiver);
// 发起变更,抄送:变更负责人上一级主管、变更管理QM(cuiyixian@corp.netease.com)
ccList.add(appConfig.getChangeManageQM());
qcSendEmail(receiver, ccList, subjectParam, EmailTemplateEnum.YX_QC_CHANGE_RELEASE_FLOW, param);
// 如果是供应商,再次发送供应商邮件
if (changeFlowCreateReq.getCreateSource().equals(CreateSourceEnum.TONG_ZHOU.getType())) {
sendSupplierEmail.sendSupplierEmail(changeRecord.getCreateSupplier(), subjectParam,
EmailTemplateEnum.YX_QC_CHANGE_RELEASE_FLOW, param);
}
// 如果是其他端发起但是是供应商变更,再次发送供应商邮件
if (!changeFlowCreateReq.getCreateSource().equals(CreateSourceEnum.TONG_ZHOU.getType())
&& ChangeSubjectEnum.SUPPLIER.getType().equals(changeRecord.getChangeSubject())) {
sendSupplierEmail.sendSupplierEmail(changeRecord.getChangeSupplier(), subjectParam,
EmailTemplateEnum.YX_QC_CHANGE_RELEASE_FLOW, param);
}
return flowId;
}
public List<String> getDepartmentInfo(List<String> receiver) {
IusDepartmentReq iusDepartmentReq = new IusDepartmentReq();
iusDepartmentReq.setHasOrgPos(true);
iusDepartmentReq.setIcac(true);
iusDepartmentReq.setUids(receiver);
HashMap<String, List<SecondaryDepartments>> map = iusService.queryDepartment(iusDepartmentReq);
ArrayList<List<SecondaryDepartments>> secondaryDepartments = new ArrayList<>(map.values());
List<String> ccList = new ArrayList<>();
if (CollectionUtils.isNotEmpty(secondaryDepartments)) {
// 外层循环是不同人,内层循环是相同人不同部门
for (List<SecondaryDepartments> secondaryDepartment : secondaryDepartments) {
for (SecondaryDepartments dep : secondaryDepartment) {
List<leaderChain> leaderChainList = dep.getLeaderChainList();
if (CollectionUtils.isNotEmpty(leaderChainList)) {
ccList.add(leaderChainList.get(leaderChainList.size()-1).getUid());
}
}
}
}
if (CollectionUtils.isNotEmpty(ccList)) {
ccList = ccList.stream().distinct().collect(Collectors.toList());
}
return ccList;
}
/**
* 严选QC端发送邮件
*
* @param subjectParam 主体参数
* @param receiver 收件人
* @param emailTemplateEnum 邮件模板
* @param param 正文参数
*/
public void qcSendEmail(List<String> receiver, List<String> ccList, String subjectParam, EmailTemplateEnum emailTemplateEnum,
Map<String, Object> param) {
try {
iEmailService.sendEmail(receiver, ccList, param, emailTemplateEnum,
subjectParam);
} catch (Exception e) {
log.error("[op:qcSendEmail] error,receiver:{}, ccList:{}, subjectParam:{}, e:{}", receiver, ccList, subjectParam,
e);
}
}
private List<ChangeFile> buildChangeFileRecord(Long changeRecordId, List<ChangeFlowFile> files, Integer type) {
return files.stream().map(f -> {
ChangeFile changeFile = new ChangeFile();
changeFile.setChangeRecordId(changeRecordId);
changeFile.setFileType(type);
changeFile.setFileName(f.getFileName());
changeFile.setFileUrl(f.getFileUrl());
changeFile.setCreateTime(DateUtils.getCurrentTime());
changeFile.setUpdateTime(DateUtils.getCurrentTime());
return changeFile;
}).collect(Collectors.toList());
}
private List<ChangeExecRecord> buildChangeExecRecord(Long changeRecordId,
List<ChangeExecConfigReq> changeExecProject) {
return changeExecProject.stream().map(c -> {
ChangeExecRecord changeExecRecord = new ChangeExecRecord();
changeExecRecord.setChangeRecordId(changeRecordId);
changeExecRecord.setChangeExecDepartment(c.getChangeExecDepartment());
changeExecRecord.setChangeExecUserType(c.getChangeExecUserType());
changeExecRecord.setChangeExecUser(c.getChangeExecUser());
changeExecRecord.setChangeExecUserEmail(c.getChangeExecUserEmail());
changeExecRecord.setChangeRiskDesc(c.getChangeRiskDesc());
changeExecRecord.setChangeExecProject(c.getChangeExecProject());
changeExecRecord.setChangeChecking(c.getChangeChecking());
changeExecRecord.setChangeExecFinishTime(c.getChangeExecFinishTime());
changeExecRecord.setChangeExecFinishDesc(c.getChangeExecFinishDesc());
changeExecRecord.setCreateTime(DateUtils.getCurrentTime());
changeExecRecord.setUpdateTime(DateUtils.getCurrentTime());
return changeExecRecord;
}).collect(Collectors.toList());
}
private void checkSubject(ChangeFlowCreateReq changeFlowCreateReq) {
ChangeSubjectEnum type = ChangeSubjectEnum.getByType(changeFlowCreateReq.getChangeSubject());
Assert.notNull(type, "变更主体不存在");
switch (type) {
case PRODUCT:
Assert.isTrue(StringUtils.isNotBlank(changeFlowCreateReq.getChangeItems()), " 变更商品不可为空");
break;
case SUPPLIER:
Assert.isTrue(StringUtils.isNotBlank(changeFlowCreateReq.getChangeSupplier()), " 变更供应商不可为空");
break;
case OTHER:
break;
default:
throw ExceptionFactory.createBiz(ResponseCode.CHANGE_SUBJECT_ERROR, "变更主体类型错误");
}
}
private FlowCreateReqDTO buildFlowCreateReqDTO(String topoId, String uid, String content, String operateResult,
String name, String flowName) {
FlowCreateReqDTO flowCreateReqDTO = new FlowCreateReqDTO();
flowCreateReqDTO.setTopoId(topoId);
flowCreateReqDTO.setUid(uid);
flowCreateReqDTO.setUserName(name);
flowCreateReqDTO.setOperateResult(operateResult);
flowCreateReqDTO.setWorkOrderId(StringUtils.joinWith("-", topoId, UUID.randomUUID().toString()));
flowCreateReqDTO.setContent(content);
flowCreateReqDTO.setFlowName(flowName);
return flowCreateReqDTO;
}
private ChangeRecord buildChangeRecord(String flowId, String nodeId, ChangeFlowCreateReq changeFlowCreateReq,
String changeCommander, String uid) {
ChangeRecord changeRecord = new ChangeRecord();
changeRecord.setFlowId(Long.parseLong(flowId));
changeRecord.setFlowNode(nodeId);
changeRecord.setChangeSubject(changeFlowCreateReq.getChangeSubject());
changeRecord.setParentChangeClassId(changeFlowCreateReq.getParentChangeClassId());
changeRecord.setSonChangeClassId(changeFlowCreateReq.getSonChangeClassId());
changeRecord.setChangeLevel(changeFlowCreateReq.getChangeLevel());
changeRecord.setChangeCommander(changeCommander);
changeRecord.setChangeDepartment(changeFlowCreateReq.getChangeDepartment());
List<ChangeExecConfigReq> changeExecProject = changeFlowCreateReq.getChangeExecProject();
List<String> execDepartmentList = changeExecProject.stream().map(ChangeExecConfigReq::getChangeExecDepartment)
.collect(Collectors.toList());
changeRecord.setParticipateChangeExecDepartment(JSON.toJSONString(execDepartmentList));
if (ChangeSubjectEnum.PRODUCT.getType().equals(changeFlowCreateReq.getChangeSubject())) {
// 当变更类型是商品时有值
changeRecord.setChangeItem(changeFlowCreateReq.getChangeItems());
}
if (ChangeSubjectEnum.SUPPLIER.getType().equals(changeFlowCreateReq.getChangeSubject())) {
changeRecord.setChangeSupplier(changeFlowCreateReq.getChangeSupplier());
}
changeRecord.setChangeReason(changeFlowCreateReq.getChangeReason());
changeRecord.setChangeContent(changeFlowCreateReq.getChangeContent());
changeRecord.setChangeRiskDesc(changeFlowCreateReq.getChangeRiskDesc());
changeRecord.setChangeProfit(changeFlowCreateReq.getChangeProfit());
changeRecord.setChangeProfitDesc(changeFlowCreateReq.getChangeProfitDesc());
changeRecord.setChangeConfirmResultTime(changeFlowCreateReq.getChangeConfirmResultTime());
changeRecord.setState(ChangeStatusEnum.WAIT.getStatus());
// 变更结论
changeRecord.setCreateSource(changeFlowCreateReq.getCreateSource());
changeRecord.setCreateSupplier(changeFlowCreateReq.getSupplier());
changeRecord.setCreateTime(DateUtils.getCurrentTime());
changeRecord.setUpdateTime(DateUtils.getCurrentTime());
changeRecord.setCreator(uid);
return changeRecord;
}
public String submit(ChangeFlowSubmitReq changeFlowSubmitReq) {
log.info("[submitFlow] changeFlowReq:{}", JSON.toJSONString(changeFlowSubmitReq));
Long flowId = changeFlowSubmitReq.getFlowId();
// 查询工单有效性
ChangeRecord changeRecord = this.getFlowInfo(flowId);
// 检查工单节点
this.checkNode(changeRecord.getFlowNode(), Collections.singletonList(changeFlowSubmitReq.getCurrentNodeId()));
String uid = RequestLocalBean.getUid();
String changeCommander = changeRecord.getChangeCommander();
if (!uid.equals(changeCommander)) {
throw ExceptionFactory.createBiz(ResponseCode.NO_AUTH, ResponseCode.NO_AUTH.getMsg());
}
// 获取工单详情
FlowDataDTO flowDataDTO = flowService.flowDetail(flowId.toString());
if (flowDataDTO == null) {
throw ExceptionFactory.createBiz(ResponseCode.DETAIL_FLOW_ERROR, "工单查询错误,不存在");
}
return checkUpdateAndSubmit(flowId, flowDataDTO, uid, changeRecord, changeRecord.getFlowNode(), changeFlowSubmitReq);
}
private String checkUpdateAndSubmit(Long flowId, FlowDataDTO flowDataDTO, String uid, ChangeRecord changeRecord,
String currentNode, ChangeFlowSubmitReq changeFlowSubmitReq) {
ChangeFlowEnum node = ChangeFlowEnum.getByNodeId(currentNode);
Assert.notNull(node, "节点配置不存在");
log.debug("[checkUpdateAndSubmit] flowId:{}, nodeEnum:{}, changeFlowSubmitReq:{}", flowId, node,
JSON.toJSONString(changeFlowSubmitReq));
// 工单流传
Map<String, Object> content = new HashMap<>(CommonConstants.INIT_HASH_MAP_SIZE);
content.put("updateTime", System.currentTimeMillis());
content.put(CommonConstants.FLOW_OPERATION_KEY, FlowOperationTypeEnum.PASS.getValue());
switch (node) {
// 变更申请提交节点,可以修改数据,以新的数据为准
case CHANGE_FLOW_SUBMIT:
// 检验是否需要资料
ChangeConfig changeConfig = changeConfigService.getSonChange(changeFlowSubmitReq.getSonChangeClassId());
Assert.notNull(changeConfig, "二级变更类型不存在");
Integer needFile = changeConfig.getNeedFile();
if (NeedFileEnum.NEED.getStatus().equals(needFile)) {
List<ChangeFlowFile> uploadFiles = changeFlowSubmitReq.getUploadFiles();
if (CollectionUtils.isEmpty(uploadFiles)) {
throw ExceptionFactory.createBiz(ResponseCode.BAD_REQUEST, "必须上传资料");
}
}
// 变更行动项不可为空,最多20项
List<ChangeExecConfigReq> changeExecProjectList = changeFlowSubmitReq.getChangeExecProjectList();
Assert.isTrue(changeExecProjectList.size() <= appConfig.getChangeExecLimit(),
"变更行动方案配置数超限");
changeRecord.setParentChangeClassId(changeFlowSubmitReq.getParentChangeClassId());
changeRecord.setSonChangeClassId(changeFlowSubmitReq.getSonChangeClassId());
List<String> execDepartmentList = changeExecProjectList.stream().map(ChangeExecConfigReq::getChangeExecDepartment)
.collect(Collectors.toList());
changeRecord.setParticipateChangeExecDepartment(JSON.toJSONString(execDepartmentList));
changeRecord.setChangeItem(changeFlowSubmitReq.getChangeItems());
changeRecord.setChangeSupplier(changeFlowSubmitReq.getChangeSupplier());
changeRecord.setChangeReason(changeFlowSubmitReq.getChangeReason());
changeRecord.setChangeContent(changeFlowSubmitReq.getChangeContent());
changeRecord.setChangeRiskDesc(changeFlowSubmitReq.getChangeRiskDesc());
changeRecord.setChangeChecking(changeFlowSubmitReq.getChangeChecking());
changeRecord.setChangeProfit(changeFlowSubmitReq.getChangeProfit());
changeRecord.setChangeProfitDesc(changeFlowSubmitReq.getChangeProfitDesc());
changeRecord.setChangeConfirmResultTime(changeFlowSubmitReq.getChangeConfirmResultTime());
changeRecord.setUpdateTime(DateUtils.getCurrentTime());
// 提交工单
String submitNode = flowService.submitFlow(flowId.toString(), flowDataDTO, uid,
ChangeFlowEnum.CHANGE_FLOW_SUBMIT.getTopoId(), JSON.toJSONString(content), true,
FlowxOperationEnum.SUBMIT.getName(), "提交工单", changeRecord.getCreateTime());
// 更新工单数据
changeRecord.setFlowNode(submitNode);
changeRecord.setState(ChangeStatusEnum.IN.getStatus());
changeRecord.setUpdateTime(DateUtils.getCurrentTime());
changeFlowService.updateRecord(changeRecord);
// 更新行动执行方案,覆盖操作,先删除,后插入
Integer changeExecCount = changeFlowExecService.deleteByChangeRecordId(changeRecord.getId());
log.debug("[CHANGE_FLOW_SUBMIT] delete id:{}, changeExecCount:{}", changeRecord.getId(), changeExecCount);
// 保存变更行动方案记录
List<ChangeExecRecord> changeExecRecords = buildChangeExecRecord(changeRecord.getId(),
changeFlowSubmitReq.getChangeExecProjectList());
changeExecRecords.forEach(exec -> changeFlowExecService.saveRecord(exec));
// 更新附件,覆盖操作,先删除,后插入
Integer fileCount = changeFileService.deleteByChangeRecordId(changeRecord.getId());
log.debug("[CHANGE_FLOW_SUBMIT] delete fileCount:{}", fileCount);
List<ChangeFile> allFiles = new ArrayList<>();
List<ChangeFlowFile> changeFiles = changeFlowSubmitReq.getChangeFiles();
if (CollectionUtils.isNotEmpty(changeFiles)) {
allFiles.addAll(buildChangeFileRecord(changeRecord.getId(), changeFiles, FileTypeEnum.CHANGE.getType()));
}
// 保存附件,根据配置看是否必传
List<ChangeFlowFile> uploadFiles = changeFlowSubmitReq.getUploadFiles();
if (CollectionUtils.isNotEmpty(uploadFiles)) {
allFiles.addAll(buildChangeFileRecord(changeRecord.getId(), uploadFiles, FileTypeEnum.UPLOAD.getType()));
}
if (CollectionUtils.isNotEmpty(allFiles)) {
allFiles.forEach(file -> changeFileService.saveRecord(file));
}
log.debug("[CHANGE_FLOW_SUBMIT] changeFiles:{}, uploadFiles:{}, allFiles:{}", JSON.toJSONString(changeFiles),
JSON.toJSONString(uploadFiles), JSON.toJSONString(allFiles));
HashMap<String, Object> param = new HashMap<>();
param.put("changeId", changeRecord.getFlowId());
param.put("changeSubject", ChangeSubjectEnum.getChangeSubjectEnum(changeRecord.getChangeSubject()).getDesc());
param.put("changeContent", changeRecord.getChangeContent());
param.put("changeReason", changeRecord.getChangeReason());
AjaxResponse<IusUserInfoRsp> user = iusRpcService.queryUserInfo(changeRecord.getChangeCommander());
param.put("changeCommander", user.getData().getName());
param.put("changeCommanderEmail", changeRecord.getChangeCommander());
param.put("flowUrl", changeRecord.getFlowId());
param.put("dataList", changeExecRecords);
ChangeConfigPo changeConfigPoV1 = changeConfigService.queryInfoPo(changeRecord.getParentChangeClassId(), changeRecord.getSonChangeClassId());
StringBuilder changeTypeV1 = new StringBuilder();
try {
changeTypeV1.append(changeConfigPoV1.getChangeTypes().get(0).getTypeName());
changeTypeV1.append(changeConfigPoV1.getChangeTypes().get(1).getTypeName());
} catch (Exception e) {
log.error("queryInfoPo error:{}", JSON.toJSONString(changeConfigPoV1));
}
String subjectParam = ChangeSubjectEnum.getChangeSubjectEnum(changeRecord.getChangeSubject()).getDesc() + changeTypeV1
+ changeRecord.getFlowId().toString();
// 负责人
String changeCommander = changeRecord.getChangeCommander();
List<ChangeFlowExecVO> changeFlowExecRecord = changeFlowExecService
.getChangeFlowExecRecord(changeRecord.getId());
List<String> execUserEmailList = changeFlowExecRecord.stream().map(ChangeFlowExecVO::getChangeExecUserEmail)
.collect(Collectors.toList());
// 获取指定人的上级部门主管邮箱
List<String> ccList = getDepartmentInfo(execUserEmailList);
// 变更执行,抄送:所有变更行动人上一级LEADER,变更负责人、变更转交人(如有)
ccList.add(changeCommander);
// 变更执行,收件人:所有变更行动人+变更管理QM(cuiyixian@corp.netease.com)
execUserEmailList.add(appConfig.getChangeManageQM());
qcSendEmail(execUserEmailList, ccList, subjectParam,
EmailTemplateEnum.YX_QC_CHANGE_EXECUTE, param);
// 如果是供应商,再次发送供应商邮件
if (changeRecord.getCreateSource().equals(CreateSourceEnum.TONG_ZHOU.getType())) {
sendSupplierEmail.sendSupplierEmail(changeRecord.getCreateSupplier(), subjectParam,
EmailTemplateEnum.YX_QC_CHANGE_EXECUTE, param);
}
// 如果是其他端发起但是是供应商变更,再次发送供应商邮件
if (!changeRecord.getCreateSource().equals(CreateSourceEnum.TONG_ZHOU.getType())
&& ChangeSubjectEnum.SUPPLIER.getType().equals(changeRecord.getChangeSubject())) {
sendSupplierEmail.sendSupplierEmail(changeRecord.getChangeSupplier(), subjectParam,
EmailTemplateEnum.YX_QC_CHANGE_EXECUTE, param);
}
return submitNode;
case CHANGE_FLOW_CONFIRM:
Integer changeResult = changeFlowSubmitReq.getChangeResult();
ChangeResultEnum changeResultStatus = ChangeResultEnum.getByStatus(changeResult);
Assert.notNull(changeResultStatus, "变更结论类型错误");
// 填写变更结论
changeRecord.setChangeResult(changeResultStatus.getStatus());
// 填写备注
changeRecord.setRemark(changeFlowSubmitReq.getRemark());
List<ChangeFlowFile> finialFiles = changeFlowSubmitReq.getChangeResultFiles();
if (CollectionUtils.isNotEmpty(finialFiles)) {
changeFileService.deleteByChangeRecordIdAndType(changeRecord.getId(), FileTypeEnum.CHANGE_RESULT_INFO);
List<ChangeFile> finialFileList = buildChangeFileRecord(changeRecord.getId(), finialFiles, FileTypeEnum.CHANGE_RESULT_INFO.getType());
finialFileList.forEach(file -> changeFileService.saveRecord(file));
}
switch (changeResultStatus) {
case FINISH_ALL:
case FINISH_PART:
String reason = changeFlowSubmitReq.getCancelReason();
changeRecord.setCancelReason(reason);
List<ChangeExecConfigReq> execProjectList = changeFlowSubmitReq.getChangeExecProjectList();
List<ChangeExecRecord> changeExecRecordList = execProjectList.stream().map(exec -> {
Long changeExecFinishTime = exec.getChangeExecFinishTime();
Assert.notNull(changeExecFinishTime, "行动完成时间不可为空" + exec.getChangeTemplateId());
ChangeExecRecord changeExecRecord = new ChangeExecRecord();
changeExecRecord.setId(exec.getChangeExecId());
changeExecRecord.setChangeExecFinishTime(exec.getChangeExecFinishTime());
changeExecRecord.setChangeExecFinishDesc(exec.getChangeExecFinishDesc());
return changeExecRecord;
}).collect(Collectors.toList());
// 完成直接完结
String confirmNode = flowService.submitFlow(flowId.toString(), flowDataDTO, uid,
ChangeFlowEnum.CHANGE_FLOW_CONFIRM.getTopoId(), JSON.toJSONString(content), true,
FlowxOperationEnum.SUBMIT.getName(), "提交工单", changeRecord.getCreateTime());
changeRecord.setState(ChangeStatusEnum.END.getStatus());
changeRecord.setFlowNode(confirmNode);
changeRecord.setUpdateTime(DateUtils.getCurrentTime());
changeFlowService.updateRecord(changeRecord);
changeExecRecordList.forEach(exec -> changeFlowExecService.update(exec));
// 发送邮件
HashMap<String, Object> finishPartMap = new HashMap<>();
finishPartMap.put("changeId", changeRecord.getFlowId());
finishPartMap.put("changeSubject", ChangeSubjectEnum.getChangeSubjectEnum(changeRecord.getChangeSubject()).getDesc());
finishPartMap.put("flowUrl", changeRecord.getFlowId());
ChangeConfigPo changeConfigPo = changeConfigService
.queryInfoPo(changeRecord.getParentChangeClassId(), changeRecord.getSonChangeClassId());
StringBuilder changeType = new StringBuilder();
try {
changeType.append(changeConfigPo.getChangeTypes().get(0).getTypeName());
} catch (Exception e) {
log.error("queryInfoPo error:{}", JSON.toJSONString(changeConfigPo));
}
try {
changeType.append(changeConfigPo.getChangeTypes().get(1).getTypeName());
} catch (Exception e) {
log.error("queryInfoPo error:{}", JSON.toJSONString(changeConfigPo));
}
//【已完结】变更主体+变更内容+工单ID 变更风险行动项已完结,请开始执行变更。
String finishSubjectParam = ChangeSubjectEnum
.getChangeSubjectEnum(changeRecord.getChangeSubject()).getDesc()
+ changeRecord.getChangeContent() + changeRecord.getFlowId();
// 变更确认,收件人:变更负责人+变更供应商+所有变更行动人+变更管理QM(cuiyixian@corp.netease.com)
List<ChangeFlowExecVO> execRecord = changeFlowExecService
.getChangeFlowExecRecord(changeRecord.getId());
List<String> userEmailList = execRecord.stream().map(ChangeFlowExecVO::getChangeExecUserEmail)
.collect(Collectors.toList());
// 变更确认,抄送人:所有变更行动人上一级LEADER+变更管理委员会(yx_change_SC@qun.mail.163.com)
List<String> list = this.getDepartmentInfo(userEmailList);
list.add(appConfig.getChangeCommittee());
userEmailList.add(changeRecord.getChangeCommander());
userEmailList.add(appConfig.getChangeManageQM());
qcSendEmail(userEmailList, list, finishSubjectParam,
EmailTemplateEnum.YX_QC_CHANGE_FINISH, finishPartMap);
// 如果是供应商,再次发送供应商邮件
if (changeRecord.getCreateSource().equals(CreateSourceEnum.TONG_ZHOU.getType())) {
sendSupplierEmail.sendSupplierEmail(changeRecord.getCreateSupplier(), finishSubjectParam,
EmailTemplateEnum.YX_QC_CHANGE_FINISH, finishPartMap);
}
// 如果是其他端发起但是是供应商变更,再次发送供应商邮件
if (!changeRecord.getCreateSource().equals(CreateSourceEnum.TONG_ZHOU.getType())
&& ChangeSubjectEnum.SUPPLIER.getType().equals(changeRecord.getChangeSubject())) {
sendSupplierEmail.sendSupplierEmail(changeRecord.getChangeSupplier(), finishSubjectParam,
EmailTemplateEnum.YX_QC_CHANGE_FINISH, finishPartMap);
}
return confirmNode;
case CANCEL:
// 取消填写取消原因
String cancelReason = changeFlowSubmitReq.getCancelReason();
Assert.isTrue(StringUtils.isNotBlank(cancelReason), "变更取消原因不可为空");
changeRecord.setCancelReason(cancelReason);
List<ChangeExecRecord> cancelChangeExecRecordList = changeFlowSubmitReq
.getChangeExecProjectList().stream().map(exec -> {
Long changeExecFinishTime = exec.getChangeExecFinishTime();
Assert.notNull(changeExecFinishTime, "行动完成时间不可为空" + exec.getChangeTemplateId());
ChangeExecRecord changeExecRecord = new ChangeExecRecord();
changeExecRecord.setId(exec.getChangeExecId());
changeExecRecord.setChangeExecFinishTime(exec.getChangeExecFinishTime());
changeExecRecord.setChangeExecFinishDesc(exec.getChangeExecFinishDesc());
return changeExecRecord;
}).collect(Collectors.toList());
String cancelNode = flowService.submitFlow(flowId.toString(), flowDataDTO, uid,
ChangeFlowEnum.CHANGE_FLOW_CONFIRM.getTopoId(), JSON.toJSONString(content), true,
FlowxOperationEnum.SUBMIT.getName(), "提交工单", changeRecord.getCreateTime());
changeRecord.setState(ChangeStatusEnum.END.getStatus());
changeRecord.setFlowNode(cancelNode);
changeRecord.setUpdateTime(DateUtils.getCurrentTime());
changeFlowService.updateRecord(changeRecord);
cancelChangeExecRecordList.forEach(exec -> changeFlowExecService.update(exec));
// 发送邮件
HashMap<String, Object> cancelMap = new HashMap<>();
cancelMap.put("changeId", changeRecord.getFlowId());
cancelMap.put("changeSubject", ChangeSubjectEnum.getChangeSubjectEnum(changeRecord.getChangeSubject()).getDesc());
cancelMap.put("flowUrl", changeRecord.getFlowId());
ChangeConfigPo changeConfigPo1 = changeConfigService
.queryInfoPo(changeRecord.getParentChangeClassId(), changeRecord.getSonChangeClassId());
StringBuilder changeType1 = new StringBuilder();
try {
changeType1.append(changeConfigPo1.getChangeTypes().get(0).getTypeName());
} catch (Exception e) {
log.error("queryInfoPo error:{}", JSON.toJSONString(changeConfigPo1));
}
try {
changeType1.append(changeConfigPo1.getChangeTypes().get(1).getTypeName());
} catch (Exception e) {
log.error("queryInfoPo error:{}", JSON.toJSONString(changeConfigPo1));
}
//【已完结】变更主体+变更内容+工单ID 变更风险行动项已完结,请开始执行变更。
String cancelFinishSubjectParam = ChangeSubjectEnum
.getChangeSubjectEnum(changeRecord.getChangeSubject()).getDesc()
+ changeRecord.getChangeContent() + changeRecord.getFlowId();
// 变更确认,收件人:变更负责人+变更供应商+所有变更行动人+变更管理QM(cuiyixian@corp.netease.com)
List<ChangeFlowExecVO> execRecordList = changeFlowExecService
.getChangeFlowExecRecord(changeRecord.getId());
List<String> userEmails = execRecordList.stream().map(ChangeFlowExecVO::getChangeExecUserEmail)
.collect(Collectors.toList());
// 变更确认,抄送人:所有变更行动人上一级LEADER+变更管理委员会(yx_change_SC@qun.mail.163.com)
List<String> departmentInfoList = this.getDepartmentInfo(userEmails);
departmentInfoList.add(appConfig.getChangeCommittee());
userEmails.add(changeRecord.getChangeCommander());
userEmails.add(appConfig.getChangeManageQM());
qcSendEmail(userEmails, departmentInfoList, cancelFinishSubjectParam,
EmailTemplateEnum.YX_QC_CHANGE_FINISH, cancelMap);
// 如果是供应商,再次发送供应商邮件
if (changeRecord.getCreateSource().equals(CreateSourceEnum.TONG_ZHOU.getType())) {
sendSupplierEmail.sendSupplierEmail(changeRecord.getCreateSupplier(), cancelFinishSubjectParam,
EmailTemplateEnum.YX_QC_CHANGE_FINISH, cancelMap);
}
// 如果是其他端发起但是是供应商变更,再次发送供应商邮件
if (!changeRecord.getCreateSource().equals(CreateSourceEnum.TONG_ZHOU.getType())
&& ChangeSubjectEnum.SUPPLIER.getType().equals(changeRecord.getChangeSubject())) {
sendSupplierEmail.sendSupplierEmail(changeRecord.getChangeSupplier(), cancelFinishSubjectParam,
EmailTemplateEnum.YX_QC_CHANGE_FINISH, cancelMap);
}
return cancelNode;
case DELAY:
// 延期不流转工单
Long changeConfirmResultTime = changeFlowSubmitReq.getChangeConfirmResultTime();
Long tomorrowSpecificTime = DateUtils.getTomorrowSpecificTime("00:00:00");
Assert.isTrue(
changeConfirmResultTime != null && changeConfirmResultTime >= tomorrowSpecificTime,
"时间不可晚于下次执行时间");
// 更改变更结果确认时间
changeRecord.setChangeConfirmResultTime(changeConfirmResultTime);
changeRecord.setUpdateTime(DateUtils.getCurrentTime());
// 延期需要重新发邮件,改变执行邮件状态
changeRecord.setAutoSubmitEmail(0);
changeFlowService.updateRecord(changeRecord);
return null;
default:
return null;
}
// 其他几点,不可提交
case CHANGE_FLOW_EXE:
case CHANGE_FLOW_START:
case END:
default:
throw ExceptionFactory.createBiz(ResponseCode.NODE_ERROR, "不可提交节点" + currentNode);
}
}
private ChangeRecord getFlowInfo(Long flowId) {
ChangeRecord changeRecord = changeFlowService.getByFlowId(flowId);
if (changeRecord == null) {
throw ExceptionFactory.createBiz(ResponseCode.ERROR_FLOW_ID, "工单id不存在");
}
return changeRecord;
}
private void checkNode(String recordNode, List<String> checkNode) {
Optional<String> nodeOptional = checkNode.stream().filter(check -> check.equals(recordNode)).findAny();
if (!nodeOptional.isPresent()) {
throw ExceptionFactory.createBiz(ResponseCode.NODE_ERROR, "工单已流转至其他节点");
}
}
public Boolean cancel(ChangeFlowCancelReq req) {
log.info("[cancel] req:{}", JSON.toJSONString(req));
Long flowId = req.getFlowId();
// 查询工单有效性
ChangeRecord changeRecord = getFlowInfo(flowId);
log.info("[cancel] nodeId:{}", changeRecord.getFlowNode());
// 检查工单节点
this.checkNode(changeRecord.getFlowNode(), Collections.singletonList(ChangeFlowEnum.CHANGE_FLOW_SUBMIT.getNodeId()));
String uid = RequestLocalBean.getUid();
String changeCommander = changeRecord.getChangeCommander();
if (!uid.equals(changeCommander)) {
throw ExceptionFactory.createBiz(ResponseCode.NO_AUTH, ResponseCode.NO_AUTH.getMsg());
}
// 获取工单详情
FlowDataDTO flowDataDTO = flowService.flowDetail(flowId.toString());
if (flowDataDTO == null) {
throw ExceptionFactory.createBiz(ResponseCode.DETAIL_FLOW_ERROR, "工单查询错误,不存在");
}
// 工单流转
Map<String, Object> content = new HashMap<>(CommonConstants.INIT_HASH_MAP_SIZE);
content.put("updateTime", System.currentTimeMillis());
content.put(CommonConstants.FLOW_OPERATION_KEY, FlowOperationTypeEnum.REFUSE.getValue());
String nextNodeId = flowService.submitFlow(String.valueOf(flowId), flowDataDTO, uid,
ChangeFlowEnum.CHANGE_FLOW_SUBMIT.getTopoId(), JSON.toJSONString(content), false,
FlowxOperationEnum.APPROVE_FAIL.getName(), "取消工单", changeRecord.getCreateTime());
log.info("[cancel] flowId:{}, nextNodeId:{}", flowId, nextNodeId);
// 填充更新数据
changeRecord.setFlowNode(nextNodeId);
changeRecord.setState(ChangeStatusEnum.CANCEL.getStatus());
changeRecord.setCancelReason(req.getCancelReason());
changeRecord.setUpdateTime(DateUtils.getCurrentTime());
Map<String, Object> cancelMap = new HashMap<>();
cancelMap.put("changeId", changeRecord.getFlowId());
cancelMap.put("changeSubject", ChangeSubjectEnum.getChangeSubjectEnum(changeRecord.getChangeSubject()).getDesc());
cancelMap.put("changeContent", changeRecord.getChangeContent());
AjaxResponse<IusUserInfoRsp> user = iusRpcService.queryUserInfo(changeRecord.getChangeCommander());
cancelMap.put("changeCommander", user.getData().getName());
cancelMap.put("cancelReason", changeRecord.getCancelReason());
String cancelSubjectParam = changeRecord.getFlowId().toString();
List<String> receiver = new ArrayList<>(Collections.singletonList(changeCommander));
List<ChangeFlowExecVO> execRecord = changeFlowExecService
.getChangeFlowExecRecord(changeRecord.getId());
List<String> userEmailList = execRecord.stream().map(ChangeFlowExecVO::getChangeExecUserEmail)
.collect(Collectors.toList());
receiver.addAll(userEmailList);
// 取消变更,抄送人:变更负责人+变更行动人上一级主管、变更管理QM(cuiyixian@corp.netease.com)
userEmailList.addAll(receiver);
List<String> ccList = this.getDepartmentInfo(userEmailList);
ccList.add(appConfig.getChangeManageQM());
// 取消变更,收件人:变更发起人(供应商邮箱号或严选发起人)、变更负责人、变更行动人
String creator = changeRecord.getCreator();
if (!creator.equals(changeCommander)) {
receiver.add(creator);
}
qcSendEmail(receiver, ccList, cancelSubjectParam, EmailTemplateEnum.YX_QC_CHANGE_SUBMIT_CANCEL, cancelMap);
// 如果是供应商,再次发送供应商邮件
if (changeRecord.getCreateSource().equals(CreateSourceEnum.TONG_ZHOU.getType())) {
sendSupplierEmail.sendSupplierEmail(changeRecord.getCreateSupplier(), cancelSubjectParam,
EmailTemplateEnum.YX_QC_CHANGE_SUBMIT_CANCEL, cancelMap);
}
// 如果是其他端发起但是是供应商变更,再次发送供应商邮件
if (!changeRecord.getCreateSource().equals(CreateSourceEnum.TONG_ZHOU.getType())
&& ChangeSubjectEnum.SUPPLIER.getType().equals(changeRecord.getChangeSubject())) {
sendSupplierEmail.sendSupplierEmail(changeRecord.getChangeSupplier(), cancelSubjectParam,
EmailTemplateEnum.YX_QC_CHANGE_SUBMIT_CANCEL, cancelMap);
}
return changeFlowService.updateRecord(changeRecord);
}
public BasicChangeFlowVO quote(Long flowId, String supplier, Integer createSource) {
// 获取工单详情
ChangeRecord changeRecord = this.getFlowInfo(flowId);
// 同舟端需校验只能引用同一供应商下的工单
if (CreateSourceEnum.TONG_ZHOU.getType().equals(createSource)) {
Assert.isTrue(changeRecord.getCreateSupplier().equals(supplier), "不能引用非本供应商工单");
}
String changeSupplier = changeRecord.getChangeSupplier();
String changeSupplierName = "";
if (StringUtils.isNotBlank(changeSupplier)) {
List<SupplierSimpleRsp> supplierSimple = supplierService.getSupplierName(changeSupplier);
if (CollectionUtils.isNotEmpty(supplierSimple)) {
SupplierSimpleRsp supplierInfo = supplierSimple.get(0);
changeSupplierName = supplierInfo.getSupplierName();
}
}
// 获取附件
List<ChangeFlowFile> changeFileList = changeFileService.getChangeFileList(changeRecord.getId());
return BasicChangeFlowVO.builder().parentChangeClassId(changeRecord.getParentChangeClassId())
.sonChangeClassId(changeRecord.getSonChangeClassId()).changeSubject(changeRecord.getChangeSubject())
.changeItem(changeRecord.getChangeItem()).changeSupplier(changeSupplier)
.changeSupplierName(changeSupplierName).changeReason(changeRecord.getChangeReason())
.changeContent(changeRecord.getChangeContent()).changeRiskDesc(changeRecord.getChangeRiskDesc())
.changeProfit(changeRecord.getChangeProfit()).changeProfitDesc(changeRecord.getChangeProfitDesc())
.files(changeFileList).build();
}
public ChangeFlowVO detail(Long flowId) {
ChangeRecord changeRecord = changeFlowService.getByFlowId(flowId);
if (changeRecord == null) {
throw ExceptionFactory.createBiz(ResponseCode.ERROR_FLOW_ID, "工单id不存在");
}
log.debug("[detail] detail:{}", JSON.toJSONString(changeRecord));
ChangeFlowVO changeFlowVO = new ChangeFlowVO();
changeFlowVO.setId(changeRecord.getId());
changeFlowVO.setFlowNode(changeRecord.getFlowNode());
changeFlowVO.setCancelReason(changeRecord.getCancelReason());
changeFlowVO.setFlowId(changeRecord.getFlowId());
changeFlowVO.setParentChangeClassId(changeRecord.getParentChangeClassId());
changeFlowVO.setSonChangeClassId(changeRecord.getSonChangeClassId());
changeFlowVO.setChangeSubject(changeRecord.getChangeSubject());
changeFlowVO.setRemark(changeRecord.getRemark());
ChangeType parentChangeType = changeTypeService.getChangeTypeById(changeRecord.getParentChangeClassId());
if (parentChangeType == null) {
throw ExceptionFactory.createBiz(ResponseCode.CHANGE_TYPE_NOT_EXIST, "变更类型不存在");
}
ChangeType sonChangeType = changeTypeService.getChangeTypeById(changeRecord.getSonChangeClassId());
if (sonChangeType == null) {
throw ExceptionFactory.createBiz(ResponseCode.CHANGE_TYPE_NOT_EXIST, "变更类型配置不存在");
}
changeFlowVO.setChangeType(parentChangeType.getTypeName() + ">" + sonChangeType.getTypeName());
changeFlowVO.setChangeLevel(changeRecord.getChangeLevel());
changeFlowVO.setChangeDepartment(changeRecord.getChangeDepartment());
changeFlowVO.setChangeCommander(changeRecord.getChangeCommander());
String changeSupplier = changeRecord.getChangeSupplier();
changeFlowVO.setChangeSupplier(changeSupplier);
String changeSupplierName = "";
if (StringUtils.isNotBlank(changeSupplier)) {
List<SupplierSimpleRsp> supplierSimple = supplierService.getSupplierName(changeSupplier);
if (CollectionUtils.isNotEmpty(supplierSimple)) {
SupplierSimpleRsp supplier = supplierSimple.get(0);
changeSupplierName = supplier.getSupplierName();
}
}
changeFlowVO.setChangeSupplierName(changeSupplierName);
changeFlowVO.setChangeReason(changeRecord.getChangeReason());
changeFlowVO.setChangeContent(changeRecord.getChangeContent());
changeFlowVO.setChangeRiskDesc(changeRecord.getChangeRiskDesc());
// 获取附件
List<ChangeFlowFile> changeFileList = changeFileService.getChangeFileList(changeRecord.getId());
changeFlowVO.setFiles(changeFileList);
changeFlowVO.setChangeProfit(changeRecord.getChangeProfit());
changeFlowVO.setChangeProfitDesc(changeRecord.getChangeProfitDesc());
String itemJsonStr = changeRecord.getChangeItem();
if (StringUtils.isNotBlank(itemJsonStr)) {
List<ItemVO> itemList = JSON.parseArray(itemJsonStr, ItemVO.class);
changeFlowVO.setChangeItems(itemList);
// 变更结果确认节点,展示变更商品基础信息
String flowNode = changeRecord.getFlowNode();
if (ChangeFlowEnum.CHANGE_FLOW_CONFIRM.getNodeId().equals(flowNode)
|| ChangeFlowEnum.END.getNodeId().equals(flowNode)) {
List<Long> itemIds = itemList.stream().map(ItemVO::getItemId).collect(Collectors.toList());
// 批量查询spu信息
List<SpuTO> spuTOS = itemService.batchQuerySpuInfo(BatchQuerySpuInfoParam.builder().ids(itemIds)
.commonProps(new ArrayList<>()).spuProps(Arrays.asList("itemSetupType", "businessForm")).build());
log.debug("[detail] spuTOS:{}", JSON.toJSONString(spuTOS));
// 批量查询物理类目
Map<Long, List<SimplePhyCateGoryResultCo>> categoryChain = itemService
.queryBySpuIds(CommonIdsParamQuery.builder().ids(itemIds).build());
// 查询商品对应负责人信息
Map<Long, ChangeGoodsPrincipalPO> longChangeGoodsPrincipalPOMap = interiorChangeConfigService
.queryGoodsPrincipalInfo(itemIds);
List<ItemBasicInfoVO> itemBasicInfoVOS = itemList.stream().map(itemVO -> {
ItemBasicInfoVO itemBasicInfoVO = new ItemBasicInfoVO();
Long itemId = itemVO.getItemId();
itemBasicInfoVO.setItemId(itemId);
itemBasicInfoVO.setItemName(itemVO.getItemName());
List<QcCategoryVO> qcCategoryList = qcService.getQcCategoryListByItemId(itemId);
if (CollectionUtils.isNotEmpty(qcCategoryList)) {
String collect = qcCategoryList.stream().map(QcCategoryVO::getCategoryName)
.collect(Collectors.joining("/"));
itemBasicInfoVO.setQcCategory(collect);
} else {
itemBasicInfoVO.setQcCategory("/");
}
List<SimplePhyCateGoryResultCo> simplePhyCateGoryResultCos = categoryChain.get(itemId);
log.debug("[detail] itemId:{}, simplePhyCateGoryResultCos:{}", itemId,
JSON.toJSONString(simplePhyCateGoryResultCos));
if (CollectionUtils.isEmpty(simplePhyCateGoryResultCos)) {
itemBasicInfoVO.setPhyCategory(null);
} else {
List<CategoryInfoVO> categoryInfoVOS = simplePhyCateGoryResultCos.stream().map(phy -> {
CategoryInfoVO categoryInfoVO = new CategoryInfoVO();
categoryInfoVO.setId(phy.getId());
categoryInfoVO.setName(phy.getName());
return categoryInfoVO;
}).collect(Collectors.toList());
itemBasicInfoVO.setPhyCategory(categoryInfoVOS);
}
Optional<SpuTO> optionalSpuTO = spuTOS.stream().filter(spu -> spu.getId() == itemId).findAny();
log.debug("[detail] itemId:{}, optionalSpuTO:{}", itemId, JSON.toJSONString(optionalSpuTO));
if (!optionalSpuTO.isPresent()) {
itemBasicInfoVO.setItemSetupType(null);
itemBasicInfoVO.setBusinessForm(null);
itemBasicInfoVO.setStatus(null);
} else {
SpuTO spuTO = optionalSpuTO.get();
Map<String, String> propertyMap = spuTO.getPropertyMap();
itemBasicInfoVO.setItemSetupType(Integer.valueOf(propertyMap.get("itemSetupType")));
String businessForm = propertyMap.get("businessForm");
int business = StringUtils.isBlank(businessForm) ? 0 : Integer.parseInt(businessForm);
itemBasicInfoVO.setBusinessForm(business);
itemBasicInfoVO.setStatus(spuTO.getStatus());
}
ChangeGoodsPrincipalPO changeGoodsPrincipalPO = longChangeGoodsPrincipalPOMap.get(itemId);
log.debug("[detail] itemId:{}, changeGoodsPrincipalPO:{}", itemId,
JSON.toJSONString(changeGoodsPrincipalPO));
itemBasicInfoVO.setChangeGoodsPrincipal(changeGoodsPrincipalPO);
return itemBasicInfoVO;
}).collect(Collectors.toList());
changeFlowVO.setItemBasicInfoList(itemBasicInfoVOS);
}
} else {
changeFlowVO.setItemBasicInfoList(null);
}
changeFlowVO.setChangeState(changeRecord.getState());
changeFlowVO.setChangeCreator(changeRecord.getCreator());
List<ChangeFlowExecVO> changeFlowExecRecord = changeFlowExecService.getChangeFlowExecRecord(changeRecord.getId());
try {
Set<String> userEmail = changeFlowExecRecord.stream().map(ChangeFlowExecVO::getChangeExecUserEmail).collect(Collectors.toSet());
AjaxResponse<List<IusUserInfoRsp>> userListInfo = iusRpcService.queryUserListInfo(UserQueryDTO.builder().uids(new ArrayList<>(userEmail)).build());
List<IusUserInfoRsp> data = userListInfo.getData();
changeFlowExecRecord.forEach(i -> {
Optional<IusUserInfoRsp> anyExeUser = data.stream().filter(u -> u.getUid().equals(i.getChangeExecUserEmail())).findAny();
if (anyExeUser.isPresent()) {
i.setChangeExecUserName(anyExeUser.get().getName());
}
});
} catch (Exception ex) {
log.error("query user info has ex", ex);
}
changeFlowVO.setChangeExecProjectList(changeFlowExecRecord);
changeFlowVO.setCreateTime(changeRecord.getCreateTime());
changeFlowVO.setChangeConfirmResultTime(changeRecord.getChangeConfirmResultTime());
changeFlowVO.setChangeResult(changeRecord.getChangeResult());
changeFlowVO.setChangeResultDesc(changeRecord.getChangeResultDesc());
changeFlowVO.setTopoId(ChangeFlowEnum.CHANGE_FLOW.getTopoId());
try {
Set<String> commanderList = new HashSet<>();
commanderList.add(changeRecord.getChangeCommander());
commanderList.add(changeRecord.getCreator());
IusDepartmentReq iusDepartmentReq = new IusDepartmentReq();
iusDepartmentReq.setUids(new ArrayList<>(commanderList));
HashMap<String, List<SecondaryDepartments>> orgMap = iusService.queryDepartment(iusDepartmentReq);
List<SecondaryDepartments> commander = orgMap.get(changeRecord.getChangeCommander());
List<SecondaryDepartments> creator = orgMap.get(changeRecord.getCreator());
if (!CollectionUtils.isEmpty(commander)) {
Optional<SecondaryDepartments> anyOrg = commander.stream().filter(o -> o.getOrgPosLevel() == 97).findAny();
String orgName = "无三级部门";
if (anyOrg.isPresent()) {
orgName = anyOrg.get().getOrgPosName();
}
changeFlowVO.setChangeCommanderView(commander.get(0).getUserName() + "(" + orgName + ")");
}
if (!CollectionUtils.isEmpty(creator)) {
Optional<SecondaryDepartments> anyOrg = creator.stream().filter(o -> o.getOrgPosLevel() == 97).findAny();
String orgName = "无三级部门";
if (anyOrg.isPresent()) {
orgName = anyOrg.get().getOrgPosName();
}
changeFlowVO.setChangeCreatorView(creator.get(0).getUserName() + "(" + orgName + ")");
}
} catch (Exception ex) {
log.error("add org has ex", ex);
}
return changeFlowVO;
}
public ChangeFlowListVO query(Integer page, Integer pageSize, ChangeFlowListQueryReq changeFlowListQueryReq) {
log.info("[query] page:{}, pageSize:{}, changeFlowListQueryReq:{}", page, pageSize,
JSON.toJSONString(changeFlowListQueryReq));
//进行分页
PageHelper.startPage(page, pageSize);
PageInfo<ChangeRecord> changeRecordPageInfo = new PageInfo<>(
changeRecordMapper.selectByCondition(changeFlowListQueryReq));
List<ChangeRecord> changeRecords = changeRecordPageInfo.getList();
List<ChangeFlowVO> list = new ArrayList<>();
// 处理数据
if (CollectionUtils.isNotEmpty(changeRecords)) {
list = changeRecords.stream().map(c -> {
ChangeFlowVO changeFlowVO = new ChangeFlowVO();
changeFlowVO.setId(c.getId());
changeFlowVO.setFlowId(c.getFlowId());
changeFlowVO.setChangeSubject(c.getChangeSubject());
ChangeType parentChangeType = changeTypeService.getChangeTypeById(c.getParentChangeClassId());
ChangeType sonChangeType = changeTypeService.getChangeTypeById(c.getSonChangeClassId());
changeFlowVO.setChangeType(parentChangeType.getTypeName() + ">" + sonChangeType.getTypeName());
changeFlowVO.setChangeDepartment(c.getChangeDepartment());
changeFlowVO.setChangeContent(c.getChangeContent());
changeFlowVO.setChangeCommander(c.getChangeCommander());
String itemJsonStr = c.getChangeItem();
if (StringUtils.isNotBlank(itemJsonStr)) {
changeFlowVO.setChangeItems(JSON.parseArray(itemJsonStr, ItemVO.class));
}
changeFlowVO.setChangeSupplier(c.getChangeSupplier());
changeFlowVO.setChangeState(c.getState() == 3 ? ChangeStatusEnum.IN.getStatus() : c.getState());
// 同舟端展示供应商id
changeFlowVO.setChangeCreator(
CreateSourceEnum.TONG_ZHOU.getType().equals(c.getCreateSource()) ? c.getCreateSupplier()
: c.getCreator());
String participateChangeExecDepartment = c.getParticipateChangeExecDepartment();
if (StringUtils.isNotBlank(participateChangeExecDepartment)) {
changeFlowVO.setExecDepartmentStrList(JSON.parseArray(participateChangeExecDepartment, String.class));
HashSet<String> validDep = new HashSet<>(changeFlowVO.getExecDepartmentStrList());
changeFlowVO.setExecDepartmentStrList(new ArrayList<>(validDep));
}
changeFlowVO.setCreateTime(c.getCreateTime());
changeFlowVO.setChangeConfirmResultTime(c.getChangeConfirmResultTime());
changeFlowVO.setCancelReason(c.getCancelReason());
changeFlowVO.setRemark(c.getRemark());
return changeFlowVO;
}).collect(Collectors.toList());
}
PageVO pageVO = buildPageVo(changeRecordPageInfo.getTotal(), pageSize, page);
ChangeFlowListVO changeFlowListVO = new ChangeFlowListVO();
changeFlowListVO.setPageVo(pageVO);
try {
Set<String> commanderList = list.stream().map(ChangeFlowVO::getChangeCommander).collect(Collectors.toSet());
Set<String> creatorList = list.stream().map(ChangeFlowVO::getChangeCreator).collect(Collectors.toSet());
commanderList.addAll(creatorList);
IusDepartmentReq iusDepartmentReq = new IusDepartmentReq();
iusDepartmentReq.setUids(new ArrayList<>(commanderList));
HashMap<String, List<SecondaryDepartments>> orgMap = iusService.queryDepartment(iusDepartmentReq);
//AjaxResponse<List<IusUserInfoRsp>> userListInfo = iusRpcService.queryUserListInfo(UserQueryDTO.builder().uids(new ArrayList<>(commanderList)).build());
log.debug("query user: {} info: {}", commanderList, JSON.toJSONString(orgMap));
//List<IusUserInfoRsp> data = userListInfo.getData();
list.forEach(i -> {
List<SecondaryDepartments> commander = orgMap.get(i.getChangeCommander());
List<SecondaryDepartments> creator = orgMap.get(i.getChangeCreator());
//Optional<IusUserInfoRsp> commander = data.stream().filter(u -> u.getUid().equals(i.getChangeCommander())).findAny();
//Optional<IusUserInfoRsp> creator = data.stream().filter(u -> u.getUid().equals(i.getChangeCreator())).findAny();
if (!CollectionUtils.isEmpty(commander)) {
Optional<SecondaryDepartments> anyOrg = commander.stream().filter(o -> o.getOrgPosLevel() == 97).findAny();
String orgName = "无三级部门";
if (anyOrg.isPresent()) {
orgName = anyOrg.get().getOrgPosName();
}
i.setChangeCommander(commander.get(0).getUserName() + "(" + orgName + ")");
}
if (!CollectionUtils.isEmpty(creator)) {
Optional<SecondaryDepartments> anyOrg = creator.stream().filter(o -> o.getOrgPosLevel() == 97).findAny();
String orgName = "无三级部门";
if (anyOrg.isPresent()) {
orgName = anyOrg.get().getOrgPosName();
}
i.setChangeCreator(creator.get(0).getUserName() + "(" + orgName + ")");
}
});
} catch (Exception ex) {
log.error("add org has ex", ex);
}
changeFlowListVO.setChangeFlowList(list);
return changeFlowListVO;
}
/**
* 构建分页信息
*
* @param total
* @param pageSize
* @param page
* @return
*/
private PageVO buildPageVo(Long total, Integer pageSize, Integer page) {
Integer totalCount = Math.toIntExact(total);
int totalPage;
int i = totalCount % pageSize;
if (i != 0) {
totalPage = totalCount / pageSize + 1;
} else {
totalPage = totalCount / pageSize;
}
return PageVO.builder().page(page).totalPage(totalPage).pageSize(pageSize).pageCount(pageSize)
.totalCount(totalCount).build();
}
public UserBaseContainerDTO getOperator(InterfaceInputDTO interfaceInput) {
log.info("[getOperator] interfaceInput:{}", JSON.toJSONString(interfaceInput));
// 根据工单flowId获取审批人,创建工单时设置,唯一
String flowId = interfaceInput.getPublicFieldDTO().getFlowMeta().getFlowId();
String nodeId = interfaceInput.getPublicFieldDTO().getFlowMeta().getCurrNodeDataList().get(0).getNodeId();
log.info("[getOperator] flowId:{}, nodeId:{}", flowId, nodeId);
ChangeRecord changeRecord;
changeRecord = changeFlowService.getByFlowId(Long.valueOf(flowId));
log.info("[getOperator] first time get changeCommander:{}", changeRecord);
// 创建工单后落库,此时审批人还未落库,工单平台无法查询到审批人,方法休眠500ms
if (changeRecord == null) {
try {
Thread.sleep(500);
changeRecord = changeFlowService.getByFlowId(Long.valueOf(flowId));
log.info("[getOperator] second time get changeCommander:{}", changeRecord);
} catch (Exception e) {
log.info("[getOperator] flowId:{}, nodeId:{}, e={}", flowId, nodeId, e);
}
}
String changeCommander = changeRecord.getChangeCommander();
UserReachDTO userReachDTO = new UserReachDTO();
// 查询邮箱对应的名字
AjaxResponse<IusUserInfoRsp> user = iusRpcService.queryUserInfo(changeRecord.getChangeCommander());
userReachDTO.setUserName(user.getData().getName());
userReachDTO.setUid(changeCommander);
List<UserReachDTO> totalUserList = Collections.singletonList(userReachDTO);
UserBaseContainerDTO userBaseContainer = new UserBaseContainerDTO();
userBaseContainer.setUserList(totalUserList);
return userBaseContainer;
}
public void export(ChangeFlowListQueryReq changeFlowListQueryReq, HttpServletResponse response) {
List<ChangeRecord> changeRecords = changeRecordMapper.selectByCondition(changeFlowListQueryReq);
if (CollectionUtils.isEmpty(changeRecords)) {
throw ExceptionFactory.createBiz(ResponseCode.EMPTY, "无导出数据");
}
List<ChangeFlowExcelDTO> changeFlowExcelDTOList = changeRecords.stream().map(record -> {
ChangeFlowExcelDTO changeFlowExcelDTO = new ChangeFlowExcelDTO();
/*changeFlowExcelDTO.setId(record.getId());
changeFlowExcelDTO.setChangeSubject(ChangeSubjectEnum.getChangeSubjectEnum(record.getChangeSubject()).getDesc());
ChangeType parentChangeType = changeTypeService.getChangeTypeById(record.getParentChangeClassId());
ChangeType sonChangeType = changeTypeService.getChangeTypeById(record.getSonChangeClassId());
changeFlowExcelDTO.setChangeType(parentChangeType.getTypeName() + ">" + sonChangeType.getTypeName());
changeFlowExcelDTO.setChangeDepartment(record.getChangeDepartment());
changeFlowExcelDTO.setChangeContent(record.getChangeContent());
changeFlowExcelDTO.setChangeCommander(record.getChangeCommander());
String changeItemJsonStr = record.getChangeItem();
if (StringUtils.isNotBlank(changeItemJsonStr)) {
List<ItemVO> itemVOS = JSON.parseArray(changeItemJsonStr, ItemVO.class);
changeFlowExcelDTO.setChangeItems(itemVOS.stream().map(item -> item.getItemId() + item.getItemName())
.collect(Collectors.joining(",")));
}
if (StringUtils.isNotBlank(record.getChangeSupplier())) {
changeFlowExcelDTO.setSupplier(record.getChangeSupplier());
}
changeFlowExcelDTO.setChangeState(record.getState());
// todo:变更发起人组织查询:姓名(组织架构三级部门)/供应商ID/system+发起时间
changeFlowExcelDTO.setChangeCreator(record.getCreator());
changeFlowExcelDTO.setExecDepartmentStrList(record.getParticipateChangeExecDepartment());
changeFlowExcelDTO.setCreateTime(record.getCreateTime());*/
return changeFlowExcelDTO;
}).collect(Collectors.toList());
Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams(), ChangeFlowExcelDTO.class, changeFlowExcelDTOList);
downLoadExcel("变更管理列表", response, workbook);
}
private void downLoadExcel(String fileName, HttpServletResponse response, Workbook workbook) {
try {
response.setCharacterEncoding("UTF-8");
response.setHeader("content-Type", "application/vnd.ms-excel");
response.setHeader("Content-Disposition",
"attachment;filename=" + URLEncoder.encode(fileName, "UTF-8") + ".xls");
ByteArrayOutputStream baos = new ByteArrayOutputStream();
workbook.write(baos);
response.setHeader("Content-Length", String.valueOf(baos.size()));
OutputStream out = response.getOutputStream();
out.write(baos.toByteArray());
} catch (IOException ex) {
throw ExceptionFactory.createBiz(ResponseCode.BAD_REQUEST);
}
}
public void deliver(@Valid ChangeFlowDeliverReq req) {
log.info("[deliver] req:{}", JSON.toJSONString(req));
Long flowId = req.getFlowId();
// 查询工单有效性
ChangeRecord changeRecord = getFlowInfo(flowId);
log.info("[deliver] nodeId:{}", changeRecord.getFlowNode());
// 检查工单节点
List<String> nodeList = Arrays.asList(ChangeFlowEnum.CHANGE_FLOW_SUBMIT.getNodeId(),
ChangeFlowEnum.CHANGE_FLOW_CONFIRM.getNodeId());
this.checkNode(changeRecord.getFlowNode(), nodeList);
String uid = RequestLocalBean.getUid();
String name = RequestLocalBean.getName();
String changeCommander = changeRecord.getChangeCommander();
if (!uid.equals(changeCommander)) {
throw ExceptionFactory.createBiz(ResponseCode.NO_AUTH, ResponseCode.NO_AUTH.getMsg());
}
if (changeCommander.equals(req.getDeliverUser())) {
throw ExceptionFactory.createBiz(ResponseCode.BAD_REQUEST, "不能转交给自己!");
}
// 工单审核人转交
String deliverUser = req.getDeliverUser();
UserBaseDTO userBaseDTO = new UserBaseDTO();
userBaseDTO.setUserName(deliverUser);
userBaseDTO.setUid(deliverUser);
String remark = req.getRemark();
Map<String, Object> content = new HashMap<>(CommonConstants.INIT_HASH_MAP_SIZE);
content.put("updateTime", System.currentTimeMillis());
flowService.updateApprovers(ChangeFlowEnum.CHANGE_FLOW_EXE.getTopoId(), flowId.toString(),
changeRecord.getFlowNode(), Collections.singletonList(userBaseDTO), uid,
name, remark, JSON.toJSONString(content));
// 更新工单负责人
changeRecord.setChangeCommander(deliverUser);
changeRecord.setRemark(remark);
changeRecord.setUpdateTime(DateUtils.getCurrentTime());
Map<String, Object> deliverMap = new HashMap<>();
deliverMap.put("changeId", changeRecord.getFlowId());
deliverMap.put("changeSubject", ChangeSubjectEnum.getChangeSubjectEnum(changeRecord.getChangeSubject()).getDesc());
deliverMap.put("changeContent", changeRecord.getChangeContent());
// 转交人名称
AjaxResponse<IusUserInfoRsp> oldUser = iusRpcService.queryUserInfo(changeCommander);
deliverMap.put("changeCommander", oldUser.getData().getName());
deliverMap.put("changeCommanderEmail", changeCommander);
// 被转交人名称
AjaxResponse<IusUserInfoRsp> newUser = iusRpcService.queryUserInfo(deliverUser);
deliverMap.put("restsChangeCommander", newUser.getData().getName());
deliverMap.put("restsChangeCommanderEmail", deliverUser);
String deliverSubjectParam = changeRecord.getFlowId().toString();
// 转交,收件人:变更转交人(工单接收人)、变更负责人(工单转交人)
List<String> receiver = Arrays.asList(changeCommander, deliverUser);
// 转交,抄送人:变更发起人+原变更负责人上一级主管、变更转交人(工单接收人)上一级主管+变更行动项负责人
List<String> ccList = this.getDepartmentInfo(receiver);
ccList.add(changeRecord.getCreator());
List<ChangeFlowExecVO> execRecord = changeFlowExecService
.getChangeFlowExecRecord(changeRecord.getId());
List<String> userEmailList = execRecord.stream().map(ChangeFlowExecVO::getChangeExecUserEmail)
.collect(Collectors.toList());
ccList.addAll(userEmailList);
qcSendEmail(receiver, ccList, deliverSubjectParam, EmailTemplateEnum.YX_QC_CHANGE_SUBMIT_FORWARD, deliverMap);
// 如果是供应商,再次发送供应商邮件
if (changeRecord.getCreateSource().equals(CreateSourceEnum.TONG_ZHOU.getType())) {
sendSupplierEmail.sendSupplierEmail(changeRecord.getCreateSupplier(), deliverSubjectParam,
EmailTemplateEnum.YX_QC_CHANGE_SUBMIT_FORWARD, deliverMap);
}
// 如果是其他端发起但是是供应商变更,再次发送供应商邮件
if (!changeRecord.getCreateSource().equals(CreateSourceEnum.TONG_ZHOU.getType())
&& ChangeSubjectEnum.SUPPLIER.getType().equals(changeRecord.getChangeSubject())) {
sendSupplierEmail.sendSupplierEmail(changeRecord.getChangeSupplier(), deliverSubjectParam,
EmailTemplateEnum.YX_QC_CHANGE_SUBMIT_FORWARD, deliverMap);
}
changeFlowService.updateRecord(changeRecord);
}
}
/**
* @(#)ChangeFlowExportCallback.java, 2022/12/8.
* <p/>
* Copyright 2022 Netease, Inc. All rights reserved.
* NETEASE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
package com.netease.mail.yanxuan.change.biz.callback;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.alibaba.fastjson.JSON;
import com.google.common.collect.Lists;
import com.netease.mail.dp.des.process.api.entity.CallbackQueryReq;
import com.netease.mail.dp.des.process.api.entity.ExcelCell;
import com.netease.mail.dp.des.process.api.entity.ExcelTitle;
import com.netease.mail.dp.des.process.api.entity.PivotTable;
import com.netease.mail.dp.des.starter.callback.DesCallbackService;
import com.netease.mail.yanxuan.change.biz.service.ChangeFlowExportQuery;
import com.netease.mail.yanxuan.change.biz.service.InteriorChangeConfigService;
import com.netease.mail.yanxuan.change.biz.service.change.ChangeTypeService;
import com.netease.mail.yanxuan.change.biz.service.rpc.ItemService;
import com.netease.mail.yanxuan.change.biz.service.rpc.IusService;
import com.netease.mail.yanxuan.change.biz.service.rpc.QCService;
import com.netease.mail.yanxuan.change.common.enums.BusinessFormEnum;
import com.netease.mail.yanxuan.change.common.enums.ChangeResultEnum;
import com.netease.mail.yanxuan.change.common.enums.ChangeStatusEnum;
import com.netease.mail.yanxuan.change.common.enums.ChangeSubjectEnum;
import com.netease.mail.yanxuan.change.common.enums.ItemSetupTypeEnum;
import com.netease.mail.yanxuan.change.common.enums.MainSpuStatusEnum;
import com.netease.mail.yanxuan.change.common.enums.ProfitTypeEnum;
import com.netease.mail.yanxuan.change.common.util.DateUtils;
import com.netease.mail.yanxuan.change.common.util.ExcelUtil;
import com.netease.mail.yanxuan.change.dal.entity.ChangeExecRecord;
import com.netease.mail.yanxuan.change.dal.entity.ChangeRecord;
import com.netease.mail.yanxuan.change.dal.entity.ChangeType;
import com.netease.mail.yanxuan.change.dal.mapper.ChangeExecRecordMapper;
import com.netease.mail.yanxuan.change.dal.mapper.ChangeRecordMapper;
import com.netease.mail.yanxuan.change.dal.meta.model.po.ChangeGoodsPrincipalPO;
import com.netease.mail.yanxuan.change.dal.meta.model.req.ChangeFlowListQueryReq;
import com.netease.mail.yanxuan.change.dal.meta.model.vo.ItemVO;
import com.netease.mail.yanxuan.change.integration.excel.ChangeFlowExcelDTO;
import com.netease.mail.yanxuan.change.integration.excel.ChangeFlowExcelVo;
import com.netease.mail.yanxuan.change.integration.flow.UserQueryDTO;
import com.netease.mail.yanxuan.change.integration.flow.ius.rsp.IusUserInfoRsp;
import com.netease.mail.yanxuan.change.integration.item.SimplePhyCateGoryResultCo;
import com.netease.mail.yanxuan.change.integration.item.meta.SpuTO;
import com.netease.mail.yanxuan.change.integration.item.param.BatchQuerySpuInfoParam;
import com.netease.mail.yanxuan.change.integration.item.param.CommonIdsParamQuery;
import com.netease.mail.yanxuan.change.integration.qc.meta.QcCategoryVO;
import lombok.extern.slf4j.Slf4j;
/**
* @Author zcwang
* @Date 2022/12/8
*/
@Slf4j
@Component
public class ChangeFlowExportCallback implements DesCallbackService {
@Autowired
private ChangeRecordMapper changeRecordMapper;
@Autowired
private ChangeTypeService changeTypeService;
@Autowired
private ChangeExecRecordMapper changeExecRecordMapper;
@Autowired
private ItemService itemService;
@Autowired
private InteriorChangeConfigService interiorChangeConfigService;
@Autowired
private QCService qcService;
@Autowired
private IusService iusService;
@Override
public ExcelTitle queryExcelTitle(CallbackQueryReq req) {
log.info("[op: change flow export callback queryExcelTitle] req={}", JSON.toJSONString(req));
ChangeFlowExportQuery query = JSON.parseObject(req.getParamJson(), ChangeFlowExportQuery.class);
ChangeFlowListQueryReq changeFlowListQueryReq = new ChangeFlowListQueryReq();
BeanUtils.copyProperties(query, changeFlowListQueryReq);
List<ChangeRecord> list = changeRecordMapper.selectByCondition(changeFlowListQueryReq);
ExcelTitle excelTitle = ExcelUtil.fetchExceltile(ChangeFlowExcelVo.class);
excelTitle.setTotal((long) list.size());
log.info("[op: change flow export callback queryExcelTitle] result={}", JSON.toJSONString(excelTitle));
return excelTitle;
}
@Override
public List<List<ExcelCell>> queryExcelData(CallbackQueryReq req) {
log.info("[op: address book export callback queryExcelData] req={}", JSON.toJSONString(req));
ChangeFlowExportQuery query = JSON.parseObject(req.getParamJson(), ChangeFlowExportQuery.class);
query.setOffset(req.getOffset());
query.setLimit(req.getLimit());
List<ChangeFlowExcelDTO> list = getExportList(query);
return list.stream().map(ChangeFlowExcelVo::init).collect(Collectors.toList());
}
private List<ChangeFlowExcelDTO> getExportList(ChangeFlowExportQuery query) {
ChangeFlowListQueryReq changeFlowListQueryReq = new ChangeFlowListQueryReq();
BeanUtils.copyProperties(query, changeFlowListQueryReq);
List<ChangeRecord> changeRecords = changeRecordMapper.selectByConditionAndLimit(changeFlowListQueryReq);
log.debug("[getExportList] changeRecords:{}", changeRecords);
if (CollectionUtils.isEmpty(changeRecords)) {
return Lists.newArrayList();
}
// 提前查询所有行动项用户名
List<String> allExecUserEmailList = new ArrayList<>();
for (ChangeRecord changeRecord : changeRecords) {
List<ChangeExecRecord> changeExecRecords = changeExecRecordMapper.selectByChangeRecordId(changeRecord.getId());
List<String> collect = changeExecRecords.stream()
.map(ChangeExecRecord::getChangeExecUserEmail)
.filter(StringUtils::isNotBlank).collect(Collectors.toList());
if (CollectionUtils.isNotEmpty(collect)) {
allExecUserEmailList.addAll(collect);
}
}
List<IusUserInfoRsp> userListInfo = new ArrayList<>();
try {
if (CollectionUtils.isNotEmpty(allExecUserEmailList)) {
List<String> userEmailList = allExecUserEmailList.stream().distinct().collect(Collectors.toList());
userListInfo = iusService.queryUserListInfo(UserQueryDTO.builder().uids(userEmailList).build());
}
} catch (Exception e) {
log.info("query user info has ex", e);
}
// 提前查询所有商品
List<Long> allItemList = new ArrayList<>();
List<String> allChangeProduct = changeRecords.stream()
.filter(changeRecord -> changeRecord.getChangeSubject().equals(ChangeSubjectEnum.PRODUCT.getType()))
.map(ChangeRecord::getChangeItem).filter(StringUtils::isNotBlank).collect(Collectors.toList());
if (CollectionUtils.isNotEmpty(allChangeProduct)) {
for (String changeItemJsonStr : allChangeProduct) {
List<ItemVO> itemVOS = JSON.parseArray(changeItemJsonStr, ItemVO.class);
List<Long> itemIds = itemVOS.stream().map(ItemVO::getItemId).collect(Collectors.toList());
allItemList.addAll(itemIds);
}
}
log.debug("[getExportList] allItemList:{}", allItemList);
List<SpuTO> spuTOS = new ArrayList<>();
Map<Long, List<SimplePhyCateGoryResultCo>> categoryChain = new HashMap<>();
Map<Long, ChangeGoodsPrincipalPO> longChangeGoodsPrincipalPOMap = new HashMap<>();
if (CollectionUtils.isNotEmpty(allItemList)) {
allItemList = allItemList.stream().distinct().collect(Collectors.toList());
// 批量查询spu信息
spuTOS = itemService.batchQuerySpuInfo(BatchQuerySpuInfoParam.builder().ids(allItemList)
.commonProps(new ArrayList<>()).spuProps(Arrays.asList("itemSetupType", "businessForm")).build());
// 批量查询物理类目
categoryChain = itemService
.queryBySpuIds(CommonIdsParamQuery.builder().ids(allItemList).build());
// 查询商品对应负责人信息
longChangeGoodsPrincipalPOMap = interiorChangeConfigService
.queryGoodsPrincipalInfo(allItemList);
log.debug("[getExportList] spuTOS:{}", spuTOS.size());
}
List<ChangeFlowExcelDTO> changeFlowExcelDTOList = new ArrayList<>();
// 导出excel,按照商品/供应商和行动项,n*n重复拆分,例2个商品3个行动项,拆分成2*3=6行,其他属性一致
for (ChangeRecord record : changeRecords) {
List<ChangeExecRecord> changeExecRecords = changeExecRecordMapper.selectByChangeRecordId(record.getId());
ChangeSubjectEnum changeSubjectEnum = ChangeSubjectEnum.getChangeSubjectEnum(record.getChangeSubject());
switch (changeSubjectEnum) {
case PRODUCT:
String changeItemJsonStr = record.getChangeItem();
List<ItemVO> itemVOS = JSON.parseArray(changeItemJsonStr, ItemVO.class);
for (ItemVO itemVO : itemVOS) {
for (ChangeExecRecord changeExecRecord : changeExecRecords) {
Long itemId = itemVO.getItemId();
// 组装通用信息,除商品信息,行动项以外其他字段一致
ChangeFlowExcelDTO changeFlowExcelDTO = this.obtainCommon(record, changeSubjectEnum);
changeFlowExcelDTO.setSupplier("/");
changeFlowExcelDTO.setChangeItem(itemVO.getItemName());
changeFlowExcelDTO.setSPUId(itemId);
List<QcCategoryVO> qcCategoryList = qcService.getQcCategoryListByItemId(itemId);
if (CollectionUtils.isNotEmpty(qcCategoryList)) {
String collect = qcCategoryList.stream().map(QcCategoryVO::getCategoryName)
.collect(Collectors.joining("/"));
changeFlowExcelDTO.setQcCategory(collect);
} else {
changeFlowExcelDTO.setQcCategory("/");
}
List<SimplePhyCateGoryResultCo> simplePhyCateGoryResultCos = categoryChain.get(itemId);
if (CollectionUtils.isNotEmpty(simplePhyCateGoryResultCos)) {
String collect = simplePhyCateGoryResultCos.stream()
.map(SimplePhyCateGoryResultCo::getName).collect(Collectors.joining("/"));
changeFlowExcelDTO.setPhyCategory(collect);
} else {
changeFlowExcelDTO.setPhyCategory("/");
}
Optional<SpuTO> optionalSpuTO = spuTOS.stream().filter(spu -> spu.getId() == itemId).findAny();
if (!optionalSpuTO.isPresent()) {
changeFlowExcelDTO.setItemSetupType(null);
changeFlowExcelDTO.setBusinessForm(null);
changeFlowExcelDTO.setStatus(null);
} else {
SpuTO spuTO = optionalSpuTO.get();
Map<String, String> propertyMap = spuTO.getPropertyMap();
Integer itemSetupType = Integer.valueOf(propertyMap.get("itemSetupType"));
changeFlowExcelDTO.setItemSetupType(ItemSetupTypeEnum.getByType(itemSetupType));
String businessForm = propertyMap.get("businessForm");
int business = StringUtils.isBlank(businessForm) ? 0 : Integer.parseInt(businessForm);
changeFlowExcelDTO.setBusinessForm(BusinessFormEnum.getByType(business));
changeFlowExcelDTO.setStatus(MainSpuStatusEnum.getByStatus(spuTO.getStatus()));
}
ChangeGoodsPrincipalPO changeGoodsPrincipalPO = longChangeGoodsPrincipalPOMap.get(itemId);
try {
if (null == changeGoodsPrincipalPO) {
changeFlowExcelDTO.setFunctionary("/");
changeFlowExcelDTO.setPurchase("/");
changeFlowExcelDTO.setGoodsProject("/");
changeFlowExcelDTO.setGoodsSqe("/");
} else {
buildGoodsPrincipal(changeGoodsPrincipalPO, changeFlowExcelDTO);
}
} catch (Exception e) {
log.debug("[getExportList] changeGoodsPrincipalPO has ex:{}",
JSON.toJSONString(changeGoodsPrincipalPO));
}
// 组装行动项相关信息
obtainChangeExec(changeExecRecord, changeFlowExcelDTO, userListInfo);
ChangeResultEnum resultEnum = ChangeResultEnum.getByStatus(record.getChangeResult());
changeFlowExcelDTO.setChangeResult(resultEnum == null ? "": resultEnum.getDesc());
changeFlowExcelDTO
.setChangeEndTime(record.getState().equals(ChangeStatusEnum.END.getStatus())
? DateUtils.parseLongToString(record.getUpdateTime(), DateUtils.DATE_TIME_FORMAT)
: "");
changeFlowExcelDTOList.add(changeFlowExcelDTO);
}
}
break;
case SUPPLIER:
case OTHER:
default:
// 供应商变更,以行动项循环
for (ChangeExecRecord changeExecRecord : changeExecRecords) {
// 组装通用信息,除商品信息,行动项以外其他字段一致
ChangeFlowExcelDTO changeFlowExcelDTO = this.obtainCommon(record, changeSubjectEnum);
changeFlowExcelDTO.setSupplier(StringUtils.isBlank(record.getChangeSupplier())? "/": record.getChangeSupplier());
changeFlowExcelDTO.setChangeItem(null);
changeFlowExcelDTO.setSPUId(null);
changeFlowExcelDTO.setQcCategory(null);
changeFlowExcelDTO.setPhyCategory(null);
changeFlowExcelDTO.setItemSetupType(null);
changeFlowExcelDTO.setBusinessForm(null);
changeFlowExcelDTO.setStatus(null);
changeFlowExcelDTO.setFunctionary(null);
changeFlowExcelDTO.setPurchase(null);
changeFlowExcelDTO.setGoodsSqe(null);
changeFlowExcelDTO.setGoodsProject(null);
// 组装行动项相关信息
this.obtainChangeExec(changeExecRecord, changeFlowExcelDTO, userListInfo);
ChangeResultEnum resultEnum = ChangeResultEnum.getByStatus(record.getChangeResult());
changeFlowExcelDTO.setChangeResult(resultEnum == null ? "": resultEnum.getDesc());
changeFlowExcelDTO
.setChangeEndTime(record.getState().equals(ChangeStatusEnum.END.getStatus())
? DateUtils.parseLongToString(record.getUpdateTime(), DateUtils.DATE_TIME_FORMAT)
: "/");
changeFlowExcelDTOList.add(changeFlowExcelDTO);
}
break;
}
}
return changeFlowExcelDTOList;
}
private void buildGoodsPrincipal(ChangeGoodsPrincipalPO changeGoodsPrincipalPO, ChangeFlowExcelDTO changeFlowExcelDTO) {
String functionaryName = StringUtils.isBlank(changeGoodsPrincipalPO.getFunctionaryName()) ? "" : changeGoodsPrincipalPO.getFunctionaryName();
String functionaryEmail = StringUtils.isBlank(changeGoodsPrincipalPO.getFunctionaryEmail()) ? "" : changeGoodsPrincipalPO.getFunctionaryEmail();
String purchaseName = StringUtils.isBlank(changeGoodsPrincipalPO.getPurchaseName()) ? "" : changeGoodsPrincipalPO.getPurchaseName();
String purchaseEmail = StringUtils.isBlank(changeGoodsPrincipalPO.getPurchaseEmail()) ? "" : changeGoodsPrincipalPO.getPurchaseEmail();
String goodsProjectName = StringUtils.isBlank(changeGoodsPrincipalPO.getGoodsProjectName()) ? "" : changeGoodsPrincipalPO.getGoodsProjectName();
String goodsProjectEmail = StringUtils.isBlank(changeGoodsPrincipalPO.getGoodsProjectEmail()) ? "" : changeGoodsPrincipalPO.getGoodsProjectEmail();
String goodsSqeName = StringUtils.isBlank(changeGoodsPrincipalPO.getGoodsSqeName()) ? "" : changeGoodsPrincipalPO.getGoodsSqeName();
String goodsSqeEmail = StringUtils.isBlank(changeGoodsPrincipalPO.getGoodsSqeEmail()) ? "" : changeGoodsPrincipalPO.getGoodsSqeEmail();
String functionary = functionaryName + functionaryEmail;
String purchase = purchaseName + purchaseEmail;
String goodsProject = goodsProjectName + goodsProjectEmail;
String goodsSqe = goodsSqeName + goodsSqeEmail;
changeFlowExcelDTO.setFunctionary(StringUtils.isBlank(functionary) ? "/" :functionary);
changeFlowExcelDTO.setPurchase(StringUtils.isBlank(purchase) ? "/" :purchase);
changeFlowExcelDTO.setGoodsProject(StringUtils.isBlank(goodsProject) ? "/" :goodsProject);
changeFlowExcelDTO.setGoodsSqe(StringUtils.isBlank(goodsSqe) ? "/" :goodsSqe);
}
private void obtainChangeExec(ChangeExecRecord changeExecRecord, ChangeFlowExcelDTO changeFlowExcelDTO,
List<IusUserInfoRsp> userListInfo) {
changeFlowExcelDTO.setExecDepartment(changeExecRecord.getChangeExecDepartment());
Optional<IusUserInfoRsp> anyExeUser = userListInfo.stream()
.filter(u -> u.getUid().equals(changeExecRecord.getChangeExecUserEmail())).findAny();
String execUserName = "";
if (anyExeUser.isPresent()) {
execUserName = anyExeUser.get().getName();
}
changeFlowExcelDTO.setChangeExecUser(execUserName + changeExecRecord.getChangeExecUserEmail());
changeFlowExcelDTO.setChangeExecRiskDesc(changeExecRecord.getChangeRiskDesc());
changeFlowExcelDTO.setChangeExecProject(changeExecRecord.getChangeExecProject());
changeFlowExcelDTO.setChangeChecking(changeExecRecord.getChangeChecking());
Long changeExecFinishTime = changeExecRecord.getChangeExecFinishTime();
if (changeExecFinishTime == 0L) {
changeFlowExcelDTO.setChangeExecFinishTime("/");
} else {
changeFlowExcelDTO.setChangeExecFinishTime(
DateUtils.parseLongToString(changeExecFinishTime, DateUtils.DATE_TIME_FORMAT));
}
changeFlowExcelDTO.setChangeExecFinishDesc(changeExecRecord.getChangeExecFinishDesc());
}
/**
* 组装通用字段
* @param record
* @param changeSubjectEnum
* @return
*/
private ChangeFlowExcelDTO obtainCommon(ChangeRecord record, ChangeSubjectEnum changeSubjectEnum) {
ChangeFlowExcelDTO changeFlowExcelDTO = new ChangeFlowExcelDTO();
changeFlowExcelDTO.setFlowId(record.getFlowId());
String createTimeStr = DateUtils.parseLongToString(record.getCreateTime(), DateUtils.DATE_TIME_FORMAT);
changeFlowExcelDTO.setCreateTime(createTimeStr);
changeFlowExcelDTO.setChangeCreator(record.getCreator());
changeFlowExcelDTO.setChangeSubject(changeSubjectEnum.getDesc());
ChangeType parentChangeType = changeTypeService.getChangeTypeById(record.getParentChangeClassId());
ChangeType sonChangeType = changeTypeService.getChangeTypeById(record.getSonChangeClassId());
changeFlowExcelDTO.setChangeType(parentChangeType.getTypeName() + ">" + sonChangeType.getTypeName());
changeFlowExcelDTO.setChangeLevel(record.getChangeLevel());
changeFlowExcelDTO.setChangeDepartment(record.getChangeDepartment());
changeFlowExcelDTO.setChangeCommander(record.getChangeCommander());
changeFlowExcelDTO.setChangeReason(record.getChangeReason());
changeFlowExcelDTO.setChangeContent(record.getChangeContent());
changeFlowExcelDTO.setChangeRiskDesc(record.getChangeRiskDesc());
// todo:变更收益类型和前端核对枚举
changeFlowExcelDTO.setChangeProfit(ProfitTypeEnum.getByType(record.getChangeProfit()));
changeFlowExcelDTO.setChangeProfitDesc(record.getChangeProfitDesc());
return changeFlowExcelDTO;
}
@Override
public PivotTable queryPivotTable(CallbackQueryReq callbackQueryReq) {
return null;
}
}
\ No newline at end of file
/**
* @(#)AppConfig.java, 2022/11/14.
* <p/>
* Copyright 2022 Netease, Inc. All rights reserved.
* NETEASE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
package com.netease.mail.yanxuan.change.biz.config;
import java.util.List;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import com.ctrip.framework.apollo.spring.annotation.EnableAutoUpdateApolloConfig;
import com.ctrip.framework.apollo.spring.annotation.ValueMapping;
import com.sun.org.apache.xpath.internal.operations.Bool;
import lombok.Data;
/**
* @Author zcwang
* @Date 2022/11/14
*/
@Component
@EnableAutoUpdateApolloConfig("application")
@Data
public class AppConfig {
@ValueMapping("${titleConfig:null}")
private TitleConfig titleConfig;
@Value("${changeExecLimit:20}")
private Integer changeExecLimit;
@Value("${testEmail:A@163.com}")
private String testEmail;
@Value("${sendEmail:[\"wb.wangzhichao01@mesg.corp.netease.com\"]}")
private List<String> receiver;
@Value("${change.goods.principal.name:aaa}")
private String defaultName;
@Value("${change.goods.principal.email:grp.gyhtest1001@corp.netease.com}")
private String defaultEmail;
@Value("${searchName:aa}")
private String searchName;
@Value("${searchUid:wb.mulongfei@mesg.corp.netease.com}")
private String searchUid;
/**
* 变更管理QM
*/
@Value("${changeManageQM:cuiyixian@corp.netease.com}")
private String changeManageQM;
/**
* 变更管理委员会
*/
@Value("${changeCommittee:yx_change_SC@qun.mail.163.com}")
private String changeCommittee;
@Value("${exportLimit:20}")
private Long exportLimit;
}
\ No newline at end of file
/**
* @(#)TitleConfig.java, 2022/11/14.
* <p/>
* Copyright 2022 Netease, Inc. All rights reserved.
* NETEASE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
package com.netease.mail.yanxuan.change.biz.config;
import java.util.List;
import lombok.Data;
/**
* @Author zcwang
* @Date 2022/11/14
*/
@Data
public class TitleConfig {
/**
* 提示文案
*/
private String title;
/**
* 文件
*/
private List<TitleFileConfig> files;
}
\ No newline at end of file
/**
* @(#)ChangeFileConfig.java, 2022/11/14.
* <p/>
* Copyright 2022 Netease, Inc. All rights reserved.
* NETEASE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
package com.netease.mail.yanxuan.change.biz.config;
import lombok.Data;
/**
* @Author zcwang
* @Date 2022/11/14
*/
@Data
public class TitleFileConfig {
/**
* 文件链接
*/
private String fileUrl;
/**
* 文件名
*/
private String fileName;
}
\ No newline at end of file
package com.netease.mail.yanxuan.change.biz.meta.exception;
import com.netease.mail.yanxuan.change.common.bean.ResponseCode;
/**
* @author: bndong
* @date: 2021/5/25
*/
public class ExceptionFactory {
public static ServiceException createBiz(ResponseCode resCode) {
return new ServiceException(resCode);
}
public static ServiceException createBiz(ResponseCode resCode, String message) {
return new ServiceException(resCode, message);
}
public static ServiceException createNotLogin() {
return createBiz(ResponseCode.NOT_LOGIN);
}
public static ServiceException createParamFail() {
return createBiz(ResponseCode.BAD_REQUEST);
}
}
package com.netease.mail.yanxuan.change.biz.meta.exception;
import com.netease.mail.yanxuan.change.common.bean.ResponseCode;
/**
* @author: bndong
* @date: 2021/5/25
*/
public class ServiceException extends RuntimeException {
private static final long serialVersionUID = 2531549421457088715L;
private ResponseCode code = ResponseCode.SUCCESS;
private String msg;
public ServiceException(ResponseCode code, String msg) {
super("code:" + code + ",msg:" + msg);
this.msg = msg;
this.code = code;
}
public ServiceException(ResponseCode code) {
super("code:" + code.getCode() + ",msg:" + code.getMsg());
this.code = code;
this.msg = code.getMsg();
}
public ResponseCode getCode() {
return code;
}
public int getIntCode() {
return code.getCode();
}
public void setCode(ResponseCode code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
}
/**
* @(#)ChangeFileService.java, 2022/11/21.
* <p/>
* Copyright 2022 Netease, Inc. All rights reserved.
* NETEASE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
package com.netease.mail.yanxuan.change.biz.service;
import java.util.List;
import com.netease.mail.yanxuan.change.common.enums.FileTypeEnum;
import com.netease.mail.yanxuan.change.dal.entity.ChangeFile;
import com.netease.mail.yanxuan.change.dal.meta.model.req.ChangeFlowFile;
/**
* @Author zcwang
* @Date 2022/11/21
*/
public interface ChangeFileService {
/**
* 获取工单对应的附件
* @param changeRecordId
* @return
*/
List<ChangeFlowFile> getChangeFileList(Long changeRecordId);
void batchSaveRecord(List<ChangeFile> changeFiles);
Integer deleteByChangeRecordId(Long changeRecordId);
void saveRecord(ChangeFile changeFile);
void deleteByChangeRecordIdAndType(Long changeRecordId, FileTypeEnum type);
}
\ No newline at end of file
/**
* @(#)ChangeFlowExecService.java, 2022/11/21.
* <p/>
* Copyright 2022 Netease, Inc. All rights reserved.
* NETEASE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
package com.netease.mail.yanxuan.change.biz.service;
import java.util.List;
import com.netease.mail.yanxuan.change.dal.entity.ChangeExecRecord;
import com.netease.mail.yanxuan.change.dal.meta.model.req.ChangeExecConfigReq;
import com.netease.mail.yanxuan.change.dal.meta.model.vo.ChangeFlowExecVO;
/**
* @Author zcwang
* @Date 2022/11/21
*/
public interface ChangeFlowExecService {
/**
* 查询行动项
* @param changeRecordId
* @return
*/
List<ChangeFlowExecVO> getChangeFlowExecRecord(Long changeRecordId);
/**
* 批量保存变更行动执行记录
* @param changeExecRecordList
*/
void batchSaveRecord(List<ChangeExecRecord> changeExecRecordList);
Boolean update(ChangeExecRecord exec);
Integer deleteByChangeRecordId(Long id);
void saveRecord(ChangeExecRecord exec);
}
\ No newline at end of file
/**
* @(#)ChangeFlowExportQuery.java, 2022/12/8.
* <p/>
* Copyright 2022 Netease, Inc. All rights reserved.
* NETEASE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
package com.netease.mail.yanxuan.change.biz.service;
import com.netease.mail.yanxuan.change.common.enums.CreateSourceEnum;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
/**
* @Author zcwang
* @Date 2022/12/8
*/
@Data
public class ChangeFlowExportQuery {
/**
* 变更商品(变更主体为商品时有效)
*/
private String itemId;
/**
* 变更供应商(变更主体为供应商时有效)
*/
private String supplier;
/**
* 一级变更类型id
*/
private Long parentChangeClassId;
/**
* 二级变更类型id
*/
private Long sonChangeClassId;
/**
* 工单状态
*/
private Integer changeState;
/**
* 变更负责人
*/
private String changeCommander;
/**
* 变更负责部门名
*/
private String changeDepartment;
/**
* 变更行动部门
*/
private String changeExecDepartment;
/**
* 开始时间
*/
private Long startTime;
/**
* 结束时间
*/
private Long endTime;
/**
* 创建端
* @see CreateSourceEnum
*/
private Integer createSource;
/**
* 服务编码 yanxuan-qc-change-flow
*/
protected String serviceCode;
/**
* 登录用户
*/
protected String uid;
private Long limit;
private Long offset;
}
\ No newline at end of file
/**
* @(#)ChangeFlowService.java, 2022/11/14.
* <p/>
* Copyright 2022 Netease, Inc. All rights reserved.
* NETEASE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
package com.netease.mail.yanxuan.change.biz.service;
import java.util.List;
import com.netease.mail.yanxuan.change.biz.config.TitleConfig;
import com.netease.mail.yanxuan.change.dal.entity.ChangeRecord;
/**
* @Author zcwang
* @Date 2022/11/14
*/
public interface ChangeFlowService {
/**
* 获取提示文案
* @return
*/
TitleConfig getTitleConfig();
/**
* 保存工单详情
* @param changeRecord
* @return
*/
Boolean saveRecord(ChangeRecord changeRecord);
/**
* 根据工单id查询
* @param flowId
* @return
*/
ChangeRecord getByFlowId(Long flowId);
/**
* 更新工单信息
* @param changeRecord
* @return
*/
Boolean updateRecord(ChangeRecord changeRecord);
/**
* 根据实例id获取工单详情
* @param id
* @return
*/
ChangeRecord getById(Long id);
/**
* 根据状态及时间获取数据
*
* @param entityId
* @param sendEmail
* @param nodeId1
* @param nodeId2
* @param tomorrowSpecificTime
* @return
*/
List<ChangeRecord> getByStatusAndTime(Long entityId, Integer sendEmail, String nodeId1, String nodeId2, long tomorrowSpecificTime);
}
\ No newline at end of file
/**
* @(#)DESExport.java, 2022/12/8.
* <p/>
* Copyright 2022 Netease, Inc. All rights reserved.
* NETEASE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
package com.netease.mail.yanxuan.change.biz.service;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.alibaba.fastjson.JSON;
import com.netease.mail.dp.des.common.api.enums.DataType;
import com.netease.mail.dp.des.common.api.enums.TaskType;
import com.netease.mail.dp.des.common.api.query.CallbackQueryParam;
import com.netease.mail.dp.des.interaction.api.req.TaskReq;
import com.netease.mail.dp.des.starter.client.DesClient;
import com.netease.mail.yanxuan.change.biz.config.AppConfig;
import com.netease.mail.yanxuan.change.dal.meta.model.req.ChangeFlowRequest;
/**
* @Author zcwang
* @Date 2022/12/8
*/
@Component
@Slf4j
public class DESExportService {
@Autowired
private DesClient desClient;
@Autowired
private AppConfig appConfig;
public String changeFlowExport(ChangeFlowRequest query) {
TaskReq taskReq = new TaskReq();
taskReq.setUserEmail(query.getUid());
taskReq.setProductCode(query.getServiceCode());
taskReq.setFileName("变更管理列表导出");
taskReq.setTaskType(TaskType.BIVARIATE);
taskReq.setDataType(DataType.CALLBACK);
CallbackQueryParam callbackQueryParam = new CallbackQueryParam();
callbackQueryParam.setParamJson(JSON.toJSONString(query));
callbackQueryParam.setCallbackBeanName("changeFlowExportCallback");
callbackQueryParam.setLimit(appConfig.getExportLimit());
taskReq.setCallbackQueryParam(callbackQueryParam);
String desResult = desClient.addTask(taskReq);
log.info("create task result: {}", desResult);
return desResult;
}
}
\ No newline at end of file
package com.netease.mail.yanxuan.change.biz.service;
import com.netease.mail.yanxuan.change.integration.flow.supplier.req.SupplierGoodsInfoReq;
import com.netease.mail.yanxuan.change.integration.todo.SupplierItemPageVO;
public interface ISupplierItemService {
/**
* 查询供应商商品信息
*
* @param supplierGoodsInfoReq
* @param itemId
* @param itemName
* @param page
* @param pageSize
* @return
*/
SupplierItemPageVO supplierGoodsInfoBySupplier(SupplierGoodsInfoReq supplierGoodsInfoReq, String itemId, String itemName, Integer page, Integer pageSize);
}
package com.netease.mail.yanxuan.change.biz.service;
import java.util.List;
import java.util.Map;
import com.netease.mail.yanxuan.change.dal.meta.model.po.ChangeCommanderPO;
import com.netease.mail.yanxuan.change.dal.meta.model.po.ChangeGoodsPrincipalPO;
import com.netease.mail.yanxuan.change.dal.meta.model.po.QueryCommanderEmailReq;
import com.netease.mail.yanxuan.change.dal.meta.model.req.ChangeFlowCreateReq;
import com.netease.mail.yanxuan.change.dal.meta.model.rpc.CommanderResponse;
import com.netease.mail.yanxuan.change.dal.meta.model.rpc.GoodsResponseRpc;
/**
* @author WangJiaXiang
* @date 2022/11/18/018$
* 内部服务接口
*/
public interface InteriorChangeConfigService {
/**
* 根据变更信息 返回住变更负责人
* @param changeCommander
* @return
*/
GoodsResponseRpc queryCommanderInfo(ChangeCommanderPO changeCommander);
/**
* 传入商品列表 返回商品信息
* @param itemIds
* @return
*/
Map<Long, ChangeGoodsPrincipalPO> queryGoodsPrincipalInfo(List<Long> itemIds);
/**
* 查询负责人信息
* @param req
* @return
*/
CommanderResponse queryCommanderEmail(QueryCommanderEmailReq req);
}
package com.netease.mail.yanxuan.change.biz.service.change;
import com.netease.mail.yanxuan.change.common.bean.AjaxResult;
import com.netease.mail.yanxuan.change.dal.meta.model.req.ChangeConfigDeleteReq;
import com.netease.mail.yanxuan.change.dal.meta.model.req.ChangeConfigQueryReq;
import com.netease.mail.yanxuan.change.dal.meta.model.req.ChangeConfigReq;
/**
* @author WangJiaXiang
* @date 2022/11/11/011$
*/
public interface AdminChangeConfigService {
/**
* 查询更改配置类型列表
* @param changeConfigQueryReq 参数
* @return
*/
AjaxResult queryChanges(Integer pageNum,Integer pageSize,ChangeConfigQueryReq changeConfigQueryReq);
/**
* 查询更改配置详情
* @param id 模板id
* @return
*/
AjaxResult queryDetail(Long id,Long sonChangeClassId);
/**
* 新增更改类型配置模板
* @param changeConfigReq
* @param uid
* @param name
* @return
*/
AjaxResult createChange(ChangeConfigReq changeConfigReq, String uid, String name);
/**
* 修改更改类型配置模板
* @param changeConfigReq
* @return
*/
AjaxResult modifyChange(ChangeConfigReq changeConfigReq);
/**
* 删除更改类型配置模板
* @param id
* @return
*/
AjaxResult deleteChange(ChangeConfigDeleteReq id);
/**
* 返回所有配置类型
* @return
*/
AjaxResult queryConfigType();
}
package com.netease.mail.yanxuan.change.biz.service.change;
import com.netease.mail.yanxuan.change.dal.entity.ChangeConfig;
import com.netease.mail.yanxuan.change.dal.meta.model.po.ChangeConfigPo;
/**
* @author WangJiaXiang
* @date 2022/11/11/011$
* 基础服务用来方便内部调用
*/
public interface ChangeConfigService {
ChangeConfig queryChangeConfig(Long id);
ChangeConfig queryChangeConfig(Long id,Long sonChangeClassId);
ChangeConfigPo queryInfoPo(Long parentChangeClassId,Long sonChangeClassId);
ChangeConfig queryChangeType(Long parentChangeClassId,Long sonChangeClassId);
Boolean deleteChangeConfig(Long id);
ChangeConfig addChangeConfig(ChangeConfig changeConfig);
Boolean updateChangeConfig(ChangeConfig changeConfig);
ChangeConfig getSonChange(Long sonChangeId);
}
package com.netease.mail.yanxuan.change.biz.service.change;
import com.netease.mail.yanxuan.change.dal.entity.ChangeExecConfig;
import java.util.List;
/**
* @author WangJiaXiang
* @date 2022/11/11/011$
* 基础服务用来方便内部调用
*/
public interface ChangeExecConfigService {
List<ChangeExecConfig> queryChangeExecConfig(Long changeTemplateId);
List<ChangeExecConfig> addChangeExecConfig(Long id,List<ChangeExecConfig> changeExecConfigs);
List<ChangeExecConfig> updateChangeExecConfig(Long id,List<ChangeExecConfig> changeExecConfigs);
Boolean deleteChangeConfig(Long changeTemplateId);
}
package com.netease.mail.yanxuan.change.biz.service.change;
import com.netease.mail.yanxuan.change.dal.entity.ChangeType;
import com.netease.mail.yanxuan.change.dal.meta.model.po.ChangeTypePo;
import java.util.List;
/**
* @author WangJiaXiang
* @date 2022/11/11/011$
* 基础服务用来方便内部调用
*/
public interface ChangeTypeService {
/**
* 查询变更类型表
* @param id id
* @Param sonChangeClassId 二级ID
* @param deleteTab 是否查伪删除数据
* @return
*/
List<ChangeType> queryChangeType(Long id,Long sonChangeClassId,Boolean deleteTab);
/**
* 添加类型 如果遇到内容一样的情况下不能覆盖直接修改伪删状态 涉及到二级关联信息
* 关系是一对一绑定的所以List里面只会存储两条对象
* @param changeTypes
* @return
*/
List<ChangeType> addChangeType(List<ChangeType> changeTypes);
/**
* 因为牵扯到历史变更查询未保证变更类型的持久性不做真实删除和修改
* 伪善原来的 后新增
* @param changeTypes
* @return
*/
List<ChangeType> updateChangeType(List<ChangeType> changeTypes);
Boolean deleteChangeTypes(List<ChangeType> changeTypes);
/**
* 一级ID 二级ID 是否存在
*/
/**
* 二级目录类型查询出所有一级二级
* @return
*/
List<ChangeTypePo> queryConfigType();
/**
* 根据主键获取类型信息
* @param id
* @return
*/
ChangeType getChangeTypeById(Long id);
}
/**
* @(#)ChangeFileServiceImpl.java, 2022/11/21.
* <p/>
* Copyright 2022 Netease, Inc. All rights reserved.
* NETEASE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
package com.netease.mail.yanxuan.change.biz.service.impl;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import com.netease.mail.yanxuan.change.common.enums.FileTypeEnum;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.netease.mail.yanxuan.change.biz.service.ChangeFileService;
import com.netease.mail.yanxuan.change.dal.entity.ChangeFile;
import com.netease.mail.yanxuan.change.dal.mapper.ChangeFileMapper;
import com.netease.mail.yanxuan.change.dal.meta.model.req.ChangeFlowFile;
/**
* @Author zcwang
* @Date 2022/11/21
*/
@Service
public class ChangeFileServiceImpl implements ChangeFileService {
@Autowired
private ChangeFileMapper changeFileMapper;
@Override
public List<ChangeFlowFile> getChangeFileList(Long changeRecordId) {
List<ChangeFile> changeFiles = changeFileMapper.selectByChangeRecordId(changeRecordId);
if (CollectionUtils.isNotEmpty(changeFiles)) {
return changeFiles.stream().map(c -> ChangeFlowFile.builder().fileType(c.getFileType()).fileName(c.getFileName())
.fileUrl(c.getFileUrl()).build()).collect(Collectors.toList());
}
return new ArrayList<>();
}
@Override
public void batchSaveRecord(List<ChangeFile> changeFiles) {
changeFileMapper.insertList(changeFiles);
}
@Override
public Integer deleteByChangeRecordId(Long changeRecordId) {
return changeFileMapper.deleteByBaseId(changeRecordId);
}
@Override
public void saveRecord(ChangeFile changeFile) {
changeFileMapper.insertSelective(changeFile);
}
@Override
public void deleteByChangeRecordIdAndType(Long changeRecordId, FileTypeEnum type) {
changeFileMapper.deleteByBaseIdAndType(changeRecordId, type.getType());
}
}
\ No newline at end of file
/**
* @(#)ChangeFlowExecServiceImpl.java, 2022/11/21.
* <p/>
* Copyright 2022 Netease, Inc. All rights reserved.
* NETEASE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
package com.netease.mail.yanxuan.change.biz.service.impl;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.netease.mail.yanxuan.change.biz.service.ChangeFlowExecService;
import com.netease.mail.yanxuan.change.dal.entity.ChangeExecRecord;
import com.netease.mail.yanxuan.change.dal.mapper.ChangeExecRecordMapper;
import com.netease.mail.yanxuan.change.dal.meta.model.vo.ChangeFlowExecVO;
/**
* @Author zcwang
* @Date 2022/11/21
*/
@Service
public class ChangeFlowExecServiceImpl implements ChangeFlowExecService {
@Autowired
private ChangeExecRecordMapper changeExecRecordMapper;
@Override
public List<ChangeFlowExecVO> getChangeFlowExecRecord(Long changeRecordId) {
List<ChangeExecRecord> changeExecRecords = changeExecRecordMapper.selectByChangeRecordId(changeRecordId);
if (CollectionUtils.isNotEmpty(changeExecRecords)) {
return changeExecRecords.stream()
.map(c -> ChangeFlowExecVO.builder().changeExecId(c.getId()).changeRecordId(c.getChangeRecordId())
.changeExecDepartment(c.getChangeExecDepartment()).changeExecUserType(c.getChangeExecUserType())
.changeExecUser(c.getChangeExecUser()).changeExecUserEmail(c.getChangeExecUserEmail())
.changeRiskDesc(c.getChangeRiskDesc()).changeExecProject(c.getChangeExecProject())
.changeChecking(c.getChangeChecking()).changeExecFinishTime(c.getChangeExecFinishTime())
.changeExecFinishDesc(c.getChangeExecFinishDesc()).build())
.collect(Collectors.toList());
}
return new ArrayList<>();
}
@Override
public void batchSaveRecord(List<ChangeExecRecord> changeExecRecordList) {
changeExecRecordMapper.insertList(changeExecRecordList);
}
@Override
public Boolean update(ChangeExecRecord changeExecRecord) {
return changeExecRecordMapper.updateByPrimaryKeySelective(changeExecRecord) > 0;
}
@Override
public Integer deleteByChangeRecordId(Long changeRecordId) {
return changeExecRecordMapper.deleteByBaseId(changeRecordId);
}
@Override
public void saveRecord(ChangeExecRecord exec) {
changeExecRecordMapper.insertSelective(exec);
}
}
\ No newline at end of file
/**
* @(#)ChangeFlowServiceImpl.java, 2022/11/14.
* <p/>
* Copyright 2022 Netease, Inc. All rights reserved.
* NETEASE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
package com.netease.mail.yanxuan.change.biz.service.impl;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.netease.mail.yanxuan.change.biz.config.AppConfig;
import com.netease.mail.yanxuan.change.biz.config.TitleConfig;
import com.netease.mail.yanxuan.change.biz.service.ChangeFlowService;
import com.netease.mail.yanxuan.change.dal.entity.ChangeRecord;
import com.netease.mail.yanxuan.change.dal.mapper.ChangeRecordMapper;
/**
* @Author zcwang
* @Date 2022/11/14
*/
@Service
public class ChangeFlowServiceImpl implements ChangeFlowService {
@Autowired
private ChangeRecordMapper changeRecordMapper;
@Autowired
private AppConfig appConfig;
@Override
public TitleConfig getTitleConfig() {
return appConfig.getTitleConfig();
}
@Override
public Boolean saveRecord(ChangeRecord changeRecord) {
return changeRecordMapper.insertSelective(changeRecord) > 0;
}
@Override
public ChangeRecord getByFlowId(Long flowId) {
return changeRecordMapper.selectByFlowId(flowId);
}
@Override
public Boolean updateRecord(ChangeRecord changeRecord) {
return changeRecordMapper.updateByPrimaryKeySelective(changeRecord) > 0;
}
@Override
public ChangeRecord getById(Long id) {
return changeRecordMapper.selectByPrimaryKey(id);
}
@Override
public List<ChangeRecord> getByStatusAndTime(Long entityId, Integer sendEmail, String nodeId1, String nodeId2, long tomorrowSpecificTime) {
return changeRecordMapper.getByStatusAndTime(entityId, sendEmail, nodeId1, nodeId2, tomorrowSpecificTime);
}
}
\ No newline at end of file
package com.netease.mail.yanxuan.change.biz.service.impl;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.netease.mail.yanxuan.change.biz.config.AppConfig;
import com.netease.mail.yanxuan.change.biz.meta.exception.ExceptionFactory;
import com.netease.mail.yanxuan.change.biz.service.InteriorChangeConfigService;
import com.netease.mail.yanxuan.change.biz.service.change.ChangeConfigService;
import com.netease.mail.yanxuan.change.common.bean.ResponseCode;
import com.netease.mail.yanxuan.change.common.enums.ChangeCommanderEnum;
import com.netease.mail.yanxuan.change.common.enums.ChangePrincipalEnum;
import com.netease.mail.yanxuan.change.common.enums.ChangeSubjectEnum;
import com.netease.mail.yanxuan.change.common.enums.CreateSourceEnum;
import com.netease.mail.yanxuan.change.common.enums.SupplierChangePrincipalEnum;
import com.netease.mail.yanxuan.change.dal.entity.ChangeConfig;
import com.netease.mail.yanxuan.change.dal.meta.model.po.ChangeCommanderPO;
import com.netease.mail.yanxuan.change.dal.meta.model.po.ChangeGoodsPrincipalPO;
import com.netease.mail.yanxuan.change.dal.meta.model.po.QueryCommanderEmailReq;
import com.netease.mail.yanxuan.change.dal.meta.model.rpc.CommanderResponse;
import com.netease.mail.yanxuan.change.dal.meta.model.rpc.GoodsPurchaseRpc;
import com.netease.mail.yanxuan.change.dal.meta.model.rpc.GoodsResponseRpc;
import com.netease.mail.yanxuan.change.dal.meta.model.rpc.GoodsResponseSqeRpc;
import com.netease.mail.yanxuan.change.dal.meta.model.vo.ItemVO;
import com.netease.mail.yanxuan.change.integration.flow.goods.ItemcenterApiRpcService;
import com.netease.mail.yanxuan.change.integration.flow.goods.PfuApiRpcService;
import com.netease.mail.yanxuan.change.integration.flow.goods.QcApiRpcService;
import com.netease.mail.yanxuan.change.integration.flow.supplier.FlowRpcSupplierInfoService;
import com.netease.mail.yanxuan.change.integration.flow.supplier.FlowRpcSupplierSendService;
import com.netease.mail.yanxuan.change.integration.flow.supplier.req.SupplierRelatedUserReq;
import com.netease.mail.yanxuan.change.integration.flow.supplier.rsp.SupplierUserRsp;
import lombok.extern.slf4j.Slf4j;
/**
* @author WangJiaXiang
* @date 2022/11/18/018$
*/
@Slf4j
@Service
public class InteriorChangeConfigServiceImpl implements InteriorChangeConfigService {
private static final Logger logger = LoggerFactory.getLogger(InteriorChangeConfigServiceImpl.class);
@Autowired
private ChangeConfigService changeConfigService;
//查询商品的SQE
@Autowired
private QcApiRpcService qcApiRpcService;
//查看执行人
@Autowired
private PfuApiRpcService pfuApiRpcService;
//查看商品BU
@Autowired
private ItemcenterApiRpcService itemcenterApiRpcService;
@Autowired
private FlowRpcSupplierSendService supplierSendService;
@Autowired
private AppConfig appConfig;
/**
* 项目上线后接口需要修改未线上环境
*/
@Autowired
private FlowRpcSupplierInfoService supplierInfoService;
/**
* 接口不完整,关于商品的查询已经完成 供应商查询不完整接口已对接 具体返回值接口测试未完成
*
* @param changeCommander
* @return
*/
@Override
public GoodsResponseRpc queryCommanderInfo(ChangeCommanderPO changeCommander) {
GoodsResponseRpc rpc = new GoodsResponseRpc();
//获取模板名称 通过一级变更类型 二级变更类型ID 定位模板
ChangeConfig changeConfig = changeConfigService.queryChangeType(changeCommander.getParentChangeClassId(),
changeCommander.getSonChangeClassId());
if (changeConfig == null) {
return null;
}
//查询出当前模板配置中选择的 角色
ChangeCommanderEnum changeCommanderEnum = ChangeCommanderEnum.getChangeCommanderEnum(changeConfig.getChangeCommanderType());
if (changeCommanderEnum == null) {
return null;
}
//直接排除 选项为固定人 或者发起人
if (Objects.equals(changeConfig.getChangeCommanderType(), ChangeCommanderEnum.COMMANDER_ORIGINATOR.getId())) {
//发起人;
// 如果是同舟端,发起人以商品开发兜底
if (changeCommander.getCreateSource().equals(CreateSourceEnum.TONG_ZHOU.getType())) {
return queryChangeSupplier(ChangeCommanderEnum.SUPPLIERS_ASSOCIATED, changeCommander.getSupplier(),
SupplierChangePrincipalEnum.GOODS_BU.getName());
}
rpc.setEmail(changeCommander.getFlowCreator());
return rpc;
}
if (Objects.equals(changeConfig.getChangeCommanderType(), ChangeCommanderEnum.FIXED_PERSON.getId())) {
//固定人;
rpc.setEmail(changeConfig.getChangeCommander());
return rpc;
}
if (Objects.equals(ChangeSubjectEnum.PRODUCT.getType(), changeConfig.getChangeSubject())) {
//商品变更
return queryGoodsCommander(changeCommanderEnum, changeCommander.getGoodsInfos(), changeConfig.getChangeCommander());
} else if (Objects.equals(ChangeSubjectEnum.SUPPLIER.getType(), changeConfig.getChangeSubject())) {
//供应商 采购 计划 SQE
return queryChangeSupplier(changeCommanderEnum, changeCommander.getChangeSupplierId(), changeConfig.getChangeCommander());
}
//其他变更 备注 其他变更之后固定人 和发起人在上面判断会被排除掉 changeConfig.getChangeCommander();
return null;
}
/**
* 商品的最终角色查询
*
* @param commanderEnum 查询方向 枚举
* @param goodsInfos 商品的列表
* @param commander 商品的关联角色 ChangeCommanderEnum
* @return
*/
private GoodsResponseRpc queryGoodsCommander(ChangeCommanderEnum commanderEnum, List<Long> goodsInfos, String commander) {
if (!commanderEnum.getId().equals(ChangeCommanderEnum.GOODS_ASSOCIATED.getId())
|| CollectionUtils.isEmpty(goodsInfos) || commander == null) {
return null;
}
Map<String, GoodsResponseRpc> map = new HashMap<String, GoodsResponseRpc>();
//记录最大出现次数
int temp = 0;
//记录最大值
GoodsResponseRpc name = new GoodsResponseRpc();
//记录出现的所有值
List<GoodsResponseRpc> emails = new ArrayList<GoodsResponseRpc>();
//遍历取出所有商品关联的人
if (ChangePrincipalEnum.GOODS_BU.getName().equals(commander)) {
String detail = itemcenterApiRpcService.getDetail(goodsInfos);
logger.error("根据商品查看商品负责BU接口返回值\t" + detail);
getGoodsNameEmail(emails, detail);
} else if (ChangePrincipalEnum.PURCHASE.getName().equals(commander)) {
//采购返回值处理逻辑
String detail = supplierSendService.queryGoodsPurchase(goodsInfos);
logger.error("根据商品查看商品负责采购接口返回值\t" + detail);
JSONObject jsonObject = JSONObject.parseObject(detail);
List<GoodsPurchaseRpc> purchaseRpcs = JSONObject.parseArray(jsonObject.get("data").toString(), GoodsPurchaseRpc.class);
for (GoodsPurchaseRpc purchaseRpc : purchaseRpcs) {
GoodsResponseRpc goodsRpc = new GoodsResponseRpc();
goodsRpc.setEmail(purchaseRpc.getSupplierTraceBusiness());
goodsRpc.setName(purchaseRpc.getSupplierName());
emails.add(goodsRpc);
}
} else if (ChangePrincipalEnum.PROSPECTUS.getName().equals(commander)) {
String detail = pfuApiRpcService.getDetail(goodsInfos);
logger.error("根据商品查看商品负责计划接口返回值\t" + detail);
getGoodsNameEmail(emails, detail);
} else if (ChangePrincipalEnum.SQE.getName().equals(commander)) {
for (Long goods : goodsInfos) {
String detail = qcApiRpcService.getDetail(goods.intValue());
logger.error("根据商品查看商品负责SQE接口返回值\t" + detail);
JSONObject jsonObject = JSONObject.parseObject(detail);
GoodsResponseSqeRpc data = jsonObject.getObject("data", GoodsResponseSqeRpc.class);
if (data != null) {
//需要验证返回值 是否正确
GoodsResponseRpc rpc = new GoodsResponseRpc();
rpc.setEmail(data.getUserName());
rpc.setName(data.getRealName());
emails.add(rpc);
}
}
}
//逻辑发生变更
for (GoodsResponseRpc email : emails) {
if (!map.containsKey(email.getName())) {
email.setOccurrenceNumber(1);
} else {
GoodsResponseRpc goodsResponseRpc = map.get(email.getName());
email.setOccurrenceNumber(goodsResponseRpc.getOccurrenceNumber() + 1);
if (temp < goodsResponseRpc.getOccurrenceNumber()) {
temp = goodsResponseRpc.getOccurrenceNumber();
name = goodsResponseRpc;
}
}
map.put(email.getName(), email);
}
if (name.getName() == null) {
Iterator<GoodsResponseRpc> iterator = map.values().iterator();
name = iterator.next();
}
return name;
}
/**
* 供应商角色最终查询
*
* @param commanderEnum 查询方向 枚举
* @param changeSupplierId 供应商信息
* @param commander 供应商关联角色
* @return
*/
private GoodsResponseRpc queryChangeSupplier(ChangeCommanderEnum commanderEnum, String changeSupplierId, String commander) {
GoodsResponseRpc rpc = new GoodsResponseRpc();
if (!commanderEnum.getId().equals(ChangeCommanderEnum.SUPPLIERS_ASSOCIATED.getId()) || changeSupplierId == null || commander == null) {
return null;
}
SupplierRelatedUserReq req = new SupplierRelatedUserReq();
List<String> supplierIdList = new ArrayList<>();
supplierIdList.add(changeSupplierId);
//changeSupplier 根据提供的信息去查询 最终返回
if (SupplierChangePrincipalEnum.PURCHASE.getName().equals(commander)) {
req.setSearchType(SupplierChangePrincipalEnum.PURCHASE.getType());
} else if (SupplierChangePrincipalEnum.PROSPECTUS.getName().equals(commander)) {
req.setSearchType(SupplierChangePrincipalEnum.PROSPECTUS.getType());
} else if (SupplierChangePrincipalEnum.SQE.getName().equals(commander)) {
req.setSearchType(SupplierChangePrincipalEnum.SQE.getType());
} else if (SupplierChangePrincipalEnum.GOODS_BU.getName().equals(commander)) {
req.setSearchType(SupplierChangePrincipalEnum.GOODS_BU.getType());
} else {
throw ExceptionFactory.createBiz(ResponseCode.BAD_REQUEST, "供应商角色类型错误");
}
req.setSupplierIdList(supplierIdList);
//进行参数解析
List<SupplierUserRsp> listAjaxResponse = supplierInfoService.querySupplierRelatedUser(req);
if (CollectionUtils.isEmpty(listAjaxResponse)) {
return null;
}
SupplierUserRsp supplierUserRsp = listAjaxResponse.get(0);
Map<String, String> uid2NameMap = supplierUserRsp.getUid2NameMap();
for (String key : uid2NameMap.keySet()) {
rpc.setName(uid2NameMap.get(key));
rpc.setEmail(key);
}
return rpc;
}
/**
* 重复代码复用方法
*
* @param emails 储存邮箱队列
* @param response 请求返结果
*/
private void getGoodsNameEmail(List<GoodsResponseRpc> emails, String response) {
JSONObject jsonObject = JSONObject.parseObject(response);
Map<String, JSONObject> rpcMap = JSONObject.parseObject(jsonObject.get("data").toString(), Map.class);
if (rpcMap == null) {
throw ExceptionFactory.createBiz(ResponseCode.OPERATOR_NOT_EXIST);
}
for (String rpc : rpcMap.keySet()) {
GoodsResponseRpc goodsRpc = new GoodsResponseRpc();
goodsRpc.setEmail(rpcMap.get(rpc).get("uid").toString());
goodsRpc.setName(rpcMap.get(rpc).get("name").toString());
emails.add(goodsRpc);
}
}
@Override
public Map<Long, ChangeGoodsPrincipalPO> queryGoodsPrincipalInfo(List<Long> itemIds) {
Map<Long, ChangeGoodsPrincipalPO> map = new HashMap<>();
for (Long itemId : itemIds) {
map.put(itemId, new ChangeGoodsPrincipalPO());
}
//商品BU
String functionary = itemcenterApiRpcService.getDetail(itemIds);
logger.error("请求商品BU结果" + functionary);
getGoodsPrincipalNameEmail(ChangePrincipalEnum.GOODS_BU.getType(), map, functionary);
//计划
String project = pfuApiRpcService.getDetail(itemIds);
logger.error("请求商品计划结果" + project);
getGoodsPrincipalNameEmail(ChangePrincipalEnum.PURCHASE.getType(), map, project);
//商品采购
String GoodsPurchase = supplierSendService.queryGoodsPurchase(itemIds);
JSONObject jsonObject = JSONObject.parseObject(GoodsPurchase);
List<GoodsPurchaseRpc> purchaseRpcs = JSONObject.parseArray(jsonObject.get("data").toString(), GoodsPurchaseRpc.class);
for (GoodsPurchaseRpc rpc : purchaseRpcs) {
map.get(rpc.getItemId().longValue()).setPurchaseName(rpc.getSupplierName());
map.get(rpc.getItemId().longValue()).setPurchaseEmail(rpc.getSupplierTraceBusiness());
goodsRpc(ChangePrincipalEnum.PURCHASE.getType(), rpc.getSupplierName(), map.get(rpc.getItemId().longValue()));
}
//SQE
for (Long itemId : itemIds) {
String sqe = qcApiRpcService.getDetail(itemId.intValue());
logger.error("根据商品查看商品负责SQE接口返回值\t" + sqe);
JSONObject jsonObject1 = JSONObject.parseObject(sqe);
GoodsResponseSqeRpc data = jsonObject1.getObject("data", GoodsResponseSqeRpc.class);
if (data != null) {
//需要验证返回值 是否正确
map.get(itemId).setGoodsSqeName(data.getRealName());
map.get(itemId).setGoodsSqeEmail(data.getUserName());
goodsRpc(ChangePrincipalEnum.SQE.getType(), data.getRealName(), map.get(itemId));
}
}
return map;
}
@Override
public CommanderResponse queryCommanderEmail(QueryCommanderEmailReq req) {
Integer changeExecUserType = req.getChangeExecUserType();
String changeExecUser = req.getChangeExecUser();
ChangeCommanderEnum changeCommanderEnum = ChangeCommanderEnum.getChangeCommanderEnum(changeExecUserType);
log.debug("[queryCommanderEmail] req:{},changeCommanderEnum:{}", JSON.toJSONString(req), changeCommanderEnum);
Assert.notNull(changeCommanderEnum, "变更负责人类型错误");
CommanderResponse commanderResponse = new CommanderResponse();
switch (changeCommanderEnum) {
case COMMANDER_ORIGINATOR:
// 如果是同舟端,发起人以商品开发兜底
if (req.getCreateSource().equals(CreateSourceEnum.TONG_ZHOU.getType())) {
try {
GoodsResponseRpc goodsResponseRpc = queryChangeSupplier(
ChangeCommanderEnum.SUPPLIERS_ASSOCIATED, req.getChangeSupplier(),
SupplierChangePrincipalEnum.GOODS_BU.getName());
commanderResponse.setName(goodsResponseRpc.getName());
commanderResponse.setEmail(goodsResponseRpc.getEmail());
} catch (Exception e) {
log.error("[queryCommanderEmail] goodsResponseRpc error,e{}", e);
}
return commanderResponse;
}else {
return null;
}
case FIXED_PERSON:
return null;
case GOODS_ASSOCIATED:
String changeItems = req.getChangeItems();
Assert.isTrue(StringUtils.isNotBlank(changeItems), "变更负责人为商品时,商品列表不可为空");
List<ItemVO> itemVOS = JSON.parseArray(changeItems, ItemVO.class);
List<Long> itemIdList = itemVOS.stream().map(ItemVO::getItemId).collect(Collectors.toList());
try {
GoodsResponseRpc goodsResponseRpc = queryGoodsCommander(changeCommanderEnum, itemIdList, changeExecUser);
log.debug("[queryCommanderEmail] queryGoodsCommander:{}", JSON.toJSONString(goodsResponseRpc));
commanderResponse.setName(goodsResponseRpc.getName());
commanderResponse.setEmail(goodsResponseRpc.getEmail());
} catch (Exception e) {
log.error("[queryGoodsCommander] error,e{}", e);
commanderResponse.setEmail(appConfig.getDefaultEmail());
}
return commanderResponse;
case SUPPLIERS_ASSOCIATED:
String changeSupplier = req.getChangeSupplier();
Assert.isTrue(StringUtils.isNotBlank(changeSupplier), "变更负责人为供应商时,供应商不可为空");
try {
GoodsResponseRpc supplierResponseRpc = queryChangeSupplier(changeCommanderEnum,
changeSupplier, changeExecUser);
log.debug("[queryCommanderEmail] queryChangeSupplier:{}", JSON.toJSONString(supplierResponseRpc));
commanderResponse.setName(supplierResponseRpc.getName());
commanderResponse.setEmail(supplierResponseRpc.getEmail());
} catch (Exception e) {
log.error("[queryChangeSupplier] error,e{}", e);
}
return commanderResponse;
default:
throw ExceptionFactory.createBiz(ResponseCode.COMMANDER_TYPE_NOT_EXIST, "变更负责人类型错误");
}
}
/**
* 请求数据解析以及装载
*
* @param type 1:BU 2:计划
* @param map
* @param response
*/
private void getGoodsPrincipalNameEmail(Integer type, Map<Long, ChangeGoodsPrincipalPO> map, String response) {
JSONObject jsonObject = JSONObject.parseObject(response);
Map<String, JSONObject> rpcMap = JSONObject.parseObject(jsonObject.get("data").toString(), Map.class);
if (rpcMap == null) {
throw ExceptionFactory.createBiz(ResponseCode.OPERATOR_NOT_EXIST);
}
for (String rpc : rpcMap.keySet()) {
ChangeGoodsPrincipalPO goodsRpc = map.get(Long.parseLong(rpc));
if (type.equals(ChangePrincipalEnum.GOODS_BU.getType())) {
goodsRpc.setFunctionaryName(rpcMap.get(rpc).get("name").toString());
goodsRpc.setFunctionaryEmail(rpcMap.get(rpc).get("uid").toString());
goodsRpc(ChangePrincipalEnum.GOODS_BU.getType(), rpcMap.get(rpc).get("uid").toString(), goodsRpc);
} else {
goodsRpc.setGoodsProjectName(rpcMap.get(rpc).get("name").toString());
goodsRpc.setGoodsProjectEmail(rpcMap.get(rpc).get("uid").toString());
goodsRpc(ChangePrincipalEnum.PROSPECTUS.getType(), rpcMap.get(rpc).get("uid").toString(), goodsRpc);
}
}
}
/**
* 负责人兜底方法
*
* @param type
* @param uid
* @param goodsRpc
*/
private void goodsRpc(Integer type, String uid, ChangeGoodsPrincipalPO goodsRpc) {
// todo:mock数据
String defaultName = appConfig.getDefaultName();
String defaultEmail = appConfig.getDefaultEmail();
if (uid == null) {
switch (type) {
case 1:
//BU
goodsRpc.setFunctionaryName(defaultName);
goodsRpc.setFunctionaryEmail(defaultEmail);
case 2:
//采购
goodsRpc.setPurchaseName(defaultName);
goodsRpc.setPurchaseEmail(defaultEmail);
case 3:
//计划
goodsRpc.setGoodsProjectName(defaultName);
goodsRpc.setGoodsProjectName(defaultEmail);
case 4:
//SQE
goodsRpc.setGoodsSqeName(defaultName);
goodsRpc.setGoodsSqeEmail(defaultEmail);
}
}
}
}
package com.netease.mail.yanxuan.change.biz.service.impl;
import com.netease.mail.yanxuan.change.biz.service.ISupplierItemService;
import com.netease.mail.yanxuan.change.common.bean.AjaxResult;
import com.netease.mail.yanxuan.change.integration.flow.supplier.FlowRpcSupplierSendService;
import com.netease.mail.yanxuan.change.integration.flow.supplier.req.SupplierGoodsInfoReq;
import com.netease.mail.yanxuan.change.integration.flow.supplier.rsp.SupplierGoodsInfoRsp;
import com.netease.mail.yanxuan.change.integration.item.ItemRpcService;
import com.netease.mail.yanxuan.change.integration.item.meta.SpuTO;
import com.netease.mail.yanxuan.change.integration.item.param.BatchQuerySpuInfoParam;
import com.netease.mail.yanxuan.change.integration.todo.PageVO;
import com.netease.mail.yanxuan.change.integration.todo.SupplierItemPageVO;
import com.netease.mail.yanxuan.change.integration.todo.SupplierItemVO;
import com.netease.yanxuan.flowx.sdk.meta.controller.communal.AjaxResponse;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
@Service
public class SupplierItemServiceImpl implements ISupplierItemService {
@Autowired
private FlowRpcSupplierSendService flowRpcSupplierSendService;
@Autowired
private ItemRpcService itemRpcService;
@Override
public SupplierItemPageVO supplierGoodsInfoBySupplier(SupplierGoodsInfoReq supplierGoodsInfoReq, String itemId, String itemName, Integer page, Integer pageSize) {
AjaxResponse<List<SupplierGoodsInfoRsp>> listAjaxResponse = flowRpcSupplierSendService.supplierGoodsInfoBySupplier(supplierGoodsInfoReq);
List<SupplierGoodsInfoRsp> data = listAjaxResponse.getData();
List<SpuTO> spuTOList = new ArrayList<>();
if (data != null) {
Set<Long> fullItemIds = data.stream().map(SupplierGoodsInfoRsp::getItemId).collect(Collectors.toSet());
while (fullItemIds.size() > 200) {
List<Long> itemIds = new ArrayList<>(fullItemIds).subList(0, 200);
AjaxResult<List<SpuTO>> listAjaxResult = itemRpcService.batchQuerySpuInfo(BatchQuerySpuInfoParam.builder().ids(itemIds).build());
List<SpuTO> pageSpuTo = listAjaxResult.getData();
if (!CollectionUtils.isEmpty(pageSpuTo)) {
spuTOList.addAll(pageSpuTo);
}
fullItemIds.removeAll(itemIds);
}
}
if (StringUtils.isNotBlank(itemId)) {
spuTOList = spuTOList.stream().filter(i -> Long.valueOf(itemId).equals(i.getId())).collect(Collectors.toList());
}
if (StringUtils.isNotBlank(itemName)) {
spuTOList = spuTOList.stream().filter(i -> i.getName().contains(itemName)).collect(Collectors.toList());
}
PageVO pageVO = buildPageVo(spuTOList.size(), page, pageSize);
Integer endIndex = page * pageSize;
if (page * pageSize > spuTOList.size()) {
endIndex = spuTOList.size();
}
List<SpuTO> pageItem = spuTOList.subList((page - 1) * pageSize, endIndex);
List<SupplierItemVO> supplierItemVOList = pageItem.stream().map(i -> {
SupplierItemVO supplierItemVO = new SupplierItemVO();
supplierItemVO.setItemId(i.getId());
supplierItemVO.setItemName(i.getName());
return supplierItemVO;
}).collect(Collectors.toList());
return SupplierItemPageVO.builder().pageVo(pageVO).supplierItemVOList(supplierItemVOList).build();
}
private PageVO buildPageVo(int size, Integer page, Integer pageSize) {
int totalPage = size % pageSize == 0 ? size / pageSize : size / pageSize + 1;
return PageVO.builder().page(page).pageSize(pageSize).totalCount(size).totalPage(totalPage).build();
}
}
package com.netease.mail.yanxuan.change.biz.service.impl.change;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.common.base.Joiner;
import com.netease.mail.yanxuan.change.biz.meta.exception.ExceptionFactory;
import com.netease.mail.yanxuan.change.biz.service.change.AdminChangeConfigService;
import com.netease.mail.yanxuan.change.biz.service.change.ChangeConfigService;
import com.netease.mail.yanxuan.change.biz.service.change.ChangeExecConfigService;
import com.netease.mail.yanxuan.change.biz.service.change.ChangeTypeService;
import com.netease.mail.yanxuan.change.common.bean.AjaxResult;
import com.netease.mail.yanxuan.change.common.bean.RequestLocalBean;
import com.netease.mail.yanxuan.change.common.bean.ResponseCode;
import com.netease.mail.yanxuan.change.common.bean.ResponseCodeEnum;
import com.netease.mail.yanxuan.change.common.enums.ChangeCommanderEnum;
import com.netease.mail.yanxuan.change.common.enums.ChangeSubjectEnum;
import com.netease.mail.yanxuan.change.dal.entity.ChangeConfig;
import com.netease.mail.yanxuan.change.dal.entity.ChangeExecConfig;
import com.netease.mail.yanxuan.change.dal.entity.ChangeType;
import com.netease.mail.yanxuan.change.dal.mapper.ChangeConfigMapper;
import com.netease.mail.yanxuan.change.dal.meta.model.dto.ChangeExecConfigDTO;
import com.netease.mail.yanxuan.change.dal.meta.model.po.ChangeConfigPo;
import com.netease.mail.yanxuan.change.dal.meta.model.req.ChangeConfigDeleteReq;
import com.netease.mail.yanxuan.change.dal.meta.model.req.ChangeConfigQueryReq;
import com.netease.mail.yanxuan.change.dal.meta.model.req.ChangeConfigReq;
import com.netease.mail.yanxuan.change.dal.meta.model.vo.ChangeConfigArrayVO;
import com.netease.mail.yanxuan.change.dal.meta.model.vo.ChangeConfigVO;
import com.netease.mail.yanxuan.change.dal.meta.model.vo.PageVO;
import com.netease.mail.yanxuan.change.integration.flow.UserQueryDTO;
import com.netease.mail.yanxuan.change.integration.flow.ius.IusRpcService;
import com.netease.mail.yanxuan.change.integration.flow.ius.rsp.IusUserInfoRsp;
import com.netease.yanxuan.flowx.sdk.meta.controller.communal.AjaxResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
/**
* @author WangJiaXiang
* @date 2022/11/11/011$
*/
@Service
public class AdminChangeConfigServiceImpl implements AdminChangeConfigService {
private static final String CHANGE_CONFIG = "changeConfig:";
@Autowired
public ChangeConfigMapper mapper;
Logger logger = LoggerFactory.getLogger(AdminChangeConfigServiceImpl.class);
@Autowired
private ChangeTypeService typeService;
@Autowired
private ChangeConfigService changeConfigService;
@Autowired
private ChangeExecConfigService execConfigService;
@Autowired
private StringRedisTemplate redisTemplate;
@Autowired
private IusRpcService iusRpcService;
private ValueOperations<String, String> value;
@Override
public AjaxResult queryChanges(Integer pageNum, Integer pageSize, ChangeConfigQueryReq req) {
ChangeConfigArrayVO vo = new ChangeConfigArrayVO();
//进行分页
PageHelper.startPage(pageNum, pageSize);
List<ChangeConfigPo> changeConfigPos = mapper.selectChangeConfigPo(req);
PageInfo<ChangeConfigPo> pageInfo = new PageInfo<>(changeConfigPos);
Long total = pageInfo.getTotal();
PageVO pageVO = buildPageVo(total.intValue(), pageSize, pageNum);
List<ChangeConfigPo> changeConfig = pageInfo.getList();
changeConfig.forEach(i -> {
String replaceDep = i.getParticipateChangeExecDepartment().replace("[", "").replace("]", "").replace(" ", "");
Set<String> finialDep = Arrays.stream(replaceDep.split(",")).collect(Collectors.toSet());
i.setParticipateChangeExecDepartment(Joiner.on(",").join(finialDep));
});
vo.setChangeConfigs(changeConfig);
vo.setPageVo(pageVO);
return AjaxResult.success(vo);
}
@Override
public AjaxResult queryDetail(Long id, Long sonChangeClassId) {
String changeConfigVO;
//尝试从reids里面 获取 如果获取到了直接返回
if (id != null) {
changeConfigVO = getValue().get(id.toString());
if (changeConfigVO != null) {
return AjaxResult.success(JSONObject.parseObject(changeConfigVO, ChangeConfigVO.class));
}
}
//从数据库中取出数据
ChangeConfig changeConfig = changeConfigService.queryChangeConfig(id, sonChangeClassId);
if (changeConfig == null) {
return AjaxResult.of(ResponseCodeEnum.NO_FOUND);
}
List<ChangeType> changeTypes = typeService.queryChangeType(changeConfig.getParentChangeClassId(), changeConfig.getSonChangeClassId(), true);
if (changeTypes == null || changeTypes.size() != 2) {
return AjaxResult.of(ResponseCodeEnum.NO_FOUND);
}
List<ChangeExecConfig> changeExecConfigs = execConfigService.queryChangeExecConfig(changeConfig.getId());
if (changeExecConfigs == null || changeExecConfigs.size() == 0) {
return AjaxResult.of(ResponseCodeEnum.NO_FOUND);
}
//组装数据
changeConfigVO = getChangeConfigVO(changeConfig, changeTypes, changeExecConfigs);
//如果没有查询后返回redis
getValue().set(CHANGE_CONFIG + id, changeConfigVO, 1, TimeUnit.DAYS);
return AjaxResult.success(JSON.parseObject(changeConfigVO, ChangeConfigVO.class));
}
@Override
@Transactional
public AjaxResult createChange(ChangeConfigReq changeConfigReq, String uid, String name) {
logger.info("查看入参值" + changeConfigReq.toString());
//添加一级二级类目
List<ChangeType> changeTypes = typeService.addChangeType(changeConfigReq.getChangeTypes());
ChangeConfig changeConfig = parameterSplicing(changeTypes, changeConfigReq);
changeConfig.setCreateTime(System.currentTimeMillis());
changeConfig.setCreator(name + " " + uid);
changeConfig = changeConfigService.addChangeConfig(changeConfig);
List<ChangeExecConfig> changeExecConfigs = execConfigService.addChangeExecConfig(changeConfig.getId(), changeConfigReq.getChangeExeConfig());
//参数拼装
String changeConfigVO = getChangeConfigVO(changeConfig, changeTypes, changeExecConfigs);
//新增后添加到redis
getValue().set(CHANGE_CONFIG + changeConfig.getId(), changeConfigVO, 1, TimeUnit.DAYS);
return AjaxResult.success();
}
@Override
@Transactional
public AjaxResult modifyChange(ChangeConfigReq changeConfigReq) {
if (changeConfigReq.getId() == null) {
return AjaxResult.of(9001, "修改变更模板主键id不能为空");
}
//先查询注入ID后在修改
ChangeConfig config = changeConfigService.queryChangeConfig(changeConfigReq.getId());
if (config == null) {
return AjaxResult.of(9001, "未找到变更类型配置");
}
changeConfigReq.getChangeTypes().get(0).setId(config.getParentChangeClassId());
changeConfigReq.getChangeTypes().get(1).setId(config.getSonChangeClassId());
//新增类似
List<ChangeType> changeTypes = typeService.updateChangeType(changeConfigReq.getChangeTypes());
ChangeConfig changeConfig = parameterSplicing(changeTypes, changeConfigReq);
changeConfigService.updateChangeConfig(changeConfig);
//修改
List<ChangeExecConfig> changeExecConfigs = execConfigService.updateChangeExecConfig(changeConfigReq.getId(), changeConfigReq.getChangeExeConfig());
//装在reids
String changeConfigVO = getChangeConfigVO(changeConfig, changeTypes, changeExecConfigs);
getValue().set(CHANGE_CONFIG + changeConfig.getId(), changeConfigVO, 1, TimeUnit.DAYS);
//修改后更新redis
return AjaxResult.success();
}
@Override
@Transactional
public AjaxResult deleteChange(ChangeConfigDeleteReq id) {
if (id == null && id.getId() == null) {
return AjaxResult.of(ResponseCodeEnum.PARAM_ERROR);
}
ChangeConfig changeConfig = changeConfigService.queryChangeConfig(id.getId());
if (changeConfig == null) {
return AjaxResult.of(ResponseCodeEnum.NO_FOUND);
}
changeConfigService.deleteChangeConfig(id.getId());
List<ChangeType> changeTypes = typeService.queryChangeType(changeConfig.getParentChangeClassId(), changeConfig.getSonChangeClassId(), true);
typeService.deleteChangeTypes(changeTypes);
execConfigService.deleteChangeConfig(id.getId());
// 缓存内删除
redisTemplate.delete(CHANGE_CONFIG + id.getId());
return AjaxResult.success();
}
/**
* 二级目录类型查询出所有一级二级
*
* @return
*/
@Override
public AjaxResult queryConfigType() {
return AjaxResult.success(typeService.queryConfigType());
}
/**
* 添加变更模板并参数拼接
*
* @param changeTypes
* @param changeConfigReq
* @return
*/
private ChangeConfig parameterSplicing(List<ChangeType> changeTypes, ChangeConfigReq changeConfigReq) {
ChangeConfig changeConfig = new ChangeConfig();
changeConfig.setParentChangeClassId(changeTypes.get(0).getId());
changeConfig.setSonChangeClassId(changeTypes.get(1).getId());
if (changeConfigReq.getId() != null) {
changeConfig.setId(changeConfigReq.getId());
}
if (changeConfigReq.getChangeSubject() == null) {
throw ExceptionFactory.createBiz(ResponseCode.PARAMETER_DEFICIENCY);
}
//验证变更主体
ChangeSubjectEnum containsChangeSubject = ChangeSubjectEnum.getByType(changeConfigReq.getChangeSubject());
if (containsChangeSubject == null) {
throw ExceptionFactory.createBiz(ResponseCode.CANT_FOUND, "变更主体不存在");
}
changeConfig.setChangeSubject(changeConfigReq.getChangeSubject());
if (changeConfigReq.getChangeLevel() == null) {
throw ExceptionFactory.createBiz(ResponseCode.PARAMETER_DEFICIENCY);
}
changeConfig.setChangeLevel(changeConfigReq.getChangeLevel());
if (changeConfigReq.getChangeDepartment() == null) {
throw ExceptionFactory.createBiz(ResponseCode.PARAMETER_DEFICIENCY);
}
changeConfig.setChangeDepartment(changeConfigReq.getChangeDepartment());
if (changeConfigReq.getChangeCommanderType() == null) {
throw ExceptionFactory.createBiz(ResponseCode.PARAMETER_DEFICIENCY);
//如果是执行人就从head里面把邮箱装载
} else if (changeConfigReq.getChangeCommanderType() == 1) {
changeConfigReq.setChangeCommander(RequestLocalBean.getUid());
}
changeConfig.setChangeCommanderType(changeConfigReq.getChangeCommanderType());
if (changeConfigReq.getChangeCommander() == null) {
throw ExceptionFactory.createBiz(ResponseCode.PARAMETER_DEFICIENCY);
}
changeConfig.setChangeCommander(changeConfigReq.getChangeCommander());
if (changeConfigReq.getNeedFile() == null) {
throw ExceptionFactory.createBiz(ResponseCode.PARAMETER_DEFICIENCY);
}
changeConfig.setNeedFile(changeConfigReq.getNeedFile());
changeConfig.setUpdateTime(System.currentTimeMillis());
if (changeConfigReq.getChangeExeConfig() == null || changeConfigReq.getChangeExeConfig().size() >= 21) {
throw ExceptionFactory.createBiz(ResponseCode.EXEC_CONFIG_LENGTH);
}
List<String> list = new ArrayList<>();
for (ChangeExecConfig execConfig : changeConfigReq.getChangeExeConfig()) {
list.add(execConfig.getChangeExecDepartment());
}
changeConfig.setParticipateChangeExecDepartment(list.toString());
return changeConfig;
}
private ValueOperations<String, String> getValue() {
if (value == null) {
value = redisTemplate.opsForValue();
}
return value;
}
private String getChangeConfigVO(ChangeConfig changeConfig, List<ChangeType> changeTypes, List<ChangeExecConfig> changeExecConfigs) {
ChangeConfigVO vo = new ChangeConfigVO();
vo.setChangeConfig(changeConfig);
vo.setChangeTypes(changeTypes);
List<ChangeExecConfig> creatorConfig = changeExecConfigs.stream().filter(i -> i.getChangeExecUserType().equals(ChangeCommanderEnum.COMMANDER_ORIGINATOR.getId())).collect(Collectors.toList());
List<ChangeExecConfig> fixedConfig = changeExecConfigs.stream().filter(i -> i.getChangeExecUserType().equals(ChangeCommanderEnum.FIXED_PERSON.getId())).collect(Collectors.toList());
List<Long> creatorIds = creatorConfig.stream().map(ChangeExecConfig::getId).collect(Collectors.toList());
List<Long> fixedIds = fixedConfig.stream().map(ChangeExecConfig::getId).collect(Collectors.toList());
Set<String> fixedEmail = fixedConfig.stream().map(ChangeExecConfig::getChangeExecUser).collect(Collectors.toSet());
AjaxResponse<List<IusUserInfoRsp>> userListInfo = iusRpcService.queryUserListInfo(UserQueryDTO.builder().uids(new ArrayList<>(fixedEmail)).build());
List<IusUserInfoRsp> userInfoRspList = userListInfo.getData();
List<ChangeExecConfigDTO> changeExecConfigDTOS = changeExecConfigs.stream().map(i -> {
ChangeExecConfigDTO changeExecConfigDTO = new ChangeExecConfigDTO();
BeanUtils.copyProperties(i, changeExecConfigDTO);
//创建人
if (creatorIds.contains(i.getId())) {
changeExecConfigDTO.setChangeExecUser(RequestLocalBean.getUid());
changeExecConfigDTO.setChangeExecUserName(RequestLocalBean.getName());
}
//固定人
if (fixedIds.contains(i.getId())) {
Optional<IusUserInfoRsp> anyFixedUser = userInfoRspList.stream().filter(u -> u.getUid().equals(i.getChangeExecUser())).findAny();
if (anyFixedUser.isPresent()) {
changeExecConfigDTO.setChangeExecUserName(anyFixedUser.get().getName());
}
}
return changeExecConfigDTO;
}).collect(Collectors.toList());
vo.setChangeExecConfigs(changeExecConfigDTOS);
return JSONObject.toJSONString(vo);
}
private PageVO buildPageVo(int totalCount, Integer pageSize, Integer page) {
int totalPage;
int i = totalCount % pageSize;
if (i != 0) {
totalPage = totalCount / pageSize + 1;
} else {
totalPage = totalCount / pageSize;
}
return PageVO.builder().page(page).totalPage(totalPage).pageSize(pageSize).pageCount(pageSize)
.totalCount(totalCount).build();
}
}
package com.netease.mail.yanxuan.change.biz.service.impl.change;
import com.netease.mail.yanxuan.change.biz.service.change.ChangeConfigService;
import com.netease.mail.yanxuan.change.dal.entity.ChangeConfig;
import com.netease.mail.yanxuan.change.dal.entity.ChangeType;
import com.netease.mail.yanxuan.change.dal.mapper.ChangeConfigMapper;
import com.netease.mail.yanxuan.change.dal.mapper.ChangeTypeMapper;
import com.netease.mail.yanxuan.change.dal.meta.model.po.ChangeConfigPo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
/**
* @author WangJiaXiang
* @date 2022/11/11/011$
*/
@Service
public class ChangeConfigServiceImpl implements ChangeConfigService {
@Autowired
public ChangeConfigMapper mapper;
@Autowired
private ChangeTypeMapper changeTypeMapper;
@Override
public ChangeConfig queryChangeConfig(Long id) {
return mapper.queryById(id);
}
@Override
public ChangeConfig queryChangeConfig(Long id, Long sonChangeClassId) {
return mapper.queryInfo(id, sonChangeClassId);
}
@Override
public ChangeConfigPo queryInfoPo(Long parentChangeClassId,Long sonChangeClassId) {
ChangeConfigPo changeConfigPo = mapper.queryInfoPo(parentChangeClassId, sonChangeClassId);
ChangeType parentChangeType = changeTypeMapper.selectByPrimaryKey(changeConfigPo.getParentChangeClassId());
ChangeType sonChangeType = changeTypeMapper.selectByPrimaryKey(changeConfigPo.getSonChangeClassId());
List<ChangeType> changeTypes = new ArrayList<>();
changeTypes.add(parentChangeType);
changeTypes.add(sonChangeType);
changeConfigPo.setChangeTypes(changeTypes);
return changeConfigPo;
}
@Override
public ChangeConfig queryChangeType(Long parentChangeClassId, Long sonChangeClassId) {
if (parentChangeClassId == null || sonChangeClassId == null){
return null;
}
return mapper.queryChangeType(parentChangeClassId, sonChangeClassId);
}
@Override
public Boolean deleteChangeConfig(Long id) {
mapper.deleteById(id);
return true;
}
@Override
public ChangeConfig addChangeConfig(ChangeConfig changeConfig) {
mapper.insertSelective(changeConfig);
return changeConfig;
}
@Override
public Boolean updateChangeConfig(ChangeConfig changeConfig) {
changeConfig.setUpdateTime(System.currentTimeMillis());
mapper.updateByPrimaryKeySelective(changeConfig);
return true;
}
@Override
public ChangeConfig getSonChange(Long sonChangeId) {
return mapper.selectBySonConfig(sonChangeId);
}
}
package com.netease.mail.yanxuan.change.biz.service.impl.change;
import com.netease.mail.yanxuan.change.biz.service.change.ChangeExecConfigService;
import com.netease.mail.yanxuan.change.common.bean.RequestLocalBean;
import com.netease.mail.yanxuan.change.dal.entity.ChangeExecConfig;
import com.netease.mail.yanxuan.change.dal.mapper.ChangeExecConfigMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* @author WangJiaXiang
* @date 2022/11/11/011$
*/
@Service
public class ChangeExecConfigServiceImpl implements ChangeExecConfigService {
@Autowired
private ChangeExecConfigMapper mapper;
@Override
public List<ChangeExecConfig> queryChangeExecConfig(Long changeTemplateId) {
return mapper.queryChangeExecConfig(changeTemplateId);
}
@Override
public List<ChangeExecConfig> addChangeExecConfig(Long id,List<ChangeExecConfig> changeExecConfigs) {
long currentTime = System.currentTimeMillis();
//循环添加
for (ChangeExecConfig changeExecConfig : changeExecConfigs){
//如果变更行动方案是变更发起人的话就填充登入人信息
if(changeExecConfig.getChangeExecUserType() == 1){
changeExecConfig.setChangeExecUser(RequestLocalBean.getUid());
}
//在修改的时候实际上删除在新增需要屏蔽掉ID
if (changeExecConfig.getId() != null){
changeExecConfig.setId(null);
}
changeExecConfig.setChangeTemplateId(id);
changeExecConfig.setCreateTime(currentTime);
changeExecConfig.setUpdateTime(currentTime);
//行动项,变更风险描述, 变更验证措施, 需要判断字段长度 参数验证 暂不验证
mapper.insertSelective(changeExecConfig);
}
return changeExecConfigs;
}
@Override
public List<ChangeExecConfig> updateChangeExecConfig(Long id,List<ChangeExecConfig> changeExecConfigs) {
//删除原来的行动
deleteChangeConfig(id);
return addChangeExecConfig(id,changeExecConfigs);
}
@Override
public Boolean deleteChangeConfig(Long changeTemplateId) {
mapper.deleteChangeConfig(changeTemplateId);
return true;
}
}
package com.netease.mail.yanxuan.change.biz.service.impl.change;
import com.netease.mail.yanxuan.change.common.bean.ResponseCode;
import com.netease.mail.yanxuan.change.biz.meta.exception.ExceptionFactory;
import com.netease.mail.yanxuan.change.biz.service.change.ChangeTypeService;
import com.netease.mail.yanxuan.change.dal.entity.ChangeType;
import com.netease.mail.yanxuan.change.dal.mapper.ChangeTypeMapper;
import com.netease.mail.yanxuan.change.dal.meta.model.po.ChangeTypePo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;
import java.util.*;
/**
* @author WangJiaXiang
* @date 2022/11/11/011$
*/
@Service
public class ChangeTypeServiceImpl implements ChangeTypeService {
@Autowired
private ChangeTypeMapper mapper;
@Override
public List<ChangeType> queryChangeType(Long id,Long sonChangeClassId, Boolean deleteTab) {
Integer delete = deleteTab?0:1;
return mapper.queryTypes(id,sonChangeClassId,delete);
}
Logger logger = LoggerFactory.getLogger(ChangeTypeServiceImpl.class);
@Override
@Transactional
public List<ChangeType> addChangeType(List<ChangeType> changeTypes) {
if (changeTypes.size() != 2){
throw ExceptionFactory.createBiz(ResponseCode.PARAMETER_LENGTH);
}
logger.info("查看一级二级入参数量"+changeTypes.size() + "值\n" +changeTypes);
//验证字符串长度
if (changeTypes.get(0).getTypeName().length() > 20 && changeTypes.get(1).getTypeName().length() > 20){
throw ExceptionFactory.createBiz(ResponseCode.PARAMETER_LENGTH);
}
ChangeType changeType = queryRepetitionChangeType(changeTypes);
if (changeType == null) {
//初始化参数载入
changeTypes.get(0).setCreateTime(System.currentTimeMillis());
changeTypes.get(0).setUpdateTime(System.currentTimeMillis());
changeTypes.get(0).setParentId(0L);
mapper.insertSelective(changeTypes.get(0));
}else{
changeTypes.set(0,changeType);
changeTypes.get(1).setParentId(changeType.getId());
}
//初始化参数载入
changeTypes.get(1).setParentId(changeTypes.get(0).getId());
changeTypes.get(1).setCreateTime(System.currentTimeMillis());
changeTypes.get(1).setUpdateTime(System.currentTimeMillis());
mapper.insertSelective(changeTypes.get(1));
return changeTypes;
}
@Override
public List<ChangeType> updateChangeType(List<ChangeType> changeTypes) {
//根据传进来的一级ID 和二级ID 进行查询
List<ChangeType> changeTypeList = mapper.queryTypes(changeTypes.get(0).getId(), changeTypes.get(1).getId(), 0);
//如果一级无变化
if (changeTypeList.get(0).getTypeName().equals(changeTypes.get(0).getTypeName())) {
if (changeTypeList.get(1).getTypeName().equals(changeTypes.get(1).getTypeName())){
//未改变情况直接返回
return changeTypes;
}else{
//一级未改变 二级发生改变
List<ChangeType> sonChanges = mapper.queryParent(changeTypes.get(0).getId());
Optional<ChangeType> sonTypeHave = sonChanges.stream()
.filter(i -> i.getTypeName().equals(changeTypes.get(1).getTypeName())).findAny();
if (sonTypeHave.isPresent()) {
throw ExceptionFactory.createBiz(ResponseCode.BAD_REQUEST, "二级分类存在");
}
//删除老的二级,增加新的二级
deleteChangeType(changeTypeList.get(1));
//发现没有直接新增并返回
changeTypes.get(1).setId(null);
changeTypes.get(1).setParentId(changeTypes.get(0).getId());
changeTypes.get(1).setCreateTime(System.currentTimeMillis());
changeTypes.get(1).setUpdateTime(System.currentTimeMillis());
mapper.insertSelective(changeTypes.get(1));
return changeTypes;
}
}else{
//查询 所有一级ID 是否有重复的
ChangeType changeParentType = mapper.queryTypeName(changeTypes.get(0).getTypeName());
if (changeParentType == null) {
deleteChangeType(changeTypeList.get(1));
//ID置空
changeTypes.get(0).setId(null);
changeTypes.get(1).setId(null);
//新增一级二级并返回
return addChangeType(changeTypes);
}
//查询二级
List<ChangeType> sonChanges = mapper.queryParent(changeParentType.getId());
Optional<ChangeType> sonTypeHave = sonChanges.stream()
.filter(i -> i.getTypeName().equals(changeTypes.get(1).getTypeName())).findAny();
if (sonTypeHave.isPresent()) {
throw ExceptionFactory.createBiz(ResponseCode.BAD_REQUEST, "二级分类存在");
}
//删除老的二级,增加新的二级
deleteChangeType(changeTypeList.get(1));
//发现没有直接新增并返回
changeTypes.get(1).setId(null);
changeTypes.set(0,changeParentType);
changeTypes.get(1).setParentId(changeParentType.getId());
changeTypes.get(1).setCreateTime(System.currentTimeMillis());
changeTypes.get(1).setUpdateTime(System.currentTimeMillis());
mapper.insertSelective(changeTypes.get(1));
return changeTypes;
}
}
@Override
@Transactional
public Boolean deleteChangeTypes(List<ChangeType> changeTypes) {
if (changeTypes.get(0) == null || changeTypes.get(1) == null){
throw ExceptionFactory.createParamFail();
}
//查询一级下班是否还存在其他二级 如果不存在就删除一级 如果存在一级就不做伪删
List<ChangeType> changeTypeList = mapper.queryParent(changeTypes.get(0).getId());
if (changeTypeList.size() != 2){
changeTypes.remove(0);
}
for (ChangeType changeType : changeTypes){
Example example = new Example(ChangeType.class);
Example.Criteria criteria = example.createCriteria();
criteria.orEqualTo("id",changeType.getId());
changeType.setDeleteType(1);
changeType.setUpdateTime(System.currentTimeMillis());
mapper.updateByExampleSelective(changeType,example);
}
return true;
}
public void deleteChangeType(ChangeType changeType) {
if (changeType == null ){
throw ExceptionFactory.createParamFail();
}
Example example = new Example(ChangeType.class);
Example.Criteria criteria = example.createCriteria();
criteria.orEqualTo("id",changeType.getId());
changeType.setDeleteType(1);
changeType.setUpdateTime(System.currentTimeMillis());
mapper.updateByExampleSelective(changeType,example);
}
@Override
public List<ChangeTypePo> queryConfigType() {
//获取数据,创建目录集合,遍历分组
List<ChangeTypePo> changeTypes = mapper.queryArrayChangeTypes();
List<ChangeTypePo> pos = new ArrayList<>();
for (ChangeTypePo changeType : changeTypes) {
if (changeType.getParentId() == 0){
//如果是一级 插入MAP 并创建List列表
changeType.setChangeTypes(new ArrayList<>());
pos.add(changeType);
}else{
for (ChangeTypePo po : pos){
if (po.getId().equals( changeType.getParentId())){
po.getChangeTypes().add(changeType);
}
}
}
}
//去重如果父类下边包裹的List数量为0的时候就自动剔除
pos.removeIf(changeTypePo -> changeTypePo.getChangeTypes().size() == 0);
return pos;
}
@Override
public ChangeType getChangeTypeById(Long id) {
return mapper.selectByPrimaryKey(id);
}
/**
* 判断变更类型是否重复(只判断未伪善出的)
* @param changeTypes
* @return
*/
private ChangeType queryRepetitionChangeType(List<ChangeType> changeTypes) {
if (changeTypes.get(0) == null || changeTypes.get(1) == null){
throw ExceptionFactory.createParamFail();
}
//获取父类是否存在
ChangeType changeParentType = mapper.queryTypeName(changeTypes.get(0).getTypeName());
if (changeParentType == null){
return null;
}
//如果存在查询父类下面所有子类 查询是否有重复的
List<ChangeType> sonChangeTypes = mapper.queryParent(changeParentType.getId());
for (ChangeType changeType : sonChangeTypes){
if (changeType.getTypeName().equals(changeTypes.get(1).getTypeName())){
throw ExceptionFactory.createBiz(ResponseCode.CHANGE_TYPE_NAME_TOW);
}
}
return changeParentType;
}
}
/**
* @(#)FlowService.java, 2022/11/29.
* <p/>
* Copyright 2022 Netease, Inc. All rights reserved.
* NETEASE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
package com.netease.mail.yanxuan.change.biz.service.rpc;
import java.util.List;
import com.netease.mail.yanxuan.change.common.bean.RequestLocalBean;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.alibaba.fastjson.JSON;
import com.netease.mail.yanxuan.change.biz.meta.exception.ExceptionFactory;
import com.netease.mail.yanxuan.change.common.bean.CommonConstants;
import com.netease.mail.yanxuan.change.common.bean.ResponseCode;
import com.netease.mail.yanxuan.change.common.bean.ResponseCodeEnum;
import com.netease.mail.yanxuan.change.common.enums.ChangeFlowEnum;
import com.netease.mail.yanxuan.change.common.enums.FlowxOperationEnum;
import com.netease.mail.yanxuan.change.integration.flow.FlowRpcService;
import com.netease.yanxuan.flowx.sdk.meta.controller.communal.AjaxResponse;
import com.netease.yanxuan.flowx.sdk.meta.dto.base.FlowDataDTO;
import com.netease.yanxuan.flowx.sdk.meta.dto.base.UserBaseDTO;
import com.netease.yanxuan.flowx.sdk.meta.dto.flow.FlowCreateReqDTO;
import com.netease.yanxuan.flowx.sdk.meta.dto.flow.NodeSubmitReqDTO;
import com.netease.yanxuan.flowx.sdk.meta.dto.flow.UpdateNodeApproverDTO;
import lombok.extern.slf4j.Slf4j;
/**
* @Author zcwang
* @Date 2022/11/29
* 工单流转相关操作
*/
@Slf4j
@Component
public class FlowService {
@Autowired
private FlowRpcService flowRpcService;
/**
* 创建工单
* @param flowCreateReqDTO
* @return
*/
public String createFlow(FlowCreateReqDTO flowCreateReqDTO) {
// 先创建工单,创建完成后直接提交
log.info("[createFlow] flowCreateReqDTO={}", flowCreateReqDTO);
AjaxResponse<String> flowCreateResponse = flowRpcService.create(CommonConstants.FLOWX_PRODUCT,
flowCreateReqDTO);
String flowId;
if (ResponseCodeEnum.SUCCESS.getCode() == flowCreateResponse.getCode()) {
flowId = flowCreateResponse.getData();
log.info("[createFlow] flowId ={}", JSON.toJSONString(flowId));
} else {
log.error("[createFlow] create flow failed, query={}, errMsg={}", JSON.toJSONString(flowCreateReqDTO),
JSON.toJSONString(flowCreateResponse));
throw ExceptionFactory.createBiz(ResponseCode.CREATE_FLOW_ERROR, "创建工单错误");
}
return flowId;
}
/**
* 提交工单
* @param flowId
* @param flowDataDTO
* @param uid
* @param topoId
* @param content
* @param approved
* @param createTime
* @return
*/
public String submitFlow(String flowId, FlowDataDTO flowDataDTO, String uid, String topoId, String content,
boolean approved, String operateResult, String remark, Long createTime) {
String name = RequestLocalBean.getName();
NodeSubmitReqDTO nodeSubmitReqDTO = new NodeSubmitReqDTO();
nodeSubmitReqDTO.setFlowId(flowId);
nodeSubmitReqDTO.setNodeId(flowDataDTO.getFlowMeta().getCurrNodeDataList().get(0).getNodeId());
nodeSubmitReqDTO.setUid(uid);
nodeSubmitReqDTO.setUserName(name);
nodeSubmitReqDTO.setTopoId(topoId);
nodeSubmitReqDTO.setContent(content);
nodeSubmitReqDTO.setOperateResult(operateResult);
nodeSubmitReqDTO.setRemark(remark);
nodeSubmitReqDTO.setCreateTime(createTime);
nodeSubmitReqDTO.setApproved(approved);
nodeSubmitReqDTO.setOccLock(flowDataDTO.getOccLock() + 1);
log.info("[submitFlow] nodeSubmitReqDTO={}", JSON.toJSONString(nodeSubmitReqDTO));
List<String> nextNodeIdList;
// 提交工单
AjaxResponse<List<String>> submitResponse = flowRpcService.submit(CommonConstants.FLOWX_PRODUCT,
nodeSubmitReqDTO);
if (ResponseCodeEnum.SUCCESS.getCode() == submitResponse.getCode()) {
nextNodeIdList = submitResponse.getData();
log.info("[submitFlow] nextNodeIdList={}", JSON.toJSONString(nextNodeIdList));
} else {
log.error("[submitFlow] submit flow failed, query={}, errMsg={}", JSON.toJSONString(nodeSubmitReqDTO),
JSON.toJSONString(submitResponse));
throw ExceptionFactory.createBiz(ResponseCode.SUBMIT_FLOW_ERROR, "提交工单错误");
}
if (CollectionUtils.isEmpty(nextNodeIdList)) {
return ChangeFlowEnum.END.getNodeId();
}
return nextNodeIdList.get(0);
}
/**
* 查询工单详情
* @param flowId
* @return
*/
public FlowDataDTO flowDetail(String flowId) {
// 查询工单详情,根据详情提交
FlowDataDTO flowDataDTO;
AjaxResponse<FlowDataDTO> flowDetailResponse = flowRpcService.getDetail(CommonConstants.FLOWX_PRODUCT, flowId);
if (ResponseCodeEnum.SUCCESS.getCode() == flowDetailResponse.getCode()) {
flowDataDTO = flowDetailResponse.getData();
log.info("[detailFlow] flowDataDTO={}", JSON.toJSONString(flowDataDTO));
} else {
log.error("[detailFlow] get flow detail failed, query={}, errMsg={}", JSON.toJSONString(flowId),
JSON.toJSONString(flowDetailResponse));
throw ExceptionFactory.createBiz(ResponseCode.DETAIL_FLOW_ERROR, "查询工单详情错误");
}
return flowDataDTO;
}
/**
* 更新待办人
* @param topoId
* @param flowId
* @param currentNodeId
* @param newApproverList
* @param uid
* @param userName
* @param remark
* @param content
*/
public void updateApprovers(String topoId, String flowId, String currentNodeId, List<UserBaseDTO> newApproverList,
String uid, String userName, String remark, String content){
FlowDataDTO flowDataDTO = this.flowDetail(flowId);
UpdateNodeApproverDTO approverDTO = new UpdateNodeApproverDTO();
approverDTO.setOccLock(flowDataDTO.getOccLock() + 1);
approverDTO.setTopoId(topoId);
approverDTO.setNodeId(currentNodeId);
approverDTO.setFlowId(flowId);
approverDTO.setNewApproverList(newApproverList);
approverDTO.setUid(uid);
approverDTO.setUserName(userName);
approverDTO.setRemark(remark);
approverDTO.setContent(content);
approverDTO.setOperateResult(FlowxOperationEnum.DELIVER.getName());
flowRpcService.updateApprovers(CommonConstants.FLOWX_PRODUCT, approverDTO);
}
}
\ No newline at end of file
/**
* @(#)itemRpcService.java, 2022/11/30.
* <p/>
* Copyright 2022 Netease, Inc. All rights reserved.
* NETEASE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
package com.netease.mail.yanxuan.change.biz.service.rpc;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.alibaba.fastjson.JSON;
import com.netease.mail.yanxuan.change.common.bean.AjaxResult;
import com.netease.mail.yanxuan.change.integration.item.ItemRpcService;
import com.netease.mail.yanxuan.change.integration.item.SimplePhyCateGoryResultCo;
import com.netease.mail.yanxuan.change.integration.item.meta.SpuTO;
import com.netease.mail.yanxuan.change.integration.item.param.BatchQuerySpuInfoParam;
import com.netease.mail.yanxuan.change.integration.item.param.CommonIdsParamQuery;
import lombok.extern.slf4j.Slf4j;
/**
* @Author zcwang
* @Date 2022/11/30
*/
@Slf4j
@Component
public class ItemService {
@Autowired
private ItemRpcService itemRpcService;
/**
* 查询物理类目
*
* @param query
* @return
* key: 商品id,value:商品的物理类目
*/
public Map<Long, List<SimplePhyCateGoryResultCo>> queryBySpuIds(CommonIdsParamQuery query) {
log.info("[ItemRpcService-queryCategoryChain] request of query={}",
JSON.toJSONString(query));
AjaxResult<Map<Long, List<SimplePhyCateGoryResultCo>>> response = itemRpcService
.queryBySpuIds(query);
log.info("[ItemRpcService-queryCategoryChain] response of query queryCategoryChain ={}",
JSON.toJSONString(response));
if (Boolean.TRUE.equals(response.isSuccess())) {
return response.getData();
}
log.error("[op:rpc-queryCategoryChain] query categoryChain detail failed, query={}, errMsg={}", query,
response.getMsg());
return new HashMap<>();
}
public List<SpuTO> batchQuerySpuInfo(BatchQuerySpuInfoParam query) {
log.info("[ItemRpcService-batchQuerySpuInfo] request of query={}",
JSON.toJSONString(query));
AjaxResult<List<SpuTO>> response = itemRpcService.batchQuerySpuInfo(query);
log.info("[ItemRpcService-batchQuerySpuInfo] response of query batchQuerySpuInfo ={}",
JSON.toJSONString(response));
if (Boolean.TRUE.equals(response.isSuccess())) {
return response.getData();
}
log.error("[op:rpc-batchQuerySpuInfo] query batchQuerySpuInfo failed, query={}, errMsg={}", query,
response.getMsg());
return new ArrayList<>();
}
}
/**
* @(#)IusService.java, 2022/12/7.
* <p/>
* Copyright 2022 Netease, Inc. All rights reserved.
* NETEASE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
package com.netease.mail.yanxuan.change.biz.service.rpc;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.alibaba.fastjson.JSON;
import com.netease.mail.yanxuan.change.biz.meta.exception.ExceptionFactory;
import com.netease.mail.yanxuan.change.common.bean.ResponseCode;
import com.netease.mail.yanxuan.change.common.bean.ResponseCodeEnum;
import com.netease.mail.yanxuan.change.integration.flow.UserQueryDTO;
import com.netease.mail.yanxuan.change.integration.flow.ius.IusRpcService;
import com.netease.mail.yanxuan.change.integration.flow.ius.req.IusDepartmentReq;
import com.netease.mail.yanxuan.change.integration.flow.ius.rsp.IusUserInfoRsp;
import com.netease.mail.yanxuan.change.integration.flow.ius.rsp.SecondaryDepartments;
import com.netease.yanxuan.flowx.sdk.meta.controller.communal.AjaxResponse;
import lombok.extern.slf4j.Slf4j;
/**
* @Author zcwang
* @Date 2022/12/7
*/
@Slf4j
@Component
public class IusService {
@Autowired
private IusRpcService iusRpcService;
public HashMap<String, List<SecondaryDepartments>> queryDepartment(IusDepartmentReq iusDepartmentReq) {
log.info("[queryDepartment] queryDepartment req:{}", JSON.toJSONString(iusDepartmentReq));
AjaxResponse<HashMap<String, List<SecondaryDepartments>>> response = iusRpcService.queryDepartment(iusDepartmentReq);
log.info("[queryDepartment] response of queryDepartment ={}",
JSON.toJSONString(response));
if (ResponseCodeEnum.SUCCESS.getCode() == response.getCode()) {
return response.getData();
} else {
log.error("[queryDepartment] queryDepartment failed, query={}, errMsg={}", JSON.toJSONString(iusDepartmentReq),
JSON.toJSONString(response));
throw ExceptionFactory.createBiz(ResponseCode.CREATE_FLOW_ERROR, "查询部门错误");
}
}
/**
* 查询用户信息
*/
public List<IusUserInfoRsp> queryUserListInfo(UserQueryDTO query) {
log.info("[queryUserListInfo] queryUserListInfo req:{}", JSON.toJSONString(query));
AjaxResponse<List<IusUserInfoRsp>> response = iusRpcService.queryUserListInfo(query);
log.info("[queryUserListInfo] response of queryUserListInfo ={}", JSON.toJSONString(response));
if (ResponseCodeEnum.SUCCESS.getCode() == response.getCode()) {
return response.getData();
} else {
log.error("[queryUserListInfo] queryUserListInfo failed, query={}, errMsg={}", JSON.toJSONString(query),
JSON.toJSONString(response));
return new ArrayList<>();
}
}
}
\ No newline at end of file
/**
* @(#)QCService.java, 2022/12/2.
* <p/>
* Copyright 2022 Netease, Inc. All rights reserved.
* NETEASE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
package com.netease.mail.yanxuan.change.biz.service.rpc;
import java.util.List;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import com.alibaba.fastjson.JSON;
import com.google.common.base.Strings;
import com.netease.mail.yanxuan.change.common.bean.AjaxResult;
import com.netease.mail.yanxuan.change.common.bean.CommonConstants;
import com.netease.mail.yanxuan.change.common.bean.ResponseCodeEnum;
import com.netease.mail.yanxuan.change.integration.qc.QcRpcService;
import com.netease.mail.yanxuan.change.integration.qc.meta.QcCategoryVO;
import com.netease.yanxuan.flowx.sdk.meta.controller.communal.AjaxResponse;
import java.util.Collections;
import java.util.concurrent.TimeUnit;
import lombok.extern.slf4j.Slf4j;
/**
* @Author zcwang
* @Date 2022/12/2
*/
@Slf4j
@Component
public class QCService {
@Autowired
private QcRpcService qcRpcService;
@Autowired
private StringRedisTemplate redisTemplate;
public List<QcCategoryVO> getQcCategoryListByItemId(Long itemId) {
log.info("[QCService-getQcCategoryListByItemId] request of query={}", itemId);
String key = String.format(CommonConstants.ITEM_QC_CATEGORY_CACHE, itemId);
String result = redisTemplate.opsForValue().get(key);
if (StringUtils.isNotBlank(result)) {
log.info("[QCService-getQcCategoryListByItemId] response from redis, query QcCategoryList ={}", result);
return JSON.parseArray(result, QcCategoryVO.class);
}
AjaxResponse<List<QcCategoryVO>> response = qcRpcService.getQcCategoryListByItemId(itemId);
log.info("[QCService-getQcCategoryListByItemId] response of query QcCategoryList ={}",
JSON.toJSONString(response));
if (ResponseCodeEnum.SUCCESS.getCode() == response.getCode()) {
redisTemplate.opsForValue().set(key, JSON.toJSONString(response.getData()),7, TimeUnit.DAYS);
return response.getData();
}
log.error("[op:rpc-getQcCategoryListByItemId] query QcCategoryList failed, query={}, errMsg={}", itemId,
response.getErrorMsg());
return Collections.emptyList();
}
}
\ No newline at end of file
/**
* @(#)SupplierSendService.java, 2022/12/8.
* <p/>
* Copyright 2022 Netease, Inc. All rights reserved.
* NETEASE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
package com.netease.mail.yanxuan.change.biz.service.rpc;
import java.util.Map;
import org.apache.logging.log4j.util.Strings;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.alibaba.fastjson.JSON;
import com.netease.mail.yanxuan.change.dal.entity.ChangeRecord;
import com.netease.mail.yanxuan.change.integration.email.email.EmailFactor;
import com.netease.mail.yanxuan.change.integration.email.enums.EmailTemplateEnum;
import com.netease.mail.yanxuan.change.integration.email.enums.EmailTypeEnum;
import com.netease.mail.yanxuan.change.integration.email.service.impl.EmailTemplateServiceImpl;
import com.netease.mail.yanxuan.change.integration.flow.supplier.FlowRpcSupplierSendService;
import com.netease.mail.yanxuan.change.integration.flow.supplier.req.SupplierSendEmailReq;
import lombok.extern.slf4j.Slf4j;
/**
* @Author zcwang
* @Date 2022/12/8
*/
@Slf4j
@Component
public class SupplierSendService {
@Autowired
private FlowRpcSupplierSendService flowRpcSupplierSendService;
@Autowired
private EmailTemplateServiceImpl emailTemplateService;
public void sendSupplierEmail(String supplier, String subjectParam, EmailTemplateEnum emailTemplateEnum,
Map<String, Object> param) {
try {
SupplierSendEmailReq req = new SupplierSendEmailReq();
req.setSupplierId(supplier);
String subject = emailTemplateEnum.getSubject();
//标题参数处理
if (Strings.isNotBlank(subjectParam)) {
subject = String.format(subject, subjectParam);
}
req.setMailSubject(subject);
EmailFactor factor = EmailFactor.builder().data(param).emailTemplateEnum(emailTemplateEnum).subject(subject)
.type(EmailTypeEnum.HTML.getType()).build();
String content = this.content(factor);
req.setMailContent(content);
log.debug("[sendSupplierEmail] supplier:{}, subjectParam:{}, subject:{}, content:{}", supplier,
subjectParam, subject, JSON.toJSONString(content));
String result = flowRpcSupplierSendService.sendEmail(req);
log.info("[sendSupplierEmail] result:{}", result);
} catch (Exception e) {
log.error("[op:sendSupplierEmail] error,supplier:{},subjectParam:{}, e:{}", supplier, subjectParam, e);
}
}
/**
* 根据邮件模版获取邮件内容
*
* @param emailFactor
* @return
*/
private String content(EmailFactor emailFactor) {
EmailTemplateEnum emailTemplateEnum = emailFactor.getEmailTemplateEnum();
return emailTemplateService.template(emailTemplateEnum.getCode(), emailFactor.getData(),
emailFactor.getType());
}
}
\ No newline at end of file
/**
* @(#)SupplierService.java, 2022/12/15.
* <p/>
* Copyright 2022 Netease, Inc. All rights reserved.
* NETEASE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
package com.netease.mail.yanxuan.change.biz.service.rpc;
import java.util.Collections;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.alibaba.fastjson.JSON;
import com.netease.mail.yanxuan.change.common.bean.AjaxResult;
import com.netease.mail.yanxuan.change.integration.flow.supplier.FlowRpcSupplierSendService;
import com.netease.mail.yanxuan.change.integration.flow.supplier.req.SupplierSearchRemoteReq;
import com.netease.mail.yanxuan.change.integration.flow.supplier.rsp.SupplierSimpleRsp;
import lombok.extern.slf4j.Slf4j;
/**
* @Author zcwang
* @Date 2022/12/15
*/
@Component
@Slf4j
public class SupplierService {
@Autowired
private FlowRpcSupplierSendService supplierSendService;
public List<SupplierSimpleRsp> getSupplierName(String supplierUid) {
log.info("[getSupplierName] request of query={}", supplierUid);
AjaxResult<List<SupplierSimpleRsp>> response = supplierSendService.queryByConditionForQc(
SupplierSearchRemoteReq.builder().limitSupplierIdList(Collections.singletonList(supplierUid)).build());
log.info("[getSupplierName] response of query={}", JSON.toJSONString(response));
if (Boolean.TRUE.equals(response.isSuccess())) {
return response.getData();
}
log.error("[op:getSupplierName] getSupplierName failed, query={}, errMsg={}", supplierUid,
response.getMsg());
return Collections.emptyList();
}
}
\ No newline at end of file
// /**
// * @(#)TodoService.java, 2022/11/29.
// * <p/>
// * Copyright 2022 Netease, Inc. All rights reserved.
// * NETEASE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
// */
// package com.netease.mail.yanxuan.change.biz.service.rpc;
//
// import java.util.HashMap;
// import java.util.Map;
//
// import org.apache.commons.lang3.StringUtils;
// import org.springframework.beans.factory.annotation.Autowired;
// import org.springframework.stereotype.Component;
//
// import com.alibaba.fastjson.JSON;
// import com.netease.mail.yanxuan.change.biz.meta.exception.ExceptionFactory;
// import com.netease.mail.yanxuan.change.common.bean.CommonConstants;
// import com.netease.mail.yanxuan.change.common.bean.ResponseCode;
// import com.netease.mail.yanxuan.change.common.bean.ResponseCodeEnum;
// import com.netease.mail.yanxuan.change.common.enums.OperateTypeEnum;
// import com.netease.mail.yanxuan.change.common.enums.TodoTaskTypeEnum;
// import com.netease.mail.yanxuan.change.dal.entity.ChangeRecord;
// import com.netease.mail.yanxuan.change.integration.todo.TaskCreateDTO;
// import com.netease.mail.yanxuan.change.integration.todo.TaskCreateParamVO;
// import com.netease.mail.yanxuan.change.integration.todo.TaskProcessParamVO;
// import com.netease.mail.yanxuan.change.integration.todo.TodoRpcService;
// import com.netease.yanxuan.flowx.sdk.meta.controller.communal.AjaxResponse;
//
// import lombok.extern.slf4j.Slf4j;
//
// /**
// * @Author zcwang
// * @Date 2022/11/29
// * 待办相关操作
// */
// @Component
// @Slf4j
// public class TodoService {
//
// @Autowired
// private TodoRpcService todoRpcService;
//
// /**
// * 创建代办
// * @param entity
// */
// public TaskCreateDTO createTodoTask(ChangeRecord entity) {
// String changeCommander = entity.getChangeCommander();
// TaskCreateDTO taskCreateDTO = new TaskCreateDTO();
// if (StringUtils.isNotEmpty(changeCommander)) {
// String flowId = String.valueOf(entity.getFlowId());
// Map<String, Object> businessContent = new HashMap<>();
// businessContent.put("nodeTitle", entity.getChangeContent());
// businessContent.put("taskFlowId", flowId);
// businessContent.put("newFlow", flowId);
// TaskCreateParamVO taskCreateParamVO = new TaskCreateParamVO();
// taskCreateParamVO.setBusinessKey(flowId);
// taskCreateParamVO.setContent(JSON.toJSONString(businessContent));
// taskCreateParamVO.setProduct(CommonConstants.FLOWX_PRODUCT);
// taskCreateParamVO.setTaskCreator(changeCommander);
// taskCreateParamVO.setTaskHandler(changeCommander);
// taskCreateParamVO.setTaskHandlerName(changeCommander);
// taskCreateParamVO.setTaskTitle("测试");
// taskCreateParamVO.setTaskTypeKey(TodoTaskTypeEnum.QC_CHANGE.getValue());
// AjaxResponse<TaskCreateDTO> taskCreateResponse = todoRpcService.create(taskCreateParamVO);
// if (ResponseCodeEnum.SUCCESS.getCode() == taskCreateResponse.getCode()) {
// taskCreateDTO = taskCreateResponse.getData();
// log.info("[createTodoTask] taskCreateDTO={}", JSON.toJSONString(taskCreateDTO));
//
// } else {
// log.error("[createTodoTask] create todo failed, param={}, errMsg={}", JSON.toJSONString(taskCreateParamVO),
// JSON.toJSONString(taskCreateResponse));
// throw ExceptionFactory.createBiz(ResponseCode.CREATE_TODO_ERROR, "查询工单详情错误");
// }
//
// }
// return taskCreateDTO;
// }
//
// /**
// * 处理待办
// * @param entity
// * @param operateType
// * @see OperateTypeEnum
// */
// public void progressTodoTask(ChangeRecord entity, Integer operateType) {
// String changeCommander = entity.getChangeCommander();
// String flowId = String.valueOf(entity.getFlowId());
// log.info("[finishSupplierTodoTask] taskFlowId={}, supplierId={}", flowId, changeCommander);
// if (StringUtils.isNotEmpty(changeCommander)) {
// TaskProcessParamVO taskProcessParamVO = new TaskProcessParamVO();
// taskProcessParamVO.setBusinessKey(flowId);
// taskProcessParamVO.setOperateType(OperateTypeEnum.FINISH.getType());
// taskProcessParamVO.setOperator(changeCommander);
// taskProcessParamVO.setOperatorName(changeCommander);
// taskProcessParamVO.setProduct(CommonConstants.FLOWX_PRODUCT);
// taskProcessParamVO.setTaskId(entity.getTodoId());
// todoRpcService.progress(taskProcessParamVO);
// }
// }
// }
\ No newline at end of file
/**
* @(#)AutoSubmit.java, 2022/11/24.
* <p/>
* Copyright 2022 Netease, Inc. All rights reserved.
* NETEASE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
package com.netease.mail.yanxuan.change.biz.task;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.alibaba.fastjson.JSON;
import com.netease.mail.yanxuan.change.biz.biz.ChangeFlowBiz;
import com.netease.mail.yanxuan.change.biz.config.AppConfig;
import com.netease.mail.yanxuan.change.biz.service.ChangeFlowExecService;
import com.netease.mail.yanxuan.change.biz.service.ChangeFlowService;
import com.netease.mail.yanxuan.change.biz.service.change.ChangeConfigService;
import com.netease.mail.yanxuan.change.biz.service.rpc.FlowService;
import com.netease.mail.yanxuan.change.biz.service.rpc.SupplierSendService;
import com.netease.mail.yanxuan.change.common.bean.CommonConstants;
import com.netease.mail.yanxuan.change.common.enums.ChangeFlowEnum;
import com.netease.mail.yanxuan.change.common.enums.ChangeSubjectEnum;
import com.netease.mail.yanxuan.change.common.enums.CreateSourceEnum;
import com.netease.mail.yanxuan.change.common.enums.FlowOperationTypeEnum;
import com.netease.mail.yanxuan.change.common.enums.FlowxOperationEnum;
import com.netease.mail.yanxuan.change.common.util.DateUtils;
import com.netease.mail.yanxuan.change.dal.entity.ChangeRecord;
import com.netease.mail.yanxuan.change.dal.meta.model.po.ChangeConfigPo;
import com.netease.mail.yanxuan.change.dal.meta.model.vo.ChangeFlowExecVO;
import com.netease.mail.yanxuan.change.integration.email.enums.EmailTemplateEnum;
import com.netease.mail.yanxuan.dschedule.core.biz.model.ReturnT;
import com.netease.mail.yanxuan.dschedule.core.handler.IJobHandler;
import com.netease.mail.yanxuan.dschedule.core.handler.annotation.JobHandler;
import com.netease.yanxuan.flowx.sdk.meta.dto.base.FlowDataDTO;
import lombok.extern.slf4j.Slf4j;
/**
* @Author zcwang
* @Date 2022/11/24
*/
@Component
@Slf4j
@JobHandler("AutoSubmit")
public class AutoSubmit extends IJobHandler {
@Autowired
private ChangeFlowService changeFlowService;
@Autowired
private FlowService flowService;
@Autowired
private ChangeFlowBiz changeFlowBiz;
@Autowired
private SupplierSendService sendSupplierEmail;
@Autowired
private ChangeConfigService changeConfigService;
@Autowired
private ChangeFlowExecService changeFlowExecService;
@Autowired
private AppConfig appConfig;
@Override
public ReturnT<String> execute(String... strings) throws Exception {
log.info("AutoSubmit start");
long startTime = DateUtils.getCurrentTime();
// 处理变更确认时间是今天24点之前的
Long tomorrowSpecificTime = DateUtils.getTomorrowSpecificTime("00:00:00");
List<Long> count = new ArrayList<>();
Long entityId = 0L;
// 查询今天时间之前的未发送邮件的数据
try {
while (true) {
List<ChangeRecord> records = changeFlowService.getByStatusAndTime(entityId, 0,
ChangeFlowEnum.CHANGE_FLOW_EXE.getNodeId(), ChangeFlowEnum.CHANGE_FLOW_CONFIRM.getNodeId(),
tomorrowSpecificTime);
if (CollectionUtils.isEmpty(records)) {
break;
}
records.forEach(this::progressRecord);
List<Long> idList = records.stream().map(ChangeRecord::getId).collect(Collectors.toList());
entityId = idList.stream().max(Long::compare).get();
count.addAll(idList);
}
} catch (Exception e) {
log.error("error on AutoSubmit,e:{}", e);
}
log.info(
"AutoSubmit end, count:{}, maxId:{}, usedTime:{}", count.size(), entityId, DateUtils.getCurrentTime() - startTime);
return ReturnT.SUCCESS;
}
public void progressRecord(ChangeRecord changeRecord) {
Long flowId = changeRecord.getFlowId();
String flowNode = changeRecord.getFlowNode();
String uid = changeRecord.getChangeCommander();
// 执行变更节点,提交节点
if (ChangeFlowEnum.CHANGE_FLOW_EXE.getNodeId().equals(flowNode)) {
// 获取工单详情
FlowDataDTO flowDataDTO = flowService.flowDetail(flowId.toString());
if (flowDataDTO == null) {
log.debug("[progressRecord] get flowDataDTO error, flowId{}", flowId);
}
// 工单流传
Map<String, Object> content = new HashMap<>(CommonConstants.INIT_HASH_MAP_SIZE);
content.put("updateTime", System.currentTimeMillis());
content.put(CommonConstants.FLOW_OPERATION_KEY, FlowOperationTypeEnum.PASS.getValue());
try {
String execNode = flowService.submitFlow(flowId.toString(), flowDataDTO, uid,
ChangeFlowEnum.CHANGE_FLOW_EXE.getTopoId(), JSON.toJSONString(content), true,
FlowxOperationEnum.SUBMIT.getName(), "提交工单", changeRecord.getCreateTime());
// 更新工单数据
changeRecord.setFlowNode(execNode);
changeRecord.setUpdateTime(DateUtils.getCurrentTime());
changeFlowService.updateRecord(changeRecord);
} catch (Exception e) {
log.debug("[progressRecord] submit error, flowId{}", flowId);
}
}
// 发送邮件
HashMap<String, Object> map = new HashMap<>();
map.put("changeId", changeRecord.getFlowId());
map.put("changeSubject", ChangeSubjectEnum.getChangeSubjectEnum(changeRecord.getChangeSubject()).getDesc());
map.put("flowUrl", changeRecord.getFlowId());
ChangeConfigPo changeConfigPo = null;
StringBuilder changeType = new StringBuilder();
try {
changeConfigPo = changeConfigService.queryInfoPo(changeRecord.getParentChangeClassId(),
changeRecord.getSonChangeClassId());
changeType.append(changeConfigPo.getChangeTypes().get(0).getTypeName());
changeType.append(changeConfigPo.getChangeTypes().get(1).getTypeName());
} catch (Exception e) {
log.error("queryInfoPo parentId:{}, sonId:{}, error:{}", changeRecord.getParentChangeClassId(),
changeRecord.getSonChangeClassId(), JSON.toJSONString(changeConfigPo));
}
String subjectParam = ChangeSubjectEnum.getChangeSubjectEnum(changeRecord.getChangeSubject()).getDesc() + changeType
+ changeRecord.getFlowId().toString();
// 变更结果确认,收件人:变更负责人
List<String> receiver = Collections.singletonList(changeRecord.getChangeCommander());
// 变更结果确认,抄送:所有行动项负责人+变更管理QM
List<ChangeFlowExecVO> execRecord = changeFlowExecService
.getChangeFlowExecRecord(changeRecord.getId());
List<String> userEmailList = execRecord.stream().map(ChangeFlowExecVO::getChangeExecUserEmail)
.collect(Collectors.toList());
userEmailList.add(appConfig.getChangeManageQM());
changeFlowBiz.qcSendEmail(receiver, userEmailList, subjectParam,
EmailTemplateEnum.YX_QC_CHANGE_AFFIRM, map);
// 发送邮件,执行邮件更新为已发送
changeRecord.setAutoSubmitEmail(1);
changeFlowService.updateRecord(changeRecord);
// 如果是供应商发起,再次发送供应商邮件
if (changeRecord.getCreateSource().equals(CreateSourceEnum.TONG_ZHOU.getType())) {
sendSupplierEmail.sendSupplierEmail(changeRecord.getCreateSupplier(), subjectParam,
EmailTemplateEnum.YX_QC_CHANGE_AFFIRM, map);
}
// 如果是其他端发起但是是供应商变更,再次发送供应商邮件
if (!changeRecord.getCreateSource().equals(CreateSourceEnum.TONG_ZHOU.getType())
&& ChangeSubjectEnum.SUPPLIER.getType().equals(changeRecord.getChangeSubject())) {
sendSupplierEmail.sendSupplierEmail(changeRecord.getChangeSupplier(), subjectParam,
EmailTemplateEnum.YX_QC_CHANGE_AFFIRM, map);
}
}
}
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.2.xsd">
<!-- scan dschedule config package -->
<!-- <context:component-scan base-package="com.netease.mail.yanxuan.dschedule.core.config">-->
<!-- </context:component-scan>-->
<!-- dschedule执行器 -->
<!-- <bean id="dscheduleExecutor"-->
<!-- class="com.netease.mail.yanxuan.dschedule.core.executor.DscheduleExecutor"-->
<!-- init-method="start" destroy-method="destroy"/>-->
</beans>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="false" scan="true" scanPeriod="60 seconds">
<contextName>yanxuan-qc-change-system</contextName>
<!--引入missa-->
<springProfile name="!dev">
<include resource="logback-missa.xml"/>
</springProfile>
<!-- 获取application配置文件中的配置 -->
<springProperty scope="context" name="log.level"
source="log.level"/>
<springProperty scope="context" name="log.path"
source="log.path"/>
<springProperty scope="context" name="log.maxHistory"
source="log.maxHistory"/>
<springProperty scope="context" name="log.maxSize"
source="log.maxSize"/>
<!--日志平台应用日志标准格式-->
<property name="patternValue"
value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%p] [%X{XTraceId}] %m%n"/>
<!-- 控制台输出 -->
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>${patternValue}</pattern>
<charset>UTF-8</charset>
</encoder>
</appender>
<!--默认日志输出 -->
<appender name="default" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.path}/default.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${log.path}/default.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<maxHistory>${log.maxHistory}</maxHistory>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>${log.maxSize}</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
<encoder>
<pattern>${patternValue}</pattern>
<charset>UTF-8</charset>
</encoder>
</appender>
<!--默认异步日志输出 -->
<appender name="default_ASYNC" class="ch.qos.logback.classic.AsyncAppender">
<!-- 不丢失日志.默认的,如果队列的80%已满,则会丢弃TRACT、DEBUG、INFO级别的日志 -->
<discardingThreshold>0</discardingThreshold>
<!-- 更改默认的队列的深度,该值会影响性能.默认值为256 -->
<queueSize>512</queueSize>
<!-- 提取调用者数据 -->
<includeCallerData>true</includeCallerData>
<!-- 添加附加的appender,最多只能添加一个 -->
<appender-ref ref="default"/>
</appender>
<root level="${log.level}">
<appender-ref ref="console"/>
<appender-ref ref="default_ASYNC"/>
</root>
</configuration>
package com.netease.mail.yanxuan.change.common.anno;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @author lfmu
*/
@Target(value = { ElementType.TYPE_PARAMETER, ElementType.FIELD })
@Retention(value = RetentionPolicy.RUNTIME)
public @interface ExcelTitleName {
/**
* 表头列名
*/
String title() default "";
/**
* 列数
*/
int order() default -1;
}
/**
* @(#)UserHolder.java, 2020/12/9.
* <p/>
* Copyright 2020 Netease, Inc. All rights reserved.
* NETEASE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
package com.netease.mail.yanxuan.change.common.bean;
import org.springframework.stereotype.Component;
/**
* B端管理系统用户信息
*
* @author: 莫闲
* @date: 2020-12-09 13:19
**/
@Component
public class AdminUserHolder {
// 当前登录用户名线程绑定
private static ThreadLocal<String> userThreadLocal = new ThreadLocal<>();
public static void clear() {
userThreadLocal.remove();
}
/**
* 获取用户名
*
* @return 用户名,null-未登录
*/
public static String getUserName() {
return userThreadLocal.get();
}
public static void setUserName(String userName) {
userThreadLocal.set(userName);
}
}
package com.netease.mail.yanxuan.change.common.bean;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
* @author lwtang
*/
@EqualsAndHashCode()
@Data
@Accessors(chain = true)
public class AjaxResult<T> {
private static final long serialVersionUID = 1L;
private Integer code;
private String msg;
private T data;
private Exception e;
public Boolean isSuccess() {
return this.code.equals(ResponseCodeEnum.SUCCESS.getCode());
}
public Boolean isFail() {
return !isSuccess();
}
public static <R> AjaxResult<R> success() {
return AjaxResult.of(ResponseCodeEnum.SUCCESS);
}
public static <R> AjaxResult<R> success(R data) {
return AjaxResult.<R>of(ResponseCodeEnum.SUCCESS).setData(data);
}
public static <R> AjaxResult<R> error() {
return AjaxResult.of(ResponseCodeEnum.INTERNAL_ERROR);
}
public static <R> AjaxResult<R> error(Exception e) {
return AjaxResult.<R>of(ResponseCodeEnum.INTERNAL_ERROR).setE(e);
}
public static <R> AjaxResult<R> badRequest() {
return AjaxResult.of(ResponseCodeEnum.BAD_REQUEST);
}
public static <R> AjaxResult<R> badRequest(String msg) {
return AjaxResult.<R>of(ResponseCodeEnum.BAD_REQUEST).setMsg(msg);
}
public static <R> AjaxResult<R> badRequest(Exception e) {
return AjaxResult.<R>of(ResponseCodeEnum.BAD_REQUEST).setE(e);
}
public static <R> AjaxResult<R> badRequest(String msg, Exception e) {
return AjaxResult.<R>of(ResponseCodeEnum.BAD_REQUEST).setMsg(msg).setE(e);
}
public static <R> AjaxResult<R> of(ResponseCodeEnum code) {
return new AjaxResult<R>().setCode(code.getCode()).setMsg(code.getMsg());
}
public static <R> AjaxResult<R> of(Integer code, String msg) {
return new AjaxResult<R>().setCode(code).setMsg(msg);
}
public static <R> AjaxResult<R> of(Integer code, String msg, R data) {
return AjaxResult.<R>of(code, msg).setData(data);
}
public static <R> AjaxResult<R> of(Integer code, String msg, R data, Exception e) {
return AjaxResult.of(code, msg, data).setE(e);
}
}
/**
* @(#)CommonConstants.java, 2022/11/11.
* <p/>
* Copyright 2022 Netease, Inc. All rights reserved.
* NETEASE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
package com.netease.mail.yanxuan.change.common.bean;
/**
* @Author zcwang
* @Date 2022/11/11
* 常量配置
*/
public class CommonConstants {
// 工单业务数据操作key
public static final String FLOW_OPERATION_KEY = "operation";;
public static final int INIT_HASH_MAP_SIZE = 10;
public static Integer SIZE = 1;
public static Integer PAGE = 10;
public static String FLOWX_PRODUCT = "qc";
public static final String ITEM_QC_CATEGORY_CACHE = "item_qc_category_cache:%s";
}
\ No newline at end of file
package com.netease.mail.yanxuan.change.common.bean;
/**
* @author: bndong
* @date: 2021/5/25
*/
public class RequestLocalBean {
/**
* 存储当前的用户的Id
*/
private static final ThreadLocal<Long> userIdLocal = new ThreadLocal<>();
/**
* 存储当期用户的uid
*/
private static final ThreadLocal<String> uidLocal = new ThreadLocal<>();
/**
* 存储当前请求的ip信息
*/
private static final ThreadLocal<String> ipLocal = new ThreadLocal<>();
/**
* 真实姓名
*/
private static final ThreadLocal<String> nameLocal = new ThreadLocal<>();
/**
* 最近登录时间
*/
private static final ThreadLocal<Long> lastLoginTimeLocal = new ThreadLocal<>();
public static void rmrRequestUserId() {
userIdLocal.remove();
}
public static Long getRequestUserId() {
return userIdLocal.get();
}
public static void setRequestUserId(Long userId) {
userIdLocal.set(userId);
}
public static void rmrRequestIp() {
ipLocal.remove();
}
public static String getRequestIp() {
return ipLocal.get();
}
public static void setRequestIp(String ip) {
ipLocal.set(ip);
}
public static void rmUid() {
uidLocal.remove();
}
public static String getUid() {
return uidLocal.get();
}
public static void setUid(String uid) {
uidLocal.set(uid);
}
public static void rmrName() {
nameLocal.remove();
}
public static String getName() {
return nameLocal.get();
}
public static void setName(String name) {
nameLocal.set(name);
}
public static void rmrLastLoginTime() {
lastLoginTimeLocal.remove();
}
public static Long getLastLoginTime() {
return lastLoginTimeLocal.get();
}
public static void setLastLoginTime(Long lastLoginTime) {
lastLoginTimeLocal.set(lastLoginTime);
}
public static void clear() {
RequestLocalBean.rmUid();
RequestLocalBean.rmrRequestIp();
RequestLocalBean.rmrRequestUserId();
RequestLocalBean.rmrName();
RequestLocalBean.rmrLastLoginTime();
}
}
package com.netease.mail.yanxuan.change.common.bean;
/**
* 返回的code
*
* @author lwtang
*/
public enum ResponseCode {
//成功
SUCCESS(200, "SUCCESS"),
// 结果、数据为空
EMPTY(201, "EMPTY"),
// 处理中
PROCESSING(202, "PROCESSING"),
//已存在
HAVE_EXIST(203, "用户{0}存在未完成任务"),
//商品已售罄
SELL_OUT(210, "SELL_OUT"),
//已加购过该福袋
HAVE_ADD(211, "HAVE_ADD"),
//购物车已满
IS_FULL(212, "IS_FULL"),
//拥有补签卡达上限
CARD_FULL(213, "CARD_FULL"),
NO_TITLE_INFO(214, "标题信息缺失"),
QUERY_FILL_CHECK_CARDS_EXCEPTION(215, "获取补签卡异常"),
SKU_NO_EXIST(216, "skuId不存在"),
HAVE_SIGN(217, "签到失败"),
NO_IN_HAND_TASK(218, "没有进行中的任务"),
NO_TASK_ID(219, "该任务不存在"),
TASK_AWARD_HAVE_CASH(220, "任务奖励已兑换"),
ACTIVITY_CLOSE(221, "活动关闭"),
N0_LOTTERY(222, "无抽奖资格"),
NO_LOTTERY_COUNT(223, "无抽奖次数"),
LOTTERY_ERROR(224, "抽奖失败"),
SEND_RED_PACKED_FAIL(225, "发红包失败"),
NO_SELECT_GOOD_POWER(226, "没有选商品的资格"),
SEND_GIFT_CARD_FAIL(227, "发福利卡失败"),
SEND_COUPON_FAIL(228, "发优惠券失败"),
SEND_POINT_FAIL(229, "发积分失败"),
SEND_BACK_GOLD_FAIL(230, "发回馈金失败"),
NO_WAIT_RECEIVE(231, "无待领取"),
PARAM_MISS(232, "参数缺失"),
//----------3xx-----------
//----------4xx-----------
//非法参数.
BAD_REQUEST(400, "BAD REQUEST"),
//未登录
NOT_LOGIN(401, "NO UID"),
//重复提交
APPLYED(402, "APPLYED"),
// 禁用,token验证失败等; 内部接口认证:非法访问
FORBIDDEN(403, "FORBIDDEN"),
// 未找到资源,具体跟业务场景有关,比如红包不存在
NOT_FOUND(404, "NOT FOUND"),
// 没有资格,如等级不够
UNQULIFIED(405, "UNQULIFIED"),
// 资源不够
RUNOUT(406, "RUNOUT"),
// 请求受限、余额不足
LIMIT(407, "LIMIT"),
//该crmId在数据库已存在
SAME_CRM_ID(408, "该crmId在数据库已存在"),
// 风控异常, UGC检查失败等
RISK(411, "RISK"),
UNIQUE_KEY(412, "唯一索引异常"),
//----------5xx-----------
// 服务器错误: db异常等
SERVER_ERROR(500, "SERVER ERROR"),
//----------others-----------
// 限流
RATE_LIMIT(700, "RATE_LIMIT"),
THIRD_ERR(800, "rpc error"),
CANT_USE(801, "激活码id 不可用"),
NO_GOOD_TASK(802, "不是商品任务"),
//----------10xx-----------
CREATE_FLOW_ERROR(1001, "创建工单错误"),
DETAIL_FLOW_ERROR(1002, "查询工单详情错误"),
ERROR_FLOW_ID(1003, "工单id不存在"),
NODE_ERROR(1004, "工单已流转至其他节点"),
NO_AUTH(1005, "没有当前节点操作权限"),
CHANGE_SUBJECT_ERROR(1006, "变更主体类型错误"),
CHANGE_TYPE_NOT_EXIST(1007, "变更类型不存在"),
OPERATOR_NOT_EXIST(1008, "操作人不存在"),
CREATE_TODO_ERROR(1009, "传单待办错误"),
COMMANDER_TYPE_NOT_EXIST(1010,"变更负责人类型错误"),
SUBMIT_FLOW_ERROR(1011, "提交工单错误"),
/**
* 无权限
*/
NO_PERMISSION(2001,"无权限") {
},
CAN_NOT_DEL(2002,"不可删除") {
},
UPDATE_FAIL(2003,"更改失败") {
},
CANT_FOUND(2004,"查询不到") {
},
SEND_FAIL(2005,"发送失败") {
},
ACT_END(2006,"活动结束") {
},
/**
* 操作记录不存在
*/
OP_RECORD_NOT_EXIST(3000,"opRecord id not existed") {
},
/**
* 只有操作成功才允许进行验证
*/
ONLY_OP_SUCCESS_ALLOWED(3001,"verify only allowed when op success") {
},
PARAMETER_LENGTH(413,"请检查参数长度") {
},
EXEC_CONFIG_LENGTH(414,"请检查行动方案配置数量") {
},
PARAMETER_DEFICIENCY(415,"参数缺失请检查参数") {
},
CHANGE_TYPE_NAME_ONE(4001,"一级变更类型重复,请检查后添加~") {
},
CHANGE_TYPE_NAME_TOW(4002,"二级变更类型重复,请检查后添加~") {
};
private int code;
private String msg;
ResponseCode(int code, String msg) {
this.code = code;
this.msg = msg;
}
public int getCode() {
return code;
}
public String getMsg() {
return msg;
}
}
/**
* @(#)ResponseCodeEnum.java, 2022/11/14.
* <p/>
* Copyright 2022 Netease, Inc. All rights reserved.
* NETEASE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
package com.netease.mail.yanxuan.change.common.bean;
import java.util.HashMap;
import java.util.Map;
/**
* @Author zcwang
* @Date 2022/11/14
*/
public enum ResponseCodeEnum {
ZERO_CODE_SUCCESS(0, "成功"),
SUCCESS(200, "成功"),
BAD_REQUEST(400, "错误请求"),
SC_UNAUTHORIZED(401, "用户未登录"),
FORBIDDEN(403, "操作无权限"),
NO_FOUND(404, "服务器上没有请求的资源"),
TOO_MANY_REQUESTS(429, "服务请求达到上限(限流)"),
INTERNAL_ERROR(500, "系统内部错误"),
SERVICE_DEGRADATION(50010, "服务已降级"),
PARAM_ERROR(51000, "参数错误"),
NO_ROLE_AUTH(51006, "用户无角色权限"),
UNAUTHORIZED(51007, "用户未登录"),
RISK_CONTROL_USERS(51010, "风控用户"),
NO_CROWD_AUTH(51011, "用户人群不满足"),
ACT_DISSATISFIED(52000, "活动不满足条件"),
BIZ_EXCEPTION(52001, "业务异常"),
SYSTEM_EXCEPTION(52002, "系统异常"),
UNKNOWN_ERROR(52003, "未知错误"),
RPC_ERROR(52004, "rpc错误"),
RPC_RESULT_ERROR(52003, "rpc结果错误"),
FRAMEWORK_EXCEPTION(55000, "martech-act-framework异常");
private final Integer code;
private final String msg;
static Map<Integer, ResponseCodeEnum> map = new HashMap();
private ResponseCodeEnum(Integer code, String msg) {
this.code = code;
this.msg = msg;
}
public static ResponseCodeEnum valueOf(Integer value) {
return (ResponseCodeEnum)map.get(value);
}
public int getCode() {
return this.code;
}
public String getMsg() {
return this.msg;
}
static {
ResponseCodeEnum[] var0 = values();
int var1 = var0.length;
for(int var2 = 0; var2 < var1; ++var2) {
ResponseCodeEnum codeEnum = var0[var2];
map.put(codeEnum.getCode(), codeEnum);
}
}
}
\ No newline at end of file
/**
* @(#)BusinessFormEnum.java, 2022/12/20.
* <p/>
* Copyright 2022 Netease, Inc. All rights reserved.
* NETEASE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
package com.netease.mail.yanxuan.change.common.enums;
/**
* @Author zcwang
* @Date 2022/12/20
*/
public enum BusinessFormEnum {
SELF_SUPPORT(0,"自营"),
YX_SELECTION_OEM(3,"严选贴牌代销"),
OTHER_BRANDS(4,"他方品牌代销"),
COMMISSION2(5,"代销2.0");
private Integer type;
private String desc;
BusinessFormEnum(Integer type, String desc) {
this.type = type;
this.desc = desc;
}
public Integer getType() {
return type;
}
public String getDesc() {
return desc;
}
public static String getByType(Integer type) {
for (BusinessFormEnum value : BusinessFormEnum.values()) {
if (value.getType().equals(type)) {
return value.getDesc();
}
}
return "";
}
}
\ No newline at end of file
package com.netease.mail.yanxuan.change.common.enums;
/**
* @author WangJiaXiang
* @date 2022/11/18/018$
*/
public enum ChangeCommanderEnum {
COMMANDER_ORIGINATOR(1,"发起人"),
FIXED_PERSON(2,"固定人"),
GOODS_ASSOCIATED(3,"商品关联角色"),
SUPPLIERS_ASSOCIATED(4,"供应商关联角色");
ChangeCommanderEnum(Integer id, String name) {
this.id = id;
this.name = name;
}
private Integer id;
private String name;
public Integer getId() {
return id;
}
public String getName() {
return name;
}
public static ChangeCommanderEnum getChangeCommanderEnum(Integer id){
for (ChangeCommanderEnum day : ChangeCommanderEnum.values()) {
if (id.equals(day.getId())){
return day;
}
}
return null;
}
}
/**
* @(#)ChangeFlowEnum.java, 2022/11/16.
* <p/>
* Copyright 2022 Netease, Inc. All rights reserved.
* NETEASE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
package com.netease.mail.yanxuan.change.common.enums;
import lombok.Getter;
/**
* @Author zcwang
* @Date 2022/11/16
*/
public enum ChangeFlowEnum {
CHANGE_FLOW("0000", "全链路变更", "qc-change-flow"),
CHANGE_FLOW_START("79560500", "开始节点", "qc-change-flow"),
CHANGE_FLOW_SUBMIT("79560501", "变更申请提交", "qc-change-flow"),
CHANGE_FLOW_EXE("79560502","变更执行", "qc-change-flow"),
CHANGE_FLOW_CONFIRM("79560503","变更结果确认", "qc-change-flow"),
END("9999", "结束", "qc-change-flow");
@Getter
private final String nodeId;
private final String name;
@Getter
private final String topoId;
ChangeFlowEnum(String nodeId, String name, String topoId) {
this.nodeId = nodeId;
this.name = name;
this.topoId = topoId;
}
public static ChangeFlowEnum getByNodeId(String nodeId) {
for (ChangeFlowEnum value : ChangeFlowEnum.values()) {
if (value.getNodeId().equals(nodeId)) {
return value;
}
}
return null;
}
}
\ No newline at end of file
package com.netease.mail.yanxuan.change.common.enums;
/**
* @author WangJiaXiang
* @date 2022/11/16/016$
*/
public enum ChangeLevelEnum {
PRINCIPAL(1,"重要变更"),
ORDINARY(2,"一般变更");
private Integer type;
private String desc;
ChangeLevelEnum(Integer status, String desc) {
this.type = status;
this.desc = desc;
}
public Integer getStatus() {
return type;
}
public String getDesc() {
return desc;
}
}
package com.netease.mail.yanxuan.change.common.enums;
/**
* @author WangJiaXiang
* @date 2022/12/6/006$
*/
public enum ChangePrincipalEnum {
GOODS_BU(1,"商品开发"),
PURCHASE(2,"采购"),
PROSPECTUS(3,"计划"),
SQE(4,"SQE");
ChangePrincipalEnum(Integer type, String name) {
this.type = type;
this.name = name;
}
private Integer type;
private String name;
public Integer getType() {
return type;
}
public String getName() {
return name;
}
}
/**
* @(#)ChangeResultEnum.java, 2022/11/21.
* <p/>
* Copyright 2022 Netease, Inc. All rights reserved.
* NETEASE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
package com.netease.mail.yanxuan.change.common.enums;
/**
* @Author zcwang
* @Date 2022/11/21
*/
public enum ChangeResultEnum {
FINISH_ALL(1, "完成变更管理,风险可控,可实施变更"),
FINISH_PART(2, "完成变更管理,部分风险不可控,待修订变更方案"),
CANCEL(3, "不通过,变更取消"),
DELAY(4, "延期确认");
private Integer status;
private String desc;
ChangeResultEnum(Integer status, String desc) {
this.status = status;
this.desc = desc;
}
public static ChangeResultEnum getByStatus(Integer status) {
for (ChangeResultEnum value : ChangeResultEnum.values()) {
if (value.getStatus().equals(status)) {
return value;
}
}
return null;
}
public Integer getStatus() {
return status;
}
public String getDesc() {
return desc;
}
}
\ No newline at end of file
/**
* @(#)ChangeStateEnum.java, 2022/11/14.
* <p/>
* Copyright 2022 Netease, Inc. All rights reserved.
* NETEASE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
package com.netease.mail.yanxuan.change.common.enums;
/**
* @Author zcwang
* @Date 2022/11/14
*/
public enum ChangeStatusEnum {
IN(1, "进行中"),
CANCEL(2, "取消完结"),
DELAY(3, "延期"),
END(4, "完结"),
WAIT(5, "待发起");
private Integer status;
private String desc;
ChangeStatusEnum(Integer status, String desc) {
this.status = status;
this.desc = desc;
}
public Integer getStatus() {
return status;
}
public String getDesc() {
return desc;
}
}
\ No newline at end of file
/**
* @(#)ChangeSubjectEnum.java, 2022/11/14.
* <p/>
* Copyright 2022 Netease, Inc. All rights reserved.
* NETEASE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
package com.netease.mail.yanxuan.change.common.enums;
/**
* @Author zcwang
* @Date 2022/11/14
* 变更主体枚举
*/
public enum ChangeSubjectEnum {
PRODUCT(1, "商品变更"),
SUPPLIER(2, "供应商变更"),
OTHER(3, "其他变更");
private Integer type;
private String desc;
ChangeSubjectEnum(Integer type, String desc) {
this.type = type;
this.desc = desc;
}
public Integer getType() {
return type;
}
public String getDesc() {
return desc;
}
public static ChangeSubjectEnum getByType(Integer type) {
for (ChangeSubjectEnum value : ChangeSubjectEnum.values()) {
if (value.getType().equals(type)) {
return value;
}
}
return null;
}
public static String getDescByType(Integer type) {
for (ChangeSubjectEnum value : ChangeSubjectEnum.values()) {
if (value.getType().equals(type)) {
return value.getDesc();
}
}
return "";
}
public static ChangeSubjectEnum getChangeSubjectEnum(Integer id){
for (ChangeSubjectEnum day : ChangeSubjectEnum.values()) {
if (id == day.getType()){
return day;
}
}
return ChangeSubjectEnum.OTHER;
}
}
\ No newline at end of file
/**
* @(#)CreateSourceEnum.java, 2022/12/7.
* <p/>
* Copyright 2022 Netease, Inc. All rights reserved.
* NETEASE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
package com.netease.mail.yanxuan.change.common.enums;
/**
* @Author zcwang
* @Date 2022/12/7
*/
public enum CreateSourceEnum {
QC(1, "网易QC端"),
TONG_ZHOU(2, "同舟端"),
PRODUCT(3, "商品端");
private Integer type;
private String desc;
CreateSourceEnum(Integer type, String desc) {
this.type = type;
this.desc = desc;
}
public Integer getType() {
return type;
}
}
\ No newline at end of file
/**
* @(#)FileTypeEnum.java, 2022/11/14.
* <p/>
* Copyright 2022 Netease, Inc. All rights reserved.
* NETEASE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
package com.netease.mail.yanxuan.change.common.enums;
/**
* @Author zcwang
* @Date 2022/11/14
*/
public enum FileTypeEnum {
CHANGE(1, "变更前后图片/视频"),
UPLOAD(2, "发起变更资料上传"),
CHANGE_RESULT(3, "基础信息资料"),
CHANGE_RESULT_INFO(4, "变更结果资料");
private Integer type;
private String desc;
FileTypeEnum(Integer type, String desc) {
this.type = type;
this.desc = desc;
}
public Integer getType() {
return type;
}
}
\ No newline at end of file
package com.netease.mail.yanxuan.change.common.enums;
import lombok.AllArgsConstructor;
/**
* @author tangld
* 工单操作类型
*/
@AllArgsConstructor
public enum FlowOperationTypeEnum {
/**
* 通过
*/
PASS("pass"),
/**
* 驳回
*/
REFUSE("refuse"),
/**
* 转交
*/
DELIVER("deliver");
private String value;
public String getValue() {
return value;
}
}
package com.netease.mail.yanxuan.change.common.enums;
import lombok.AllArgsConstructor;
@AllArgsConstructor
public enum FlowxOperationEnum {
/**
* 创建成功
*/
CREATE(1, "创建成功"),
/**
* 提交工单
*/
SUBMIT(2, "提交工单"),
/**
* 审核通过
*/
APPROVE(3, "审核通过"),
/**
* 审批不通过
*/
APPROVE_FAIL(4, "审批不通过"),
/**
* 驳回
*/
REFUSE(5, "驳回"),
/**
* 转交
*/
DELIVER(6, "转交"),
/**
* 系统自动提交
*/
SYSTEM(7, "系统自动提交工单");
/**
* 类型
*/
private Integer type;
/**
* 名称
*/
private String name;
public Integer getType() {
return type;
}
public String getName() {
return name;
}
}
/**
* @(#)ItemSetupTypeEnum.java, 2022/12/20.
* <p/>
* Copyright 2022 Netease, Inc. All rights reserved.
* NETEASE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
package com.netease.mail.yanxuan.change.common.enums;
/**
* @Author zcwang
* @Date 2022/12/20
*/
public enum ItemSetupTypeEnum {
normal(0, "正常立项商品"),
special(2, "特殊免立项商品"),
combination(3, "组合装");
private Integer type;
private String desc;
ItemSetupTypeEnum(Integer type, String desc) {
this.type = type;
this.desc = desc;
}
public Integer getType() {
return type;
}
public String getDesc() {
return desc;
}
public static String getByType(Integer type) {
for (ItemSetupTypeEnum value : ItemSetupTypeEnum.values()) {
if (value.getType().equals(type)) {
return value.getDesc();
}
}
return "";
}
}
\ No newline at end of file
/**
* @(#)MainSpuStatusEmum.java, 2022/12/20.
* <p/>
* Copyright 2022 Netease, Inc. All rights reserved.
* NETEASE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
package com.netease.mail.yanxuan.change.common.enums;
/**
* @Author zcwang
* @Date 2022/12/20
*/
public enum MainSpuStatusEnum {
INIT(0,"未上架"),
NOT_ON_SHELVES(3,"未上架"),
ON_SHELVES(4,"已上架"),
PRESHELVING(5,"预上架");
private Integer status;
private String desc;
MainSpuStatusEnum(Integer status, String desc) {
this.status = status;
this.desc = desc;
}
public Integer getStatus() {
return status;
}
public String getDesc() {
return desc;
}
public static String getByStatus(Integer status) {
for (MainSpuStatusEnum value : MainSpuStatusEnum.values()) {
if (value.getStatus().equals(status)) {
return value.getDesc();
}
}
return "";
}
}
\ No newline at end of file
/**
* @(#)NeedFileEnum.java, 2022/11/15.
* <p/>
* Copyright 2022 Netease, Inc. All rights reserved.
* NETEASE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
package com.netease.mail.yanxuan.change.common.enums;
/**
* @Author zcwang
* @Date 2022/11/15
*/
public enum NeedFileEnum {
NEED(1, "需要上传文件"),
NOT_NEED(2, "无需上传文件");
private Integer status;
private String desc;
NeedFileEnum(Integer status, String desc) {
this.status = status;
this.desc = desc;
}
public Integer getStatus() {
return status;
}
}
\ No newline at end of file
/**
* @(#)OperateType.java, 2022/11/28.
* <p/>
* Copyright 2022 Netease, Inc. All rights reserved.
* NETEASE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
package com.netease.mail.yanxuan.change.common.enums;
/**
* @Author zcwang
* @Date 2022/11/28
*/
public enum OperateTypeEnum {
FINISH(1, "完成"),
CANCEL(2, "取消"),
DELIVER(3, "转交"),
DALAY(4, "延期"),
SAVE(7, "保存");
private Integer type;
private String desc;
OperateTypeEnum(Integer type) {
this.type = type;
}
OperateTypeEnum(Integer type, String desc) {
this.type = type;
this.desc = desc;
}
public Integer getType() {
return type;
}
}
\ No newline at end of file
/**
* @(#)ProfitTypeEnum.java, 2022/12/2.
* <p/>
* Copyright 2022 Netease, Inc. All rights reserved.
* NETEASE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
package com.netease.mail.yanxuan.change.common.enums;
/**
* @Author zcwang
* @Date 2022/12/2
*/
public enum ProfitTypeEnum {
RISK_CONTROL(1, "风险控制类"),
REDUCE_COST(2, "降本类"),
PRODUCT_IMPROVE(3, "商品改善"),
REPLACE_CERTIFICATES_WHEN_EXPIRE(4, "证件到期更换"),
OTHER(5, "其他"),
NO(6, "无");
private Integer type;
private String desc;
ProfitTypeEnum(Integer type, String desc) {
this.type = type;
this.desc = desc;
}
public Integer getType() {
return type;
}
public String getDesc() {
return desc;
}
public static String getByType(Integer type) {
for (ProfitTypeEnum value : ProfitTypeEnum.values()) {
if (value.getType().equals(type)) {
return value.getDesc();
}
}
return "";
}
}
\ No newline at end of file
/**
* @(#)SupplierChangePrincipalEnum.java, 2022/12/19.
* <p/>
* Copyright 2022 Netease, Inc. All rights reserved.
* NETEASE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
package com.netease.mail.yanxuan.change.common.enums;
/**
* @Author zcwang
* @Date 2022/12/19
*/
public enum SupplierChangePrincipalEnum {
PURCHASE(1,"采购"),
PROSPECTUS(2,"计划"),
SQE(3,"SQE"),
GOODS_BU(4,"商品开发");
SupplierChangePrincipalEnum(Integer type, String name) {
this.type = type;
this.name = name;
}
private Integer type;
private String name;
public Integer getType() {
return type;
}
public String getName() {
return name;
}
}
\ No newline at end of file
package com.netease.mail.yanxuan.change.common.enums;
/**
* 待办任务类型枚举值
*
* @author dmx
*/
public enum TodoTaskTypeEnum {
QC_CHANGE("101", "变更工单处理");
TodoTaskTypeEnum(String value, String desc) {
this.value = value;
this.desc = desc;
}
private final String value;
private final String desc;
public String getValue() {
return value;
}
}
...@@ -4,4 +4,4 @@ ...@@ -4,4 +4,4 @@
* @author 莫闲. * @author 莫闲.
* @date 2021/1/29. * @date 2021/1/29.
*/ */
package com.netease.mail.yanxuan.change.biz.meta.enums; package com.netease.mail.yanxuan.change.common.enums;
/**
* @(#)EnumUtil.java, 2015年8月28日.
*
* Copyright 2015 Netease, Inc. All rights reserved. NETEASE PROPRIETARY/CONFIDENTIAL. Use is
* subject to license terms.
*/
package com.netease.mail.yanxuan.change.common.util;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;
/**
* 工具类:[日期]、[字符串]、[时间]三者的转换工具类
* <p>
* 三者的转换是非常常用的,所以定义此工具类。三者的简要说明如下:
* <li>[日期]:日期对象
* <li>[字符串]:指的是日期的字符串表示
* <li>[时间]:long型的值
*
* @author hzyurui
*/
public class DateUtils {
private static Logger logger = LoggerFactory.getLogger(DateUtils.class);
public static final String DATETIMEFORMAT = "yyyyMMddHHmmss";
public static final String DATEFORMAT = "yyyyMMdd";
public static final String DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
public static final String DATE_TIME_FORMAT_2 = "yyyy-MM-dd HH:mm";
public static final String TIME_FORMAT = "HH:mm:ss";
public static final String DATE_FORMAT = "yyyy-MM-dd";
public static final String DATE_FORMAT_POINT = "yyyy.MM.dd";
public static final long TIME_OF_SECOND = 1000L;
public static final long TIME_OF_MINUTE = 60000L;
public static final long TIME_OF_HOUR = 3600000L;
public static final long TIME_OF_DAY = 86400000L;
private static long CURRENT_TIME = 0;
/**
* 将[日期]按照给定的[日期格式]转成[字符串]
*
* @param date
* 日期
* @param format
* 日期格式
*/
public static String parseDateToString(Date date, String format) {
if (date == null) {
return null;
}
if (StringUtils.isEmpty(format)) {
format = DATE_TIME_FORMAT;
}
SimpleDateFormat sdf = new SimpleDateFormat(format);
return sdf.format(date);
}
/**
* 将[时间]按照指定的[日期格式]转成[字符串]
*
* @param time
* 时间
* @param format
* 日期格式
*/
public static String parseLongToString(long time, String format) {
SimpleDateFormat mydate = new SimpleDateFormat(format);
return mydate.format(new Date(time));
}
/**
* 将[字符串]按照指定的[日期格式]转成[时间]
*
* @param time
* 字符串
* @param format
* 日期格式
*/
public static long parseStringToLong(String time, String format) {
SimpleDateFormat mydate = new SimpleDateFormat(format);
try {
Date date = mydate.parse(time);
if (date != null) {
return date.getTime();
}
} catch (ParseException e) {
logger.error("Date parse error:", e);
}
return 0;
}
/**
* 将[字符串]按照指定的[日期格式]转成[日期]
*
* @param time
* 字符串
* @param format
* 日期格式
*/
public static Date parseStringToDate(String time, String format) {
SimpleDateFormat mydate = new SimpleDateFormat(format);
try {
Date date = mydate.parse(time);
if (date != null) {
return date;
}
} catch (ParseException e) {
logger.error("Date parse error:", e);
}
return null;
}
/**
* 添加天数
*
* @param date
* 日期
* @param amount
* 增加天数
*/
public static Date addDay(Date date, int amount) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
calendar.add(Calendar.DAY_OF_MONTH, amount);
return calendar.getTime();
}
/**
* 获取某天的开始时间
*
* @param date
* 日期
*/
public static Date getStartTime(Date date) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
return calendar.getTime();
}
/**
* 获取某天零点的时间戳 xxxx-xx-xx 00:00:00:000
*
* @param date
* 日期
*/
public static long getStartTimeInMillis(Date date) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
return calendar.getTimeInMillis();
}
public static long getStartTimeInMillis(long time) {
return getStartTimeInMillis(new Date(time));
}
/**
* 获取某天的结束时间
*
* @param date
* 日期
*/
public static Date getEndTime(Date date) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
calendar.set(Calendar.HOUR_OF_DAY, 23);
calendar.set(Calendar.MINUTE, 59);
calendar.set(Calendar.SECOND, 59);
return calendar.getTime();
}
/**
* 获取某天的结束时间
*
* @param date
* 日期
*/
public static long getEndTimeInMillis(Date date) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
calendar.set(Calendar.HOUR_OF_DAY, 23);
calendar.set(Calendar.MINUTE, 59);
calendar.set(Calendar.SECOND, 59);
calendar.set(Calendar.MILLISECOND, 0);
return calendar.getTimeInMillis();
}
/**
* 获取某天的结束时间前一秒
* <p>
* 预留到最后一秒
*
* @param date
* 日期
*/
public static Date getEndTimeWithLastSecond(Date date) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
calendar.set(Calendar.HOUR_OF_DAY, 23);
calendar.set(Calendar.MINUTE, 59);
calendar.set(Calendar.SECOND, 59);
calendar.set(Calendar.MILLISECOND, 0);
return calendar.getTime();
}
/**
* 获取某天的结束时间前N秒
* <p>
* 预留到最后N秒
*
* @param date
* 日期
*/
public static Date getEndTimeWithLastSecond(Date date, int second) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
calendar.set(Calendar.HOUR_OF_DAY, 23);
calendar.set(Calendar.MINUTE, 59);
calendar.set(Calendar.SECOND, 60 - second);
calendar.set(Calendar.MILLISECOND, 0);
return calendar.getTime();
}
/**
* 获取当前时间在一天中的分钟数
*/
public static int getCurrentMinutesOfDay(Calendar c) {
//获取当前小时数
int hour = c.get(Calendar.HOUR_OF_DAY);
//获取当前小时的分钟数
int minute = c.get(Calendar.MINUTE);
return hour * 60 + minute;
}
/**
* 获取某天开始的时间戳
*
* @param month
* 0-11
*/
public static long getStartTimeOfDayInMillis(int year, int month,
int date) {
Calendar calendar = Calendar.getInstance();
calendar.set(year, month, date);
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
return calendar.getTimeInMillis();
}
/**
* 获取某天结束的时间戳
*
* @param month
* 0-11
*/
public static long getEndTimeOfDayInMillis(int year, int month, int date) {
Calendar calendar = Calendar.getInstance();
calendar.set(year, month, date);
calendar.set(Calendar.HOUR_OF_DAY, 23);
calendar.set(Calendar.MINUTE, 59);
calendar.set(Calendar.SECOND, 59);
return calendar.getTimeInMillis();
}
/**
* 获取某月开始的时间戳
*
* @param month
* 0-11
*/
public static long getStartTimeOfMonthInMillis(int year, int month) {
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.YEAR, year);
calendar.set(Calendar.MONTH, month);
calendar.set(Calendar.DAY_OF_MONTH, 1);
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
return calendar.getTimeInMillis();
}
/**
* 获取某月结束的时间戳
*
* @param month
* 0-11
*/
public static long getEndTimeOfMonthInMillis(int year, int month) {
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.YEAR, year);
calendar.set(Calendar.MONTH, month);
calendar.set(Calendar.DAY_OF_MONTH,
calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
calendar.set(Calendar.HOUR_OF_DAY, 23);
calendar.set(Calendar.MINUTE, 59);
calendar.set(Calendar.SECOND, 59);
return calendar.getTimeInMillis();
}
/**
* 获取指定个月后的时间戳
*/
public static long getMonthsDelayTime(long currentTime, int months) {
Calendar c = Calendar.getInstance();
c.setTimeInMillis(currentTime);
c.add(Calendar.MONTH, months);
return c.getTimeInMillis();
}
/**
* 获取指定个天后的时间戳
*/
public static long getDaysDelayTime(long currentTime, int days) {
Calendar c = Calendar.getInstance();
c.setTimeInMillis(currentTime);
c.add(Calendar.DAY_OF_YEAR, days);
return c.getTimeInMillis();
}
/**
* 获取指定分钟后的时间戳
*/
public static long getHoursDelayTime(long currentTime, int mins) {
Calendar c = Calendar.getInstance();
c.setTimeInMillis(currentTime);
c.add(Calendar.HOUR_OF_DAY, mins);
return c.getTimeInMillis();
}
/**
* 获取指定分钟后的时间戳
*/
public static long getMinutesDelayTime(long currentTime, int mins) {
Calendar c = Calendar.getInstance();
c.setTimeInMillis(currentTime);
c.add(Calendar.MINUTE, mins);
return c.getTimeInMillis();
}
/**
* 获取指定时间的星期一
*/
public static long getStartTimeOfWeek(Date date) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
calendar.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
return calendar.getTimeInMillis();
}
/**
* 获取指定时间剩余毫秒数
*/
public static long getLeftTimeMilesForDate(Date date) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
calendar.add(Calendar.DAY_OF_YEAR, 1);
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
return calendar.getTimeInMillis() - date.getTime();
}
/**
* 获取指定时间+mins分钟后的整分时间
*/
public static long getStartTimeOfMinitue(long currentTime, int mins) {
Calendar c = Calendar.getInstance();
c.setTimeInMillis(currentTime);
c.set(Calendar.SECOND, 0);
c.set(Calendar.MILLISECOND, 0);
c.add(Calendar.MINUTE, mins);
return c.getTimeInMillis();
}
/**
* 获取指定时间的周一
*
* @param currentTime
* 时间戳
*/
public static String getWeekFirstDay(long currentTime) {
Calendar c = Calendar.getInstance();
c.setTimeInMillis(currentTime);
c.setFirstDayOfWeek(Calendar.MONDAY);
c.set(Calendar.DAY_OF_WEEK, c.getFirstDayOfWeek());
return parseDateToString(c.getTime(), "yyyyMMdd");
}
/**
* 获取当前周在第几天
*
* @param currentTime
* 时间戳
*/
public static int dayForWeek(long currentTime) {
Calendar c = Calendar.getInstance();
c.setTimeInMillis(currentTime);
int dayForWeek;
if (c.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY) {
dayForWeek = 7;
} else {
dayForWeek = c.get(Calendar.DAY_OF_WEEK) - 1;
}
return dayForWeek;
}
/**
* 获取当前的小时数
*
* @param currentTime
* 时间戳
*/
public static int getHour(long currentTime) {
Calendar c = Calendar.getInstance();
c.setTimeInMillis(currentTime);
return c.get(Calendar.HOUR_OF_DAY);
}
/**
* 获取当前的时间
*/
public static long getCurrentTime() {
if (CURRENT_TIME > 0) {
return CURRENT_TIME;
} else {
return System.currentTimeMillis();
}
}
/**
* 设置当前的时间
*
* @param currentTime
* 当前时间
*/
public static void setCurrentTime(long currentTime) {
CURRENT_TIME = currentTime;
}
/**
* 获取今天特定时间的时间戳
* @param timeStr
* @return
*/
public static Long getToDaySpecificTime(String timeStr) {
SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT);
String dateStr = sdf.format(new Date());
String fullStr = dateStr + " " + timeStr;
Long time = parseStringToLong(fullStr, DATE_TIME_FORMAT);
return time;
}
/**
* 获取今天的日期字符串
* @return
*/
public static String getToDayStr() {
SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT);
String dateStr = sdf.format(new Date());
return dateStr;
}
/**
* 获取明天特定时间的时间戳
* @param timeStr
* @return
*/
public static Long getTomorrowSpecificTime(String timeStr) {
return getToDaySpecificTime(timeStr) + TIME_OF_DAY;
}
}
/**
* @(#)ExcelUtil.java, 2022/7/5.
* <p/>
* Copyright 2022 Netease, Inc. All rights reserved.
* NETEASE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
package com.netease.mail.yanxuan.change.common.util;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.springframework.web.multipart.MultipartFile;
import com.netease.mail.dp.des.common.api.enums.ExcelCellType;
import com.netease.mail.dp.des.process.api.entity.ExcelCell;
import com.netease.mail.dp.des.process.api.entity.ExcelTitle;
import com.netease.mail.yanxuan.change.common.anno.ExcelTitleName;
import cn.afterturn.easypoi.excel.ExcelImportUtil;
import cn.afterturn.easypoi.excel.entity.ImportParams;
/**
* @author ysl (wb.yeshunliang01@mesg.corp.netease.com)
*/
public class ExcelUtil {
private static final List<Field> NULL_FIELDS = Collections.emptyList();
private static Map<Class<?>, List<Field>> annotedFieldMap = new ConcurrentHashMap<>(4);
/**
* 解析excel,转换成list
* @param file
* @param clazz
* @param <T>
* @return
*/
public static <T> List<T> parseExcelList(MultipartFile file, Class<T> clazz) {
List<T> list;
try {
InputStream inputStream = file.getInputStream();
ImportParams importParams = new ImportParams();
list = ExcelImportUtil.importExcel(inputStream, clazz, importParams);
} catch (Exception e) {
throw new IllegalArgumentException("上传的文件错误");
}
return list;
}
public static <T> ExcelTitle fetchExceltile(Class<T> clazz) {
if (clazz == null) {
throw new RuntimeException("clazz参数不能为空");
}
List<Field> sortedFields = fetchAnnotedFields(clazz);
if (sortedFields == NULL_FIELDS) {
throw new RuntimeException("未找到表头字段");
}
ExcelTitle excelTitle = new ExcelTitle();
List<ExcelCell> excelCells = new ArrayList<>();
sortedFields.forEach(field -> {
ExcelCell excelCell = new ExcelCell();
excelCell.setValue(field.getAnnotation(ExcelTitleName.class).title());
excelCell.setCellType(ExcelCellType.NORMAL);
excelCells.add(excelCell);
});
excelTitle.setTitle(excelCells);
return excelTitle;
}
private static <T> List<Field> fetchAnnotedFields(Class<T> clazz) {
if (annotedFieldMap.containsKey(clazz)) {
return annotedFieldMap.get(clazz);
}
Field[] fields = clazz.getDeclaredFields();
Map<Field, ExcelTitleName> fieldMap = new HashMap<>(4);
for (Field field: fields) {
ExcelTitleName column = field.getAnnotation(ExcelTitleName.class);
if (column == null) {
continue;
}
fieldMap.put(field, column);
}
if (fieldMap.isEmpty()) {
annotedFieldMap.put(clazz, NULL_FIELDS);
return NULL_FIELDS;
}
List<Field> fieldList = new ArrayList<>(fieldMap.keySet());
Collections.sort(fieldList, (field1, field2) -> {
ExcelTitleName column1 = fieldMap.get(field1);
ExcelTitleName column2 = fieldMap.get(field2);
return column1.order() - column2.order();
});
annotedFieldMap.put(clazz, fieldList);
return fieldList;
}
}
\ No newline at end of file
package com.netease.mail.yanxuan.change.common.util;
import java.io.BufferedReader;
import javax.servlet.http.HttpServletRequest;
import org.springframework.util.StringUtils;
/**
* @author cyZhao
* @date 2019/1/28
*/
public class RequestUtil {
public static final String CHAR_SET = "UTF-8";
private static final String POST_METHOD = "POST";
public static String getRequestPath(HttpServletRequest request) {
if (request == null) {
return null;
}
String path = request.getRequestURI();
String queryStr = request.getQueryString();
if (!StringUtils.isEmpty(queryStr)) {
path = path + "?" + queryStr;
}
if (POST_METHOD.equals(request.getMethod().toUpperCase())) {
String body = getRequestBody(request);
if (!StringUtils.isEmpty(body)) {
path += "\nbody: " + body;
}
}
return path;
}
private static String getRequestBody(HttpServletRequest request) {
StringBuffer json = new StringBuffer();
String line;
try {
BufferedReader reader = request.getReader();
while ((line = reader.readLine()) != null) {
json.append(line);
}
} catch (Exception e) {
}
return json.toString();
}
}
package com.netease.mail.yanxuan.change.common.util;
import java.io.IOException;
import javax.servlet.http.HttpServletResponse;
import com.alibaba.fastjson.JSONObject;
/**
* @author cyZhao
* @date 2019/1/28
*/
public class ResponseUtil {
/**
* 输出json
*/
public static void writeJson(HttpServletResponse response, String json) throws IOException {
response.setContentType("application/json;charset=UTF-8");
response.setHeader("CACHE-CONTROL", "no-aspect");
response.getWriter().write(json);
response.flushBuffer();
}
/**
* 输出json
*/
public static void writeJson(HttpServletResponse response, Object json) throws IOException {
writeJson(response, JSONObject.toJSONString(json));
}
}
...@@ -17,22 +17,17 @@ ...@@ -17,22 +17,17 @@
<artifactId>yanxuan-qc-change-system-common</artifactId> <artifactId>yanxuan-qc-change-system-common</artifactId>
</dependency> </dependency>
<!-- store-db <!--store-db-->
<dependency> <dependency>
<groupId>org.mybatis.spring.boot</groupId> <groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId> <artifactId>mybatis-spring-boot-starter</artifactId>
</dependency> </dependency>
<dependency> <dependency>
<groupId>netease.ddb</groupId>
<artifactId>db</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId> <groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId> <artifactId>mysql-connector-java</artifactId>
</dependency> </dependency>
-->
<!-- store-redis <!--store-redis-->
<dependency> <dependency>
<groupId>redis.clients</groupId> <groupId>redis.clients</groupId>
<artifactId>jedis</artifactId> <artifactId>jedis</artifactId>
...@@ -41,7 +36,6 @@ ...@@ -41,7 +36,6 @@
<groupId>org.springframework.data</groupId> <groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId> <artifactId>spring-data-redis</artifactId>
</dependency> </dependency>
-->
</dependencies> </dependencies>
</project> </project>
\ No newline at end of file
/**
* @(#)ChangeConfig.java, 2022/11/11.
* <p/>
* Copyright 2022 Netease, Inc. All rights reserved.
* NETEASE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
package com.netease.mail.yanxuan.change.dal.entity;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @Author zcwang
* @Date 2022/11/11
*/
@AllArgsConstructor
@NoArgsConstructor
@Builder
@Data
@Entity
@Table(name = "TB_YX_QC_CHANGE_CONFIG")
public class ChangeConfig {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
/**
* 变更主体
*/
private Integer changeSubject;
/**
* 一级变更类型id
*/
private Long parentChangeClassId;
/**
* 二级变更类型id
*/
private Long sonChangeClassId;
/**
* 变更等级
*/
private Integer changeLevel;
/**
* 变更负责部门名
*/
private String changeDepartment;
/**
* 变更执行部门
*/
private String participateChangeExecDepartment;
/**
* 变更负责人类型
*/
private Integer changeCommanderType;
/**
* 变更负责人详情(不同类型存储不同内容)
*/
private String changeCommander;
/**
* 是否需要资料上传
*/
private Integer needFile;
/**
* 创建人
*/
private String creator;
/**
* 创建时间
*/
private Long createTime;
/**
* 更新时间
*/
private Long updateTime;
}
\ No newline at end of file
/**
* @(#)ChangeExecConfig.java, 2022/11/11.
* <p/>
* Copyright 2022 Netease, Inc. All rights reserved.
* NETEASE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
package com.netease.mail.yanxuan.change.dal.entity;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @Author zcwang
* @Date 2022/11/11
*/
@AllArgsConstructor
@NoArgsConstructor
@Builder
@Data
@Entity
@Table(name = "TB_YX_QC_CHANGE_EXEC_CONFIG")
public class ChangeExecConfig {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
/**
* 变更类型配置记录id
*/
private Long changeTemplateId;
/**
* 变更执行部门名
*/
private String changeExecDepartment;
/**
* 变更行动人类型
*/
private Integer changeExecUserType;
/**
* 变更行动人(不同类型存储不同内容)
*/
private String changeExecUser;
/**
* 变更风险描述
*/
private String changeRiskDesc;
/**
* 行动项
*/
private String changeExecProject;
/**
* 变更验证措施
*/
private String changeChecking;
/**
* 创建时间
*/
private Long createTime;
/**
* 更新时间
*/
private Long updateTime;
}
\ No newline at end of file
/**
* @(#)ChangeExecRecord.java, 2022/11/11.
* <p/>
* Copyright 2022 Netease, Inc. All rights reserved.
* NETEASE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
package com.netease.mail.yanxuan.change.dal.entity;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @Author zcwang
* @Date 2022/11/11
*/
@AllArgsConstructor
@NoArgsConstructor
@Builder
@Data
@Entity
@Table(name = "TB_YX_QC_CHANGE_EXEC_RECORD")
public class ChangeExecRecord {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
/**
* 变更记录id
*/
private Long changeRecordId;
/**
* 变更执行部门名
*/
private String changeExecDepartment;
/**
* 变更行动人类型
*/
private Integer changeExecUserType;
/**
* 变更行动人(不同类型存储不同内容)
*/
private String changeExecUser;
/**
* 变更行动人邮箱
*/
private String changeExecUserEmail;
/**
* 变更风险描述
*/
private String changeRiskDesc;
/**
* 行动项
*/
private String changeExecProject;
/**
* 变更措施验证
*/
private String changeChecking;
/**
* 行动完成时间
*/
private Long changeExecFinishTime;
/**
* 行动完成情况
*/
private String changeExecFinishDesc;
/**
* 创建时间
*/
private Long createTime;
/**
* 更新时间
*/
private Long updateTime;
}
\ No newline at end of file
/**
* @(#)ChangeFile.java, 2022/11/11.
* <p/>
* Copyright 2022 Netease, Inc. All rights reserved.
* NETEASE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
package com.netease.mail.yanxuan.change.dal.entity;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @Author zcwang
* @Date 2022/11/11
*/
@AllArgsConstructor
@NoArgsConstructor
@Builder
@Data
@Entity
@Table(name = "TB_YX_QC_CHANGE_FILE")
public class ChangeFile {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
/**
* change_record_id
*/
private Long changeRecordId;
/**
* 文件类型(基础信息图片/基础信息视频/基础信息资料/变更结果资料)
*/
private Integer fileType;
/**
* 文件名称
*/
private String fileName;
/**
* 文件地址
*/
private String fileUrl;
/**
* 创建时间
*/
private Long createTime;
/**
* 更新时间
*/
private Long updateTime;
}
\ No newline at end of file
/**
* @(#)ChangeRecord.java, 2022/11/11.
* <p/>
* Copyright 2022 Netease, Inc. All rights reserved.
* NETEASE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
package com.netease.mail.yanxuan.change.dal.entity;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @Author zcwang
* @Date 2022/11/11
*/
@AllArgsConstructor
@NoArgsConstructor
@Builder
@Data
@Entity
@Table(name = "TB_YX_QC_CHANGE_RECORD")
public class ChangeRecord {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
/**
* 工单id
*/
private Long flowId;
/**
* 工单当前节点
*/
private String flowNode;
/**
* 变更主体
*/
private Integer changeSubject;
/**
* 一级变更类型id
*/
private Long parentChangeClassId;
/**
* 二级变更类型id
*/
private Long sonChangeClassId;
/**
* 变更等级
*/
private Integer changeLevel;
/**
* 变更负责人
*/
private String changeCommander;
/**
* 变更负责部门名
*/
private String changeDepartment;
/**
* 参与变更行动部门,json格式,查询用
*/
private String participateChangeExecDepartment;
/**
* 变更商品(变更主体为商品时有效)
*/
private String changeItem;
/**
* 变更供应商(变更主体为供应商时有效)
*/
private String changeSupplier;
/**
* 变更原因
*/
private String changeReason;
/**
* 变更内容
*/
private String changeContent;
/**
* 变更潜在风险描述
*/
private String changeRiskDesc;
/**
* 变更验证措施
*/
private String changeChecking;
/**
* 变更收益类型
*/
private Integer changeProfit;
/**
* 变更收益说明
*/
private String changeProfitDesc;
/**
* 变更结果确认时间
*/
private Long changeConfirmResultTime;
/**
* 工单状态
*/
private Integer state;
/**
* 取消原因
*/
private String cancelReason;
/**
* 变更结论
*/
private Integer changeResult;
/**
* 创建端(普通or同舟)
*/
private Integer createSource;
/**
* 创建人所属供应商(同舟创建)
*/
private String createSupplier;
/**
* 结论说明
*/
private String changeResultDesc;
/**
* 备注
*/
private String remark;
/**
* 创建人邮箱
*/
private String creator;
/**
* 待办id
*/
private Integer todoId;
/**
* 自动执行邮件发送
*/
private Integer autoSubmitEmail;
/**
* 创建时间
*/
private Long createTime;
/**
* 更新时间
*/
private Long updateTime;
}
\ No newline at end of file
/**
* @(#)ChangeType.java, 2022/11/11.
* <p/>
* Copyright 2022 Netease, Inc. All rights reserved.
* NETEASE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
package com.netease.mail.yanxuan.change.dal.entity;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @Author zcwang
* @Date 2022/11/11
*/
@AllArgsConstructor
@NoArgsConstructor
@Builder
@Data
@Entity
@Table(name = "TB_YX_QC_CHANGE_TYPE")
public class ChangeType {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
/**
* 类型名
*/
private String typeName;
/**
* 父类id
*/
private Long parentId;
/**
* 是否删除
*/
private Integer deleteType;
/**
* 创建时间
*/
private Long createTime;
/**
* 更新时间
*/
private Long updateTime;
}
\ No newline at end of file
/**
* @(#)ChangeConfigMapper.java, 2022/11/11.
* <p/>
* Copyright 2022 Netease, Inc. All rights reserved.
* NETEASE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
package com.netease.mail.yanxuan.change.dal.mapper;
import com.netease.mail.yanxuan.change.dal.entity.ChangeType;
import com.netease.mail.yanxuan.change.dal.meta.model.po.ChangeConfigPo;
import com.netease.mail.yanxuan.change.dal.meta.model.req.ChangeConfigQueryReq;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Mapper;
import com.netease.mail.yanxuan.change.dal.entity.ChangeConfig;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import java.util.List;
/**
* @Author zcwang
* @Date 2022/11/11
*/
@Mapper
public interface ChangeConfigMapper extends tk.mybatis.mapper.common.Mapper<ChangeConfig> {
@Select("select * from TB_YX_QC_CHANGE_CONFIG where id = #{id}")
ChangeConfig queryById(@Param("id") Long id);
ChangeConfig queryInfo(@Param("id") Long id,@Param("sonChangeClassId") Long sonChangeClassId);
ChangeConfigPo queryInfoPo(@Param("parentChangeClassId")Long parentChangeClassId,
@Param("sonChangeClassId")Long sonChangeClassId);
@Delete("delete from TB_YX_QC_CHANGE_CONFIG where id = #{id}")
void deleteById(@Param("id") Long id);
@Select("select * from TB_YX_QC_CHANGE_CONFIG where parent_change_class_id = #{parentChangeClassId} and son_change_class_id = #{sonChangeClassId}")
ChangeConfig queryChangeType(
@Param("parentChangeClassId")Long parentChangeClassId,
@Param("sonChangeClassId")Long sonChangeClassId);
List<ChangeConfigPo> selectChangeConfigPo(ChangeConfigQueryReq req);
List<ChangeType> queryByparentChangeClassId();
//暂时弃用
//ChangeExecConfigPo queryChangeDepartment(@Param("id")Long id);
void add(ChangeConfig changeConfig);
@Select("select * from TB_YX_QC_CHANGE_CONFIG where son_change_class_id = #{sonChangeId} limit 1")
ChangeConfig selectBySonConfig(@Param("sonChangeId") Long sonChangeId);
}
\ No newline at end of file
/**
* @(#)ChangeExecConfig.java, 2022/11/11.
* <p/>
* Copyright 2022 Netease, Inc. All rights reserved.
* NETEASE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
package com.netease.mail.yanxuan.change.dal.mapper;
import com.netease.mail.yanxuan.change.dal.meta.model.po.ChangeExecConfigPo;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Mapper;
import com.netease.mail.yanxuan.change.dal.entity.ChangeExecConfig;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import java.util.List;
/**
* @Author zcwang
* @Date 2022/11/11
*/
@Mapper
public interface ChangeExecConfigMapper extends tk.mybatis.mapper.common.Mapper<ChangeExecConfig> {
@Select("select * from TB_YX_QC_CHANGE_EXEC_CONFIG where change_template_id = #{changeTemplateId}")
List<ChangeExecConfig> queryChangeExecConfig(@Param("changeTemplateId")Long changeTemplateId);
@Select("select COUNT(change_template_id) as coreDepartment, change_exec_department " +
"from TB_YX_QC_CHANGE_EXEC_CONFIG where change_template_id = #{id} " +
"group by change_exec_department order by coreDepartment DESC LIMIT 1;")
ChangeExecConfigPo queryChangeDepartment(@Param("id")Long id);
@Delete("delete from TB_YX_QC_CHANGE_EXEC_CONFIG where change_template_id = #{changeTemplateId}")
int deleteChangeConfig(@Param("changeTemplateId")Long changeTemplateId);
}
\ No newline at end of file
/**
* @(#)ChangeExecRecordMapper.java, 2022/11/11.
* <p/>
* Copyright 2022 Netease, Inc. All rights reserved.
* NETEASE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
package com.netease.mail.yanxuan.change.dal.mapper;
import java.util.List;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import com.netease.mail.yanxuan.change.dal.entity.ChangeExecRecord;
/**
* @Author zcwang
* @Date 2022/11/11
*/
@Mapper
public interface ChangeExecRecordMapper extends tk.mybatis.mapper.common.Mapper<ChangeExecRecord> {
@Select("SELECT * FROM TB_YX_QC_CHANGE_EXEC_RECORD WHERE change_record_id = #{changeRecordId}")
List<ChangeExecRecord> selectByChangeRecordId(@Param("changeRecordId") Long id);
@Insert({ "<script>",
"insert into TB_YX_QC_CHANGE_EXEC_RECORD(change_record_id, change_exec_department, change_exec_user_type, change_exec_user, change_risk_desc,change_exec_project, change_checking, change_exec_finish_time, change_exec_finish_desc, create_time, update_time) values ",
"<foreach collection='list' item='item' index='index' separator=','>",
"(#{item.changeRecordId}, #{item.changeExecDepartment}, #{item.changeExecUserType}, #{item.changeExecUser}, #{item.changeRiskDesc}, #{item.changeExecProject}, #{item.changeChecking}, #{item.changeExecFinishTime}, #{item.changeExecFinishDesc}, #{item.createTime}, #{item.updateTime})",
"</foreach>", "</script>" })
void insertList(@Param("list") List<ChangeExecRecord> changeExecRecordList);
@Delete("delete from TB_YX_QC_CHANGE_EXEC_RECORD where change_record_id = #{changeRecordId}")
Integer deleteByBaseId(@Param("changeRecordId") Long changeRecordId);
}
/**
* @(#)ChangeFileMapper.java, 2022/11/11.
* <p/>
* Copyright 2022 Netease, Inc. All rights reserved.
* NETEASE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
package com.netease.mail.yanxuan.change.dal.mapper;
import java.util.List;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import com.netease.mail.yanxuan.change.dal.entity.ChangeFile;
/**
* @Author zcwang
* @Date 2022/11/11
*/
@Mapper
public interface ChangeFileMapper extends tk.mybatis.mapper.common.Mapper<ChangeFile> {
@Select("SELECT * FROM TB_YX_QC_CHANGE_FILE WHERE change_record_id = #{changeRecordId}")
List<ChangeFile> selectByChangeRecordId(@Param("changeRecordId") Long changeRecordId);
@Insert({ "<script>",
"insert into TB_YX_QC_CHANGE_FILE(change_record_id, file_type, file_name, file_url, create_time, update_time) values ",
"<foreach collection='list' item='item' index='index' separator=','>",
"(#{item.changeRecordId}, #{item.fileType}, #{item.fileName}, #{item.fileUrl}, #{item.createTime}, #{item.updateTime})",
"</foreach>", "</script>" })
void insertList(List<ChangeFile> changeFiles);
@Delete("delete from TB_YX_QC_CHANGE_FILE where change_record_id = #{changeRecordId}")
Integer deleteByBaseId(Long changeRecordId);
@Delete("delete from TB_YX_QC_CHANGE_FILE where change_record_id = #{changeRecordId} and file_type = #{type}")
void deleteByBaseIdAndType(@Param("changeRecordId") Long changeRecordId, @Param("type") Integer type);
}
\ No newline at end of file
/**
* @(#)ChangeRecordMapper.java, 2022/11/11.
* <p/>
* Copyright 2022 Netease, Inc. All rights reserved.
* NETEASE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
package com.netease.mail.yanxuan.change.dal.mapper;
import java.util.List;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import com.netease.mail.yanxuan.change.dal.entity.ChangeRecord;
import com.netease.mail.yanxuan.change.dal.meta.model.req.ChangeFlowListQueryReq;
/**
* @Author zcwang
* @Date 2022/11/11
*/
@Mapper
public interface ChangeRecordMapper extends tk.mybatis.mapper.common.Mapper<ChangeRecord> {
@Select("select * from TB_YX_QC_CHANGE_RECORD where `flow_id` = #{flowId} limit 1")
ChangeRecord selectByFlowId(@Param("flowId") Long flowId);
List<ChangeRecord> selectByCondition(ChangeFlowListQueryReq changeFlowListQueryReq);
List<ChangeRecord> selectByConditionAndLimit(ChangeFlowListQueryReq changeFlowListQueryReq);
@Select("select * from TB_YX_QC_CHANGE_RECORD where id > #{entityId} and auto_submit_email = #{sendEmail} and `flow_node` in (#{nodeId1}, #{nodeId2}) and change_confirm_result_time <= #{currentTime} limit 200")
List<ChangeRecord> getByStatusAndTime(@Param("entityId") Long entityId, @Param("sendEmail") Integer sendEmail, @Param("nodeId1") String nodeId1,
@Param("nodeId2") String nodeId2, @Param("currentTime") long currentTime);
}
/**
* @(#)ChangeTypeMapper.java, 2022/11/11.
* <p/>
* Copyright 2022 Netease, Inc. All rights reserved.
* NETEASE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
package com.netease.mail.yanxuan.change.dal.mapper;
import com.netease.mail.yanxuan.change.dal.meta.model.po.ChangeTypePo;
import org.apache.ibatis.annotations.Mapper;
import com.netease.mail.yanxuan.change.dal.entity.ChangeType;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import java.util.List;
/**
* @Author zcwang
* @Date 2022/11/11
*/
@Mapper
public interface ChangeTypeMapper extends tk.mybatis.mapper.common.Mapper<ChangeType> {
@Select("select * from TB_YX_QC_CHANGE_TYPE where type_name = #{typeName} and parent_id = 0 and delete_type = 0")
ChangeType queryTypeName(@Param("typeName") String typeName);
@Select("select * from TB_YX_QC_CHANGE_TYPE where id in(#{id},#{sonChangeClassId}) and delete_type = #{deleteType} order by parent_id ")
List<ChangeType> queryTypes(
@Param("id") Long id,
@Param("sonChangeClassId")Long sonChangeClassId,
@Param("deleteType")Integer deleteType);
@Select("select * from TB_YX_QC_CHANGE_TYPE where delete_type = 0 ")
List<ChangeTypePo> queryArrayChangeTypes();
@Select("select * from TB_YX_QC_CHANGE_TYPE where parent_id = #{id} and delete_type = 0")
List<ChangeType> queryParent(@Param("id") Long id);
}
\ No newline at end of file
package com.netease.mail.yanxuan.change.dal.meta.model.dto;
import lombok.Data;
@Data
public class ChangeExecConfigDTO {
private Long id;
/**
* 变更类型配置记录id
*/
private Long changeTemplateId;
/**
* 变更执行部门名
*/
private String changeExecDepartment;
/**
* 变更行动人类型
*/
private Integer changeExecUserType;
/**
* 变更行动人(不同类型存储不同内容)
*/
private String changeExecUser;
/**
* 行动人名
*/
private String changeExecUserName;
/**
* 变更风险描述
*/
private String changeRiskDesc;
/**
* 行动项
*/
private String changeExecProject;
/**
* 变更验证措施
*/
private String changeChecking;
/**
* 创建时间
*/
private Long createTime;
/**
* 更新时间
*/
private Long updateTime;
}
package com.netease.mail.yanxuan.change.dal.meta.model.po;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
import javax.validation.constraints.NotNull;
/**
* @author WangJiaXiang
* @date 2022/11/18/018$
* 用来查询最终负责人信息
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class ChangeCommanderPO {
/**
* 一级类型ID
*/
private Long parentChangeClassId;
/**
* 二级类型ID
*/
private Long sonChangeClassId;
/**
* 供应商信息
*/
private String changeSupplierId;
/**
* 商品信息
*/
private List<Long> goodsInfos;
/**
* 创建人
*/
private String flowCreator;
/**
* 创建端(普通or同舟)
*/
private Integer createSource;
/**
* 同舟端所属供应商
*/
private String supplier;
}
package com.netease.mail.yanxuan.change.dal.meta.model.po;
import com.netease.mail.yanxuan.change.dal.entity.ChangeType;
import lombok.Data;
import java.util.List;
/**
* @author WangJiaXiang
* @date 2022/11/11/011$
* 变更任务PO
*/
@Data
public class ChangeConfigPo {
private Long id;
/**
* 变更主体
*/
private Integer changeSubject;
/**
* 一级变更类型id
*/
private Integer parentChangeClassId;
/**
* 二级变更类型id
*/
private Integer sonChangeClassId;
/**
* 变更等级
*/
private Integer changeLevel;
/**
* 变更负责人类型
*/
private Integer changeCommanderType;
/**
* 变更负责人详情(不同类型存储不同内容)
*/
private String changeCommander;
/**
* 是否需要资料上传
*/
private Integer needFile;
/**
* 创建人
*/
private String creator;
/**
* 创建时间
*/
private Long createTime;
/**
* 更新时间
*/
private Long updateTime;
/**
* 变更负责部门名
*/
private String changeDepartment;
/**
* 变更执行部门
*/
private String participateChangeExecDepartment;
/**
* 关联的一级二级类目
*/
List<ChangeType> changeTypes;
}
package com.netease.mail.yanxuan.change.dal.meta.model.po;
import lombok.Data;
/**
* @author WangJiaXiang
* @date 2022/11/15/015$
*/
@Data
public class ChangeExecConfigPo {
/**
* 主要负责修改部门出现次数
*/
private Integer coreDepartment;
/**
* 变更负责部门名
*/
private String changeExecDepartment;
}
package com.netease.mail.yanxuan.change.dal.meta.model.po;
import lombok.Data;
/**
* @author WangJiaXiang
* @date 2022/12/2/002$
*/
@Data
public class ChangeGoodsPrincipalPO {
/**
* 负责人名称
*/
private String functionaryName;
/**
* 负责人邮箱
*/
private String functionaryEmail;
/**
* 采购名称
*/
private String purchaseName;
/**
* 采购邮箱
*/
private String purchaseEmail;
/**
* 计划负责人名称
*/
private String goodsProjectName;
/**
* 计划负责人邮箱
*/
private String goodsProjectEmail;
/**
* SQE 名称
*/
private String goodsSqeName;
/**
* SQE 邮箱
*/
private String goodsSqeEmail;
}
package com.netease.mail.yanxuan.change.dal.meta.model.po;
import lombok.Data;
import java.util.List;
/**
* @author WangJiaXiang
* @date 2022/11/16/016$
*/
@Data
public class ChangeTypePo {
private Long id;
/**
* 类型名
*/
private String typeName;
/**
* 父类id
*/
private Long parentId;
/**
* 是否删除
*/
private Integer delete;
/**
* 创建时间
*/
private Long createTime;
/**
* 更新时间
*/
private Long updateTime;
private List<ChangeTypePo> changeTypes;
}
/**
* @(#)QueryCommanderEmailReq.java, 2022/12/6.
* <p/>
* Copyright 2022 Netease, Inc. All rights reserved.
* NETEASE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
package com.netease.mail.yanxuan.change.dal.meta.model.po;
import lombok.Data;
/**
* @Author zcwang
* @Date 2022/12/6
*/
@Data
public class QueryCommanderEmailReq {
/**
* 变更行动人类型
*/
private Integer changeExecUserType;
/**
* 变更行动人二级类型
*/
private String changeExecUser;
/**
* 变更商品列表,JSON格式
*/
private String changeItems;
/**
* 变更供应商
*/
private String changeSupplier;
/**
* 创建端
* @see com.netease.mail.yanxuan.change.common.enums.CreateSourceEnum
*/
private Integer createSource;
}
\ No newline at end of file
package com.netease.mail.yanxuan.change.dal.meta.model.req;
import lombok.Data;
/**
* @author WangJiaXiang
* @date 2022/12/7/007$
*/
@Data
public class ChangeConfigDeleteReq {
private Long id;
}
package com.netease.mail.yanxuan.change.dal.meta.model.req;
import lombok.Data;
/**
* @author WangJiaXiang
* @date 2022/11/11/011$
*/
@Data
public class ChangeConfigQueryReq {
/**
* 变更负责部门名
*/
private String changeDepartment;
/**
* 变更执行部门名
*/
private String changeExecDepartment;
/**
* 变更类型
*/
private String changeType;
/**
* 一级变更ID
*/
private Integer parentChangeClassId;
/**
* 二级变更ID
*/
private Integer sonChangeClassId;
private Integer changeLevel;
/**
* 创建时间
*/
private Long createTime;
/**
* 更新时间
*/
private Long updateTime;
}
package com.netease.mail.yanxuan.change.dal.meta.model.req;
import com.netease.mail.yanxuan.change.dal.entity.ChangeExecConfig;
import com.netease.mail.yanxuan.change.dal.entity.ChangeType;
import lombok.Data;
import java.util.List;
/**
* @author WangJiaXiang
* @date 2022/11/11/011$
*/
@Data
public class ChangeConfigReq {
/**
* 主键ID 用户修改
*/
private Long id;
/**
* 变更主体
*/
private Integer changeSubject;
/**
* 变更等级
*/
private Integer changeLevel;
/**
* 变更负责部门名
*/
private String changeDepartment;
/**
* 变更负责人类型
*/
private Integer changeCommanderType;
/**
* 变更负责人详情(不同类型存储不同内容)
*/
private String changeCommander;
/**
* 是否需要资料上传
*/
private Integer needFile;
/**
* 变更类型
*/
private List<ChangeType> changeTypes;
/**
* 变更执行方案
*/
private List<ChangeExecConfig> changeExeConfig;
}
/**
* @(#)ChangeExecConfigReq.java, 2022/11/15.
* <p/>
* Copyright 2022 Netease, Inc. All rights reserved.
* NETEASE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
package com.netease.mail.yanxuan.change.dal.meta.model.req;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import lombok.Data;
/**
* @Author zcwang
* @Date 2022/11/15
*/
@Data
public class ChangeExecConfigReq {
/**
* 变更行动项记录id
*/
private Long changeExecId;
/**
* 变更类型配置记录id
*/
//@NotNull(message = "变更记录id不可为空")
private Long changeTemplateId;
/**
* 变更执行部门名
*/
@NotBlank(message = "变更执行部门名不能为空")
private String changeExecDepartment;
/**
* 变更行动人类型
*/
private Integer changeExecUserType;
/**
* 变更行动人(不同类型存储不同内容)
*/
private String changeExecUser;
/**
* 变更行动人邮箱
*/
private String changeExecUserEmail;
/**
* 变更风险描述
*/
private String changeRiskDesc;
/**
* 行动项
*/
private String changeExecProject;
/**
* 变更验证措施
*/
private String changeChecking;
/**
* 行动完成时间
*/
private Long changeExecFinishTime;
/**
* 行动完成情况
*/
private String changeExecFinishDesc;
}
\ No newline at end of file
/**
* @(#)ChangeExecProject.java, 2022/11/14.
* <p/>
* Copyright 2022 Netease, Inc. All rights reserved.
* NETEASE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
package com.netease.mail.yanxuan.change.dal.meta.model.req;
import lombok.Data;
/**
* @Author zcwang
* @Date 2022/11/14
*/
@Data
public class ChangeExecProject {
/**
* 变更类型配置记录id
*/
private Long changeTemplateId;
/**
* 变更执行部门名
*/
private String changeExecDepartment;
/**
* 变更行动人类型
*/
private Integer changeExecUserType;
/**
* 变更行动人(不同类型存储不同内容)
*/
private String changeExecUser;
/**
* 变更风险描述
*/
private String changeRiskDesc;
/**
* 行动项
*/
private String changeExecProject;
/**
* 变更验证措施
*/
private String changeChecking;
/**
* 行动完成时间
*/
private Long changeExecFinishTime;
/**
* 行动完成情况
*/
private String changeExecFinishDesc;
}
\ No newline at end of file
/**
* @(#)ChangeFlowCancelReq.java, 2022/11/21.
* <p/>
* Copyright 2022 Netease, Inc. All rights reserved.
* NETEASE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
package com.netease.mail.yanxuan.change.dal.meta.model.req;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import lombok.Data;
/**
* @Author zcwang
* @Date 2022/11/21
*/
@Data
public class ChangeFlowCancelReq {
/**
* 工单id
*/
@NotNull(message = "工单id不能为空")
private Long flowId;
@NotBlank(message = "取消原因不能为空")
@Size(max = 200, message = "取消原因限制200字")
private String cancelReason;
}
\ No newline at end of file
/**
* @(#)ChangeFlowCreateReq.java, 2022/11/15.
* <p/>
* Copyright 2022 Netease, Inc. All rights reserved.
* NETEASE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
package com.netease.mail.yanxuan.change.dal.meta.model.req;
import java.util.List;
import javax.validation.Valid;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import lombok.Data;
/**
* @Author zcwang
* @Date 2022/11/15
*/
@Data
public class ChangeFlowCreateReq {
/**
* 变更主体
*/
@NotNull(message = "变更主体不能为空")
private Integer changeSubject;
/**
* 一级变更类型id
*/
@NotNull(message = "一级变更类型不能为空")
private Long parentChangeClassId;
/**
* 二级变更类型id
*/
@NotNull(message = "二级变更类型不能为空")
private Long sonChangeClassId;
/**
* 变更等级
*/
@NotNull(message = "变更等级不能为空")
private Integer changeLevel;
/**
* 变更负责人
*/
private String changeCommander;
/**
* 变更负责部门名
*/
private String changeDepartment;
/**
* 变更商品列表
*/
private String changeItems;
/**
* 变更供应商
*/
private String changeSupplier;
/**
* 变更原因
*/
@NotBlank(message = "变更原因不能为空")
@Size(max = 500,message = "变更原因限500字")
private String changeReason;
/**
* 变更内容
*/
@NotBlank(message = "变更内容不能为空")
@Size(max = 500,message = "变更内容限500字")
private String changeContent;
/**
* 变更前后图片/视频
*/
private List<ChangeFlowFile> changeFiles;
/**
* 资料上传
*/
private List<ChangeFlowFile> uploadFiles;
/**
* 变更潜在风险描述
*/
private String changeRiskDesc;
/**
* 变更验证措施
*/
private String changeChecking;
/**
* 变更收益类型
*/
@NotNull(message = "变更收益类型不能为空")
private Integer changeProfit;
/**
* 变更收益说明
*/
@NotBlank(message = "变更收益说明不能为空")
@Size(max = 500, message = "变更收益说明限500字")
private String changeProfitDesc;
/**
* 变更结果确认时间
*/
//@NotNull(message = "变更结果确认时间不能为空")
private Long changeConfirmResultTime;
/**
* 行动项
*/
@NotEmpty(message = "变更行动项不可为空")
@Valid
private List<ChangeExecConfigReq> changeExecProject;
/**
* 变更管理及行动项结果相关的资料文件
*/
private List<ChangeFlowFile> changeResultFiles;
/**
* 创建端(普通or同舟)
*/
@NotNull(message = "创建端不能为空")
private Integer createSource;
/**
* 同舟用户所属供应商
*/
private String supplier;
}
\ No newline at end of file
/**
* @(#)ChangeFlowDeliverReq.java, 2022/11/25.
* <p/>
* Copyright 2022 Netease, Inc. All rights reserved.
* NETEASE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
package com.netease.mail.yanxuan.change.dal.meta.model.req;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import lombok.Data;
/**
* @Author zcwang
* @Date 2022/11/25
*/
@Data
public class ChangeFlowDeliverReq {
/**
* 工单id
*/
@NotNull(message = "工单id不能为空")
private Long flowId;
/**
* 变更负责人
*/
@NotBlank(message = "转交人不可为空")
private String deliverUser;
/**
* 转交备注
*/
private String remark;
}
\ No newline at end of file
/**
* @(#)ChangeFlowFile.java, 2022/11/14.
* <p/>
* Copyright 2022 Netease, Inc. All rights reserved.
* NETEASE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
package com.netease.mail.yanxuan.change.dal.meta.model.req;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @Author zcwang
* @Date 2022/11/14
*/
@AllArgsConstructor
@NoArgsConstructor
@Builder
@Data
public class ChangeFlowFile {
/**
* 文件名
*/
private String fileName;
/**
* 文件链接
*/
private String fileUrl;
/**
* 文件类型(基础信息图片/基础信息视频/基础信息资料/变更结果资料)
* @see com.netease.mail.yanxuan.change.common.enums.FileTypeEnum
*/
private Integer fileType;
}
\ No newline at end of file
/**
* @(#)ChangeFlowListQueryReq.java, 2022/11/21.
* <p/>
* Copyright 2022 Netease, Inc. All rights reserved.
* NETEASE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
package com.netease.mail.yanxuan.change.dal.meta.model.req;
import com.netease.mail.yanxuan.change.common.enums.CreateSourceEnum;
import lombok.Data;
/**
* @Author zcwang
* @Date 2022/11/21
*/
@Data
public class ChangeFlowListQueryReq {
/**
* 变更商品(变更主体为商品时有效)
*/
private String itemId;
/**
* 变更供应商(变更主体为供应商时有效)
*/
private String supplier;
/**
* 一级变更类型id
*/
private Long parentChangeClassId;
/**
* 二级变更类型id
*/
private Long sonChangeClassId;
/**
* 工单状态
*/
private Integer changeState;
/**
* 变更负责人
*/
private String changeCommander;
/**
* 变更负责部门名
*/
private String changeDepartment;
/**
* 变更行动部门
*/
private String changeExecDepartment;
/**
* 开始时间
*/
private Long startTime;
/**
* 结束时间
*/
private Long endTime;
/**
* 创建端
* @see CreateSourceEnum
*/
private Integer createSource;
/**
* 创建端
*/
private String createSupplier;
/**
* 工单id
*/
private Long flowId;
private Long limit;
private Long offset;
}
\ No newline at end of file
/**
* @(#)ChangeFlowRequest.java, 2022/12/8.
* <p/>
* Copyright 2022 Netease, Inc. All rights reserved.
* NETEASE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
package com.netease.mail.yanxuan.change.dal.meta.model.req;
import com.netease.mail.yanxuan.change.common.enums.CreateSourceEnum;
import lombok.Data;
/**
* @Author zcwang
* @Date 2022/12/8
*/
@Data
public class ChangeFlowRequest {
/**
* 变更商品(变更主体为商品时有效)
*/
private String itemId;
/**
* 变更供应商(变更主体为供应商时有效)
*/
private String supplier;
/**
* 一级变更类型id
*/
private Long parentChangeClassId;
/**
* 二级变更类型id
*/
private Long sonChangeClassId;
/**
* 工单状态
*/
private Integer changeState;
/**
* 变更负责人
*/
private String changeCommander;
/**
* 变更负责部门名
*/
private String changeDepartment;
/**
* 变更行动部门
*/
private String changeExecDepartment;
/**
* 开始时间
*/
private Long startTime;
/**
* 结束时间
*/
private Long endTime;
/**
* 创建端
* @see CreateSourceEnum
*/
private Integer createSource;
private String serviceCode;
private String uid;
}
\ No newline at end of file
/**
* @(#)ChangeFlowReq.java, 2022/11/14.
* <p/>
* Copyright 2022 Netease, Inc. All rights reserved.
* NETEASE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
package com.netease.mail.yanxuan.change.dal.meta.model.req;
import java.util.List;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import lombok.Data;
/**
* @Author zcwang
* @Date 2022/11/14
*/
@Data
public class ChangeFlowSubmitReq {
/**
* 工单id
*/
@NotNull(message = "工单id不能为空")
private Long flowId;
/**
* 当前节点id
*/
@NotBlank(message = "当前节点不能为空")
private String currentNodeId;
/**
* 一级类型id
*/
private Long parentChangeClassId;
/**
* 二级类型id
*/
private Long sonChangeClassId;
/**
* 变更商品
*/
private String changeItems;
/**
* 变更供应商
*/
private String changeSupplier;
/**
* 变更原因
*/
private String changeReason;
/**
* 变更内容
*/
private String changeContent;
/**
* 变更前后图片/视频
*/
private List<ChangeFlowFile> changeFiles;
/**
* 资料上传
*/
private List<ChangeFlowFile> uploadFiles;
/**
* 变更管理及行动项结果相关的资料文件
*/
private List<ChangeFlowFile> changeResultFiles;
/**
* 变更潜在风险
*/
private String changeRiskDesc;
/**
* 变更验证措施
*/
private String changeChecking;
/**
* 变更收益类型
*/
private Integer changeProfit;
/**
* 变更收益说明
*/
private String changeProfitDesc;
/**
* 变更结果确认时间,时间戳
*/
private Long changeConfirmResultTime;
/**
* 变更行动项
*/
private List<ChangeExecConfigReq> changeExecProjectList;
/**
* 变更结论
*/
private Integer changeResult;
/**
* 取消原因说明(取消时存在)
*/
private String cancelReason;
/**
* 备注
*/
private String remark;
}
\ No newline at end of file
/**
* @(#)SendMailReq.java, 2022/12/9.
* <p/>
* Copyright 2022 Netease, Inc. All rights reserved.
* NETEASE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
package com.netease.mail.yanxuan.change.dal.meta.model.req;
import lombok.Data;
/**
* @Author zcwang
* @Date 2022/12/9
*/
@Data
public class SendMailReq {
private Long id;
private String code;
private String mapToJson;
private Integer createSource;
private String changeSupplier;
}
\ No newline at end of file
/**
* @(#)CommanderResponse.java, 2022/12/6.
* <p/>
* Copyright 2022 Netease, Inc. All rights reserved.
* NETEASE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
package com.netease.mail.yanxuan.change.dal.meta.model.rpc;
import lombok.Data;
/**
* @Author zcwang
* @Date 2022/12/6
*/
@Data
public class CommanderResponse {
/**
* 用户名
*/
private String name;
/**
* 邮箱
*/
private String email;
}
\ No newline at end of file
package com.netease.mail.yanxuan.change.dal.meta.model.rpc;
import lombok.Data;
/**
* @author WangJiaXiang
* @date 2022/11/24/024$
* 商品采购人返回信息
*/
@Data
public class GoodsPurchaseRpc {
private String supplierName;
private Integer itemId;
private String supplierTraceBusiness;
}
package com.netease.mail.yanxuan.change.dal.meta.model.rpc;
import lombok.Data;
/**
* @author WangJiaXiang
* @date 2022/11/24/024$
* 根据商品查询对应负责人的信息
*/
@Data
public class GoodsResponseRpc {
/**
* 商品负责人名称
*/
private String name;
/**
* 商品负责人邮箱
*/
private String email;
/**
* 计数器
*/
private Integer occurrenceNumber;
}
package com.netease.mail.yanxuan.change.dal.meta.model.rpc;
import lombok.Data;
/**
* @author WangJiaXiang
* @date 2022/11/21/021$
* 商品SQE返回值
*/
@Data
public class GoodsResponseSqeRpc {
private String userName;
private String realName;
}
/**
* @(#)BasicChangeFlowVO.java, 2022/11/21.
* <p/>
* Copyright 2022 Netease, Inc. All rights reserved.
* NETEASE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
package com.netease.mail.yanxuan.change.dal.meta.model.vo;
import java.util.List;
import com.netease.mail.yanxuan.change.dal.entity.ChangeFile;
import com.netease.mail.yanxuan.change.dal.meta.model.req.ChangeFlowFile;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @Author zcwang
* @Date 2022/11/21
*/
@AllArgsConstructor
@NoArgsConstructor
@Builder
@Data
public class BasicChangeFlowVO {
/**
* 一级变更类型id
*/
private Long parentChangeClassId;
/**
* 二级变更类型id
*/
private Long sonChangeClassId;
/**
* 变更主体
*/
private Integer changeSubject;
/**
* 变更商品(变更主体为商品时有效)
*/
private String changeItem;
/**
* 变更供应商(变更主体为供应商时有效)
*/
private String changeSupplier;
/**
* 变更供应商详情展示,供应商名称
*/
private String changeSupplierName;
/**
* 变更原因
*/
private String changeReason;
/**
* 变更内容
*/
private String changeContent;
/**
* 变更潜在风险描述
*/
private String changeRiskDesc;
/**
* 变更收益类型
*/
private Integer changeProfit;
/**
* 变更收益说明
*/
private String changeProfitDesc;
/**
* 附件
*/
private List<ChangeFlowFile> files;
}
\ No newline at end of file
/**
* @(#)CategoryInfoDTO.java, 2022/8/24.
* <p/>
* Copyright 2022 Netease, Inc. All rights reserved.
* NETEASE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
package com.netease.mail.yanxuan.change.dal.meta.model.vo;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @Author zcwang
* @Date 2022/8/24
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class CategoryInfoVO {
/**
* 类目id
*/
private Long id;
/**
* 类目名称
*/
private String name;
}
\ No newline at end of file
package com.netease.mail.yanxuan.change.dal.meta.model.vo;
import com.netease.mail.yanxuan.change.dal.meta.model.po.ChangeConfigPo;
import lombok.Data;
import java.util.List;
/**
* @author WangJiaXiang
* @date 2022/11/28/028$
*/
@Data
public class ChangeConfigArrayVO {
/**
* 分页信息
*/
private PageVO pageVo;
private List<ChangeConfigPo> changeConfigs;
}
package com.netease.mail.yanxuan.change.dal.meta.model.vo;
import com.netease.mail.yanxuan.change.dal.entity.ChangeConfig;
import com.netease.mail.yanxuan.change.dal.entity.ChangeExecConfig;
import com.netease.mail.yanxuan.change.dal.entity.ChangeType;
import java.util.List;
import com.netease.mail.yanxuan.change.dal.meta.model.dto.ChangeExecConfigDTO;
import lombok.Data;
/**
* @author WangJiaXiang
* @date 2022/11/11/011$
*/
@Data
public class ChangeConfigVO {
/**
* 主体内容
*/
private ChangeConfig changeConfig;
/**
* 变更类型
*/
private List<ChangeType> changeTypes;
/**
* 变更执行方案
*/
private List<ChangeExecConfigDTO> changeExecConfigs;
}
/**
* @(#)ChangeFlowExecVO.java, 2022/11/21.
* <p/>
* Copyright 2022 Netease, Inc. All rights reserved.
* NETEASE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
package com.netease.mail.yanxuan.change.dal.meta.model.vo;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @Author zcwang
* @Date 2022/11/21
*/
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Data
public class ChangeFlowExecVO {
/**
* 变更行动项记录id
*/
private Long changeExecId;
/**
* 变更记录id
*/
private Long changeRecordId;
/**
* 变更执行部门名
*/
private String changeExecDepartment;
/**
* 变更行动人类型
*/
private Integer changeExecUserType;
/**
* 变更行动人(不同类型存储不同内容)
*/
private String changeExecUser;
/**
* 变更负责人邮箱
*/
private String changeExecUserEmail;
/**
* 用户名
*/
private String changeExecUserName;
/**
* 变更风险描述
*/
private String changeRiskDesc;
/**
* 行动项
*/
private String changeExecProject;
/**
* 变更措施验证
*/
private String changeChecking;
/**
* 行动完成时间
*/
private Long changeExecFinishTime;
/**
* 行动完成情况
*/
private String changeExecFinishDesc;
}
\ No newline at end of file
/**
* @(#)ChangeFlowListVO.java, 2022/11/14.
* <p/>
* Copyright 2022 Netease, Inc. All rights reserved.
* NETEASE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
package com.netease.mail.yanxuan.change.dal.meta.model.vo;
import java.util.List;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @Author zcwang
* @Date 2022/11/14
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class ChangeFlowListVO {
/**
* 分页信息
*/
private PageVO pageVo;
/**
* 变更工单列表
*/
private List<ChangeFlowVO> changeFlowList;
}
\ No newline at end of file
/**
* @(#)ChangeFlowVO.java, 2022/11/14.
* <p/>
* Copyright 2022 Netease, Inc. All rights reserved.
* NETEASE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
package com.netease.mail.yanxuan.change.dal.meta.model.vo;
import java.util.List;
import com.netease.mail.yanxuan.change.common.enums.ChangeStatusEnum;
import com.netease.mail.yanxuan.change.common.enums.ChangeSubjectEnum;
import com.netease.mail.yanxuan.change.dal.entity.ChangeExecRecord;
import com.netease.mail.yanxuan.change.dal.meta.model.req.ChangeFlowFile;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @Author zcwang
* @Date 2022/11/14
*/
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Data
public class ChangeFlowVO {
/**
* 主键id
*/
private Long id;
/**
* 工单id
*/
private Long flowId;
/**
* 一级变更类型id
*/
private Long parentChangeClassId;
/**
* 二级变更类型id
*/
private Long sonChangeClassId;
/**
* 变更主体
* @see ChangeSubjectEnum
*/
private Integer changeSubject;
/**
* 变更类型,一级类型>二级类型
*/
private String changeType;
/**
* 变更等级
*/
private Integer changeLevel;
/**
* 变更负责部门名
*/
private String changeDepartment;
/**
* 变更原因
*/
private String changeReason;
/**
* 变更内容
*/
private String changeContent;
/**
* 变更负责人
*/
private String changeCommander;
/**
* 名称+部门
*/
private String changeCommanderView;
/**
* 变更潜在风险描述
*/
private String changeRiskDesc;
/**
* 附件
*/
private List<ChangeFlowFile> files;
/**
* 变更收益类型
*/
private Integer changeProfit;
/**
* 变更收益说明
*/
private String changeProfitDesc;
/**
* 变更商品列表
*/
private List<ItemVO> changeItems;
/**
* 变更供应商
*/
private String changeSupplier;
/**
* 变更供应商详情展示,供应商名称
*/
private String changeSupplierName;
/**
* 变更状态
* @see ChangeStatusEnum
*/
private Integer changeState;
/**
* 变更发起人
*/
private String changeCreator;
/**
* 名称+部门
*/
private String changeCreatorView;
/**
* 变更行动方案
*/
private List<ChangeFlowExecVO> changeExecProjectList;
/**
* 变更行动部门列表
*/
private List<String> execDepartmentStrList;
/**
* 创建时间
*/
private Long createTime;
/**
* 变更结果确认时间
*/
private Long changeConfirmResultTime;
/**
* 取消原因
*/
private String cancelReason;
/**
* 变更结论
*/
private Integer changeResult;
/**
* 变更结论详情
*/
private String changeResultDesc;
/**
* 备注
*/
private String remark;
/**
* 变更商品基础信息
*/
private List<ItemBasicInfoVO> itemBasicInfoList;
/**
* topoId
*/
private String topoId;
/**
* 当前节点
*/
private String flowNode;
}
\ No newline at end of file
/**
* @(#)ChangeItems.java, 2022/11/14.
* <p/>
* Copyright 2022 Netease, Inc. All rights reserved.
* NETEASE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
package com.netease.mail.yanxuan.change.dal.meta.model.vo;
import lombok.Builder;
import lombok.Data;
/**
* @Author zcwang
* @Date 2022/11/14
*/
@Data
@Builder
public class ChangeItemVO {
/**
* 商品id
*/
private Long itemId;
/**
* 商品名
*/
private String itemName;
}
\ No newline at end of file
/**
* @(#)ItemBasicInfoVO.java, 2022/11/30.
* <p/>
* Copyright 2022 Netease, Inc. All rights reserved.
* NETEASE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
package com.netease.mail.yanxuan.change.dal.meta.model.vo;
import java.util.List;
import com.netease.mail.yanxuan.change.dal.meta.model.po.ChangeGoodsPrincipalPO;
import lombok.Data;
/**
* @Author zcwang
* @Date 2022/11/30
*/
@Data
public class ItemBasicInfoVO {
/**
* 商品id
*/
private Long itemId;
/**
* 商品名
*/
private String itemName;
/**
* 品控类目
*/
private String qcCategory;
/**
* 物理类目
*/
private List<CategoryInfoVO> phyCategory;
/**
* 商品立项类型,0-正常立项商品,2-特殊免立项商品 3-组合装
*/
private Integer itemSetupType;
/**
* 经营形式,0-自营,3-严选贴牌代销,4-他方品牌代销,5-代销2.0
*/
private Integer businessForm;
/**
* 商品状态,0-未上架,1-未上架,2-已上架,4-预上架
*/
private Integer status;
/**
* 商品负责人信息
*/
private ChangeGoodsPrincipalPO changeGoodsPrincipal;
}
\ No newline at end of file
/**
* @(#)ItemVO.java, 2022/11/21.
* <p/>
* Copyright 2022 Netease, Inc. All rights reserved.
* NETEASE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
package com.netease.mail.yanxuan.change.dal.meta.model.vo;
import lombok.Data;
/**
* @Author zcwang
* @Date 2022/11/21
*/
@Data
public class ItemVO {
/**
* 商品spuId
*/
private Long itemId;
/**
* 商品名
*/
private String itemName;
}
\ No newline at end of file
package com.netease.mail.yanxuan.change.dal.meta.model.vo;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @author lfmu
*/
@AllArgsConstructor
@NoArgsConstructor
@Builder
@Data
public class PageVO {
/**
* 当前页
*/
private Integer page;
/**
* 总页数
*/
private Integer totalPage;
/**
* 总条数
*/
private Integer totalCount;
/**
* 每页条数
*/
private Integer pageSize;
/**
* 页码
*/
private Integer pageCount;
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.netease.mail.yanxuan.change.dal.mapper.ChangeConfigMapper">
<resultMap id="BaseResultPoMap" type="com.netease.mail.yanxuan.change.dal.meta.model.po.ChangeConfigPo">
<id column="id" jdbcType="BIGINT" property="id" />
<result column="change_subject" jdbcType="INTEGER" property="changeSubject" />
<result column="parent_change_class_id" jdbcType="INTEGER" property="parentChangeClassId" />
<result column="son_change_class_id" jdbcType="INTEGER" property="sonChangeClassId" />
<result column="change_level" jdbcType="INTEGER" property="changeLevel" />
<result column="change_department" jdbcType="VARCHAR" property="changeDepartment" />
<result column="participate_change_exec_department" jdbcType="VARCHAR" property="participateChangeExecDepartment" />
<result column="change_commander_type" jdbcType="INTEGER" property="changeCommanderType" />
<result column="change_commander" jdbcType="VARCHAR" property="changeCommander" />
<result column="creator" jdbcType="VARCHAR" property="creator" />
<result column="need_file" jdbcType="INTEGER" property="needFile" />
<result column="create_time" jdbcType="BIGINT" property="createTime" />
<result column="update_time" jdbcType="BIGINT" property="updateTime" />
<!--查询出现次数最多的部门? 由于业务逻辑转变 不知道是否需要咱是注销-->
<!-- <association property="changeExecConfigPo" column="id" javaType="com.netease.mail.yanxuan.change.dal.meta.model.po.ChangeExecConfigPo"-->
<!-- select="queryChangeDepartment">-->
<!-- <result column="coreDepartment" javaType="INTEGER" property="coreDepartment" />-->
<!-- <result column="changeExecDepartment" javaType="VARCHAR" property="changeExecDepartment" />-->
<!-- </association>-->
<!--查询变更类型-->
<collection property="changeTypes" column="{parentId=parent_change_class_id,sonId=son_change_class_id}" javaType="list" ofType="com.netease.mail.yanxuan.change.dal.entity.ChangeType"
select="queryByparentChangeClassId" >
</collection>
</resultMap>
<sql id="Base_Column_List">
id, change_subject, parent_change_class_id, son_change_class_id, change_level,participate_change_exec_department, change_department,
change_commander_type, change_commander, need_file, create_time, update_time, creator
</sql>
<select id="selectChangeConfigPo" resultMap="BaseResultPoMap" parameterType="com.netease.mail.yanxuan.change.dal.meta.model.req.ChangeConfigQueryReq">
select <include refid="Base_Column_List" />
from TB_YX_QC_CHANGE_CONFIG
<where>
<if test="parentChangeClassId != null ">
parent_change_class_id = #{parentChangeClassId} and
</if>
<if test="sonChangeClassId != null ">
son_change_class_id = #{sonChangeClassId} and
</if>
<if test="changeLevel != null and changeLevel != ''">
change_level = #{changeLevel} and
</if>
<if test="changeDepartment != null and changeDepartment != ''">
change_department = #{changeDepartment} and
</if>
<if test="createTime != null">
create_time <![CDATA[ > ]]> #{createTime} and
</if>
<if test="updateTime != null">
create_time <![CDATA[ < ]]> #{updateTime} and
</if>
<if test="changeExecDepartment != null and changeExecDepartment != ''">
participate_change_exec_department like "%" #{changeExecDepartment} "%" and
</if>
1=1
</where>
order by create_time desc
</select>
<select id="queryByparentChangeClassId" resultType="com.netease.mail.yanxuan.change.dal.entity.ChangeType">
select * from TB_YX_QC_CHANGE_TYPE where id = #{parentId} or id = #{sonId} and delete_type = 0 order by parent_id
</select>
<select id="queryInfo" resultType="com.netease.mail.yanxuan.change.dal.entity.ChangeConfig">
select * from TB_YX_QC_CHANGE_CONFIG
<where>
1=1
<if test="id != null">
and id = #{id}
</if>
<if test="sonChangeClassId != null ">
and son_change_class_id = #{sonChangeClassId}
</if>
</where>
</select>
<select id="queryInfoPo" resultMap="BaseResultPoMap" >
select <include refid="Base_Column_List" />
from TB_YX_QC_CHANGE_CONFIG
<where>
1=1
<if test="parentChangeClassId != null ">
and parent_change_class_id = #{parentChangeClassId}
</if>
<if test="sonChangeClassId != null ">
and son_change_class_id = #{sonChangeClassId}
</if>
</where>
</select>
<!--此查询暂时不需要。。。-->
<!-- <select id="queryChangeDepartment" resultType="com.netease.mail.yanxuan.change.dal.meta.model.po.ChangeExecConfigPo" parameterType="java.lang.Long">-->
<!-- select-->
<!-- COUNT(change_template_id) as coreDepartment, change_exec_department as changeExecDepartment-->
<!-- from tb_yx_change_exec_config-->
<!-- where change_template_id = #{id}-->
<!-- GROUP BY change_exec_department-->
<!-- ORDER BY coreDepartment DESC LIMIT 1;-->
<!-- </select>-->
<insert id="add" keyColumn="id" keyProperty="id" parameterType="com.netease.mail.yanxuan.change.dal.entity.ChangeConfig" useGeneratedKeys="true">
insert into TB_YX_QC_CHANGE_CONFIG
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="changeSubject != null">
change_subject,
</if>
<if test="parentChangeClassId != null">
parent_change_class_id,
</if>
<if test="sonChangeClassId != null">
son_change_class_id,
</if>
<if test="changeLevel != null">
change_level,
</if>
<if test="changeDepartment != null">
change_department,
</if>
<if test="changeCommanderType != null">
change_commander_type,
</if>
<if test="participateChangeExecDepartment != null">
participate_change_exec_department,
</if>
<if test="changeCommander != null">
change_commander,
</if>
<if test="needFile != null">
need_file,
</if>
<if test="createTime != null">
create_time,
</if>
<if test="updateTime != null">
update_time,
</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="changeSubject != null">
#{changeSubject,jdbcType=INTEGER},
</if>
<if test="parentChangeClassId != null">
#{parentChangeClassId,jdbcType=INTEGER},
</if>
<if test="sonChangeClassId != null">
#{sonChangeClassId,jdbcType=INTEGER},
</if>
<if test="changeLevel != null">
#{changeLevel,jdbcType=INTEGER},
</if>
<if test="changeDepartment != null">
#{changeDepartment,jdbcType=VARCHAR},
</if>
<if test="changeCommanderType != null">
#{changeCommanderType,jdbcType=INTEGER},
</if>
<if test="participateChangeExecDepartment != null">
#{participateChangeExecDepartment,jdbcType=VARCHAR},
</if>
<if test="changeCommander != null">
#{changeCommander,jdbcType=VARCHAR},
</if>
<if test="needFile != null">
#{needFile,jdbcType=INTEGER},
</if>
<if test="createTime != null">
#{createTime,jdbcType=BIGINT},
</if>
<if test="updateTime != null">
#{updateTime,jdbcType=BIGINT},
</if>
</trim>
</insert>
</mapper>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.netease.mail.yanxuan.change.dal.mapper.ChangeRecordMapper">
<resultMap id="BaseResultMap" type="com.netease.mail.yanxuan.change.dal.entity.ChangeRecord">
<id column="id" jdbcType="BIGINT" property="id" />
<result column="flow_id" jdbcType="BIGINT" property="flowId" />
<result column="flow_node" jdbcType="VARCHAR" property="flowNode" />
<result column="change_subject" jdbcType="INTEGER" property="changeSubject" />
<result column="parent_change_class_id" jdbcType="INTEGER" property="parentChangeClassId" />
<result column="son_change_class_id" jdbcType="INTEGER" property="sonChangeClassId" />
<result column="change_level" jdbcType="INTEGER" property="changeLevel" />
<result column="change_commander" jdbcType="VARCHAR" property="changeCommander" />
<result column="change_department" jdbcType="VARCHAR" property="changeDepartment" />
<result column="participate_change_exec_department" jdbcType="VARCHAR" property="participateChangeExecDepartment" />
<result column="change_item" jdbcType="VARCHAR" property="changeItem" />
<result column="change_supplier" jdbcType="VARCHAR" property="changeSupplier" />
<result column="change_reason" jdbcType="VARCHAR" property="changeReason" />
<result column="change_content" jdbcType="VARCHAR" property="changeContent" />
<result column="change_risk_desc" jdbcType="VARCHAR" property="changeRiskDesc" />
<result column="change_checking" jdbcType="VARCHAR" property="changeChecking" />
<result column="change_profit" jdbcType="INTEGER" property="changeProfit" />
<result column="change_profit_desc" jdbcType="VARCHAR" property="changeProfitDesc" />
<result column="change_confirm_result_time" jdbcType="BIGINT" property="changeConfirmResultTime" />
<result column="state" jdbcType="INTEGER" property="state" />
<result column="cancel_reason" jdbcType="VARCHAR" property="cancelReason" />
<result column="change_result" jdbcType="INTEGER" property="changeResult" />
<result column="create_source" jdbcType="INTEGER" property="createSource" />
<result column="create_supplier" jdbcType="VARCHAR" property="createSupplier" />
<result column="change_result_desc" jdbcType="VARCHAR" property="changeResultDesc" />
<result column="remark" jdbcType="VARCHAR" property="remark" />
<result column="creator" jdbcType="VARCHAR" property="creator" />
<result column="create_time" jdbcType="BIGINT" property="createTime" />
<result column="update_time" jdbcType="BIGINT" property="updateTime" />
</resultMap>
<sql id="Base_Column_List">
id, flow_id, flow_node, change_subject, parent_change_class_id, son_change_class_id,
change_level, change_commander, change_department, participate_change_exec_department,
change_item, change_supplier, change_reason, change_content, change_risk_desc, change_checking,
change_profit, change_profit_desc, change_confirm_result_time, `state`, cancel_reason,
change_result, create_source, create_supplier, change_result_desc, remark, creator,
create_time, update_time
</sql>
<select id="selectByCondition" resultMap="BaseResultMap" parameterType="com.netease.mail.yanxuan.change.dal.meta.model.req.ChangeFlowListQueryReq">
select <include refid="Base_Column_List" />
from TB_YX_QC_CHANGE_RECORD
<where>
<if test="createSource != null ">
and create_source = #{createSource}
</if>
<if test="itemId != null ">
and change_item like concat('%',#{itemId},'%')
</if>
<if test="supplier != null ">
and change_supplier = #{supplier}
</if>
<if test="parentChangeClassId != null">
and parent_change_class_id = #{parentChangeClassId}
</if>
<if test="sonChangeClassId != null">
and son_change_class_id = #{sonChangeClassId}
</if>
<if test="changeState != null">
and `state` = #{changeState}
</if>
<if test="changeCommander != null and changeCommander != ''">
and `change_commander` = #{changeCommander}
</if>
<if test="changeDepartment != null and changeDepartment != ''">
and `change_department` = #{changeDepartment}
</if>
<if test="changeExecDepartment != null and changeExecDepartment != ''">
and participate_change_exec_department like concat('%',#{changeExecDepartment},'%')
</if>
<if test="startTime != null">
and create_time > #{startTime}
</if>
<if test="endTime != null">
and create_time <![CDATA[ < ]]> #{endTime}
</if>
<if test="createSupplier != null">
and create_supplier = #{createSupplier}
</if>
<if test="flowId != null">
and flow_id = #{flowId}
</if>
</where>
order by create_time desc
</select>
<select id="selectByConditionAndLimit"
resultMap="BaseResultMap">
select <include refid="Base_Column_List" />
from TB_YX_QC_CHANGE_RECORD
<where>
<if test="createSource != null ">
and create_source = #{createSource}
</if>
<if test="itemId != null ">
and change_item like concat('%',#{itemId},'%')
</if>
<if test="supplier != null ">
and change_supplier = #{supplier}
</if>
<if test="parentChangeClassId != null">
and parent_change_class_id = #{parentChangeClassId}
</if>
<if test="sonChangeClassId != null">
and son_change_class_id = #{sonChangeClassId}
</if>
<if test="changeState != null">
and `state` = #{changeState}
</if>
<if test="changeCommander != null and changeCommander != ''">
and `change_commander` = #{changeCommander}
</if>
<if test="changeDepartment != null and changeDepartment != ''">
and `change_department` = #{changeDepartment}
</if>
<if test="changeExecDepartment != null and changeExecDepartment != ''">
and participate_change_exec_department like concat('%',#{changeExecDepartment},'%')
</if>
<if test="startTime != null">
and create_time > #{startTime}
</if>
<if test="endTime != null">
and create_time <![CDATA[ < ]]> #{endTime}
</if>
<if test="createSupplier != null">
and create_supplier = #{createSupplier}
</if>
</where>
limit #{offset},#{limit}
</select>
</mapper>
\ No newline at end of file
...@@ -16,6 +16,52 @@ ...@@ -16,6 +16,52 @@
<groupId>com.netease.yanxuan</groupId> <groupId>com.netease.yanxuan</groupId>
<artifactId>yanxuan-qc-change-system-common</artifactId> <artifactId>yanxuan-qc-change-system-common</artifactId>
</dependency> </dependency>
<dependency>
<groupId>com.netease.yanxuan</groupId>
<artifactId>yanxuan-finance-pms-remote</artifactId>
<version>1.0-RELEASE</version>
<scope>system</scope>
<systemPath>${project.basedir}/src/main/resources/lib/yanxuan-finance-pms-remote-1.0-RELEASE.jar</systemPath>
</dependency>
</dependencies> </dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.1.1.RELEASE</version>
<configuration>
<fork>true</fork> <!-- 如果没有该配置,devtools不会生效 -->
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>3.0.0</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
<warName>${project.artifactId}</warName>
</configuration>
</plugin>
</plugins>
<finalName>${project.artifactId}</finalName>
<!--指定引入外部包的位置 mvn package -Dmaven.test.skip=true-->
<!--打包部署放开以下注释-->
<!--正常启动需注释以下resources代码,否则会包shiro错误-->
<resources>
<resource>
<directory>${project.basedir}/src/main/resources/lib</directory>
<targetPath>/BOOT-INF/lib/</targetPath>
<includes>
<include>**/*.jar</include>
</includes>
</resource>
<resource>
<directory>src/main/resources</directory>
<targetPath>BOOT-INF/classes/</targetPath>
</resource>
</resources>
</build>
</project> </project>
\ No newline at end of file
package com.netease.mail.yanxuan.change.integration.email.email;
import com.netease.mail.yanxuan.change.integration.email.enums.EmailTemplateEnum;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import java.util.Map;
@AllArgsConstructor
@NoArgsConstructor
@Builder
@Data
public class EmailFactor {
private static final String SUBJECT_PREFIX = "【品控工作台】";
protected String subject;
/**
* 邮件模版
*/
private EmailTemplateEnum emailTemplateEnum;
/**
* 邮件模版组装数据对
*/
private Map<String, Object> data;
/**
* 邮件类型
*/
private String type;
public String getSubject() {
String subject = emailTemplateEnum.getSubject();
if(StringUtils.isNotBlank(subject)){
return subject;
}
/*if (data != null) {
Object flowId = data.get(EmailParamEnum.FLOW_ID.getKey());
Object taskType = data.get(EmailParamEnum.TASK_TYPE.getKey());
String format = emailTemplateEnum.getSubject();
if(flowId != null && taskType == null){
return String.format(format, flowId);
}else if(flowId != null && taskType != null){
return String.format(format, taskType, flowId);
}else {
return SUBJECT_PREFIX;
}
}*/
return SUBJECT_PREFIX;
}
}
package com.netease.mail.yanxuan.change.integration.email.email;
import lombok.Data;
@Data
public class EmailTemplateResponResult {
/**
* ResponseCode,状态码
*/
private Integer code;
/**
* 错误说明
*/
private String errorMessage;
/**
* 组装结果
*/
private String data;
}
\ No newline at end of file
package com.netease.mail.yanxuan.change.integration.email.enums;
public enum EmailParamEnum {
FLOW_ID("flowId", "工单ID"),
RELEASE_ID("releaseId", "发起人账号"),
RELEASE_NAME("releaseName", "发起人姓名"),
RELEASE_RMAIL("releaseEmail", "发起人邮箱"),
ABNORMAL_TITLE("abnormalTitle", "异常标题"),
FLOW_LINK("flowLink", "工单链接"),
CARE_OF_NAME("careOfName", "转交人姓名"),
CARE_OF_EMAIL("careOfEmail", "转交人邮箱"),
ABNORMAL_DUTY_NAME("abnormalDutyName", "异常责任人姓名"),
ABNORMAL_DUTY_EMAIL("abnormalDutyEmail", "异常责任人邮箱"),
GROUP_LEADER_NAME("groupLeaderName", "组长姓名"),
GROUP_LEADER_EMAIL("groupLeaderEmail", "组长邮箱"),
ABNORMAL_CHECK_NAME("abnormalCheckName", "异常审批人姓名"),
ABNORMAL_CHECK_EMAIL("abnormalCheckEmail", "异常审批人邮箱"),
REJECT_NAME("rejectName", "驳回人姓名"),
REJECT_EMAIL("rejectEmail", "驳回人邮箱"),
TASK_TYPE("taskType", "异常任务类型"),
TASK_PROCESS_NAME("taskProcessName", "任务处理人姓名"),
TASK_PROCESS_EMAIL("taskProcessEmail", "任务处理人邮箱"),
CHECK_NAME("checkName", "审批人姓名"),
CHECK_EMAIL("checkEmail", "审批人邮箱"),
NAME("name", "姓名"),
FIND_TIME("findTime", "发现时间"),//yyyy-MM-dd HH:mm:ss
FIND_DES("findDes", "发现人描述"),
SERVICE_CODE("serviceCode", "服务平台"),
ABNORMAL_FLOW_TYPE("abnormalFlowType", "异常种类"),
CREATE_TIME("createTime", "异常创建时间"),
ABNORMAL_TASK_DES("abnormalTaskDes", "任务描述"),
BREACH_OF_CONTRACT_TYPE("breachOfContractType", "违约类型"),
RESPONSIBILITY("responsibility", "责任判定"),
/**
* 查询数仓
*/
QUERY_PART("queryPart", "查询部分"),
/**
* 监控过期或临期工单
*/
TITLE("title", "提示文案"),
ABNORMAL_PROBLEM_FLOW_LIST_DEC("abnormalProblemFlowListDec", "判定异常等级制定临时措施临期延期提醒"),
ABNORMAL_PROBLEM_FLOW_LIST_CAU("abnormalProblemFlowListCau", "原因分析和纠正措施、标准化和验证措施临期延期提醒"),
ABNORMAL_PROBLEM_FLOW_LIST("abnormalProblemFlowList", "异常工单临期延期提醒"),
ABNORMAL_TASK_FLOW_LIST("abnormalTaskFlowList", "任务工单临期延期提"),
TEST("test", "测试");
private String key;
private String info;
EmailParamEnum(String key, String info){
this.key = key;
this.info = info;
}
public String getKey() {
return key;
}
}
package com.netease.mail.yanxuan.change.integration.email.enums;
public enum EmailTemplateEnum {
/**
* 异常问题跟进工单邮件
*/
YX_QC_RELEASE_FLOW("yxqc_release_flow","品控发起工单", "【ECR异常工单新建】 %s,请判定异常等级和制定临时措施"),
YX_QC_CHANGE_RELEASE_FLOW("yxqc_change_release_flow","发起变更","【待处理】%s 变更申请提交 "),
YX_QC_CHANGE_SUBMIT_CANCEL("yx_qc_change_submit_cancel","变更取消","%s 变更取消通知"),
YX_QC_CHANGE_SUBMIT_FORWARD("yx_qc_change_submit_forward","变更转交","%s 变更工单转交通知"),
YX_QC_CHANGE_EXECUTE("yx_qc_change_execute","变更执行","【待处理】变更行动项确认 %s"),
YX_QC_CHANGE_AFFIRM("yx_qc_change_affirm","变更确认","【待处理】变更结果确认 %s"),
YX_QC_CHANGE_FINISH("yx_qc_change_finish","工单完结","【已完结】%s 变更风险行动项已完结,请开始执行变更。"),
YX_QC_CHANGE_PENDING("yx_qc_change_pending","待处理","【待处理】执行标准号 执行标准名称已变更 请排查对应的商品变更");
/**
* 模版code
*/
private String code;
/**
* 模版名称
*/
private String name;
/**
* 邮件标题format
*/
private String subject;
EmailTemplateEnum(String code, String name, String subject){
this.code = code;
this.name = name;
this.subject = subject;
}
public String getCode(){
return code;
}
public String getSubject(){
return subject;
}
public static EmailTemplateEnum getEmailTemplateEnum(String code){
for (EmailTemplateEnum template : EmailTemplateEnum.values()) {
if (template.getCode().equals(code)) {
return template;
}
}
return null;
}
}
package com.netease.mail.yanxuan.change.integration.email.enums;
public enum EmailType {
NULL(""), //NULL
RPC("RPC"), //RPC请求
HTTP("HTTP"), //HTTP请求
CACHE("CACHE"), //缓存问题
DB("DB"), //DB问题
MQ("MQ"), //消息队列问题
PARAM("PARAM"), //入参问题
SERVICE("SERVICE"), //业务逻辑问题
EXT_DEPENDENCY("EXT_DEPENDENCY"); //外部依赖问题
private String value;
private EmailType(String value) {
this.value = value;
}
public String getValue() {
return this.value;
}
}
\ No newline at end of file
package com.netease.mail.yanxuan.change.integration.email.enums;
public enum EmailTypeEnum {
TEXT("text"),
HTML("html");
private String type;
EmailTypeEnum(String type){
this.type = type;
}
public String getType(){
return this.type;
}
}
\ No newline at end of file
package com.netease.mail.yanxuan.change.integration.email.exception;
/**
* @author lwtang
* @date 2019-02-19
*/
public class RpcConnectException extends RpcException{
public RpcConnectException(String message) {
super(message);
}
}
package com.netease.mail.yanxuan.change.integration.email.exception;
/**
* @author lwtang
* @date 2019-02-19
*/
public class RpcException extends RuntimeException {
public RpcException(String message) {
super(message);
}
public RpcException(Throwable t) {
super(t);
}
public RpcException(String message, Throwable t) {
super(message, t);
}
}
package com.netease.mail.yanxuan.change.integration.email.exception;
/**
* http status code 非 200
*
* @author lwtang
* @date 2019-02-19
*/
public class RpcStatusException extends RpcException {
private int code;
public RpcStatusException(int code, String message) {
super(message);
this.code = code;
}
public int getCode() {
return this.code;
}
}
package com.netease.mail.yanxuan.change.integration.email.exception;
/**
* @author lwtang
* @date 2019-02-19
*/
public class RpcTimeoutException extends RpcException {
public RpcTimeoutException(String message) {
super(message);
}
}
package com.netease.mail.yanxuan.change.integration.email.service;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.netease.mail.yanxuan.change.integration.email.enums.EmailTemplateEnum;
/**
* 发送邮件
*/
public interface IEmailService {
/**
*
* @param toList 接收人
* @param ccList 抄送人
* @param map 邮箱参数
* @param emailTemplateEnum 标题枚举
* @param subjectParam 标题参数
*/
void sendEmail(Collection<String> toList, Collection<String> ccList, Map<String, Object> map,
EmailTemplateEnum emailTemplateEnum, String subjectParam);
}
package com.netease.mail.yanxuan.change.integration.email.service;
import java.io.File;
import java.util.Collection;
import java.util.List;
/**
* @author WangJiaXiang
* @date 2022/11/28/028$
*/
public interface UasClientService {
void sendEmail(String subject, String content, Collection<String> toList, Collection<String> ccList, List<File> fileList);
}
package com.netease.mail.yanxuan.change.integration.email.service.impl;
import com.netease.mail.yanxuan.change.integration.email.email.EmailFactor;
import com.netease.mail.yanxuan.change.integration.email.enums.EmailTemplateEnum;
import com.netease.mail.yanxuan.change.integration.email.enums.EmailTypeEnum;
import com.netease.mail.yanxuan.change.integration.email.service.IEmailService;
import com.netease.mail.yanxuan.change.integration.email.service.UasClientService;
import lombok.extern.slf4j.Slf4j;
import org.apache.logging.log4j.util.Strings;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
@Service
@Slf4j
public class EmailServiceImpl implements IEmailService {
@Autowired
private UasClientService uasClient;
@Autowired
private EmailTemplateServiceImpl emailTemplateService;
@Override
@Async("asyncEmail")
public void sendEmail(Collection<String> toList, Collection<String> ccList, Map<String, Object> map,
EmailTemplateEnum emailTemplateEnum, String subjectParam) {
EmailFactor emailFactor = new EmailFactor();
//固定
emailFactor.setType(EmailTypeEnum.TEXT.getType());
emailFactor.setEmailTemplateEnum(emailTemplateEnum);
emailFactor.setData(map);
if (map != null) {
String content = this.content(emailFactor);
if (!CollectionUtils.isEmpty(toList)) {
toList = toList.stream().filter(e -> e != null).collect(Collectors.toList());
}
if (!CollectionUtils.isEmpty(ccList)) {
ccList = ccList.stream().filter(e -> e != null).collect(Collectors.toList());
}
String subject = emailFactor.getSubject();
//标题参数处理
if (Strings.isNotBlank(subjectParam)) {
subject = String.format(subject, subjectParam);
}
log.info("send email param: {}, {}, {}, {}", subject, content, toList, ccList);
uasClient.sendEmail(subject, content, toList, ccList, null);
}
}
/**
* 根据邮件模版获取邮件内容
*
* @param emailFactor
* @return
*/
public String content(EmailFactor emailFactor) {
EmailTemplateEnum emailTemplateEnum = emailFactor.getEmailTemplateEnum();
return emailTemplateService.template(emailTemplateEnum.getCode(), emailFactor.getData(),
emailFactor.getType());
}
}
package com.netease.mail.yanxuan.change.integration.email.service.impl;
import com.alibaba.fastjson.JSONObject;
import com.netease.mail.yanxuan.change.integration.flow.email.EmailTemplateRpcService;
import com.netease.yanxuan.flowx.sdk.meta.controller.communal.AjaxResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.Map;
@Service
public class EmailTemplateServiceImpl {
/**
* 调用链接
* private static final String TEST_URL = "http://127.0.0.1:8550/proxy/test.yanxuan-template.service.mailsaas/templates/flowx/template/assemble.json";
* private static final String ONELINE_URL = "http://127.0.0.1:8550/proxy/online.yanxuan-template.service.mailsaas/templates/flowx/template/assemble.json";
*/
Logger logger = LoggerFactory.getLogger(EmailTemplateServiceImpl.class);
@Autowired
private EmailTemplateRpcService service;
public String template(String templateCode, Object mockData, String type) {
Map<String, Object> params = new HashMap<>();
params.put("mockData", mockData);
params.put("templateCode", templateCode);
params.put("type", type);
logger.info(JSONObject.toJSONString("邮箱接口参数展示mockData={},templateCode={},type={}"),mockData,templateCode, type);
AjaxResponse<String> response = service.template(params);
logger.info("请求后参数展示\n"+response);
return response.getData();
}
}
package com.netease.mail.yanxuan.change.integration.email.service.impl;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.netease.mail.yanxuan.change.integration.email.service.UasClientService;
import com.netease.mail.yanxuan.change.integration.flow.email.EmailRpcService;
import com.netease.mail.yanxuan.change.integration.rpc.RpcResultException;
import com.netease.mail.yanxuan.change.integration.rpc.RpcTemplate;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import java.io.File;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @author WangJiaXiang
* @date 2022/11/28/028$
*/
@Service
public class UasClientServiceImpl implements UasClientService {
Logger logger = LoggerFactory.getLogger(UasClientServiceImpl.class);
private static final String TEST_URL = "http://127.0.0.1:8550/proxy/test.logistics-uas.service.mailsaas/push/email/qc";
private static final String ONLINE_URL = "http://127.0.0.1:8550/proxy/online.logistics-uas.service.mailsaas/push/email/qc";
@Autowired
private EmailRpcService service;
@Value("${env:online}")
private String env;
@Autowired
private RpcTemplate rpcTemplate;
@Override
public void sendEmail(String subject, String content, Collection<String> toList, Collection<String> ccList, List<File> fileList) {
if (!CollectionUtils.isEmpty(toList)) {
String url = ONLINE_URL;
if ("test".equals(env)) {
url = TEST_URL;
}
Map<String, Object> params = new HashMap();
params.put("subject", subject);
params.put("content", content);
params.put("to", StringUtils.join(toList, ","));
params.put("topic", "qc");
if (!CollectionUtils.isEmpty(ccList)) {
params.put("cc", StringUtils.join(ccList, ","));
}
logger.info(JSONObject.toJSONString("邮箱接口入参 subject={},content={},toList={},ccList={}"), subject, content, StringUtils.join(toList, ","), params.get("cc"));
rpcTemplate.post(url, params, -1, resp -> {
JSONObject json = JSON.parseObject(resp);
int code = json.getInteger("code");
if (code != 200) {
throw new RpcResultException("检测异常");
}
return Boolean.TRUE;
});
//String res = service.sendEmail(subject, content, StringUtils.join(toList, ","), params.get("cc"));
}
}
}
package com.netease.mail.yanxuan.change.integration.email.util;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang3.StringUtils;
/**
* @author lwtang
* @date 2019-02-19
*/
public class EncodeUtil {
private static final char[] CHARS = new char[] { '0', '1', '2', '3', '4', '5', '6', '7', '8',
'9', 'a', 'b', 'c', 'd', 'e', 'f' };
public static String encode(String text) {
try {
return URLEncoder.encode(text, "UTF-8");
} catch (Exception e) {
return text;
}
}
public static String encodeMap(Map<?, ?> map) {
List<String> lines = new ArrayList<>();
for (Map.Entry<?, ?> entry: map.entrySet()) {
lines.add(String.valueOf(entry.getKey()) + "=" + String.valueOf(entry.getValue()));
}
return StringUtils.join(lines, "&");
}
public static String decode(String text) {
try {
return URLDecoder.decode(text, "UTF-8");
} catch (Exception e) {
return text;
}
}
public static String ASCIIHex(String text) {
byte[] bytes = text.getBytes();
char[] chars = new char[bytes.length * 2];
for (int i = 0; i < bytes.length; i++) {
chars[2 * i] = CHARS[bytes[i] >> 4];
chars[2 * i + 1] = CHARS[bytes[i] % 16];
}
return new String(chars).toUpperCase();
}
}
package com.netease.mail.yanxuan.change.integration.email.util;
import com.netease.mail.yanxuan.change.integration.email.exception.RpcConnectException;
import com.netease.mail.yanxuan.change.integration.email.exception.RpcException;
import com.netease.mail.yanxuan.change.integration.email.exception.RpcStatusException;
import com.netease.mail.yanxuan.change.integration.email.exception.RpcTimeoutException;
import org.apache.http.Consts;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.config.*;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.BasicHeader;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.ssl.SSLContexts;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.ConnectException;
import java.net.SocketTimeoutException;
import java.net.URI;
import java.net.URLEncoder;
import java.nio.charset.CodingErrorAction;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* HttpClient 封装
*
* @author lwtang
* @date 2019-02-19
*/
public class HttpClientUtil {
private static final Logger LOG = LoggerFactory.getLogger(HttpClientUtil.class);
private static final int DEFAULT_TIME_OUT = 5000;
private static final String DEFAULT_ENCODING = "UTF-8";
private static PoolingHttpClientConnectionManager connManager = null;
private static CloseableHttpClient httpclient = null;
static {
try {
SSLContext sslContext = SSLContexts.custom().build();
sslContext.init(null, new TrustManager[] { new DefaultTrustManager() }, null);
Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder
.<ConnectionSocketFactory>create()
.register("http", PlainConnectionSocketFactory.INSTANCE)
.register("https", new SSLConnectionSocketFactory(sslContext)).build();
connManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
httpclient = HttpClients.custom().setConnectionManager(connManager).build();
// Create socket configuration
SocketConfig socketConfig = SocketConfig.custom().setSoKeepAlive(true)
.setSoReuseAddress(true).setSoTimeout(DEFAULT_TIME_OUT).setTcpNoDelay(true).build();
connManager.setDefaultSocketConfig(socketConfig);
// Create message constraints
MessageConstraints messageConstraints = MessageConstraints.custom()
.setMaxHeaderCount(200).setMaxLineLength(2000).build();
// Create connection configuration
ConnectionConfig connectionConfig = ConnectionConfig.custom()
.setMalformedInputAction(CodingErrorAction.IGNORE)
.setUnmappableInputAction(CodingErrorAction.IGNORE).setCharset(Consts.UTF_8)
.setMessageConstraints(messageConstraints).build();
connManager.setDefaultConnectionConfig(connectionConfig);
connManager.setMaxTotal(300);
connManager.setDefaultMaxPerRoute(100);
} catch (KeyManagementException e) {
LOG.error("KeyManagementException", e);
} catch (NoSuchAlgorithmException e) {
LOG.error("NoSuchAlgorithmException", e);
}
}
public static String get(String url, Map<String, Object> params, Map<String, String> header,
int timeout) {
return doGet(url, params, header, DEFAULT_ENCODING, timeout);
}
public static String doGet(String url, Map<String, Object> params, Map<String, String> header,
String encoding, int timeout) {
String responseString = null;
HttpGet get = new HttpGet();
fillUrl(url, params, encoding, get);
fillHeader(header, get);
fillConfig(timeout, timeout, get);
try {
CloseableHttpResponse response = httpclient.execute(get);
try {
int resHttpCode = response.getStatusLine().getStatusCode();
if( resHttpCode != 200) {
throw new RpcStatusException(resHttpCode, "status code " + resHttpCode + " not equal 200");
}
HttpEntity entity = response.getEntity();
try {
if (entity != null) {
responseString = EntityUtils.toString(entity, encoding);
}
} finally {
if (entity != null) {
entity.getContent().close();
}
}
return responseString;
} catch (Exception e) {
LOG.error("[HttpUtils Get response error]", e);
throw e;
} finally {
if (response != null) {
response.close();
}
}
} catch (ConnectException e) {
throw new RpcConnectException("request connect failed!");
} catch (SocketTimeoutException e) {
throw new RpcTimeoutException("request timeout!");
} catch (IOException e) {
LOG.error("[query webservice error]", e);
} finally {
get.releaseConnection();
}
return responseString;
}
public static String postJson(String url, String params, int timeout) {
Map<String, String> header = new HashMap<>();
header.put("Content-type", ContentType.APPLICATION_JSON.getMimeType());
return doPost(url, new StringEntity(params, DEFAULT_ENCODING), header, DEFAULT_ENCODING,
timeout);
}
public static String post(String url, Map<String, Object> params, int timeout) {
Map<String, String> header = new HashMap<>();
header.put("Content-type", ContentType.APPLICATION_FORM_URLENCODED.getMimeType());
HttpEntity httpEntity = null;
if (params != null && params.size() > 0) {
List<BasicNameValuePair> formParams = params.entrySet().stream()
.map(entry -> new BasicNameValuePair(entry.getKey(),
entry.getValue() == null ? "" : entry.getValue().toString()))
.collect(Collectors.toList());
try {
httpEntity = new UrlEncodedFormEntity(formParams, DEFAULT_ENCODING);
} catch (UnsupportedEncodingException e) {
throw new RpcException(e);
}
}
return doPost(url, httpEntity, header, DEFAULT_ENCODING, timeout);
}
public static String doPost(String url, HttpEntity params, Map<String, String> header,
String encoding, int timeout) {
String responseContent = null;
HttpPost post = new HttpPost(url);
fillHeader(header, post);
fillConfig(timeout, timeout, post);
post.setEntity(params);
try {
CloseableHttpResponse response = httpclient.execute(post);
try {
HttpEntity entity = response.getEntity();
responseContent = EntityUtils.toString(entity, encoding);
} finally {
if (response != null) {
response.close();
}
}
} catch (ConnectException e) {
throw new RpcConnectException("request connect failed!");
} catch (SocketTimeoutException e) {
throw new RpcTimeoutException("request timeout!");
} catch (IOException e) {
LOG.error("[query webservice error]", e);
} finally {
post.releaseConnection();
}
return responseContent;
}
/**
* concat url
*/
private static String fillUrl(String url, Map<String, Object> params, String encoding,
HttpRequestBase requestBase) {
StringBuilder sb = new StringBuilder();
sb.append(url);
int i = 0;
if (params != null && params.size() > 0) {
for (Map.Entry<String, Object> entry: params.entrySet()) {
if (i == 0 && !url.contains("?")) {
sb.append("?");
} else {
sb.append("&");
}
sb.append(entry.getKey());
sb.append("=");
Object v = entry.getValue();
String value = v == null ? "" : v.toString();
encoding = encoding == null ? Consts.UTF_8.name() : encoding;
try {
sb.append(URLEncoder.encode(value, encoding));
} catch (UnsupportedEncodingException e) {
LOG.warn("encoding common get params error, value={}", value, e);
try {
sb.append(URLEncoder.encode(value, encoding));
} catch (Exception ex) {
e.printStackTrace();
}
}
i++;
}
}
requestBase.setURI(URI.create(sb.toString()));
return sb.toString();
}
private static void fillHeader(Map<String, String> header, HttpRequestBase requestBase) {
if (header == null || header.size() == 0) {
return;
}
Header[] headers = header.entrySet().stream()
.map(entry -> new BasicHeader(entry.getKey(), entry.getValue()))
.collect(Collectors.toList()).toArray(new Header[header.size()]);
if (headers.length > 0) {
requestBase.setHeaders(headers);
}
}
/**
* fill common conf
*/
private static void fillConfig(int connectTimeout, int soTimeout, HttpRequestBase requestBase) {
if (connectTimeout <= 0) {
connectTimeout = DEFAULT_TIME_OUT;
}
if (soTimeout <= 0) {
soTimeout = DEFAULT_TIME_OUT;
}
RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(soTimeout)
.setConnectTimeout(connectTimeout).setConnectionRequestTimeout(connectTimeout).build();
requestBase.setConfig(requestConfig);
}
public static class DefaultTrustManager implements X509TrustManager {
@Override
public void checkClientTrusted(X509Certificate[] x509Certificates, String s)
throws CertificateException {}
@Override
public void checkServerTrusted(X509Certificate[] x509Certificates, String s)
throws CertificateException {}
@Override
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}
}
}
/**
* @(#)ChangeFlowExcelDTO.java, 2022/11/25.
* <p/>
* Copyright 2022 Netease, Inc. All rights reserved.
* NETEASE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
package com.netease.mail.yanxuan.change.integration.excel;
import com.netease.mail.yanxuan.change.common.enums.ChangeSubjectEnum;
import cn.afterturn.easypoi.excel.annotation.Excel;
import lombok.Data;
/**
* @Author zcwang
* @Date 2022/11/25
*/
@Data
public class ChangeFlowExcelDTO {
/**
* 变更id
*/
@Excel(name = "变更id")
private Long flowId;
/**
* 变更发起时间
*/
@Excel(name = "变更发起时间")
private String createTime;
/**
* 变更发起人
*/
@Excel(name = "变更发起人")
private String changeCreator;
/**
* 变更主体
* @see ChangeSubjectEnum
*/
@Excel(name = "变更主体")
private String changeSubject;
/**
* 变更类型,一级类型>二级类型
*/
@Excel(name = "变更类型")
private String changeType;
/**
* 变更等级
*/
@Excel(name = "变更等级")
private Integer changeLevel;
/**
* 变更负责部门名
*/
@Excel(name = "变更负责部门名")
private String changeDepartment;
/**
* 变更负责人
*/
@Excel(name = "变更负责人")
private String changeCommander;
/**
* 变更供应商:供应商ID+供应商名称
*/
@Excel(name = "变更供应商")
private String supplier;
/**
* 变更原因
*/
@Excel(name = "变更原因")
private String changeReason;
/**
* 变更内容
*/
@Excel(name = "变更内容")
private String changeContent;
/**
* 变更潜在风险描述
*/
@Excel(name = "变更潜在风险描述")
private String changeRiskDesc;
/**
* 变更收益类型
*/
@Excel(name = "变更收益类型")
private String changeProfit;
/**
* 变更收益说明
*/
@Excel(name = "变更收益说明")
private String changeProfitDesc;
/**
* 变更商品,商品名称
*/
@Excel(name = "变更商品")
private String changeItem;
/**
* SPUID
*/
@Excel(name = "SPUID")
private Long SPUId;
/**
* 品控类目
*/
@Excel(name = "品控类目")
private String qcCategory;
/**
* 物理类目
*/
@Excel(name = "物理类目")
private String phyCategory;
/**
* 商品立项类型,0-正常立项商品,2-特殊免立项商品 3-组合装
*/
@Excel(name = "商品立项类型")
private String itemSetupType;
/**
* 经营形式,0-自营,3-严选贴牌代销,4-他方品牌代销,5-代销2.0
*/
@Excel(name = "经营形式")
private String businessForm;
/**
* 商品状态,0-未上架,1-未上架,2-已上架,4-预上架
*/
@Excel(name = "商品状态")
private String status;
/**
* 商品负责人
*/
@Excel(name = "商品负责人")
private String functionary;
/**
* 采购负责人
*/
@Excel(name = "采购负责人")
private String purchase;
/**
* SQE负责人
*/
@Excel(name = "SQE负责人")
private String goodsSqe;
/**
* 计划负责人
*/
@Excel(name = "计划负责人")
private String goodsProject;
/**
* 变更行动部门
*/
@Excel(name = "变更行动部门")
private String execDepartment;
/**
* 变更行动人
*/
@Excel(name = "变更行动人")
private String changeExecUser;
/**
* 行动项变更风险描述
*/
@Excel(name = "行动项变更风险描述")
private String changeExecRiskDesc;
/**
* 行动项
*/
@Excel(name = "行动项")
private String changeExecProject;
/**
* 变更验证措施
*/
@Excel(name = "变更验证措施")
private String changeChecking;
/**
* 行动完成时间
*/
@Excel(name = "行动完成时间")
private String changeExecFinishTime;
/**
* 行动完成情况
*/
@Excel(name = "行动完成情况")
private String changeExecFinishDesc;
/**
* 变更结论
*/
@Excel(name = "变更结论")
private String changeResult;
/**
* 变更完结时间
*/
@Excel(name = "变更完结时间")
private String changeEndTime;
}
\ No newline at end of file
/**
* @(#)ChangeFlowExcelVo.java, 2022/12/8.
* <p/>
* Copyright 2022 Netease, Inc. All rights reserved.
* NETEASE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
package com.netease.mail.yanxuan.change.integration.excel;
import java.util.ArrayList;
import java.util.List;
import com.netease.mail.dp.des.common.api.enums.ExcelCellType;
import com.netease.mail.dp.des.process.api.entity.ExcelCell;
import com.netease.mail.yanxuan.change.common.anno.ExcelTitleName;
import com.netease.mail.yanxuan.change.common.enums.ChangeSubjectEnum;
import lombok.Data;
/**
* @Author zcwang
* @Date 2022/12/8
*/
@Data
public class ChangeFlowExcelVo {
/**
* 变更id
*/
@ExcelTitleName(title = "变更id", order = 1)
private Long flowId;
/**
* 变更发起时间
*/
@ExcelTitleName(title = "变更发起时间", order = 2)
private String createTime;
/**
* 变更发起人
*/
@ExcelTitleName(title = "变更发起人", order = 3)
private String changeCreator;
/**
* 变更主体
* @see ChangeSubjectEnum
*/
@ExcelTitleName(title = "变更主体", order = 4)
private String changeSubject;
/**
* 变更类型,一级类型>二级类型
*/
@ExcelTitleName(title = "变更类型", order = 5)
private String changeType;
/**
* 变更等级
*/
@ExcelTitleName(title = "变更等级", order = 6)
private String changeLevel;
/**
* 变更负责部门名
*/
@ExcelTitleName(title = "变更负责部门名", order = 7)
private String changeDepartment;
/**
* 变更负责人
*/
@ExcelTitleName(title = "变更负责人", order = 8)
private String changeCommander;
/**
* 变更供应商:供应商ID+供应商名称
*/
@ExcelTitleName(title = "变更供应商", order = 9)
private String supplier;
/**
* 变更原因
*/
@ExcelTitleName(title = "变更原因", order = 10)
private String changeReason;
/**
* 变更内容
*/
@ExcelTitleName(title = "变更内容", order = 11)
private String changeContent;
/**
* 变更潜在风险描述
*/
@ExcelTitleName(title = "变更潜在风险描述", order = 12)
private String changeRiskDesc;
/**
* 变更收益类型
*/
@ExcelTitleName(title = "变更收益类型", order = 13)
private String changeProfit;
/**
* 变更收益说明
*/
@ExcelTitleName(title = "变更收益说明", order = 14)
private String changeProfitDesc;
/**
* 变更商品,商品名称
*/
@ExcelTitleName(title = "变更商品", order = 15)
private String changeItem;
/**
* SPUID
*/
@ExcelTitleName(title = "SPUID", order = 16)
private String SPUId;
/**
* 品控类目
*/
@ExcelTitleName(title = "品控类目", order = 17)
private String qcCategory;
/**
* 物理类目
*/
@ExcelTitleName(title = "物理类目", order = 18)
private String phyCategory;
/**
* 商品立项类型,0-正常立项商品,2-特殊免立项商品 3-组合装
*/
@ExcelTitleName(title = "商品立项类型", order = 19)
private Integer itemSetupType;
/**
* 经营形式,0-自营,3-严选贴牌代销,4-他方品牌代销,5-代销2.0
*/
@ExcelTitleName(title = "经营形式", order = 20)
private Integer businessForm;
/**
* 商品状态,0-未上架,1-未上架,2-已上架,4-预上架
*/
@ExcelTitleName(title = "商品状态", order = 21)
private String status;
/**
* 商品负责人
*/
@ExcelTitleName(title = "商品负责人", order = 22)
private String functionary;
/**
* 采购负责人
*/
@ExcelTitleName(title = "采购负责人", order = 23)
private String purchase;
/**
* SQE负责人
*/
@ExcelTitleName(title = "SQE负责人", order = 24)
private String goodsSqe;
/**
* 计划负责人
*/
@ExcelTitleName(title = "计划负责人", order = 25)
private String goodsProjectName;
/**
* 变更行动部门
*/
@ExcelTitleName(title = "变更行动部门", order = 26)
private String execDepartment;
/**
* 变更行动人
*/
@ExcelTitleName(title = "变更行动人", order = 27)
private String changeExecUser;
/**
* 行动项变更风险描述
*/
@ExcelTitleName(title = "行动项变更风险描述", order = 28)
private String changeExecRiskDesc;
/**
* 行动项
*/
@ExcelTitleName(title = "行动项", order = 29)
private String changeExecProject;
/**
* 变更验证措施
*/
@ExcelTitleName(title = "变更验证措施", order = 30)
private String changeChecking;
/**
* 行动完成时间
*/
@ExcelTitleName(title = "行动完成时间", order = 31)
private String changeExecFinishTime;
/**
* 行动完成情况
*/
@ExcelTitleName(title = "行动完成情况", order = 32)
private String changeExecFinishDesc;
/**
* 变更结论
*/
@ExcelTitleName(title = "变更结论", order = 33)
private String changeResult;
/**
* 变更完结时间
*/
@ExcelTitleName(title = "变更完结时间", order = 34)
private Integer changeEndTime;
public static List<ExcelCell> init(ChangeFlowExcelDTO dto) {
List<ExcelCell> cellInfo = new ArrayList<>();
ExcelCell excelCell = new ExcelCell();
excelCell.setCellType(ExcelCellType.TEXT);
// 1.id
excelCell.setValue(dto.getFlowId());
cellInfo.add(excelCell);
// 2.变更发起时间
excelCell = new ExcelCell();
excelCell.setValue(dto.getCreateTime());
cellInfo.add(excelCell);
// 3.变更发起人
excelCell = new ExcelCell();
excelCell.setValue(dto.getChangeCreator());
cellInfo.add(excelCell);
// 4.变更主体
excelCell = new ExcelCell();
excelCell.setValue(dto.getChangeSubject());
cellInfo.add(excelCell);
// 5.变更类型,一级类型>二级类型
excelCell = new ExcelCell();
excelCell.setValue(dto.getChangeType());
cellInfo.add(excelCell);
// 6.变更等级
excelCell = new ExcelCell();
excelCell.setValue(dto.getChangeLevel());
cellInfo.add(excelCell);
// 7.变更负责部门名
excelCell = new ExcelCell();
excelCell.setValue(dto.getChangeDepartment());
cellInfo.add(excelCell);
// 8.变更负责人
excelCell = new ExcelCell();
excelCell.setValue(dto.getChangeCommander());
cellInfo.add(excelCell);
// 9.变更供应商
excelCell = new ExcelCell();
excelCell.setValue(dto.getSupplier());
cellInfo.add(excelCell);
// 10.变更原因
excelCell = new ExcelCell();
excelCell.setValue(dto.getChangeReason());
cellInfo.add(excelCell);
// 11.变更内容
excelCell = new ExcelCell();
excelCell.setValue(dto.getChangeContent());
cellInfo.add(excelCell);
// 12.变更潜在风险描述
excelCell = new ExcelCell();
excelCell.setValue(dto.getChangeRiskDesc());
cellInfo.add(excelCell);
// 13.变更收益类型
excelCell = new ExcelCell();
excelCell.setValue(dto.getChangeProfit());
cellInfo.add(excelCell);
// 14.变更收益说明
excelCell = new ExcelCell();
excelCell.setValue(dto.getChangeProfitDesc());
cellInfo.add(excelCell);
// 15.变更商品,商品名称
excelCell = new ExcelCell();
excelCell.setValue(dto.getChangeItem());
cellInfo.add(excelCell);
// 16.SPUID
excelCell = new ExcelCell();
excelCell.setValue(dto.getSPUId());
cellInfo.add(excelCell);
// 17.品控类目
excelCell = new ExcelCell();
excelCell.setValue(dto.getQcCategory());
cellInfo.add(excelCell);
// 18.物理类目
excelCell = new ExcelCell();
excelCell.setValue(dto.getPhyCategory());
cellInfo.add(excelCell);
// 19.商品立项类型.0-正常立项商品,2-特殊免立项商品 3-组合装
excelCell = new ExcelCell();
excelCell.setValue(dto.getItemSetupType());
cellInfo.add(excelCell);
// 20.经营形式,0-自营,3-严选贴牌代销,4-他方品牌代销,5-代销2.0
excelCell = new ExcelCell();
excelCell.setValue(dto.getBusinessForm());
cellInfo.add(excelCell);
// 21.商品状态,0-未上架,1-未上架,2-已上架,4-预上架
excelCell = new ExcelCell();
excelCell.setValue(dto.getStatus());
cellInfo.add(excelCell);
// 22.商品负责人
excelCell = new ExcelCell();
excelCell.setValue(dto.getFunctionary());
cellInfo.add(excelCell);
// 23.采购负责人
excelCell = new ExcelCell();
excelCell.setValue(dto.getPurchase());
cellInfo.add(excelCell);
// 24.SQE负责人
excelCell = new ExcelCell();
excelCell.setValue(dto.getGoodsSqe());
cellInfo.add(excelCell);
// 25.计划负责人
excelCell = new ExcelCell();
excelCell.setValue(dto.getGoodsProject());
cellInfo.add(excelCell);
// 26.变更行动部门
excelCell = new ExcelCell();
excelCell.setValue(dto.getExecDepartment());
cellInfo.add(excelCell);
// 27.变更行动人
excelCell = new ExcelCell();
excelCell.setValue(dto.getChangeExecUser());
cellInfo.add(excelCell);
// 28.行动项变更风险描述
excelCell = new ExcelCell();
excelCell.setValue(dto.getChangeExecRiskDesc());
cellInfo.add(excelCell);
// 29.行动项
excelCell = new ExcelCell();
excelCell.setValue(dto.getChangeExecProject());
cellInfo.add(excelCell);
// 30.变更验证措施
excelCell = new ExcelCell();
excelCell.setValue(dto.getChangeChecking());
cellInfo.add(excelCell);
// 31.行动完成时间
excelCell = new ExcelCell();
excelCell.setValue(dto.getChangeExecFinishTime());
cellInfo.add(excelCell);
// 32.行动完成情况
excelCell = new ExcelCell();
excelCell.setValue(dto.getChangeExecFinishDesc());
cellInfo.add(excelCell);
// 33.变更结论
excelCell = new ExcelCell();
excelCell.setValue(dto.getChangeResult());
cellInfo.add(excelCell);
// 34.变更完结时间
excelCell = new ExcelCell();
excelCell.setValue(dto.getChangeEndTime());
cellInfo.add(excelCell);
return cellInfo;
}
}
\ No newline at end of file
/**
* @(#)FlowRpcService.java, 2022/11/16.
* <p/>
* Copyright 2022 Netease, Inc. All rights reserved.
* NETEASE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
package com.netease.mail.yanxuan.change.integration.flow;
import java.util.List;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import com.netease.yanxuan.flowx.sdk.meta.controller.communal.AjaxResponse;
import com.netease.yanxuan.flowx.sdk.meta.dto.base.FlowDataDTO;
import com.netease.yanxuan.flowx.sdk.meta.dto.flow.FlowCreateReqDTO;
import com.netease.yanxuan.flowx.sdk.meta.dto.flow.NodeSubmitReqDTO;
import com.netease.yanxuan.flowx.sdk.meta.dto.flow.UpdateNodeApproverDTO;
import com.netease.yanxuan.missa.client.annotation.MissaClient;
/**
* @Author zcwang
* @Date 2022/11/16
*/
@Service
@MissaClient(serviceCode = "yanxuan-flowx-server")
public interface FlowRpcService {
/**
* 创建流转工单
*
* @param product
* @param req
* @return
*/
@PostMapping(value = "/{product}/workOrderFlow/v1/create", consumes = MediaType.APPLICATION_JSON_VALUE)
AjaxResponse<String> create(@PathVariable("product") String product, FlowCreateReqDTO req);
/**
* 工单详情查询
* @param flowxProduct
* @param flowId
* @return
*/
@GetMapping(value = "/{product}/workOrder/v1/{flowId}/detail")
AjaxResponse<FlowDataDTO> getDetail(@PathVariable("product") String flowxProduct,
@PathVariable("flowId") String flowId);
/**
* 工单提交
* @param flowxProduct
* @param nodeSubmitReqDTO
* @return
*/
@PostMapping(value = "/{product}/workOrderFlow/v1/submit", consumes = MediaType.APPLICATION_JSON_VALUE)
AjaxResponse<List<String>> submit(@PathVariable("product") String flowxProduct, NodeSubmitReqDTO nodeSubmitReqDTO);
/**
* 更新待办负责人
* @param flowxProduct
* @param approverDTO
*/
@PutMapping(value = "/{product}/workOrderFlow/v1/approvers/update", consumes = MediaType.APPLICATION_JSON_VALUE)
void updateApprovers(@PathVariable("product")String flowxProduct, UpdateNodeApproverDTO approverDTO);
}
/**
* @(#)FlowxCreateDTO.java, 2022/11/16.
* <p/>
* Copyright 2022 Netease, Inc. All rights reserved.
* NETEASE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
package com.netease.mail.yanxuan.change.integration.flow;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @Author zcwang
* @Date 2022/11/16
*/
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class FlowxCreateDTO {
/**
* 执行更新操作的员工id
*/
private String uid;
/**
* xxx@corp.netease.com
*/
private String userName;
/**
* 业务数据
*/
private String content;
/**
* topoId
*/
private String topoId;
/**
* 工单实例ID
*/
private String workOrderId;
/**
* 备注,提交操作时填写的备注框内容
*/
private String remark;
/**
* 操作结果,用于展示在操作日志中
*/
private String operateResult;
}
\ No newline at end of file
/**
* @(#)WorkflowApproveDTO.java, 2021年1月19日.
*
* Copyright 2021 Netease, Inc. All rights reserved.
* NETEASE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
package com.netease.mail.yanxuan.change.integration.flow;
import java.util.Map;
public class FlowxSubmitDTO {
private String topoId;
/**
* 流程id
*/
private String flowId;
/**
* 当前节点
*/
private String currentNodeId;
/**
* 审核节点时是审核通过与否,自动执行节点时是执行成功与否
*/
private boolean approved;
/**
* 用户id
*/
private String uid;
/**
* 用户名
*/
private String userName;
/**
* 业务数据
*/
private String content;
/**
* 网关使用的判断条件传入
*/
private Map<String, Object> paramMap;
/**
* 审核节点时是不通过理由,自动执行节点时是执行结果描述
*/
private String rejectReason;
private String extension;
/**
* 操作结果
*/
private String operateResult;
private String approveFormExtensionInfo;
/**
* 备注
*/
private String remark;
public String getApproveFormExtensionInfo() {
return approveFormExtensionInfo;
}
public void setApproveFormExtensionInfo(String approveFormExtensionInfo) {
this.approveFormExtensionInfo = approveFormExtensionInfo;
}
public String getOperateResult() {
return operateResult;
}
public void setOperateResult(String operateResult) {
this.operateResult = operateResult;
}
public String getTopoId() {
return topoId;
}
public void setTopoId(String topoId) {
this.topoId = topoId;
}
public String getFlowId() {
return flowId;
}
public void setFlowId(String flowId) {
this.flowId = flowId;
}
public String getCurrentNodeId() {
return currentNodeId;
}
public void setCurrentNodeId(String currentNodeId) {
this.currentNodeId = currentNodeId;
}
public boolean isApproved() {
return approved;
}
public void setApproved(boolean approved) {
this.approved = approved;
}
public String getRejectReason() {
return rejectReason;
}
public void setRejectReason(String rejectReason) {
this.rejectReason = rejectReason;
}
public String getExtension() {
return extension;
}
public void setExtension(String extension) {
this.extension = extension;
}
public String getRemark() {
return remark;
}
public void setRemark(String remark) {
this.remark = remark;
}
public Map<String, Object> getParamMap() {
return paramMap;
}
public void setParamMap(Map<String, Object> paramMap) {
this.paramMap = paramMap;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String getUid() {
return uid;
}
public void setUid(String uid) {
this.uid = uid;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
}
package com.netease.mail.yanxuan.change.integration.flow;
import lombok.Data;
@Data
public class OrgPosDTO {
/**
*部门id
*/
private Long orgPosId;
/**
*部门名称
*/
private String orgPosName;
/**
*上一级部门id
*/
private Long parentOrgPosId;
/**
*部门结构类型 0:职能部门,1:项目部门
*/
private Integer posStructType;
/**
*部门的级别
*/
private Integer level;
/**
* 对应oa
*/
private String deptId;
}
package com.netease.mail.yanxuan.change.integration.flow;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class UserQueryDTO {
/**
* 邮箱集合
*/
private List<String> uids;
/**
* 用户邮箱类型 0 严选员工,1 非严选员工
*/
private Integer userType = 0;
}
package com.netease.mail.yanxuan.change.integration.flow.email;
import com.netease.yanxuan.missa.client.annotation.MissaClient;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import java.util.Map;
/**
* @author WangJiaXiang
* @date 2022/11/28/028$
*/
@Service
@MissaClient(serviceCode = "logistics-uas")
public interface EmailRpcService {
//push/email/attach/qc/upload.json
@PostMapping("/push/email/attach/qc/upload.json")
String sendEmailAttach(Map<String, String> params);
@PostMapping("/push/email/qc")
String sendEmail(@RequestParam(name = "subject")String subject,
@RequestParam(name = "content")String content,
@RequestParam(name = "to") String to,
@RequestParam(name = "cc",required = false)String cc);
}
package com.netease.mail.yanxuan.change.integration.flow.email;
import com.netease.yanxuan.flowx.sdk.meta.controller.communal.AjaxResponse;
import com.netease.yanxuan.missa.client.annotation.MissaClient;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import java.util.Map;
/**
* @author WangJiaXiang
* @date 2022/11/29/029$
*/
@Service
@MissaClient(serviceCode = "yanxuan-template")
public interface EmailTemplateRpcService {
@PostMapping("/templates/flowx/template/assemble.json")
AjaxResponse<String> template(@RequestBody Map<String,Object> params);
}
package com.netease.mail.yanxuan.change.integration.flow.goods;
import com.netease.yanxuan.missa.client.annotation.MissaClient;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import java.util.List;
/**
* @author WangJiaXiang
* @date 2022/11/24/024$
* 查询商品BU
*/
@Service
@MissaClient(serviceCode = "yanxuan-itemcenter-admin")
public interface ItemcenterApiRpcService {
/**
* 根据商品Id 查询商品BU
* @param goodsId
* @return
*/
@PostMapping(value = "/yxicadmin/api/xhr/item/group/itemIds.json")
String getDetail(@RequestBody List<Long> goodsId);
/*
* 调用案例
SupplierSendEmailReq req = new SupplierSendEmailReq();
req.setSupplierId("YX0001");
req.setMailSubject("测试发送主题");
req.setMailContent("测试发送内容");
req.setIsAllAccountResolved(1);
String s = sendEmailService.sendEmail(req);
*/
}
package com.netease.mail.yanxuan.change.integration.flow.goods;
import com.netease.yanxuan.missa.client.annotation.MissaClient;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import java.util.List;
/**
* @author WangJiaXiang
* @date 2022/11/23/023$
*/
@Service
@MissaClient(serviceCode = "yanxuan-pfu-api")
public interface PfuApiRpcService {
/**
* 根据商品ID查看对应的执行人
* @param goodsId
* @return
*/
@PostMapping(value = "/api/negotiation/queryExecuteUserByItemId")
String getDetail(@RequestBody List<Long> goodsId);
}
package com.netease.mail.yanxuan.change.integration.flow.goods;
import com.netease.yanxuan.missa.client.annotation.MissaClient;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
/**
* @author WangJiaXiang
* @date 2022/11/18/018$
*/
@Service
@MissaClient(serviceCode = "yanxuan-qc-api")
public interface QcApiRpcService {
//查询商品的SQE
@GetMapping(value = "/xhr/item/basic/sqe.json")
String getDetail(@RequestParam("itemId") Integer itemId);
}
package com.netease.mail.yanxuan.change.integration.flow.ius;
import com.netease.mail.yanxuan.change.integration.flow.UserQueryDTO;
import com.netease.mail.yanxuan.change.integration.flow.ius.req.IusDepartmentReq;
import com.netease.mail.yanxuan.change.integration.flow.ius.rsp.IusUserInfoRsp;
import com.netease.mail.yanxuan.change.integration.flow.ius.rsp.OrgPosLeaderChainRsp;
import com.netease.mail.yanxuan.change.integration.flow.ius.rsp.SecondaryDepartments;
import com.netease.yanxuan.flowx.sdk.meta.controller.communal.AjaxResponse;
import com.netease.yanxuan.missa.client.annotation.MissaClient;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import java.util.HashMap;
import java.util.List;
/**
* @author WangJiaXiang
* @date 2022/11/24/024$
*/
@Service
@MissaClient(serviceCode = "yanxuan-ius")
public interface IusRpcService {
/**
* 获取指定用户信息,是否返回操作记录、关联的角色信息。当uid和userId都传时,需保证指向同一个用户。
* @param uid
* @return
*/
@GetMapping("/v1/qc/user/get")
AjaxResponse<IusUserInfoRsp> queryUserInfo(@RequestParam(name = "uid")String uid);
/**
* 获取指定用户信息,是否返回操作记录、关联的角色信息。当uid和userId都传时,需保证指向同一个用户。
* @param query
* @return
*/
@PostMapping("/v1/qc/user/query")
AjaxResponse<List<IusUserInfoRsp>> queryUserListInfo(@RequestBody UserQueryDTO query);
/**
* 查询指定用户部门下的上级部门(含本部门)负责人链(支持一级或多级)
* @param uid
* @return
*/
@GetMapping("/v1/qc/allTeam/pos/queryLeaderChain")
AjaxResponse<List<OrgPosLeaderChainRsp>> queryLeaderChain(@RequestParam(name = "uid")String uid);
/**
* 查询用户的负责人链(直接上级和所有上级),返回(key=用户邮箱,value=用户所属所有部门的上级(包括本部门)负责人链)
* @param uid
* @return
*/
@PostMapping("/v1/qc/user/queryLeaderChain")
AjaxResponse<HashMap<String, List<SecondaryDepartments>>> queryDepartment(@RequestBody IusDepartmentReq uid);
}
package com.netease.mail.yanxuan.change.integration.flow.ius.req;
import java.util.List;
/**
* @author WangJiaXiang
* @date 2022/11/25/025$
*/
public class IusDepartmentReq {
private boolean hasOrgPos;
private boolean icac;
private List<String> uids;
public IusDepartmentReq() {
this.hasOrgPos = true;
this.icac = true;
}
public IusDepartmentReq(List<String> uids) {
this.hasOrgPos = true;
this.icac = true;
this.uids = uids;
}
public boolean isHasOrgPos() {
return hasOrgPos;
}
public void setHasOrgPos(boolean hasOrgPos) {
this.hasOrgPos = hasOrgPos;
}
public boolean isIcac() {
return icac;
}
public void setIcac(boolean icac) {
this.icac = icac;
}
public List<String> getUids() {
return uids;
}
public void setUids(List<String> uids) {
this.uids = uids;
}
@Override
public String toString() {
return "IusDepartmentReq{" +
"hasOrgPos=" + hasOrgPos +
", icac=" + icac +
", uids=" + uids +
'}';
}
}
package com.netease.mail.yanxuan.change.integration.flow.ius.rsp;
import lombok.Data;
import java.util.List;
/**
* @author WangJiaXiang
* @date 2022/11/25/025$
*/
@Data
public class IusDepartmentRsp {
List<SecondaryDepartments> secondaryDepartments;
}
package com.netease.mail.yanxuan.change.integration.flow.ius.rsp;
import com.netease.mail.yanxuan.change.integration.flow.OrgPosDTO;
import lombok.Data;
import java.util.ArrayList;
import java.util.List;
/**
* @author WangJiaXiang
* @date 2022/11/25/025$
* 用来接受查询用户信息接口
*/
@Data
public class IusUserInfoRsp {
private Long createTime;
private String extEmail;
private Long firstLoginTime;
private Long lastLoginTime;
private Boolean locked;
private String name;
private Integer orgPosId;
private Integer srcCode;
private Integer staffStatus;
private String uid;
private String userId;
private String virtual;
/**
* 部门信息列表
*/
private List<OrgPosDTO> orgPosList = new ArrayList<>();
}
package com.netease.mail.yanxuan.change.integration.flow.ius.rsp;
import lombok.Data;
/**
* @author WangJiaXiang
* @date 2022/11/25/025$
*/
@Data
public class OrgPos {
//对应OA部门编码
private String deptId;
//部门的级别
private Integer level;
//部门id
private Long orgPosId;
//部门名称
private String orgPosName;
//上一级部门id
private Long parentOrgPosId;
//部门结构类型,0-职能部门,1-项目部门
private Integer posStructType;
private Long rootOrgPosId;
}
package com.netease.mail.yanxuan.change.integration.flow.ius.rsp;
import lombok.Data;
import java.util.List;
@Data
public class OrgPosLeaderChainRsp {
//用户所属部门id
private Integer orgPosId;
private List<UserOrgPosMetaRsp> leaderChainList;
//所属部门的级别
private Integer orgPosLevel;
//用户所属部门名称
private String orgPosName;
//所属一级部门id
private Integer rootOrgPosId;
//用户邮箱
private String uid;
}
package com.netease.mail.yanxuan.change.integration.flow.ius.rsp;
import lombok.Data;
import java.util.List;
/**
* @author WangJiaXiang
* @date 2022/11/25/025$
*/
@Data
public class SecondaryDepartments {
//用户身份用户身份
private Integer identity;
private List<leaderChain> leaderChainList;
//用户所属部门id
private Long orgPosId;
//所属部门的级别
private Integer orgPosLevel;
//用户所属部门名称
private String orgPosName;
//用户邮箱
private String uid;
//用户ID
private Long userId;
//用户姓名
private String userName;
}
package com.netease.mail.yanxuan.change.integration.flow.ius.rsp;
import lombok.Data;
@Data
public class UserOrgPosMetaRsp {
//员工职责
private String duty;
//业务方附加信息
private String extInfo;
//部门的级别
private String level;
//锁定状态
private boolean locked;
//部门id
private Integer orgPosId;
//部门名称
private String orgPosName;
//上一级部门id
private Integer parentOrgPosId;
//上一级部门名称
private Integer posType;
//所属一级部门id
private Integer rootOrgPosId;
//关联类型0-普通职员, 1-外包, 2-实习
private Integer type;
//用户邮箱
private String uid;
//用户唯一id
private Integer userId;
//用户的真名
private String userName;
}
package com.netease.mail.yanxuan.change.integration.flow.ius.rsp;
import lombok.Data;
/**
* @author WangJiaXiang
* @date 2022/11/25/025$
*/
@Data
public class leaderChain {
//创建时间
private Long createTime;
//额外的邮件接收地址
private String extEmail;
//首次登录时间、注册时间
private Long firstLoginTime;
//用户身份
private Integer identity;
//上次登录时间
private Long lastLoginTime;
//是否被锁定
private boolean locked;
//用户名称
private String name;
private OrgPos orgPos;
//所属部门
private Long orgPosId;
//所属部门级别
private Integer orgPosLevel;
//用户来源编码
private String srcCode;
//用户的身份信息,0 正式,1 试用,2 外包,3 派遣,4 实习-签三方,5 实习-未签三方,6 离职
private Integer staffStatus;
//邮箱地址
private String uid;
//用户唯一id
private Long userId;
//是否为虚拟用户 - 产品下没有该用户但是产品关联的组织身份包含该用户
private boolean virtual;
}
package com.netease.mail.yanxuan.change.integration.flow.supplier;
import com.netease.mail.yanxuan.change.integration.flow.supplier.req.SupplierRelatedUserReq;
import com.netease.mail.yanxuan.change.integration.flow.supplier.rsp.SupplierUserRsp;
import com.netease.yanxuan.flowx.sdk.meta.controller.communal.AjaxResponse;
import java.util.List;
/**
* @author WangJiaXiang
* @date 2022/12/8/008$
*/
public interface FlowRpcSupplierInfoService {
/**
* 查询供应商关联角色
*/
List<SupplierUserRsp> querySupplierRelatedUser(SupplierRelatedUserReq req);
}
package com.netease.mail.yanxuan.change.integration.flow.supplier;
import com.netease.mail.yanxuan.change.common.bean.AjaxResult;
import com.netease.mail.yanxuan.change.integration.flow.supplier.req.SupplierGoodsInfoReq;
import com.netease.mail.yanxuan.change.integration.flow.supplier.req.SupplierSearchRemoteReq;
import com.netease.mail.yanxuan.change.integration.flow.supplier.req.SupplierSendEmailReq;
import com.netease.mail.yanxuan.change.integration.flow.supplier.rsp.SupplierGoodsInfoRsp;
import com.netease.mail.yanxuan.change.integration.flow.supplier.rsp.SupplierSimpleRsp;
import com.netease.yanxuan.flowx.sdk.meta.controller.communal.AjaxResponse;
import com.netease.yanxuan.missa.client.annotation.MissaClient;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import java.util.List;
/**
* @author WangJiaXiang
* @date 2022/11/24/024$
*/
@Service
@MissaClient(serviceCode = "yanxuan-supplier-ms")
public interface FlowRpcSupplierSendService {
/**
* 邮件通知接口
* @param req
* @return
*/
@PostMapping("/api/supplier/msg/sendMail.json")
String sendEmail(@RequestBody SupplierSendEmailReq req);
/**
* 获取商品采购人信息
* @param itemIds
* @return
*/
@PostMapping("/api/initiateProject/source/getBatchRelatedSupplier.json")
String queryGoodsPurchase(@RequestBody List<Long> itemIds);
/**
* 供应商模糊查询
*/
@PostMapping("/api/supplier/queryByConditionForQc.json")
AjaxResult<List<SupplierSimpleRsp>> queryByConditionForQc(@RequestBody SupplierSearchRemoteReq req);
/**
* 查询供应商+商品对应的跟进采购 ?有存疑参数不对
*/
@PostMapping("/api/initiateProject/source/batchGetRelatedSupplier.json")
String batchGetRelatedSupplier(@RequestBody List<Integer> req);
/**
* 跟进供应商ID 互殴去供应商的商品
* @return
*/
@PostMapping("/api/initiateProject/quote/listSupplierQuoteInfoBySupplierIds.json")
AjaxResponse<List<SupplierGoodsInfoRsp>> supplierGoodsInfoBySupplier(@RequestBody SupplierGoodsInfoReq req);
}
package com.netease.mail.yanxuan.change.integration.flow.supplier;
import com.netease.mail.yanxuan.change.integration.flow.supplier.rsp.SupplierInfoRsp;
import com.netease.yanxuan.flowx.sdk.meta.controller.communal.AjaxResponse;
import com.netease.yanxuan.missa.client.annotation.MissaClient;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import java.util.List;
/**
* @author WangJiaXiang
* @date 2022/12/7/007$
*/
@Service
@MissaClient(serviceCode = "yanxuan-supplier-api")
public interface FlowRpcSupplierService {
/**
* 供应商模糊查询
* @return
*/
@GetMapping("/api/supplier/getSupplierInfo.json")
AjaxResponse<List<SupplierInfoRsp>> getSupplierInfo(@RequestParam(name = "name") String name,
@RequestParam(name = "uid") String uid,
@RequestParam(name = "fuzzySearchText") String fuzzySearchText);
}
package com.netease.mail.yanxuan.change.integration.flow.supplier.impl;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import com.alibaba.fastjson.JSON;
import com.netease.mail.yanxuan.change.integration.flow.supplier.FlowRpcSupplierInfoService;
import com.netease.mail.yanxuan.change.integration.flow.supplier.req.SupplierRelatedUserReq;
import com.netease.mail.yanxuan.change.integration.flow.supplier.rsp.SupplierUserRsp;
import com.netease.mail.yanxuan.change.integration.rpc.RpcListData;
import com.netease.mail.yanxuan.change.integration.rpc.RpcTemplate;
/**
* @author WangJiaXiang
* @date 2022/12/8/008$
*/
@Service
public class FlowRpcSupplierInfoServiceImpl implements FlowRpcSupplierInfoService {
private final String path = "/api/supplier/batchGetSupplierRelatedUser.json";
@Autowired
private RpcTemplate rpcTemplate;
@Value("${supplier.url}")
private String supplierUrl;
Logger logger = LoggerFactory.getLogger(FlowRpcSupplierInfoServiceImpl.class);
@Override
public List<SupplierUserRsp> querySupplierRelatedUser(SupplierRelatedUserReq req) {
List<SupplierUserRsp> objects = null;
try {
String url = supplierUrl + path;
objects = rpcTemplate.postJson(url, JSON.toJSONString(req), 500,
new RpcListData<>(SupplierUserRsp.class));
} catch (Exception e) {
e.printStackTrace();
logger.error("请求返回结果,e:{}", e);
}
return objects;
}
}
package com.netease.mail.yanxuan.change.integration.flow.supplier.req;
import lombok.Data;
/**
* @author WangJiaXiang
* @date 2022/12/2/002$
*/
@Data
public class SupplierGoodsInfoReq {
//是用英文逗号分隔的供应商ID列表
private String supplierIds;
}
package com.netease.mail.yanxuan.change.integration.flow.supplier.req;
import lombok.Data;
import java.util.List;
/**
* @author WangJiaXiang
* @date 2022/11/30/030$
*/
@Data
public class SupplierRelatedUserReq {
/**
* 搜索类型(1-采购 2-计划 3-SQE 4-商品开发)
*/
private Integer searchType;
/**
* 供应商ID列表
*/
private List<String> supplierIdList;
}
package com.netease.mail.yanxuan.change.integration.flow.supplier.req;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
/**
* @author WangJiaXiang
* @date 2022/12/1/001$
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class SupplierSearchRemoteReq {
private List<Integer> coopStateList;
private List<String> limitSupplierIdList;
private List<String> orInPhyCategoryIds;
/**
* 模糊查询文本
*/
private String searchText;
}
package com.netease.mail.yanxuan.change.integration.flow.supplier.req;
import lombok.Data;
/**
* @author WangJiaXiang
* @date 2022/11/24/024$
* 供应商发送邮件模板
*/
@Data
public class SupplierSendEmailReq {
//供应商ID
private String supplierId;
//邮件主题
private String mailSubject;
//邮件内容
private String mailContent;
//是否要发送所有账号标记 1:是;0:不是(范围:供应商信息中的通知邮箱 + 除供应商信息中的主账号以外的所有登录邮箱)
private Integer isAllAccountResolved;
}
package com.netease.mail.yanxuan.change.integration.flow.supplier.rsp;
import lombok.Data;
/**
* @author WangJiaXiang
* @date 2022/12/2/002$
*/
@Data
public class SupplierGoodsInfoRsp {
//注释不一定准确
//营业编号
private Integer businessForm;
//合同编号
private String contractNum;
//创建时间
private Long createTime;
//创建用户
private String createUser;
//默认标记
private Integer defaultFlag;
//商品是否有效 0: 有效;1: 失效
private Integer invalid;
//有效类型
private Integer invoiceType;
//商品主键ID
private Long itemId;
//报价货币
private String quoteCurrency;
//报价模式
private Integer quoteMode;
//结算模式
private Integer settleMode;
//供应商ID
private String supplierId;
private Integer taxRate;
//修改时间
private Long updateTime;
//修改名称
private String updateUser;
}
package com.netease.mail.yanxuan.change.integration.flow.supplier.rsp;
import lombok.Data;
/**
* @author WangJiaXiang
* @date 2022/12/7/007$
*/
@Data
public class SupplierInfoRsp {
private String supplierId;
private String supplierName;
private String email;
private String smsPhone;
private Integer isSupportCustomsClearance;
}
package com.netease.mail.yanxuan.change.integration.flow.supplier.rsp;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @author WangJiaXiang
* @date 2022/12/1/001$
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class SupplierSimpleRsp {
/**
* 供应商ID
*/
private String supplierId;
/**
* 供应商名称
*/
private String supplierName;
}
package com.netease.mail.yanxuan.change.integration.flow.supplier.rsp;
import lombok.Data;
import java.util.Map;
/**
* @author WangJiaXiang
* @date 2022/12/1/001$
*/
@Data
public class SupplierUserRsp {
/**
* 供应商ID
*/
private String supplierId;
/**
* 角色ID(1-采购 2-计划 3-SQE 4-商品开发) 以及名称
*/
private Map<String,String> uid2NameMap;
}
/**
* @(#)ItemCategoryRpcService.java, 2022/11/30.
* <p/>
* Copyright 2022 Netease, Inc. All rights reserved.
* NETEASE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
package com.netease.mail.yanxuan.change.integration.item;
import java.util.List;
import java.util.Map;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.PostMapping;
import com.netease.mail.yanxuan.change.common.bean.AjaxResult;
import com.netease.mail.yanxuan.change.integration.item.meta.SpuTO;
import com.netease.mail.yanxuan.change.integration.item.param.BatchQuerySpuInfoParam;
import com.netease.mail.yanxuan.change.integration.item.param.CommonIdsParamQuery;
import com.netease.yanxuan.missa.client.annotation.MissaClient;
/**
* @Author zcwang
* @Date 2022/11/30
*/
@Service
@MissaClient(serviceCode = "ic-basis")
public interface ItemRpcService {
/**
* 批量查询商品分类物理类目链
* @param query
* @return
*/
@PostMapping(value = "/spu/phy/queryBySpuIds", consumes = MediaType.APPLICATION_JSON_VALUE)
AjaxResult<Map<Long, List<SimplePhyCateGoryResultCo>>> queryBySpuIds(CommonIdsParamQuery query);
@PostMapping(value = "/spu/queryByIds", consumes = MediaType.APPLICATION_JSON_VALUE)
AjaxResult<List<SpuTO>> batchQuerySpuInfo(BatchQuerySpuInfoParam query);
}
\ No newline at end of file
/**
* @(#)SimplePhyCateGoryCo.java, 2022/8/18.
* <p/>
* Copyright 2022 Netease, Inc. All rights reserved.
* NETEASE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
package com.netease.mail.yanxuan.change.integration.item;
import lombok.Data;
/**
* @Author zcwang
* @Date 2022/8/18
*/
@Data
public class SimplePhyCateGoryResultCo {
/**
* 主键Id
*/
private Long id;
/**
* 类目名
*/
private String name;
/**
* number 上级类目id,首级类目为0
*/
private Long superId;
/**
* 类目描述
*/
private String description;
/**
* 类目级别 0-首级 1-中级 2-末级
*/
private Integer level;
/**
* 级别序号,由序号1从首级到末级依次递增
*/
private Integer levelNo;
/**
* 同级排序值,小的置顶
*/
private Integer rank;
}
\ No newline at end of file
package com.netease.mail.yanxuan.change.integration.item.meta;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @author jmt
* @Date 2021/6/7
*/
@AllArgsConstructor
@NoArgsConstructor
@Data
@Builder
public class ChildSkuTO {
//父sku id
private long superSkuId;
//子sku id
private long childSkuId;
//商品id
private long spuId;
//商品名称
private String spuName;
//商品昵称/销售名称
private String spuNickName;
//sku下的规格值展示字符串
private String specValueDisplayString;
//子sku数量
private int num;
}
package com.netease.mail.yanxuan.change.integration.item.meta;
import java.util.List;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @author jmt
* @Date 2021/6/7
*/
@AllArgsConstructor
@NoArgsConstructor
@Data
@Builder
public class MultiMediaDetailTO {
/**
* 透底图(原商品主图)
*/
private String primaryPicUrl;
/**
* listPicUrl
*/
private String listPicUrl;
/**
* scenePicUrl
*/
private String scenePicUrl;
/**
* 详情页图列表
*/
private List<String> detailPicUrls;
/**
* 质检报告图列表
*/
private List<String> reportPicUrls;
/**
* 商品详情页头图视频Json对象
*/
private SpuDetailVideoTO videoInfo;
/**
* 放大透底图
*/
private String zoomTransPicUrl;
/**
* 放大透底图
*/
private String zoomTransPicV2Url;
}
package com.netease.mail.yanxuan.change.integration.item.meta;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @author jmt
* @Date 2021/6/7
*/
@AllArgsConstructor
@NoArgsConstructor
@Data
@Builder
public class PolicyTO {
private long id;
//标题
private String title;
//内容
private String content;
//是否强制勾选 0-否 1-是
private int defaultChecked;
}
package com.netease.mail.yanxuan.change.integration.item.meta;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @author jmt
* @Date 2021/6/7
*/
@AllArgsConstructor
@NoArgsConstructor
@Data
@Builder
public class PreSellDetailTO {
//预售ID
private long preSellId;
//SKU ID
private long skuId;
//预售开始时间
private long startTime;
//预售结束时间
private long endTime;
//0-待预售 1-预售中 2 预售结束
private int status;
//是否已确认发货
private boolean deliverConfirmed;
//预计发货日期,UNIX时间戳,当前(2020年6月)精确到日期,取到日期即可
private long deliverDate;
//预售数据版本号,2020年6月预售接入库存中心后版本为1,在此之前为0
private int version;
}
package com.netease.mail.yanxuan.change.integration.item.meta;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @author jmt
* @Date 2021/6/7
*/
@AllArgsConstructor
@NoArgsConstructor
@Data
@Builder
public class SkuSpecCombineTO {
private long id;
private long skuId;
private long skuSpecId;
private long skuSpecValueId;
}
package com.netease.mail.yanxuan.change.integration.item.meta;
import java.util.List;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @author jmt
* @Date 2021/6/7
*/
@AllArgsConstructor
@NoArgsConstructor
@Data
@Builder
public class SkuSpecTO {
//主键
private long id;
//规格名称
private String name;
//前台显示用的名称
private String frontDesc;
//规格类型: 0-文字;1-图片
private int type;
//显示顺序
private int viewOrder;
//是否在详情页隐藏,默认false-不隐藏
private boolean firstHideFlag;
//规格值列表
private List<SkuSpecValueTO> specValueList;
}
package com.netease.mail.yanxuan.change.integration.item.meta;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @author jmt
* @Date 2021/6/7
*/
@AllArgsConstructor
@NoArgsConstructor
@Data
@Builder
public class SkuSpecValueTO {
private long id;
/**
* 所属的规格
*/
private long skuSpecId;
/**
* 显示顺序
*/
private int viewOrder;
/**
* 值
*/
private String value;
/**
* 规格图片url
*/
private String picUrl;
}
package com.netease.mail.yanxuan.change.integration.item.meta;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @author jmt
* @Date 2021/6/7
*/
@AllArgsConstructor
@NoArgsConstructor
@Data
@Builder
public class SkuTo {
//ID
private Long id;
//SPU ID
private Long spuId;
//sku展示名
private String displayName;
//sku图片
private String picUrl;
//是否是主sku
private boolean primarySku;
//是否是组合装:0-否;1-是
private int isCombine;
//是否启用过:0-否;1-是
private int isUsed;
//商品原始销售价,不会因单品变价活动而变动
private BigDecimal retailPrice;
//仓库id
private long storeHouseId;
//商品条码
private List<String> barCodeList;
private long operationAttribute;
//0-关闭;1-开启;2-作废(对应原invalid=1)
private int status;
//SKU描述(目前仅定制商品使用)
private String skuDesc;
//SKU规格构成对象
private List<SkuSpecCombineTO> skuSpecCombine;
//SPU对象,查询参数增加spu时有值
private SpuTO spu;
private Map<String, String> propertyMap;
//子SKU信息
private List<ChildSkuTO> childSkuList;
//预售详情
private PreSellDetailTO preSellDetail;
}
package com.netease.mail.yanxuan.change.integration.item.meta;
import java.util.List;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @author jmt
* @Date 2021/6/7
*/
@AllArgsConstructor
@NoArgsConstructor
@Data
@Builder
public class SpuDetailTO {
/**
* SPU ID
*/
private long id;
/**
* 商品短链
*/
private String shortUrl;
/**
* seo描述信息
*/
private String seoDesc;
/**
* 详情页html
*/
private String detailHtml;
/**
* 商详展示的SPU前台属性,null或者空表示没有
*/
private List<SpuPropTO> frontSpuPropList;
}
package com.netease.mail.yanxuan.change.integration.item.meta;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @author jmt
* @Date 2021/6/7
*/
@AllArgsConstructor
@NoArgsConstructor
@Data
@Builder
public class SpuDetailVideoTO {
/**
* 商品详情页头图MP4视频
*/
private String mp4VideoUrl;
/**
* 商品详情页头图MP4视频大小
*/
private long mp4VideoSize;
/**
* 商品详情页头图WEBM视频
*/
private String webmVideoUrl;
/**
* 商品详情页头图WEBM视频大小
*/
private long webmVideoSize;
}
package com.netease.mail.yanxuan.change.integration.item.meta;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @author jmt
* @Date 2021/6/7
*/
@AllArgsConstructor
@NoArgsConstructor
@Data
@Builder
public class SpuIssueTO {
private long id;
//0-商品配置;1-通用问题
private long type;
private String question;
private String answer;
private int rank;
}
package com.netease.mail.yanxuan.change.integration.item.meta;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @author jmt
* @Date 2021/6/7
*/
@AllArgsConstructor
@NoArgsConstructor
@Data
@Builder
public class SpuPropTO {
/**
* 商品id
*/
private Long itemId;
/**
* 属性名
*/
private String attrName;
/**
* 属性值
*/
private String attrValue;
/**
* 属性排序
*/
private int showIndex;
}
package com.netease.mail.yanxuan.change.integration.item.meta;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@AllArgsConstructor
@NoArgsConstructor
@Data
@Builder
public class SpuTO {
//商品ID
private long id;
//商品名
private String name;
//商品销售标题
private String nickName;
// itemType http://yx.mail.netease.com/wiki#/doc/791608
private int itemType;
//商品状态 0,1:未上架 2:已上架 4:预上架
private int status;
//主skuId
private long primarySkuId;
//商品零售价,如果商品未设置主SKU,售价为null
private BigDecimal retailPrice;
//商品描述
private String simpleDesc;
//上架时间
private long onSaleTime;
//更新时间
private long updateTime;
//款式信息,X件装可选
private int pieceNum;
//pieceNum的单位描述
private String pieceUnitDesc;
//款式信息,X色可选
private int colorNum;
//产地
private String productPlace;
//商品中心发布状态:0:草稿;1:未发布 2:已发布(仅在已发布情况下各渠道可以进行售卖)3:作废
private int icStatus;
//商品多媒体信息
private MultiMediaDetailTO mediaDetail;
//SPU详情信息
private SpuDetailTO detail;
//SPU关联的SKU列表
private List<SkuTo> skuList;
//SPU关联的规格信息列表
private List<SkuSpecTO> specList;
//商品常见问题列表
private List<SpuIssueTO> issueList;
//标签列表(当前仅有制造商标签)
private List<TagTO> tagList;
//服务政策列表
private List<PolicyTO> policyList;
//SPU属性集合,值范围和内容
private Map<String, String> propertyMap;
}
package com.netease.mail.yanxuan.change.integration.item.meta;
import java.util.List;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @author jmt
* @Date 2021/6/7
*/
@AllArgsConstructor
@NoArgsConstructor
@Data
@Builder
public class TagTO {
private long id;
//标签所属类目id
private long categoryId;
//标签所属类名
private String categoryName;
//名称
private String name;
//排序号
private int showIndex;
private List<Long> spuIds;
}
/**
* @(#)BatchQuerySpuInfoParam.java, 2022/11/30.
* <p/>
* Copyright 2022 Netease, Inc. All rights reserved.
* NETEASE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
package com.netease.mail.yanxuan.change.integration.item.param;
import java.util.List;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @Author zcwang
* @Date 2022/11/30
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class BatchQuerySpuInfoParam {
/**
* id列表,上限200
*/
private List<Long> ids;
/**
* 常规属性
*/
private List<String> commonProps;
/**
* 额外需要查询的
*/
private List<String> spuProps;
}
\ No newline at end of file
/**
* @(#)CommonIdsParamQuery.java, 2022/8/18.
* <p/>
* Copyright 2022 Netease, Inc. All rights reserved.
* NETEASE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
package com.netease.mail.yanxuan.change.integration.item.param;
import java.util.List;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @Author zcwang
* @Date 2022/8/18
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class CommonIdsParamQuery {
/**
* id列表,上限200
*/
private List<Long> ids;
}
\ No newline at end of file
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* 分包规则按照依赖源(比如系统名)来定义,内部的类命名以Client结尾,例如AbcClient。 * 分包规则按照依赖源(比如系统名)来定义,内部的类命名以Client结尾,例如AbcClient。
* 为了兼容spring的通用模式,也建议在外部定义接口类 * 为了兼容spring的通用模式,也建议在外部定义接口类
* *
* @author hzwangliyuan. * @author hzwangliyuan. 1
* @date 2019/11/28. * @date 2019/11/28.
*/ */
package com.netease.mail.yanxuan.change.integration; package com.netease.mail.yanxuan.change.integration;
/**
* @(#)QCRpcService.java, 2022/12/2.
* <p/>
* Copyright 2022 Netease, Inc. All rights reserved.
* NETEASE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
package com.netease.mail.yanxuan.change.integration.qc;
import java.util.List;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import com.netease.mail.yanxuan.change.common.bean.AjaxResult;
import com.netease.mail.yanxuan.change.integration.qc.meta.QcCategoryVO;
import com.netease.yanxuan.flowx.sdk.meta.controller.communal.AjaxResponse;
import com.netease.yanxuan.missa.client.annotation.MissaClient;
/**
* @Author zcwang
* @Date 2022/12/2
*/
@Service
@MissaClient(serviceCode = "yanxuan-qc-api")
public interface QcRpcService {
@GetMapping("/xhr/item/getQcCategoryListByItemId.json")
AjaxResponse<List<QcCategoryVO>> getQcCategoryListByItemId(@RequestParam("itemId") Long itemId);
}
\ No newline at end of file
/**
* @(#)QcCategory.java, 2022/11/30.
* <p/>
* Copyright 2022 Netease, Inc. All rights reserved.
* NETEASE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
package com.netease.mail.yanxuan.change.integration.qc.meta;
import java.io.Serializable;
/**
* @Author zcwang
* @Date 2022/11/30
*/
public class QcCategory implements Serializable {
private static final long serialVersionUID = -1862762370395334378L;
/**
* 主键id
*/
private Long id;
/**
* 类目名称
*/
private String categoryName;
/**
* 类目说明
*/
private String categoryDesc;
/**
* 等级
*/
private Integer categoryLevel;
/**
* 上级id
*/
private Long parentId;
/**
* 创建时间
*/
private Long createTime;
/**
* 修改时间
*/
private Long modifyTime;
/**
* 创建人uid
*/
private String creator;
/**
* 最后编辑人uid
*/
private String updator;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getCategoryName() {
return categoryName;
}
public void setCategoryName(String categoryName) {
this.categoryName = categoryName;
}
public String getCategoryDesc() {
return categoryDesc;
}
public void setCategoryDesc(String categoryDesc) {
this.categoryDesc = categoryDesc;
}
public Integer getCategoryLevel() {
return categoryLevel;
}
public void setCategoryLevel(Integer categoryLevel) {
this.categoryLevel = categoryLevel;
}
public Long getParentId() {
return parentId;
}
public void setParentId(Long parentId) {
this.parentId = parentId;
}
public Long getCreateTime() {
return createTime;
}
public void setCreateTime(Long createTime) {
this.createTime = createTime;
}
public Long getModifyTime() {
return modifyTime;
}
public void setModifyTime(Long modifyTime) {
this.modifyTime = modifyTime;
}
public String getCreator() {
return creator;
}
public void setCreator(String creator) {
this.creator = creator;
}
public String getUpdator() {
return updator;
}
public void setUpdator(String updator) {
this.updator = updator;
}
}
\ No newline at end of file
/**
* @(#)QcCategoryVO.java, 2022/11/30.
* <p/>
* Copyright 2022 Netease, Inc. All rights reserved.
* NETEASE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
package com.netease.mail.yanxuan.change.integration.qc.meta;
import java.util.List;
import org.springframework.beans.BeanUtils;
import com.google.common.collect.Lists;
/**
* @Author zcwang
* @Date 2022/11/30
*/
public class QcCategoryVO extends QcCategory {
private static final long serialVersionUID = 6925160563010855926L;
private List<QcCategoryVO> children;
public QcCategoryVO() {
}
public static QcCategoryVO init(QcCategory qcCategory) {
QcCategoryVO qcCategoryVO = new QcCategoryVO();
BeanUtils.copyProperties(qcCategory, qcCategoryVO);
qcCategoryVO.setChildren(Lists.newArrayList());
return qcCategoryVO;
}
public List<QcCategoryVO> getChildren() {
return children;
}
public void setChildren(List<QcCategoryVO> children) {
this.children = children;
}
}
package com.netease.mail.yanxuan.change.integration.rpc;
@FunctionalInterface
public interface Checker {
/**
* 校验结果是否成功
* @return
*/
boolean check();
}
\ No newline at end of file
package com.netease.mail.yanxuan.change.integration.rpc;
import org.apache.commons.lang3.StringUtils;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* @author lwtang
* @date 2019-02-19
*/
public class EncodeUtil {
private static final char[] CHARS = new char[] { '0', '1', '2', '3', '4', '5', '6', '7', '8',
'9', 'a', 'b', 'c', 'd', 'e', 'f' };
public static String encode(String text) {
try {
return URLEncoder.encode(text, "UTF-8");
} catch (Exception e) {
return text;
}
}
public static String encodeMap(Map<?, ?> map) {
List<String> lines = new ArrayList<>();
for (Map.Entry<?, ?> entry: map.entrySet()) {
lines.add(String.valueOf(entry.getKey()) + "=" + String.valueOf(entry.getValue()));
}
return StringUtils.join(lines, "&");
}
public static String decode(String text) {
try {
return URLDecoder.decode(text, "UTF-8");
} catch (Exception e) {
return text;
}
}
public static String ASCIIHex(String text) {
byte[] bytes = text.getBytes();
char[] chars = new char[bytes.length * 2];
for (int i = 0; i < bytes.length; i++) {
chars[2 * i] = CHARS[bytes[i] >> 4];
chars[2 * i + 1] = CHARS[bytes[i] % 16];
}
return new String(chars).toUpperCase();
}
}
package com.netease.mail.yanxuan.change.integration.rpc;
import com.netease.mail.yanxuan.change.integration.email.exception.RpcException;
import org.apache.http.Consts;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.config.*;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.BasicHeader;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.ssl.SSLContexts;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.ConnectException;
import java.net.SocketTimeoutException;
import java.net.URI;
import java.net.URLEncoder;
import java.nio.charset.CodingErrorAction;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* HttpClient 封装
*
* @author lwtang
* @date 2019-02-19
*/
public class HttpClientUtil {
private static final Logger LOG = LoggerFactory.getLogger(HttpClientUtil.class);
private static final int DEFAULT_TIME_OUT = 5000;
private static final String DEFAULT_ENCODING = "UTF-8";
private static PoolingHttpClientConnectionManager connManager = null;
private static CloseableHttpClient httpclient = null;
static {
try {
SSLContext sslContext = SSLContexts.custom().build();
sslContext.init(null, new TrustManager[] { new DefaultTrustManager() }, null);
Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder
.<ConnectionSocketFactory>create()
.register("http", PlainConnectionSocketFactory.INSTANCE)
.register("https", new SSLConnectionSocketFactory(sslContext)).build();
connManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
httpclient = HttpClients.custom().setConnectionManager(connManager).build();
// Create socket configuration
SocketConfig socketConfig = SocketConfig.custom().setSoKeepAlive(true)
.setSoReuseAddress(true).setSoTimeout(DEFAULT_TIME_OUT).setTcpNoDelay(true).build();
connManager.setDefaultSocketConfig(socketConfig);
// Create message constraints
MessageConstraints messageConstraints = MessageConstraints.custom()
.setMaxHeaderCount(200).setMaxLineLength(2000).build();
// Create connection configuration
ConnectionConfig connectionConfig = ConnectionConfig.custom()
.setMalformedInputAction(CodingErrorAction.IGNORE)
.setUnmappableInputAction(CodingErrorAction.IGNORE).setCharset(Consts.UTF_8)
.setMessageConstraints(messageConstraints).build();
connManager.setDefaultConnectionConfig(connectionConfig);
connManager.setMaxTotal(300);
connManager.setDefaultMaxPerRoute(100);
} catch (KeyManagementException e) {
LOG.error("KeyManagementException", e);
} catch (NoSuchAlgorithmException e) {
LOG.error("NoSuchAlgorithmException", e);
}
}
public static String get(String url, Map<String, Object> params, Map<String, String> header,
int timeout) {
return doGet(url, params, header, DEFAULT_ENCODING, timeout);
}
public static String doGet(String url, Map<String, Object> params, Map<String, String> header,
String encoding, int timeout) {
String responseString = null;
HttpGet get = new HttpGet();
fillUrl(url, params, encoding, get);
fillHeader(header, get);
fillConfig(timeout, timeout, get);
try {
CloseableHttpResponse response = httpclient.execute(get);
try {
int resHttpCode = response.getStatusLine().getStatusCode();
if( resHttpCode != 200) {
throw new RpcStatusException(resHttpCode, "status code " + resHttpCode + " not equal 200");
}
HttpEntity entity = response.getEntity();
try {
if (entity != null) {
responseString = EntityUtils.toString(entity, encoding);
}
} finally {
if (entity != null) {
entity.getContent().close();
}
}
return responseString;
} catch (Exception e) {
LOG.error("[HttpUtils Get response error]", e);
throw e;
} finally {
if (response != null) {
response.close();
}
}
} catch (ConnectException e) {
throw new RpcConnectException("request connect failed!");
} catch (SocketTimeoutException e) {
throw new RpcTimeoutException("request timeout!");
} catch (IOException e) {
LOG.error("[query webservice error]", e);
} finally {
get.releaseConnection();
}
return responseString;
}
public static String postJson(String url, String params, int timeout) {
Map<String, String> header = new HashMap<>();
header.put("Content-type", ContentType.APPLICATION_JSON.getMimeType());
return doPost(url, new StringEntity(params, DEFAULT_ENCODING), header, DEFAULT_ENCODING,
timeout);
}
public static String post(String url, Map<String, Object> params, int timeout) {
Map<String, String> header = new HashMap<>();
header.put("Content-type", ContentType.APPLICATION_FORM_URLENCODED.getMimeType());
HttpEntity httpEntity = null;
if (params != null && params.size() > 0) {
List<BasicNameValuePair> formParams = params.entrySet().stream()
.map(entry -> new BasicNameValuePair(entry.getKey(),
entry.getValue() == null ? "" : entry.getValue().toString()))
.collect(Collectors.toList());
try {
httpEntity = new UrlEncodedFormEntity(formParams, DEFAULT_ENCODING);
} catch (UnsupportedEncodingException e) {
throw new RpcException(e);
}
}
return doPost(url, httpEntity, header, DEFAULT_ENCODING, timeout);
}
public static String doPost(String url, HttpEntity params, Map<String, String> header,
String encoding, int timeout) {
String responseContent = null;
HttpPost post = new HttpPost(url);
fillHeader(header, post);
fillConfig(timeout, timeout, post);
post.setEntity(params);
try {
CloseableHttpResponse response = httpclient.execute(post);
try {
HttpEntity entity = response.getEntity();
responseContent = EntityUtils.toString(entity, encoding);
} finally {
if (response != null) {
response.close();
}
}
} catch (ConnectException e) {
throw new RpcConnectException("request connect failed!");
} catch (SocketTimeoutException e) {
throw new RpcTimeoutException("request timeout!");
} catch (IOException e) {
LOG.error("[query webservice error]", e);
} finally {
post.releaseConnection();
}
return responseContent;
}
/**
* concat url
*/
private static String fillUrl(String url, Map<String, Object> params, String encoding,
HttpRequestBase requestBase) {
StringBuilder sb = new StringBuilder();
sb.append(url);
int i = 0;
if (params != null && params.size() > 0) {
for (Map.Entry<String, Object> entry: params.entrySet()) {
if (i == 0 && !url.contains("?")) {
sb.append("?");
} else {
sb.append("&");
}
sb.append(entry.getKey());
sb.append("=");
Object v = entry.getValue();
String value = v == null ? "" : v.toString();
encoding = encoding == null ? Consts.UTF_8.name() : encoding;
try {
sb.append(URLEncoder.encode(value, encoding));
} catch (UnsupportedEncodingException e) {
LOG.warn("encoding common get params error, value={}", value, e);
try {
sb.append(URLEncoder.encode(value, encoding));
} catch (Exception ex) {
e.printStackTrace();
}
}
i++;
}
}
requestBase.setURI(URI.create(sb.toString()));
return sb.toString();
}
private static void fillHeader(Map<String, String> header, HttpRequestBase requestBase) {
if (header == null || header.size() == 0) {
return;
}
Header[] headers = header.entrySet().stream()
.map(entry -> new BasicHeader(entry.getKey(), entry.getValue()))
.collect(Collectors.toList()).toArray(new Header[header.size()]);
if (headers.length > 0) {
requestBase.setHeaders(headers);
}
}
/**
* fill common conf
*/
private static void fillConfig(int connectTimeout, int soTimeout, HttpRequestBase requestBase) {
if (connectTimeout <= 0) {
connectTimeout = DEFAULT_TIME_OUT;
}
if (soTimeout <= 0) {
soTimeout = DEFAULT_TIME_OUT;
}
RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(soTimeout)
.setConnectTimeout(connectTimeout).setConnectionRequestTimeout(connectTimeout).build();
requestBase.setConfig(requestConfig);
}
public static class DefaultTrustManager implements X509TrustManager {
@Override
public void checkClientTrusted(X509Certificate[] x509Certificates, String s)
throws CertificateException {}
@Override
public void checkServerTrusted(X509Certificate[] x509Certificates, String s)
throws CertificateException {}
@Override
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}
}
}
package com.netease.mail.yanxuan.change.integration.rpc;
/**
* @author jmt
* @Date 2021/6/7
*/
public enum RpcCode {
/**
* 成功响应
*/
OK(200),
/**
* 业务失败
*/
FAIL(400),
/**
* 系统异常
*/
SERVER_ERROR(500);
private int value;
RpcCode(int value) {
this.value = value;
}
public int getValue() {
return value;
}
}
package com.netease.mail.yanxuan.change.integration.rpc;
import com.netease.mail.yanxuan.change.integration.email.exception.RpcException;
public class RpcConnectException extends RpcException {
public RpcConnectException(String message) {
super(message);
}
}
package com.netease.mail.yanxuan.change.integration.rpc;
/**
* @author jmt
* @Date 2021/6/7
*/
public interface RpcConst {
String CODE = "code";
String RESULT = "result";
String DATA = "data";
String ERRCODE = "errorCode";
}
package com.netease.mail.yanxuan.change.integration.rpc;
public class RpcException extends RuntimeException {
public RpcException(String message) {
super(message);
}
public RpcException(Throwable t) {
super(t);
}
public RpcException(String message, Throwable t) {
super(message, t);
}
}
\ No newline at end of file
package com.netease.mail.yanxuan.change.integration.rpc;
import java.io.IOException;
import java.util.List;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
/**
* @author jmt
* @Date 2021/6/7
*/
public class RpcListData<T> implements RpcTemplate.CallHandler<List<T>> {
private final Class<T> tClass;
public RpcListData(Class<T> tClass) {
this.tClass = tClass;
}
@Override
public List<T> handle(String resp) throws IOException {
JSONObject rpcResult = JSON.parseObject(resp);
int code = rpcResult.getIntValue(RpcConst.CODE);
if (code == RpcCode.OK.getValue()) {
return JSON.parseArray(rpcResult.getString(RpcConst.DATA), tClass);
}
throw new RpcResultException("response error, code = " + code);
}
}
package com.netease.mail.yanxuan.change.integration.rpc;
import com.alibaba.fastjson.JSON;
import java.io.IOException;
public class RpcObjectHandler<T> implements RpcTemplate.CallHandler<T> {
private Class<T> tClass;
public RpcObjectHandler(Class<T> tClass) {this.tClass = tClass;}
@Override
public T handle(String resp) throws IOException {
return JSON.parseObject(resp, tClass);
}
}
\ No newline at end of file
package com.netease.mail.yanxuan.change.integration.rpc;
/**
* @author: bndong
* @date: 2021/5/29
*/
public class RpcResultException extends RpcException {
public RpcResultException(String message) {
super(message);
}
public RpcResultException(Throwable t) {
super(t);
}
public RpcResultException(String message, Throwable t) {
super(message, t);
}
}
package com.netease.mail.yanxuan.change.integration.rpc;
import com.netease.mail.yanxuan.change.integration.email.exception.RpcException;
public class RpcStatusException extends RpcException {
private int code;
public RpcStatusException(int code, String message) {
super(message);
this.code = code;
}
public int getCode() {
return this.code;
}
}
\ No newline at end of file
package com.netease.mail.yanxuan.change.integration.rpc;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.parser.ParserConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import java.io.IOException;
import java.util.List;
import java.util.Map;
/**
* rpc 请求封装,在 HttpClientUtil 基础上加入了返回值处理和日志
*
* @author lwtang
* @date 2019-02-19
*/
@Component
public class RpcTemplate {
@Value("${act.rpc.get.retry:1}")
private int rpcGetRetry;
@Value("${act.rpc.post.retry:0}")
private int rpcPostRetry;
Logger logger = LoggerFactory.getLogger(RpcTemplate.class);
public RpcTemplate() {
ParserConfig.getGlobalInstance().setAutoTypeSupport(true);
}
/**
* 校验resp
*
* @param t
* @param <T>
* @return
*/
private <T> RpcStatus checkResp(CallHandler<T> handler, T t) {
RpcStatus status = RpcStatus.SUCCESS;
try {
// 为空,或handlerCheck为false直接判断FAIL
if (t == null || !handler.check(t)) {
return RpcStatus.WARNING;
}
if (t instanceof Checker) {
status = ((Checker) t).check() ? RpcStatus.SUCCESS : RpcStatus.WARNING;
} else if (t instanceof List) {
// 为空认为不是理想结果
if (CollectionUtils.isEmpty((List) t)) {
status = RpcStatus.WARNING;
} else {
// 列表数据简单检测第一个元素
Object obj = ((List) t).get(0);
if (obj instanceof Checker) {
status = ((Checker) obj).check() ? RpcStatus.SUCCESS : RpcStatus.WARNING;
}
}
}
} catch (Exception e) {
logger.error("collect error, msg={}", e.getMessage());
}
return status;
}
private String convertParam(Object param) {
if (param instanceof String) {
return (String) param;
}
String reqParam = "";
if (param instanceof Map) {
reqParam = EncodeUtil.encodeMap((Map) param);
} else if (param != null) {
reqParam = JSON.toJSONString(param);
}
return reqParam;
}
private <T> T execute(String url, Object params, CallHandler<T> handler,
CallTemplate callTemplate, int retryTime, Method method) {
int tryTimes = 0;
RpcException rpcException = null;
String respBody = null;
int statusCode = 200;
while (tryTimes <= retryTime) {
long startTime = System.currentTimeMillis();
try {
respBody = callTemplate.executeCall();
if (StringUtils.isEmpty(respBody)) {
throw new RpcException("response empty");
}
T t = handler.handle(respBody);
return t;
} catch (RpcTimeoutException e) {
} catch (RpcStatusException e) {
statusCode = e.getCode();
} catch (RpcException e) {
rpcException = e;
} catch (Exception e) {
rpcException = new RpcException(e);
} finally {
if (logger.isDebugEnabled()) {
long costTime = System.currentTimeMillis() - startTime;
String reqParam = convertParam(params);
logger.debug(
"process request, url={}, method={}, params={}, statusCode = {}, response={}, cost={}ms",
url, method.name(), reqParam, statusCode, respBody, costTime);
}
}
tryTimes++;
}
logger.error("request error, url={}, params={}, statusCode = {}, respBody={}", url,
convertParam(params), statusCode, respBody, rpcException);
if (rpcException == null) {
rpcException = new RpcException("服务异常");
}
throw rpcException;
}
/**
* Get 请求
*
* @param url
* @param params
* @param header
* @param timeout
* -1 取默认的超时时间
* @param handler
* @param <T>
* @return
*/
public <T> T get(String url, Map<String, Object> params, Map<String, String> header,
int timeout, CallHandler<T> handler, Integer retryTimes) {
CallTemplate template = () -> HttpClientUtil.get(url, params, header, timeout);
return this.execute(url, params, handler, template, retryTimes, Method.GET);
}
public <T> T get(String url, Map<String, Object> params, CallHandler<T> handler) {
return get(url, params, null, -1, handler, rpcGetRetry);
}
/**
* Post请求(url encoded)
*
* @param url
* @param params
* @param timeout
* @param handler
* @param <T>
* @return
*/
public <T> T post(String url, Map<String, Object> params, int timeout, CallHandler<T> handler,
Integer retryTime) {
CallTemplate template = () -> HttpClientUtil.post(url, params, timeout);
return this.execute(url, params, handler, template, retryTime, Method.POST);
}
/**
* Post请求(url encoded)
*
* @param url
* @param params
* @param timeout
* @param handler
* @param <T>
* @return
*/
public <T> T post(String url, Map<String, Object> params, int timeout, CallHandler<T> handler) {
CallTemplate template = () -> HttpClientUtil.post(url, params, timeout);
return this.execute(url, params, handler, template, rpcPostRetry, Method.POST);
}
/**
* Post Json请求
*
* @param url
* @param params
* @param timeout
* @param handler
* @param <T>
* @return
*/
public <T> T postJson(String url, String params, int timeout, CallHandler<T> handler,
Integer retryTime) {
CallTemplate template = () -> HttpClientUtil.postJson(url, params, timeout);
return this.execute(url, params, handler, template, retryTime, Method.POST);
}
/**
* Post Json请求
*
* @param url
* @param params
* @param timeout
* @param handler
* @param <T>
* @return
*/
public <T> T postJson(String url, String params, int timeout, CallHandler<T> handler) {
CallTemplate template = () -> HttpClientUtil.postJson(url, params, timeout);
return this.execute(url, params, handler, template, rpcPostRetry, Method.POST);
}
enum RpcStatus {
/**
* 成功
*/
SUCCESS(1),
/**
* 告警(请求成功,但非理想值)
*/
WARNING(2),
/**
* 异常
*/
EXCEPTION(3),
/**
* 超时
*/
TIMEOUT(4);
private int value;
RpcStatus(int value) {
this.value = value;
}
public int getValue() {
return value;
}
}
enum Method {
/**
* Get请求
*/
GET,
/**
* Post表单请求
*/
POST,
}
/**
* 模板调用
*/
@FunctionalInterface
public interface CallTemplate {
/**
* 模板调用类
*/
String executeCall();
}
/**
* 报文解析
*/
@FunctionalInterface
public interface CallHandler<T> {
/**
* 报文解析
*
* @param resp
* response body
*/
T handle(String resp) throws IOException;
/**
* 校验数据体
*
* @param t
* @return
*/
default boolean check(T t) {
return true;
}
}
}
package com.netease.mail.yanxuan.change.integration.rpc;
import com.netease.mail.yanxuan.change.integration.email.exception.RpcException;
public class RpcTimeoutException extends RpcException {
public RpcTimeoutException(String message) {
super(message);
}
}
package com.netease.mail.yanxuan.change.integration.rpc;
import com.netease.yanxuan.user.ula.sdk.AuthClient;
import com.netease.yanxuan.user.ula.sdk.meta.bean.AuthenticateResult;
import com.netease.yanxuan.user.ula.sdk.meta.common.Response;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class UserTicketClient {
@Autowired
private AuthClient authClient;
/**
* 用户鉴权
*
* @param cookie(cookie中的字段)
*/
public AuthenticateResult getUserInfo(String cookie) {
Response<AuthenticateResult> authenticate = authClient.authenticate(cookie, false);
return authenticate.getData();
}
/**
* 用户鉴权
*
* @param cookie(cookie中的字段)
*/
public AuthenticateResult getFullUserInfo(String cookie) {
Response<AuthenticateResult> authenticate = authClient.authenticate(cookie, true);
return authenticate.getData();
}
}
package com.netease.mail.yanxuan.change.integration.todo;
import lombok.Data;
@Data
public class ChangeExecuteEmailDTO {
private String changeExecDepartment;
private String changeExecUser;
private String changeRiskDesc;
private String changeExecProject;
private String changeChecking;
}
package com.netease.mail.yanxuan.change.integration.todo;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class PageVO {
/**
* 当前页
*/
private Integer page;
/**
* 页面大小
*/
private Integer pageSize;
/**
* 总页数
*/
private Integer totalPage;
/**
* 总条数
*/
private Integer totalCount;
}
package com.netease.mail.yanxuan.change.integration.todo;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class SupplierItemPageVO {
private PageVO pageVo;
private List<SupplierItemVO> supplierItemVOList;
}
package com.netease.mail.yanxuan.change.integration.todo;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class SupplierItemVO {
/**
* 商品id
*/
private Long itemId;
/**
* 商品名称
*/
private String itemName;
}
/**
* @(#)TaskCreateDTO.java, 2022/11/29.
* <p/>
* Copyright 2022 Netease, Inc. All rights reserved.
* NETEASE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
package com.netease.mail.yanxuan.change.integration.todo;
import java.util.List;
import lombok.Data;
/**
* @Author zcwang
* @Date 2022/11/29
*/
@Data
public class TaskCreateDTO {
/**
* 待办id
*/
private Integer id;
/**
* 废弃
*/
@Deprecated
private Long taskTypeId;
/**
* 任务类型key
*/
private String taskTypeKey;
/**
* 任务标题
*/
private String taskTitle;
/**
* 任务类型名
*/
private String taskTypeName;
/**
* 产品号
*/
private String product;
/**
* 业务key
*/
private String businessKey;
/**
* 业务数据
*/
private String content;
/**
* 任务状态
*/
private Integer taskState;
/**
*
*/
private Integer taskAdvanceState;
/**
* 任务过期时间
*/
private String taskOriginalExpireTime;
/**
* 任务过期时间
*/
private Integer taskExpireTime;
/**
*
*/
private Integer taskAdvanceTime;
/**
* 剩余日期
*/
private String remainDays;
/**
* 处理人列表
*/
private List<UserInfo> taskHandlerList;
private String recentlyOperator;
private String recentylyOperatorName;
private String sourceRemark;
private String creator;
private String updator;
private long createTime;
private long updateTime;
private String childTaskList;
private String taskDetailUrl;
}
\ No newline at end of file
/**
* @(#)CreateParamVO.java, 2022/11/28.
* <p/>
* Copyright 2022 Netease, Inc. All rights reserved.
* NETEASE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
package com.netease.mail.yanxuan.change.integration.todo;
import java.util.List;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @Author zcwang
* @Date 2022/11/28
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class TaskCreateParamVO {
/**
* 业务key
*/
private String businessKey;
/**
* 任务详情数据
*/
private String content;
/**
* 产品号
*/
private String product;
/**
* 任务创建人
*/
private String taskCreator;
/**
* 任务处理人
*/
private String taskHandler;
/**
* 任务处理人集合
*/
private List<UserInfo> taskHandlerList;
/**
* 单个任务处理人场景
*/
private String taskHandlerName;
/**
* 任务标题
*/
private String taskTitle;
/**
* 已废弃
*/
@Deprecated
private Integer taskTypeId;
/**
* 任务类型key
*/
private String taskTypeKey;
}
\ No newline at end of file
/**
* @(#)TaskProcessParamVO.java, 2022/11/28.
* <p/>
* Copyright 2022 Netease, Inc. All rights reserved.
* NETEASE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
package com.netease.mail.yanxuan.change.integration.todo;
import com.netease.mail.yanxuan.change.common.enums.OperateTypeEnum;
import lombok.Data;
/**
* @Author zcwang
* @Date 2022/11/28
*/
@Data
public class TaskProcessParamVO {
/**
* 业务key,非必填
*/
private String businessKey;
/**
* 系统自定义抄送人,非必填
*/
private String cc;
/**
* 任务详情,仅保存操作时必填
*/
private String content;
/**
* 延期时间,仅延期操作时必填
*/
private Integer delayTime;
/**
* 任务的上次更新时间,用于版本控制,非必填
*/
private Integer lastUpdateTime;
/**
* 操作:1 完成 2 取消 3 转交 4 延期 7 保存,必填
* @see OperateTypeEnum
*/
private Integer operateType;
/**
* 操作人邮箱,必填
*/
private String operator;
/**
* 操作人名称,必填
*/
private String operatorName;
/**
* 系统产品号,必填
*/
private String product;
/**
* 系统自定义收件人,非必填
*/
private String recipient;
/**
* 备注信息,非必填
*/
private String remark;
/**
* 任务ID,必填
*/
private Integer taskId;
/**
* 被转交人邮箱,仅转交操作时必填
*/
private String transfer;
/**
* 被转交人姓名,仅转交操作时必填
*/
private String transferName;
}
\ No newline at end of file
/**
* @(#)FlowRpcService.java, 2022/11/16.
* <p/>
* Copyright 2022 Netease, Inc. All rights reserved.
* NETEASE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
package com.netease.mail.yanxuan.change.integration.todo;
import java.util.List;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import com.netease.yanxuan.flowx.sdk.meta.controller.communal.AjaxResponse;
import com.netease.yanxuan.flowx.sdk.meta.dto.base.FlowDataDTO;
import com.netease.yanxuan.flowx.sdk.meta.dto.flow.NodeSubmitReqDTO;
import com.netease.yanxuan.missa.client.annotation.MissaClient;
/**
* @Author zcwang
* @Date 2022/11/16
*/
@Service
@MissaClient(serviceCode = "yanxuan-sc-todo-center")
public interface TodoRpcService {
/**
* 创建待办
* @param param
* @return
*/
@PostMapping(value = "/xhr/todo/task/create.json", consumes = MediaType.APPLICATION_JSON_VALUE)
AjaxResponse<TaskCreateDTO> create(TaskCreateParamVO param);
/**
* 处理待办
* @param param
* @return
*/
@PostMapping(value = "/xhr/todo/task/process.json", consumes = MediaType.APPLICATION_JSON_VALUE)
AjaxResponse<List<String>> progress(TaskProcessParamVO param);
}
/**
* @(#)TaskHandlerList.java, 2022/11/28.
* <p/>
* Copyright 2022 Netease, Inc. All rights reserved.
* NETEASE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
package com.netease.mail.yanxuan.change.integration.todo;
/**
* @Author zcwang
* @Date 2022/11/28
*/
public class UserInfo {
private String name;
private String uid;
}
\ No newline at end of file
package com.netease.mail.yanxuan.change.web.aop;
import java.io.IOException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.TypeMismatchException;
import org.springframework.http.HttpStatus;
import org.springframework.util.StringUtils;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import com.alibaba.fastjson.JSON;
import com.netease.mail.yanxuan.change.common.bean.AjaxResult;
import com.netease.mail.yanxuan.change.biz.meta.exception.ServiceException;
import com.netease.mail.yanxuan.change.common.util.RequestUtil;
import com.netease.mail.yanxuan.change.common.util.ResponseUtil;
import lombok.extern.slf4j.Slf4j;
@ControllerAdvice
@Slf4j
public class GlobalExceptionHandler {
@ExceptionHandler(value = Exception.class)
public void handle(HttpServletRequest request, HttpServletResponse response, Exception ex) throws IOException {
String pathInfo = RequestUtil.getRequestPath(request);
if (ex instanceof ServiceException) {
log.error("biz error on handle request: {},{}", pathInfo, ((ServiceException) ex).getMsg());
} else if (ex instanceof TypeMismatchException) {
ex = new IllegalArgumentException("参数" + ((TypeMismatchException) ex).getRequiredType() + "类型不匹配");
log.error("handleException pathInfo:{},param:{}", pathInfo,JSON.toJSONString(request.getParameterMap()), ex);
} else if (ex instanceof MissingServletRequestParameterException) {
ex = new IllegalArgumentException(
"缺少参数" + ((MissingServletRequestParameterException) ex).getParameterName());
log.error("handleException pathInfo:{},param:{}", pathInfo,JSON.toJSONString(request.getParameterMap()), ex);
} else {
log.error("error on handle request: {}", pathInfo, ex);
}
AjaxResult result = new AjaxResult();
result.setCode(monitorException(ex));
if (ex instanceof IllegalArgumentException) {
result.setMsg(ex.getMessage());
} else if (ex instanceof ServiceException) {
result.setMsg(((ServiceException) ex).getMsg());
} else if (ex instanceof MethodArgumentNotValidException) {
// controller参数校验错误
StringBuilder builder = new StringBuilder();
for (FieldError error: ((MethodArgumentNotValidException) ex).getBindingResult().getFieldErrors()) {
builder.append(error.getDefaultMessage()).append(".");
}
result.setMsg(builder.toString());
} else {
int index = ex.getMessage().indexOf(":");
if (index != -1) {
result.setMsg(ex.getMessage().substring(index + 1));
} else {
result.setMsg(ex.getMessage());
}
}
String text = JSON.toJSONString(result);
String callback = request.getParameter("callback");
if (!StringUtils.isEmpty(callback)) {
text = callback + "(" + text + ")";
}
ResponseUtil.writeJson(response, text);
}
private int monitorException(Exception ex) {
if (ex instanceof IOException) {
return HttpStatus.BAD_REQUEST.value();
} else if (ex instanceof IllegalArgumentException) {
return HttpStatus.BAD_REQUEST.value();
} else if (ex instanceof ServiceException) {
return ((ServiceException) ex).getCode().getCode();
} else {
return HttpStatus.INTERNAL_SERVER_ERROR.value();
}
}
}
package com.netease.mail.yanxuan.change.web.config;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import com.netease.mail.yanxuan.change.common.bean.AdminUserHolder;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@Component
public class AdminUserLoginInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler) throws Exception {
Map<String, String> headerMap = new HashMap<>();
Enumeration<String> enumeration = request.getHeaderNames();
while (enumeration.hasMoreElements()) {
String name = enumeration.nextElement();
String value = request.getHeader(name);
headerMap.put(name, value);
}
log.info("adminUserLoginInterceptor headerMap ={}", headerMap);
String uid = request.getHeader("uid");
log.info("adminUserLoginInterceptor uid ={}", uid);
AdminUserHolder.setUserName(uid);
return true;
}
@Override
public void postHandle(HttpServletRequest request,
HttpServletResponse response, Object handler, ModelAndView modelAndView)
throws Exception {
}
@Override
public void afterCompletion(HttpServletRequest request,
HttpServletResponse response, Object handler, Exception ex)
throws Exception {
AdminUserHolder.clear();
}
}
\ No newline at end of file
/**
* @(#)LoginInterceptor.java, 2022/11/22.
* <p/>
* Copyright 2022 Netease, Inc. All rights reserved.
* NETEASE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
package com.netease.mail.yanxuan.change.web.config;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import com.alibaba.fastjson.JSON;
import com.netease.mail.yanxuan.change.common.bean.AjaxResult;
import com.netease.mail.yanxuan.change.common.bean.RequestLocalBean;
import com.netease.mail.yanxuan.change.common.bean.ResponseCodeEnum;
import com.netease.mail.yanxuan.change.common.util.ResponseUtil;
import lombok.extern.slf4j.Slf4j;
/**
* @Author zcwang
* @Date 2022/11/22
*/
@Slf4j
@Component
public class LoginInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
String yxUid = RequestLocalBean.getUid();
log.info("[LoginInterceptor] yxUid:{}", yxUid);
/*if (yxUid == null) {
String text = JSON.toJSONString(AjaxResult.of(ResponseCodeEnum.SC_UNAUTHORIZED.getCode(), "not-login"));
String callback = request.getParameter("callback");
if (!StringUtils.isEmpty(callback)) {
text = callback + "(" + text + ")";
}
ResponseUtil.writeJson(response, text);
return false;
}*/
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
log.info("postHandle");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception {
log.info("afterCompletion");
}
}
/**
* @(#)UserInterceptor.java, 2022/11/23.
* <p/>
* Copyright 2022 Netease, Inc. All rights reserved.
* NETEASE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
package com.netease.mail.yanxuan.change.web.config;
/**
* @Author zcwang
* @Date 2022/11/23
*/
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.alibaba.fastjson.JSON;
import com.netease.mail.yanxuan.change.integration.rpc.UserTicketClient;
import com.netease.yanxuan.user.ula.sdk.meta.bean.AuthenticateResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import com.netease.mail.yanxuan.change.common.bean.RequestLocalBean;
import com.netease.mail.yx.openid.YxOpenidLogin;
import com.netease.mail.yx.openid.YxOpenidUser;
import lombok.extern.slf4j.Slf4j;
/**
* 提取用户uid
*
* @author lwtang
*/
@Component
@Slf4j
public class UserInterceptor implements HandlerInterceptor {
@Value("${product:product}")
String product;
@Autowired
private UserTicketClient userTicketClient;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
//获取cookie信息
Cookie[] cookies = request.getCookies();
String userCookie = null;
if (cookies != null) {
for (Cookie cookie: cookies) {
if (cookie.getName().equals("YX_OPENID_SESS")) {
userCookie = cookie.getValue();
}
}
}
log.info("YX_OPENID_SESS: {}", userCookie);
// 解析cookie
YxOpenidUser yxuser = null;
if (userCookie != null) {
yxuser = YxOpenidLogin.parseCookie(userCookie);
}
// ajax请求,走返回码
String accept = request.getHeader("Accept");
// cookie不存在或者超过一个小时(时间自己定)
if (yxuser == null || yxuser.getLoginTime() < System.currentTimeMillis() - 60 * 1000 * 1000) {
//获取urs登陆态
String cookie = request.getHeader("Cookie");
AuthenticateResult userInfo = userTicketClient.getFullUserInfo(cookie);
log.info("userInfo: {}", JSON.toJSONString(userInfo));
if (userInfo != null) {
RequestLocalBean.setUid(userInfo.getUsername());
RequestLocalBean.setName(userInfo.getProfile().getNickName());
}
} else {
// 获取用户信息
// 邮箱地址
String email = yxuser.getEmail();
RequestLocalBean.setUid(email);
// 中文姓名
String fullname = yxuser.getFullName();
RequestLocalBean.setName(fullname);
// 用户登录时间戳
long loginTime = yxuser.getLoginTime();
log.info("[UserAccess] user: {}, url: {}", email, request.getPathInfo());
RequestLocalBean.setLastLoginTime(loginTime);
}
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception {
RequestLocalBean.clear();
}
}
package com.netease.mail.yanxuan.change.web.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/**
* @author zhangbingQAQ
* @date 2021/8/27 10:18
*/
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
@Autowired
private UserInterceptor userInterceptor;
@Autowired
private AdminUserLoginInterceptor adminUserLoginInterceptor;
/**`
* 拦截器配置
*
* @param registry
*/
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(userInterceptor).addPathPatterns("/**").excludePathPatterns("/i/health")
.excludePathPatterns("/change/flow/getOperator", "/test/**", "/api/des/callback/**");
registry.addInterceptor(adminUserLoginInterceptor).addPathPatterns("test/**");
}
}
package com.netease.mail.yanxuan.change.web.controller;
import com.netease.mail.yanxuan.change.common.bean.AjaxResult;
import com.netease.mail.yanxuan.change.biz.service.change.AdminChangeConfigService;
import com.netease.mail.yanxuan.change.common.bean.RequestLocalBean;
import com.netease.mail.yanxuan.change.dal.meta.model.req.ChangeConfigDeleteReq;
import com.netease.mail.yanxuan.change.dal.meta.model.req.ChangeConfigQueryReq;
import com.netease.mail.yanxuan.change.dal.meta.model.req.ChangeConfigReq;
import com.netease.mail.yanxuan.change.integration.flow.supplier.FlowRpcSupplierSendService;
import com.netease.mail.yanxuan.change.integration.flow.supplier.req.SupplierSearchRemoteReq;
import com.netease.mail.yanxuan.change.integration.flow.supplier.rsp.SupplierSimpleRsp;
import com.netease.yanxuan.flowx.sdk.meta.controller.communal.AjaxResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.List;
/**
* @author WangJiaXiang
* @date 2022/11/11/011$
*/
@RestController
@RequestMapping("/config/change")
public class ChangeConfigController {
@Autowired
private AdminChangeConfigService service;
@Autowired
private FlowRpcSupplierSendService supplierSendService;
/**
* 通过参数查询配置模板
* @return
*/
@GetMapping("/list")
public AjaxResult queryChanges(
@RequestParam(name = "page",defaultValue = "1") Integer page,
@RequestParam(name = "pageSize",defaultValue = "10")Integer pageSize,
@RequestParam(name = "changeDepartment",required = false) String changeDepartment,
@RequestParam(name = "changeExecDepartment",required = false) String changeExecDepartment,
@RequestParam(name = "parentChangeClassId",required = false)Integer parentChangeClassId,
@RequestParam(name = "sonChangeClassId",required = false)Integer sonChangeClassId,
@RequestParam(name = "changeLevel",required = false)Integer changeLevel,
@RequestParam(name = "createTime",required = false)Long createTime,
@RequestParam(name = "endTime",required = false)Long endTime){
ChangeConfigQueryReq req = new ChangeConfigQueryReq();
req.setChangeDepartment(changeDepartment);
req.setChangeExecDepartment(changeExecDepartment);
req.setParentChangeClassId(parentChangeClassId);
req.setSonChangeClassId(sonChangeClassId);
req.setChangeLevel(changeLevel);
req.setCreateTime(createTime);
req.setUpdateTime(endTime);
return service.queryChanges(page,pageSize,req);
}
/**
* 查询变更模板详情
* @param id
* @return
*/
@GetMapping("/detail")
public AjaxResult queryDetail(
@RequestParam(name = "id",required = false) Long id,
@RequestParam(name = "sonChangeClassId",required = false) Long sonChangeClassId){
return service.queryDetail(id,sonChangeClassId);
}
/**
* 新增变更模板详情
* @param changeConfigReq
* @return
*/
@PostMapping("/create")
public AjaxResult createChange(
@RequestBody ChangeConfigReq changeConfigReq){
String name = RequestLocalBean.getName();
String uid = RequestLocalBean.getUid();
return service.createChange(changeConfigReq, uid, name);
}
/**
* 修改变更模板详情
* @param changeConfigReq
* @return
*/
@PostMapping("/modify")
public AjaxResult modifyChange(
@RequestBody ChangeConfigReq changeConfigReq){
return service.modifyChange(changeConfigReq);
}
/**
* 删除模板配置
* @param id
* @return
*/
@PostMapping("/delete")
public AjaxResult deleteChange(
@RequestBody ChangeConfigDeleteReq id){
return service.deleteChange(id);
}
/**
* 查询所有模板配置类型
* @return
*/
@GetMapping("/query/config/type")
public AjaxResult queryConfigType(){
return service.queryConfigType();
}
/**
* 跟进供应商名称模糊查询
*/
@GetMapping("/query/supplier/infos")
public AjaxResponse<List<SupplierSimpleRsp>> queryByConditionForQc(@RequestParam(name = "searchText") String searchText){
SupplierSearchRemoteReq req = new SupplierSearchRemoteReq();
req.setSearchText(searchText);
//暂时使用模拟数据
//AjaxResponse<List<SupplierSimpleRsp>> listAjaxResponse = service.queryByConditionForQc(req);
AjaxResponse<List<SupplierSimpleRsp>> listAjaxResponse = new AjaxResponse<List<SupplierSimpleRsp>>();
List<SupplierSimpleRsp> suppliers = new ArrayList<>();
SupplierSimpleRsp supplierSimpleRsp1 = new SupplierSimpleRsp("YX0778","gyhtest1009");
SupplierSimpleRsp supplierSimpleRsp2 = new SupplierSimpleRsp("YX0528","gyhtest1010");
suppliers.add(supplierSimpleRsp1);
suppliers.add(supplierSimpleRsp2);
listAjaxResponse.setData(suppliers);
listAjaxResponse.setCode(200);
//return supplierSendService.queryByConditionForQc(req); 暂用模拟数据
return listAjaxResponse;
}
}
/**
* @(#)ChangeFlowController.java, 2022/11/14.
* <p/>
* Copyright 2022 Netease, Inc. All rights reserved.
* NETEASE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
package com.netease.mail.yanxuan.change.web.controller;
import javax.validation.Valid;
import org.apache.logging.log4j.util.Strings;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.netease.mail.yanxuan.change.biz.biz.ChangeFlowBiz;
import com.netease.mail.yanxuan.change.biz.config.TitleConfig;
import com.netease.mail.yanxuan.change.biz.service.ChangeFlowService;
import com.netease.mail.yanxuan.change.biz.service.DESExportService;
import com.netease.mail.yanxuan.change.biz.service.InteriorChangeConfigService;
import com.netease.mail.yanxuan.change.common.bean.AjaxResult;
import com.netease.mail.yanxuan.change.common.bean.RequestLocalBean;
import com.netease.mail.yanxuan.change.common.enums.CreateSourceEnum;
import com.netease.mail.yanxuan.change.dal.meta.model.po.QueryCommanderEmailReq;
import com.netease.mail.yanxuan.change.dal.meta.model.req.ChangeFlowCancelReq;
import com.netease.mail.yanxuan.change.dal.meta.model.req.ChangeFlowCreateReq;
import com.netease.mail.yanxuan.change.dal.meta.model.req.ChangeFlowDeliverReq;
import com.netease.mail.yanxuan.change.dal.meta.model.req.ChangeFlowListQueryReq;
import com.netease.mail.yanxuan.change.dal.meta.model.req.ChangeFlowRequest;
import com.netease.mail.yanxuan.change.dal.meta.model.req.ChangeFlowSubmitReq;
import com.netease.mail.yanxuan.change.dal.meta.model.rpc.CommanderResponse;
import com.netease.mail.yanxuan.change.dal.meta.model.vo.BasicChangeFlowVO;
import com.netease.mail.yanxuan.change.dal.meta.model.vo.ChangeFlowListVO;
import com.netease.mail.yanxuan.change.dal.meta.model.vo.ChangeFlowVO;
import com.netease.yanxuan.flowx.sdk.meta.dto.exec.InterfaceInputDTO;
import com.netease.yanxuan.flowx.sdk.meta.dto.exec.UserBaseContainerDTO;
import lombok.extern.slf4j.Slf4j;
/**
* @Author zcwang
* @Date 2022/11/14
*/
@Slf4j
@RestController
@RequestMapping("/change/flow")
public class ChangeFlowController {
@Autowired
private ChangeFlowService changeFlowService;
@Autowired
private ChangeFlowBiz changeFlowBiz;
@Autowired
private InteriorChangeConfigService interiorChangeConfigService;
@Autowired
private DESExportService desExportService;
/**
* 变更工单详情查询
*
* @return
*/
@GetMapping("/detail")
public AjaxResult<ChangeFlowVO> detail(@RequestParam Long flowId) {
return AjaxResult.success(changeFlowBiz.detail(flowId));
}
/**
* 变更工单列表查询
*
* @return
*/
@GetMapping("/query")
public AjaxResult<ChangeFlowListVO> query(@RequestParam(name = "page", defaultValue = "1") Integer page,
@RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
@RequestParam(name = "createSource") Integer createSource,
@RequestParam(name = "itemId", required = false) String itemId,
@RequestParam(name = "supplier", required = false) String supplier,
@RequestParam(name = "parentChangeClassId", required = false) Long parentChangeClassId,
@RequestParam(name = "sonChangeClassId", required = false) Long sonChangeClassId,
@RequestParam(name = "changeState", required = false) Integer changeState,
@RequestParam(name = "changeCommander", required = false) String changeCommander,
@RequestParam(name = "changeDepartment", required = false) String changeDepartment,
@RequestParam(name = "changeExecDepartment", required = false) String changeExecDepartment,
@RequestParam(name = "startTime", required = false) Long startTime,
@RequestParam(name = "endTime", required = false) Long endTime,
@RequestParam(name = "flowId", required = false) Long flowId) {
ChangeFlowListQueryReq changeFlowListQueryReq = new ChangeFlowListQueryReq();
changeFlowListQueryReq.setItemId(itemId);
changeFlowListQueryReq.setSupplier(supplier);
changeFlowListQueryReq.setParentChangeClassId(parentChangeClassId);
changeFlowListQueryReq.setSonChangeClassId(sonChangeClassId);
changeFlowListQueryReq.setChangeState(changeState);
changeFlowListQueryReq.setChangeCommander(changeCommander);
changeFlowListQueryReq.setChangeDepartment(changeDepartment);
changeFlowListQueryReq.setChangeExecDepartment(changeExecDepartment);
changeFlowListQueryReq.setStartTime(startTime);
changeFlowListQueryReq.setEndTime(endTime);
changeFlowListQueryReq.setFlowId(flowId);
// QC端可以查看所有,不加入过滤条件
if (!CreateSourceEnum.QC.getType().equals(createSource)) {
changeFlowListQueryReq.setCreateSource(createSource);
}
if (CreateSourceEnum.TONG_ZHOU.getType().equals(createSource)) {
Assert.isTrue(Strings.isNotBlank(supplier), "同舟端查询供应商id不可为空");
changeFlowListQueryReq.setCreateSource(createSource);
changeFlowListQueryReq.setSupplier(null);
changeFlowListQueryReq.setCreateSupplier(supplier);
}
return AjaxResult.success(changeFlowBiz.query(page, pageSize, changeFlowListQueryReq));
}
/**
* 返回提示文案
*
* @return
*/
@GetMapping("/title")
public AjaxResult<TitleConfig> title() {
return AjaxResult.success(changeFlowService.getTitleConfig());
}
/**
* 发起变更,如果发起人=审核人,自动跳转到第一个节点
*
* @return
*/
@PostMapping("/create")
public AjaxResult<String> createAndSubmit(@RequestBody @Valid ChangeFlowCreateReq changeFlowCreateReq) {
return AjaxResult.success(changeFlowBiz.createAndSubmit(changeFlowCreateReq));
}
/**
* 变更工单提交
*
* @return
*/
@PostMapping("/submit")
public AjaxResult<String> submit(@RequestBody @Valid ChangeFlowSubmitReq changeFlowSubmitReq) {
return AjaxResult.success(changeFlowBiz.submit(changeFlowSubmitReq));
}
/**
* 工单转交
*
* @return
*/
@PostMapping("/deliver")
public AjaxResult<Void> deliver(@RequestBody @Valid ChangeFlowDeliverReq req) {
changeFlowBiz.deliver(req);
return AjaxResult.success();
}
/**
* 工单取消
*
* @return
*/
@PostMapping("/cancel")
public AjaxResult<Boolean> cancel(@RequestBody @Valid ChangeFlowCancelReq changeFlowCancelReq) {
return AjaxResult.success(changeFlowBiz.cancel(changeFlowCancelReq));
}
/**
* 引用变更工单
*
* @return
*/
@GetMapping("/quote")
public AjaxResult<BasicChangeFlowVO> quote(@RequestParam Long flowId,
@RequestParam(name = "supplier", required = false) String supplier,
@RequestParam(name = "createSource", required = false, defaultValue = "1") Integer createSource) {
return AjaxResult.success(changeFlowBiz.quote(flowId, supplier, createSource));
}
/**
* 导出变更
*
* @return
*/
@GetMapping("/export")
public AjaxResult<String> export(@RequestParam(name = "itemId", required = false) String itemId,
@RequestParam(name = "supplier", required = false) String supplier,
@RequestParam(name = "parentChangeClassId", required = false) Long parentChangeClassId,
@RequestParam(name = "sonChangeClassId", required = false) Long sonChangeClassId,
@RequestParam(name = "changeState", required = false) Integer changeState,
@RequestParam(name = "changeCommander", required = false) String changeCommander,
@RequestParam(name = "changeDepartment", required = false) String changeDepartment,
@RequestParam(name = "changeExecDepartment", required = false) String changeExecDepartment,
@RequestParam(name = "startTime", required = false) Long startTime,
@RequestParam(name = "endTime", required = false) Long endTime,
@RequestParam(name = "createSource", required = false, defaultValue = "1") Integer createSource,
@RequestParam(name = "serviceCode") String serviceCode) {
ChangeFlowRequest changeFlowRequest = new ChangeFlowRequest();
changeFlowRequest.setItemId(itemId);
changeFlowRequest.setSupplier(supplier);
changeFlowRequest.setParentChangeClassId(parentChangeClassId);
changeFlowRequest.setSonChangeClassId(sonChangeClassId);
changeFlowRequest.setChangeState(changeState);
changeFlowRequest.setChangeCommander(changeCommander);
changeFlowRequest.setChangeDepartment(changeDepartment);
changeFlowRequest.setChangeExecDepartment(changeExecDepartment);
changeFlowRequest.setStartTime(startTime);
changeFlowRequest.setEndTime(endTime);
changeFlowRequest.setServiceCode(serviceCode);
// QC端可以查看所有,不加入过滤条件
if (!CreateSourceEnum.QC.getType().equals(createSource)) {
changeFlowRequest.setCreateSource(createSource);
}
if (CreateSourceEnum.TONG_ZHOU.getType().equals(createSource)) {
Assert.isTrue(Strings.isNotBlank(supplier), "同舟端查询供应商id不可为空");
}
String s = this.exportAddressBook(changeFlowRequest);
return AjaxResult.success(s);
}
public String exportAddressBook(ChangeFlowRequest req) {
req.setUid(RequestLocalBean.getUid());
return desExportService.changeFlowExport(req);
}
/**
* 获取审批人
*
* @param interfaceInput
* @return
*/
@PostMapping("/getOperator")
public AjaxResult<UserBaseContainerDTO> getOperator(@RequestBody InterfaceInputDTO interfaceInput) {
return AjaxResult.success(changeFlowBiz.getOperator(interfaceInput));
}
/**
* 查询负责人信息
* @param req
* @return
*/
@PostMapping("/queryCommanderInfo")
public AjaxResult<CommanderResponse> queryCommanderInfo(@RequestBody QueryCommanderEmailReq req) {
return AjaxResult.success(interiorChangeConfigService.queryCommanderEmail(req));
}
}
package com.netease.mail.yanxuan.change.web.controller;
import com.alibaba.fastjson.JSON;
import com.netease.mail.yanxuan.change.biz.config.AppConfig;
import com.netease.mail.yanxuan.change.biz.service.ISupplierItemService;
import com.netease.mail.yanxuan.change.common.bean.AjaxResult;
import com.netease.mail.yanxuan.change.common.bean.ResponseCodeEnum;
import com.netease.mail.yanxuan.change.integration.flow.supplier.FlowRpcSupplierSendService;
import com.netease.mail.yanxuan.change.integration.flow.supplier.FlowRpcSupplierService;
import com.netease.mail.yanxuan.change.integration.flow.supplier.req.SupplierGoodsInfoReq;
import com.netease.mail.yanxuan.change.integration.flow.supplier.req.SupplierSearchRemoteReq;
import com.netease.mail.yanxuan.change.integration.flow.supplier.rsp.SupplierInfoRsp;
import com.netease.mail.yanxuan.change.integration.flow.supplier.rsp.SupplierSimpleRsp;
import com.netease.mail.yanxuan.change.integration.todo.SupplierItemPageVO;
import com.netease.yanxuan.flowx.sdk.meta.controller.communal.AjaxResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.Collections;
import java.util.List;
/**
* @author WangJiaXiang
* @date 2022/12/7/007$
*/
@Slf4j
@RestController
@RequestMapping("/supplier")
public class SupplierController {
@Autowired
private FlowRpcSupplierService rpcSupplierService;
@Autowired
private ISupplierItemService supplierItemService;
@Autowired
private FlowRpcSupplierSendService supplierSendService;
@Autowired
private AppConfig appConfig;
@GetMapping("/query/supplier/infos")
public AjaxResult<List<SupplierSimpleRsp>> querySupplierInfos(
@RequestParam(name = "name", required = false) String name,
@RequestParam(name = "uid", required = false) String uid,
@RequestParam(name = "fuzzySearchText") String fuzzySearchText) {
if (name == null) {
name = appConfig.getSearchName();
}
if (uid == null) {
uid = appConfig.getSearchUid();
}
SupplierSearchRemoteReq req = new SupplierSearchRemoteReq();
req.setSearchText(fuzzySearchText);
AjaxResult<List<SupplierSimpleRsp>> supplierInfo = supplierSendService.queryByConditionForQc(req);
if (ResponseCodeEnum.SUCCESS.getCode() == (supplierInfo.getCode())) {
return supplierInfo;
}
log.error("[querySupplierInfos] querySupplierInfos failed, name={},uid={},fuzzySearchText={}, errMsg={}", name,
uid, fuzzySearchText, JSON.toJSONString(supplierInfo));
return null;
}
@GetMapping("/query/supplier/item")
public AjaxResponse<SupplierItemPageVO> querySupplier(@RequestParam String supplier,
@RequestParam(required = false) String itemId,
@RequestParam(required = false) String itemName,
@RequestParam(defaultValue = "1") Integer page,
@RequestParam(defaultValue = "10") Integer pageSize) {
SupplierGoodsInfoReq supplierGoodsInfoReq = new SupplierGoodsInfoReq();
supplierGoodsInfoReq.setSupplierIds(supplier);
return AjaxResponse.initSuccessResult(supplierItemService.supplierGoodsInfoBySupplier(supplierGoodsInfoReq, itemId, itemName, page, pageSize));
}
}
/**
* @(#)TestController.java, 2022/11/28.
* <p/>
* Copyright 2022 Netease, Inc. All rights reserved.
* NETEASE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
package com.netease.mail.yanxuan.change.web.controller;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.alibaba.fastjson.JSON;
import com.netease.mail.yanxuan.change.biz.biz.ChangeFlowBiz;
import com.netease.mail.yanxuan.change.biz.config.AppConfig;
import com.netease.mail.yanxuan.change.biz.meta.exception.ExceptionFactory;
import com.netease.mail.yanxuan.change.biz.service.ChangeFlowService;
import com.netease.mail.yanxuan.change.biz.service.change.ChangeConfigService;
import com.netease.mail.yanxuan.change.biz.service.rpc.QCService;
import com.netease.mail.yanxuan.change.biz.service.rpc.SupplierSendService;
import com.netease.mail.yanxuan.change.biz.task.AutoSubmit;
import com.netease.mail.yanxuan.change.common.bean.AjaxResult;
import com.netease.mail.yanxuan.change.common.bean.RequestLocalBean;
import com.netease.mail.yanxuan.change.common.bean.ResponseCode;
import com.netease.mail.yanxuan.change.common.enums.ChangeFlowEnum;
import com.netease.mail.yanxuan.change.common.enums.CreateSourceEnum;
import com.netease.mail.yanxuan.change.dal.entity.ChangeRecord;
import com.netease.mail.yanxuan.change.dal.meta.model.po.ChangeConfigPo;
import com.netease.mail.yanxuan.change.dal.meta.model.req.SendMailReq;
import com.netease.mail.yanxuan.change.integration.email.enums.EmailTemplateEnum;
import com.netease.mail.yanxuan.change.integration.flow.supplier.FlowRpcSupplierInfoService;
import com.netease.mail.yanxuan.change.integration.flow.supplier.req.SupplierRelatedUserReq;
import com.netease.mail.yanxuan.change.integration.flow.supplier.rsp.SupplierUserRsp;
import com.netease.mail.yanxuan.change.integration.qc.meta.QcCategoryVO;
import lombok.extern.slf4j.Slf4j;
/**
* @Author zcwang
* @Date 2022/11/28
*/
@Slf4j
@RestController
@RequestMapping("/test")
public class TestController {
@Autowired
private ChangeFlowService changeFlowService;
@Autowired
private AutoSubmit autoSubmit;
@Autowired
private ChangeFlowBiz changeFlowBiz;
@Autowired
private AppConfig appConfig;
@Autowired
private SupplierSendService sendSupplierEmail;
@Autowired
private ChangeConfigService changeConfigService;
@Autowired
private QCService qcService;
// @PostMapping("/submit")
// public AjaxResult<Void> submit(Long id) {
// ChangeRecord record = changeFlowService.getById(id);
// Assert.notNull(record, "工单不存在");
// if (!record.getFlowNode().equals(ChangeFlowEnum.CHANGE_FLOW_EXE.getNodeId())) {
// throw ExceptionFactory.createBiz(ResponseCode.SUBMIT_FLOW_ERROR, "不是变更执行节点,不可运维提交");
// }
// autoSubmit.progressRecord(record);
// return AjaxResult.success();
// }
@GetMapping("/getUid")
public AjaxResult<String> getUid() {
return AjaxResult.success(RequestLocalBean.getUid());
}
@Autowired
private FlowRpcSupplierInfoService supplierInfoService;
@PostMapping("/test")
public List<SupplierUserRsp> test(@RequestBody SupplierRelatedUserReq req) {
return supplierInfoService.querySupplierRelatedUser(req);
}
// @PostMapping("/send")
// public void sendEmail(@RequestBody SendMailReq req) {
// String subjectParam = req.getId().toString();
// EmailTemplateEnum emailTemplateEnum = EmailTemplateEnum.getEmailTemplateEnum(req.getCode());
// String mapToJson = req.getMapToJson();
// log.debug("[testSendEmail] subjectParam:{}, emailTemplateEnum:{}, mapToJson:{}", subjectParam,
// emailTemplateEnum, mapToJson);
// changeFlowBiz.qcSendEmail(appConfig.getReceiver(), appConfig.getReceiver(), subjectParam,
// emailTemplateEnum, JSON.parseObject(mapToJson, Map.class));
// // 如果是供应商,再次发送供应商邮件
// if (req.getCreateSource().equals(CreateSourceEnum.TONG_ZHOU.getType())) {
// Assert.notNull(req.getChangeSupplier(), "同舟端负责人不可为空");
// sendSupplierEmail.sendSupplierEmail(req.getChangeSupplier(), subjectParam,
// emailTemplateEnum, JSON.parseObject(mapToJson, Map.class));
// }
// }
@GetMapping("/ccList")
public AjaxResult<List<String>> ccList(@RequestParam List<String> receiver){
return AjaxResult.success(changeFlowBiz.getDepartmentInfo(receiver));
}
@GetMapping("/getByOneAndTwo")
public AjaxResult<ChangeConfigPo> getByOneAndTwo(@RequestParam Long parentId, @RequestParam Long sonId) {
return AjaxResult.success(changeConfigService.queryInfoPo(parentId, sonId));
}
@GetMapping("/getQc")
public AjaxResult<List<QcCategoryVO>> getQc(@RequestParam("itemId") Long itemId) {
return AjaxResult.success(qcService.getQcCategoryListByItemId(itemId));
}
}
\ No newline at end of file
/**
* @(#)TitleVo.java, 2022/11/14.
* <p/>
* Copyright 2022 Netease, Inc. All rights reserved.
* NETEASE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
package com.netease.mail.yanxuan.change.web.meta.model.vo;
import com.netease.mail.yanxuan.change.biz.config.TitleFileConfig;
import lombok.Data;
/**
* @Author zcwang
* @Date 2022/11/14
*/
@Data
public class TitleVo {
/**
* 提示文案
*/
private String title;
/**
*
*/
private TitleFileConfig titleFileConfig;
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment