Commit 77e27ca4 authored by hongguangwu's avatar hongguangwu

Merge branch 'develop'

# Conflicts:
#	yifu-common/yifu-common-dapr/src/main/resources/daprConfig.properties
#	yifu-social/yifu-social-biz/src/main/java/com/yifu/cloud/plus/v1/yifu/social/config/SocialFriendConfig.java
parents ae97cfa4 e3a999d7
apiVersion: apps/v1 # 指定api版本,此值必须在kubectl api-versions中
kind: Deployment # 指定创建资源的角色/类型
metadata: # 资源的元数据/属性
name: yifu-process # 资源的名字,在同一个namespace中必须唯一
namespace: qas-mvp # 部署在哪个namespace中
spec: # 资源规范字段
selector: # 选择器
matchLabels: # 匹配标签
app: yifu-process
replicas: 1 # 声明副本数目
#revisionHistoryLimit: 3 # 保留历史版本
#strategy: # 策略
# rollingUpdate: # 滚动更新
# maxSurge: 30% # 最大额外可以存在的副本数,可以为百分比,也可以为整数
# maxUnavailable: 30% # 示在更新过程中能够进入不可用状态的 Pod 的最大值,可以为百分比,也可以为整数
# type: RollingUpdate # 滚动更新策略
template: # 模版
metadata: # 模版
labels: # 设定资源的标签
app: yifu-process
annotations:
dapr.io/enabled: "true" #设定此参数为 true 注入Dapr sidecar到pod
dapr.io/app-id: "yifu-process" #应用程序唯一 ID。 用于服务发现、状态封装 和 发布/订阅 消费者ID
dapr.io/app-port: "25087" #这个参数告诉Dapr你的应用程序正在监听哪个端口。
#dapr.io/log-level: "debug" #为 Dapr sidecar设置日志级别。 允许的值是debug,info,warn,error。 默认是 info
#dapr.io/log-as-json: "false" #将此参数设置为true以JSON格式输出日志。 默认值为 false.
#dapr.io/config: file #告诉 Dapr 要使用哪个配置 CRD
dapr.io/app-protocol: "http" #告诉 Dapr 你的应用程序正在使用哪种协议。 有效选项是 http and grpc。 Default is http
#dapr.io/app-max-concurrency: "20" #限制应用程序的并发量。 有效的数值是大于 0
#dapr.io/app-ssl: "false" #告诉Dapr通过不安全的SSL连接调用应用程序。 同时适用于HTTP和gRPC。 Traffic between your app and the Dapr sidecar is encrypted with a certificate issued by a non-trusted certificate authority, which is considered insecure. 默认值为 false.
dapr.io/metrics-port: "9090" #设置 sidecar 度量服务器的端口。 默认值为 9090
#dapr.io/sidecar-cpu-limit: 2 #Dapr sidecar可以使用的最大CPU数量。 默认情况下未设置
#dapr.io/sidecar-memory-limit: "800Mi" #Dapr sidecar可以使用的最大内存量。默认情况下未设置 请参阅 https://kubernetes.io/docs/tasks/administer-cluster/manage-resources/quota-memory-cpu-namespace/ 的有效值。
#dapr.io/sidecar-cpu-request: 1 #Dapr sidecar要求的 CPU 数量
#dapr.io/sidecar-memory-request #Dapr sidecar 请求的内存数量
dapr.io/http-max-request-size: "100" #增加http和grpc服务器请求正文参数的最大大小,单位为MB,以处理大文件的上传。 默认值为 4 MB
dapr.io/http-read-buffer-size: "16" #Dapr has a default limit of 4KB for the http header read buffer size. When sending http headers that are bigger than the default 4KB, you can increase this value. Otherwise, you may encounter a Too big request header
dapr.io/sidecar-listen-addresses: "0.0.0.0"
# 更多dapr配置请参考 https://www.bookstack.cn/read/dapr-1.5-zh/cc77b74e2cc2f4d4.md
spec: # 资源规范字段
nodeSelector: # node 选择器
node-type: worker # node标签
kubernetes.io/hostname: yfmaster1
containers: # 容器
- name: yifu-process # 容器的名字
image: hub.worfu.com/qas-mvp/yifu-process-biz:1.0.0 #临时地址
# image: 192.168.1.110:5500/qas-mvp/yifu-insurances-biz:1.0.0 # 容器镜像地址
imagePullPolicy: Always # 每次Pod启动拉取镜像策略,三个选择 Always、Never、IfNotPresent
# Always,每次都检查;Never,每次都不检查(不管本地是否有);IfNotPresent,如果本地有就不检查,如果没有就拉取(手动测试时,
# 已经打好镜像存在docker容器中时,使用存在不检查级别,
# 默认为每次都检查,然后会进行拉取新镜像,因镜像仓库不存在,导致部署失败)
ports:
- containerPort: 25087 # 容器端口
env: # 启动环境配置信息 active and timeZone set
- name: SPRING_PROFILES_ACTIVE
value: test
- name: TZ
value: Asia/Shanghai
resources: #资源配置限制
limits: # 最大使用
memory: "2048Mi"
#cpu: 300m # CPU,1核心 = 1000m
requests: # 容器运行时,最低资源需求,也就是说最少需要多少资源容器才能正常运行
#cpu: 100m
memory: "500Mi"
#livenessProbe: # pod 内部健康检查的设置
# httpGet: # 通过httpget检查健康,返回200-399之间,则认为容器正常
# path: /healthCheck # URI地址
# port: 8080 # 端口
# scheme: HTTP # 协议
# # host: 127.0.0.1 # 主机地址
# initialDelaySeconds: 30 # 表明第一次检测在容器启动后多长时间后开始
# timeoutSeconds: 5 # 检测的超时时间
# periodSeconds: 30 # 检查间隔时间
# successThreshold: 1 # 成功门槛
# failureThreshold: 5 # 失败门槛,连接失败5次,pod杀掉,重启一个新的pod
# readinessProbe: # Pod 准备服务健康检查设置
# httpGet:
# path: /healthCheck
# port: 8080
# scheme: HTTP
# initialDelaySeconds: 30
# timeoutSeconds: 5
# periodSeconds: 10
# successThreshold: 1
# failureThreshold: 5
#也可以用这种方法
#exec: 执行命令的方法进行监测,如果其退出码不为0,则认为容器正常
# command:
# - cat
# - /tmp/health
#也可以用这种方法
#tcpSocket: # 通过tcpSocket检查健康
# port: number
#ports:
# - name: http # 名称
# containerPort: 8080 # 容器开发对外的端口
# protocol: TCP # 协议
imagePullSecrets: # 镜像仓库拉取密钥
- name: login
#affinity: # 亲和性调试
# nodeAffinity: # 节点亲和力
# requiredDuringSchedulingIgnoredDuringExecution: # pod 必须部署到满足条件的节点上
# nodeSelectorTerms: # 节点满足任何一个条件就可以
# - matchExpressions: # 有多个选项,则只有同时满足这些逻辑选项的节点才能运行 pod
# - key: beta.kubernetes.io/arch
# operator: In
# values:
# - amd64
apiVersion: v1 # 指定api版本,此值必须在kubectl api-versions中
kind: Service # 指定创建资源的角色/类型
metadata: # 资源的元数据/属性
labels: # 设定资源的标签
app: yifu-process # 资源的名字,在同一个namespace中必须唯一
name: yifu-process # 资源的名字,在同一个namespace中必须唯一
namespace: qas-mvp # 部署在哪个namespace中
spec: # 资源规范字段
ports:
- port: 25087 # service 端口
protocol: TCP # 协议
targetPort: 25087 # 容器暴露的端口
name: http-process # 端口名称
- port: 3500 # service 端口
protocol: TCP # 协议
targetPort: 3500 # 容器暴露的端口
name: http-process-dapr
selector: # 选择器
app: yifu-process # 资源名称
type: ClusterIP # ClusterIP 类型
apiVersion: apps/v1 # 指定api版本,此值必须在kubectl api-versions中
kind: Deployment # 指定创建资源的角色/类型
metadata: # 资源的元数据/属性
name: yifu-process # 资源的名字,在同一个namespace中必须唯一
namespace: prd-mvp # 部署在哪个namespace中
spec: # 资源规范字段
selector: # 选择器
matchLabels: # 匹配标签
app: yifu-process
replicas: 1 # 声明副本数目
#revisionHistoryLimit: 3 # 保留历史版本
#strategy: # 策略
# rollingUpdate: # 滚动更新
# maxSurge: 30% # 最大额外可以存在的副本数,可以为百分比,也可以为整数
# maxUnavailable: 30% # 示在更新过程中能够进入不可用状态的 Pod 的最大值,可以为百分比,也可以为整数
# type: RollingUpdate # 滚动更新策略
template: # 模版
metadata: # 模版
labels: # 设定资源的标签
app: yifu-process
annotations:
dapr.io/enabled: "true" #设定此参数为 true 注入Dapr sidecar到pod
dapr.io/app-id: "yifu-process" #应用程序唯一 ID。 用于服务发现、状态封装 和 发布/订阅 消费者ID
dapr.io/app-port: "25087" #这个参数告诉Dapr你的应用程序正在监听哪个端口。
#dapr.io/log-level: "debug" #为 Dapr sidecar设置日志级别。 允许的值是debug,info,warn,error。 默认是 info
#dapr.io/log-as-json: "false" #将此参数设置为true以JSON格式输出日志。 默认值为 false.
#dapr.io/config: file #告诉 Dapr 要使用哪个配置 CRD
dapr.io/app-protocol: "http" #告诉 Dapr 你的应用程序正在使用哪种协议。 有效选项是 http and grpc。 Default is http
#dapr.io/app-max-concurrency: "20" #限制应用程序的并发量。 有效的数值是大于 0
#dapr.io/app-ssl: "false" #告诉Dapr通过不安全的SSL连接调用应用程序。 同时适用于HTTP和gRPC。 Traffic between your app and the Dapr sidecar is encrypted with a certificate issued by a non-trusted certificate authority, which is considered insecure. 默认值为 false.
dapr.io/metrics-port: "9090" #设置 sidecar 度量服务器的端口。 默认值为 9090
#dapr.io/sidecar-cpu-limit: 2 #Dapr sidecar可以使用的最大CPU数量。 默认情况下未设置
#dapr.io/sidecar-memory-limit: "800Mi" #Dapr sidecar可以使用的最大内存量。默认情况下未设置 请参阅 https://kubernetes.io/docs/tasks/administer-cluster/manage-resources/quota-memory-cpu-namespace/ 的有效值。
#dapr.io/sidecar-cpu-request: 1 #Dapr sidecar要求的 CPU 数量
#dapr.io/sidecar-memory-request #Dapr sidecar 请求的内存数量
dapr.io/http-max-request-size: "100" #增加http和grpc服务器请求正文参数的最大大小,单位为MB,以处理大文件的上传。 默认值为 4 MB
dapr.io/http-read-buffer-size: "16" #Dapr has a default limit of 4KB for the http header read buffer size. When sending http headers that are bigger than the default 4KB, you can increase this value. Otherwise, you may encounter a Too big request header
# dapr.io/sidecar-listen-addresses: "0.0.0.0"
# 更多dapr配置请参考 https://www.bookstack.cn/read/dapr-1.5-zh/cc77b74e2cc2f4d4.md
spec: # 资源规范字段
nodeSelector: # node 选择器
node-type: worker # node标签
containers: # 容器
- name: yifu-process # 容器的名字
image: hub.worfu.com/prd-mvp/yifu-process-biz:1.0.0 #临时地址
imagePullPolicy: Always # 每次Pod启动拉取镜像策略,三个选择 Always、Never、IfNotPresent
# Always,每次都检查;Never,每次都不检查(不管本地是否有);IfNotPresent,如果本地有就不检查,如果没有就拉取(手动测试时,
# 已经打好镜像存在docker容器中时,使用存在不检查级别,
# 默认为每次都检查,然后会进行拉取新镜像,因镜像仓库不存在,导致部署失败)
ports:
- containerPort: 25087 # 容器端口
env: # 启动环境配置信息 active and timeZone set
- name: SPRING_PROFILES_ACTIVE
value: prd
- name: TZ
value: Asia/Shanghai
resources: #资源配置限制
limits: # 最大使用
memory: "2048Mi"
#cpu: 300m # CPU,1核心 = 1000m
requests: # 容器运行时,最低资源需求,也就是说最少需要多少资源容器才能正常运行
#cpu: 100m
memory: "500Mi"
#livenessProbe: # pod 内部健康检查的设置
# httpGet: # 通过httpget检查健康,返回200-399之间,则认为容器正常
# path: /healthCheck # URI地址
# port: 8080 # 端口
# scheme: HTTP # 协议
# # host: 127.0.0.1 # 主机地址
# initialDelaySeconds: 30 # 表明第一次检测在容器启动后多长时间后开始
# timeoutSeconds: 5 # 检测的超时时间
# periodSeconds: 30 # 检查间隔时间
# successThreshold: 1 # 成功门槛
# failureThreshold: 5 # 失败门槛,连接失败5次,pod杀掉,重启一个新的pod
# readinessProbe: # Pod 准备服务健康检查设置
# httpGet:
# path: /healthCheck
# port: 8080
# scheme: HTTP
# initialDelaySeconds: 30
# timeoutSeconds: 5
# periodSeconds: 10
# successThreshold: 1
# failureThreshold: 5
#也可以用这种方法
#exec: 执行命令的方法进行监测,如果其退出码不为0,则认为容器正常
# command:
# - cat
# - /tmp/health
#也可以用这种方法
#tcpSocket: # 通过tcpSocket检查健康
# port: number
#ports:
# - name: http # 名称
# containerPort: 8080 # 容器开发对外的端口
# protocol: TCP # 协议
imagePullSecrets: # 镜像仓库拉取密钥
- name: login
#affinity: # 亲和性调试
# nodeAffinity: # 节点亲和力
# requiredDuringSchedulingIgnoredDuringExecution: # pod 必须部署到满足条件的节点上
# nodeSelectorTerms: # 节点满足任何一个条件就可以
# - matchExpressions: # 有多个选项,则只有同时满足这些逻辑选项的节点才能运行 pod
# - key: beta.kubernetes.io/arch
# operator: In
# values:
# - amd64
apiVersion: v1 # 指定api版本,此值必须在kubectl api-versions中
kind: Service # 指定创建资源的角色/类型
metadata: # 资源的元数据/属性
labels: # 设定资源的标签
app: yifu-process # 资源的名字,在同一个namespace中必须唯一
name: yifu-process # 资源的名字,在同一个namespace中必须唯一
namespace: prd-mvp # 部署在哪个namespace中
spec: # 资源规范字段
ports:
- port: 25087 # service 端口
protocol: TCP # 协议
targetPort: 25087 # 容器暴露的端口
name: http-process # 端口名称
# - port: 3500 # service 端口
# protocol: TCP # 协议
# targetPort: 3500 # 容器暴露的端口
# name: http-process-dapr
selector: # 选择器
app: yifu-process # 资源名称
type: ClusterIP # ClusterIP 类型
......@@ -114,6 +114,7 @@
<module>yifu-msg</module>
<module>yifu-permission</module>
<module>yifu-ekp</module>
<module>yifu-process</module>
</modules>
<dependencyManagement>
......
......@@ -276,9 +276,9 @@ public class TEmployeeProject extends BaseEntity {
/**
* 是否完整 0是 1 否
* 档案是否完整 0是 1 否
*/
@Schema(description ="是否完整0是 1 否")
@Schema(description ="档案是否完整0是 1 否")
private String isComplete;
/**
......
......@@ -527,6 +527,22 @@ public class TSettleDomain extends BaseEntity {
@Schema(description = "二级指标归属", name = "secondIndicatorBelong")
private String secondIndicatorBelong ;
/**
* 是否含风险 fxj 2025-01-10 v1.7.5
*/
@Schema(description = "是否含风险",name = "hasContainRisks")
private String hasContainRisks;
/**
* 事业部条线 fxj 2025-01-10 v1.7.5
*/
@Schema(description = "事业部条线",name = "newLine")
private String newLine ;
/**
* 事业部 fxj 2025-01-10 v1.7.5
*/
@Schema(description = "事业部",name = "division")
private String division ;
/**
* 代发户状态(0否;1是代发户)
*/
......
......@@ -490,6 +490,11 @@ public class EmployeeProjectExportParamVO extends BaseEntity {
@ExcelAttribute(name = "合同甲方")
private String contractParty;
@HeadFontStyle(fontHeightInPoints = 11)
@ExcelProperty(value = "档案是否完整")
@ExcelAttribute(name = "档案是否完整", readConverterExp = "0=是,1=否")
private String isComplete;
private String[] socialStatusArray;
private String[] fundStatusArray;
......
......@@ -181,7 +181,7 @@ public class EmployeeProjectExportVO {
private String fileTown;
/**
* 是否大专及以上(0否1是)
* 是否大专及以上(0否1是)—— readConverterExp 无效,手动翻译
*/
@HeadFontStyle(fontHeightInPoints = 11)
@ExcelProperty(value = "是否大专及以上")
......@@ -235,6 +235,7 @@ public class EmployeeProjectExportVO {
/**
* 人员档案来源(字典:4人员档案新建、5项目档案新建、1社保/公积金、3商险、2薪酬)
* 人员档案来源(字典:1=社保、公积金派单,2=人员发薪,3=商险派单,4=档案新建,5=批量导入、6电子签,7:预入职)
*/
@HeadFontStyle(fontHeightInPoints = 11)
@ExcelProperty(value = "人员档案来源")
......@@ -529,6 +530,11 @@ public class EmployeeProjectExportVO {
@ExcelAttribute(name = "合同甲方")
private String contractParty;
@HeadFontStyle(fontHeightInPoints = 11)
@ExcelProperty(value = "档案是否完整")
@ExcelAttribute(name = "档案是否完整", readConverterExp = "0=是,1=否")
private String isComplete;
private String[] socialStatusArray;
private String[] fundStatusArray;
......
package com.yifu.cloud.plus.v1.yifu.archives.vo;
import com.baomidou.mybatisplus.annotation.TableField;
import com.yifu.cloud.plus.v1.yifu.archives.entity.TAttaInfo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
/**
* @Author fxj
* @Description 附件信息表
* @Date 11:07 2022/6/22
**/
@Data
public class TAttaInfoVo extends TAttaInfo {
private static final long serialVersionUID = 1L;
/**
* 其他分租名称
*/
@TableField(exist = false)
private String groupName;
/**
* 姓名
*/
@Schema(description = "姓名")
private String empName;
/**
* 身份证
*/
@Schema(description = "身份证")
private String empIdcard;
}
......@@ -447,4 +447,20 @@ public class TSettleDomainEkpVo implements Serializable {
@Schema(description = "二级指标归属",name = "secondIndicatorBelong")
private String secondIndicatorBelong ;
/**
* 是否含风险
*/
@Schema(description = "是否含风险",name = "hasContainRisks")
private String hasContainRisks;
/**
* 事业部条线
*/
@Schema(description = "事业部条线",name = "newLine")
private String newLine ;
/**
* 事业部
*/
@Schema(description = "事业部",name = "division")
private String division ;
}
package com.yifu.cloud.plus.v1.yifu.archives.config;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
import java.util.Collections;
/**
* Description: 允许跨域以
* CORS资源共享配置
*
* @author fxju
* @since JDK 1.8
*/
@Slf4j
@Configuration
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
//是否发送Cookie
.allowCredentials(true)
//放行哪些原始域
.allowedOriginPatterns("*")
.allowedMethods(new String[]{"GET", "POST", "PUT", "DELETE"})
.allowedHeaders("*")
.exposedHeaders("*");
}
public class CorsConfig {
@Bean
public FilterRegistrationBean filterRegistrationBean() {
CorsConfiguration corsConfiguration = new CorsConfiguration();
//1.允许任何来源
corsConfiguration.setAllowedOriginPatterns(Collections.singletonList("*"));
//2.允许任何请求头
corsConfiguration.addAllowedHeader(CorsConfiguration.ALL);
//3.允许任何方法
corsConfiguration.addAllowedMethod(CorsConfiguration.ALL);
//4.允许凭证
corsConfiguration.setAllowCredentials(true);
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", corsConfiguration);
CorsFilter corsFilter = new CorsFilter(source);
FilterRegistrationBean<CorsFilter> filterRegistrationBean=new FilterRegistrationBean<>(corsFilter);
// 前Spring Security 过滤器是通过 SecurityFilterAutoConfiguration 的 DelegatingFilterProxyRegistrationBean 注册到 servletContext上下文,其中过滤器的顺序属性 Order 读取的 是 SecurityProperties 的默认配置也就是 -100;
filterRegistrationBean.setOrder(-101); // 小于 SpringSecurity Filter的 Order(-100) 即可
return filterRegistrationBean;
}
}
......@@ -105,7 +105,7 @@ public class MSetttleCustomerUserController {
*/
@Inner
@PostMapping("/inner/getCustomerUserMap")
public Map<String,String> getCustomerUserMap(@RequestBody List<Integer> userIdList) {
public Map<String,String> getCustomerUserMap(@RequestBody List<String> userIdList) {
return mSetttleCustomerUserService.getCustomerUser(userIdList);
}
/**
......
......@@ -35,6 +35,7 @@ import com.yifu.cloud.plus.v1.yifu.common.dapr.util.MenuUtil;
import com.yifu.cloud.plus.v1.yifu.common.log.annotation.SysLog;
import com.yifu.cloud.plus.v1.yifu.common.security.annotation.Inner;
import com.yifu.cloud.plus.v1.yifu.common.security.util.SecurityUtils;
import com.yifu.cloud.plus.v1.yifu.salary.vo.TInsuranceUnpurchasePersonCardVo;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
......@@ -353,4 +354,17 @@ public class TEmployeeProjectController {
public R<List<TSettleDomainDataVo>> selectSettleMentData(@RequestBody List<String> deptNoList) {
return tEmployeeProjectService.selectSettleMentData(deptNoList);
}
/**
* @param cardVo
* @Description: 判断员工是否存在在项的项目档案
* @Author: huyc
* @Date: 2025/1/15
* @return:
**/
@Inner
@PostMapping("/inner/selectExitEmpProject")
public Boolean selectExitEmpProject(@RequestBody TInsuranceUnpurchasePersonCardVo cardVo) {
return tEmployeeProjectService.selectExitEmpProject(cardVo);
}
}
......@@ -322,5 +322,38 @@ public class TPreEmpMainController {
}
return tPreEmpMainService.checkCode(empPhone, verifyCode);
}
/**
* @Author fxj
* @Description 预入职C端签名图盘打包下载
* @Date 14:07 2025/1/10
* @Param
* @return
**/
@Operation(summary = "预入职C端签名图盘打包下载ZIP包", description = "预入职C端签名图盘打包下载ZIP包")
@SysLog("预入职C端签名图盘打包下载ZIP包")
@GetMapping("/preEmpExport")
public void preEmpExport(@RequestParam(value = "departNo",required = true) String departNo,
@RequestParam(value ="departName",required = true) String departName,
@RequestParam(value ="startDate",required = true) String startDate,
@RequestParam(value ="endDate",required = true) String endDate,
HttpServletResponse response) throws Exception{
tPreEmpMainService.exportEmpsFile(departName,departNo,startDate,endDate, response);
}
/**
* @Author fxj
* @Description 预入职C端签名图盘打包下载 count
* @Date 14:07 2025/1/10
* @Param
* @return
**/
@Operation(summary = "预入职C端签名图盘打包下载ZIP包count", description = "预入职C端签名图盘打包下载ZIP包count")
@SysLog("预入职C端签名图盘打包下载ZIP包count")
@GetMapping("/preEmpCount")
public R preEmpCount(@RequestParam(value ="departNo",required = true) String departNo,
@RequestParam(value ="startDate",required = true) String startDate,
@RequestParam(value ="endDate",required = true) String endDate,
HttpServletResponse response) throws Exception{
return tPreEmpMainService.preEmpCount(departNo,startDate,endDate);
}
}
......@@ -27,7 +27,7 @@ public interface MSetttleCustomerUserMapper extends BaseMapper<MSetttleCustomerU
IPage<MSetttleCustomerUser> getMSetttleCustomerUserPage(Page<MSetttleCustomerUser> page, @Param("mSetttleCustomerUser") MSetttleCustomerUser mSetttleCustomerUser);
List<MSetttleCustomerUserVo> getCustomerUser(@Param("userIdList")List<Integer> userIdList);
List<MSetttleCustomerUserVo> getCustomerUser(@Param("userIdList")List<String> userIdList);
Integer getCustomerCount();
......
......@@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yifu.cloud.plus.v1.yifu.archives.entity.TAttaInfo;
import com.yifu.cloud.plus.v1.yifu.archives.vo.TAttaInfoVo;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
......@@ -51,4 +52,7 @@ public interface TAttaInfoMapper extends BaseMapper<TAttaInfo> {
// 删除学历与职业资格之外的附件
void deleteByDomainIdAndOther(@Param("domainId") String domainId);
List<TAttaInfoVo> getAttInfoByParam(@Param("departNo")String departNo, @Param("startDate")String startDate, @Param("endDate")String endDate);
int getAttInfoCountByParam(@Param("departNo")String departNo, @Param("startDate")String startDate, @Param("endDate")String endDate);
}
......@@ -26,7 +26,7 @@ public interface MSetttleCustomerUserService extends IService<MSetttleCustomerUs
IPage<MSetttleCustomerUser> getMSetttleCustomerUserPage(Page<MSetttleCustomerUser> page, MSetttleCustomerUser mSetttleCustomerUser);
Map<String,String> getCustomerUser(List<Integer> userIdList);
Map<String,String> getCustomerUser(List<String> userIdList);
Integer getCustomerCount();
......
......@@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.yifu.cloud.plus.v1.yifu.archives.entity.TAttaInfo;
import com.yifu.cloud.plus.v1.yifu.archives.vo.TAttaInfoVo;
import com.yifu.cloud.plus.v1.yifu.common.core.util.R;
import java.time.LocalDateTime;
......@@ -83,4 +84,7 @@ public interface TAttaInfoService extends IService<TAttaInfo> {
void deleteByDomainIdAndType(String domainId, int relationType);
List<TAttaInfoVo> getAttInfoByParam(String departNo, String startDate, String endDate);
int getAttInfoCountByParam(String departNo, String startDate, String endDate);
}
......@@ -26,6 +26,7 @@ import com.yifu.cloud.plus.v1.yifu.archives.entity.TEmployeeProject;
import com.yifu.cloud.plus.v1.yifu.archives.vo.*;
import com.yifu.cloud.plus.v1.yifu.common.core.util.ErrorMessage;
import com.yifu.cloud.plus.v1.yifu.common.core.util.R;
import com.yifu.cloud.plus.v1.yifu.salary.vo.TInsuranceUnpurchasePersonCardVo;
import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
......@@ -282,4 +283,6 @@ public interface TEmployeeProjectService extends IService<TEmployeeProject> {
**/
Map<String, TEmployeeProject> getMapByDeptIdAndDelete(String deptId);
Boolean selectExitEmpProject(TInsuranceUnpurchasePersonCardVo cardVo);
}
......@@ -131,4 +131,7 @@ public interface TPreEmpMainService extends IService<TPreEmpMain> {
*/
R<String> checkCode(String empPhone, String verifyCode);
void exportEmpsFile(String departName,String departNo, String startDate, String endDate, HttpServletResponse response);
R preEmpCount(String departNo, String startDate, String endDate);
}
......@@ -40,7 +40,7 @@ public class MSetttleCustomerUserServiceImpl extends ServiceImpl<MSetttleCustome
}
@Override
public Map<String, String> getCustomerUser(List<Integer> userIdList) {
public Map<String, String> getCustomerUser(List<String> userIdList) {
Map<String,String> map = new HashMap<>();
List<MSetttleCustomerUserVo> list = baseMapper.getCustomerUser(userIdList);
if(Common.isNotNull(list)){
......
......@@ -6,6 +6,7 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yifu.cloud.plus.v1.yifu.archives.entity.TAttaInfo;
import com.yifu.cloud.plus.v1.yifu.archives.mapper.TAttaInfoMapper;
import com.yifu.cloud.plus.v1.yifu.archives.service.TAttaInfoService;
import com.yifu.cloud.plus.v1.yifu.archives.vo.TAttaInfoVo;
import com.yifu.cloud.plus.v1.yifu.common.core.util.Common;
import com.yifu.cloud.plus.v1.yifu.common.core.util.OSSUtil;
import com.yifu.cloud.plus.v1.yifu.common.core.util.R;
......@@ -154,4 +155,13 @@ public class TAttaInfoServiceImpl extends ServiceImpl<TAttaInfoMapper, TAttaInfo
}
}
@Override
public List<TAttaInfoVo> getAttInfoByParam(String departNo, String startDate, String endDate) {
return baseMapper.getAttInfoByParam(departNo,startDate,endDate);
}
@Override
public int getAttInfoCountByParam(String departNo, String startDate, String endDate) {
return baseMapper.getAttInfoCountByParam(departNo,startDate,endDate);
}
}
......@@ -52,6 +52,7 @@ import com.yifu.cloud.plus.v1.yifu.common.dapr.config.DaprSocialProperties;
import com.yifu.cloud.plus.v1.yifu.common.dapr.config.DaprUpmsProperties;
import com.yifu.cloud.plus.v1.yifu.common.dapr.util.HttpDaprUtil;
import com.yifu.cloud.plus.v1.yifu.common.security.util.SecurityUtils;
import com.yifu.cloud.plus.v1.yifu.salary.vo.TInsuranceUnpurchasePersonCardVo;
import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
......@@ -1942,4 +1943,15 @@ public class TEmployeeProjectServiceImpl extends ServiceImpl<TEmployeeProjectMap
return proMap;
}
@Override
public Boolean selectExitEmpProject(TInsuranceUnpurchasePersonCardVo cardVo) {
long count = baseMapper.selectCount(Wrappers.<TEmployeeProject>query().lambda()
.eq(TEmployeeProject::getDeptNo, cardVo.getDeptNo())
.eq(TEmployeeProject::getProjectStatus, CommonConstants.ZERO_INT)
.eq(TEmployeeProject::getEmpIdcard, cardVo.getEmpIdcardNo())
.eq(TEmployeeProject::getEmpName, cardVo.getEmpName())
.eq(TEmployeeProject::getDeleteFlag, CommonConstants.ZERO_STRING));
return count > 0;
}
}
......@@ -59,10 +59,20 @@ import com.yifu.cloud.plus.v1.yifu.salary.entity.TSalaryEmployee;
import com.yifu.cloud.plus.v1.yifu.salary.vo.ExportErrorVo;
import com.yifu.cloud.plus.v1.yifu.salary.vo.ListStringVo;
import com.yifu.cloud.plus.v1.yifu.salary.vo.TBankNameMapVo;
import com.yifu.cloud.plus.v1.yifu.salary.vo.TSalaryEmpMapVo;
import lombok.AllArgsConstructor;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream;
import org.apache.commons.compress.utils.Lists;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.http.HttpHeaders;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.stereotype.Service;
......@@ -164,6 +174,8 @@ public class TPreEmpMainServiceImpl extends ServiceImpl<TPreEmpMainMapper, TPreE
private final AtomicInteger preImportAtomicInteger = new AtomicInteger(0);
private final AtomicInteger preExportAtomicInteger = new AtomicInteger(0);
private final AtomicInteger zipAtomicInteger = new AtomicInteger(0);
/**
* 预入职-主表简单分页查询
*
......@@ -3685,6 +3697,8 @@ public class TPreEmpMainServiceImpl extends ServiceImpl<TPreEmpMainMapper, TPreE
String empId = null;
// 组装1 预入职 档案
List<TPreEmployeeInfo> preEmployeeInfoList = new ArrayList<>();
List<TPreEmployeeInfo> preEmployeeInfoNeedSalaryList = new ArrayList<>();
List<String> needSalaryList = new ArrayList<>();
List<TPreEmployeeProject> preEmployeeProjectList = new ArrayList<>();
List<TPreEmpBadRecord> preEmpBadRecordList = new ArrayList<>();
List<TPreEmpContactInfo> preEmpContactInfoList = new ArrayList<>();
......@@ -3800,6 +3814,9 @@ public class TPreEmpMainServiceImpl extends ServiceImpl<TPreEmpMainMapper, TPreE
tPreEmployeeInfo.setBankSubName(info.getBankSubName());
tPreEmployeeInfo.setBankNo(info.getBankNo());
tPreEmployeeInfo.setTaxMonth(info.getTaxMonthValue());
} else {
preEmployeeInfoNeedSalaryList.add(tPreEmployeeInfo);
needSalaryList.add(empIdCard);
}
tPreEmployeeInfo.setTaxMonthFlag(CommonConstants.ONE_STRING);
tPreEmployeeInfo.setContactProvince(info.getContactProvinceValue());
......@@ -3984,6 +4001,36 @@ public class TPreEmpMainServiceImpl extends ServiceImpl<TPreEmpMainMapper, TPreE
}
if (!preEmployeeInfoList.isEmpty()) {
if (!preEmployeeInfoNeedSalaryList.isEmpty()) {
if (!needSalaryList.isEmpty()) {
// 查薪资服务的卡号
R<TSalaryEmpMapVo> salaryEmpBankRes = HttpDaprUtil.invokeMethodPost(salaryProperties.getAppUrl()
, salaryProperties.getAppId(), "/tsalaryemployee/inner/getSalaryEmpMap", needSalaryList, TSalaryEmpMapVo.class, SecurityConstants.FROM_IN);
Map<String, TSalaryEmployee> salaryEmpBankMap;
if (Common.isEmpty(salaryEmpBankRes) || Common.isEmpty(salaryEmpBankRes.getCode()) || salaryEmpBankRes.getCode() != CommonConstants.SUCCESS){
return R.failed("获取薪资服务开户行信息失败!");
} else {
if (salaryEmpBankRes.getData() != null && salaryEmpBankRes.getData().getSalaryEmpMap() != null
&& !salaryEmpBankRes.getData().getSalaryEmpMap().isEmpty()) {
salaryEmpBankMap = salaryEmpBankRes.getData().getSalaryEmpMap();
TSalaryEmployee info;
for (TPreEmployeeInfo emp : preEmployeeInfoNeedSalaryList) {
info = salaryEmpBankMap.get(emp.getEmpIdcard());
if (info != null) {
emp.setBankName(info.getBankName());
emp.setBankProvince(info.getBankProvince());
emp.setBankCity(info.getBankCity());
emp.setBankSubName(info.getBankSubName());
emp.setBankNo(info.getBankNo());
emp.setTaxMonth(info.getTaxMonth());
}
}
}
}
}
}
tPreEmployeeInfoService.saveBatch(preEmployeeInfoList);
}
if (!preEmployeeProjectList.isEmpty()) {
......@@ -4280,6 +4327,120 @@ public class TPreEmpMainServiceImpl extends ServiceImpl<TPreEmpMainMapper, TPreE
redisUtil.remove(phoneCodeKey);
return R.ok("验证码通过");
}
@Override
public R preEmpCount(String departNo, String startDate, String endDate){
if (Common.isEmpty(departNo)
|| Common.isEmpty(startDate)
|| Common.isEmpty(endDate)
|| DateUtil.isDate(startDate)
|| DateUtil.isDate(endDate)) {
return R.failed(CommonConstants.PARAM_IS_NOT_ERROR);
}
return R.ok(tAttaInfoService.getAttInfoCountByParam(departNo,startDate,endDate));
}
/**
* @Author fxj
* @Description 预入职C端签名图盘打包下载
* @Date 14:07 2025/1/10
* @Param
* @return
**/
@Override
public void exportEmpsFile(String departName,String departNo, String startDate, String endDate, HttpServletResponse response) {
if (zipAtomicInteger.incrementAndGet() <= 1) {
try {
extracted(departName, departNo, startDate, endDate, response);
} catch (Exception e) {
log.error("导出异常:", e);
} finally {
zipAtomicInteger.decrementAndGet();
}
} else {
// 前面做了+1(atomicInteger.incrementAndGet())这里也要-1
zipAtomicInteger.decrementAndGet();
log.error("预入职签名文件导出超出阈值:" + ResultConstants.FILE_DOWN_LOAD_DATA);
exportError(response, ResultConstants.FILE_DOWN_LOAD_DATA);
}
}
private void extracted(String departName, String departNo, String startDate, String endDate, HttpServletResponse response) {
if (Common.isEmpty(departNo)
|| Common.isEmpty(startDate)
|| Common.isEmpty(endDate)
|| DateUtil.isDate(startDate)
|| DateUtil.isDate(endDate)) {
throw new RuntimeException(CommonConstants.PARAM_IS_NOT_ERROR);
}
List<TAttaInfoVo> handles = tAttaInfoService.getAttInfoByParam(departNo, startDate, endDate);
if (Common.isEmpty(handles)) {
exportError(response, CommonConstants.NO_DATA_TO_HANDLE);
}
// 判断文件大小 超出100M 104,857,600 直接提示重新筛选条件
long size = 0;
if (Common.isNotNull(handles)){
for (TAttaInfoVo vo:handles){
size = size + vo.getAttaSize();
}
if (size > 104857600){
exportError(response, CommonConstants.DATA_TOO_LARGER_FOR_DOWN);
}
}
HttpGet httpGet;
try {
//初始化导出 response
response.setContentType("application/octet-stream");
response.setHeader("content-type", "application/octet-stream");
response.setHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + URLEncoder.encode(departName + departNo, "UTF-8") + ".zip");
CloseableHttpClient httpClient = HttpClients.createDefault();
// 获取人员档案所有的附件信息
getFilesInfo(handles);
// 处理附件 压缩并下载
if (Common.isNotNull(handles)) {
try (ZipArchiveOutputStream zipOutput = new ZipArchiveOutputStream(response.getOutputStream())){
CloseableHttpResponse response1;
HttpEntity entity;
byte[] data;
ZipArchiveEntry entry;
for (TAttaInfoVo fileAtta : handles) {
if (Common.isNotNull(fileAtta.getAttaUrl())){
httpGet = new HttpGet(fileAtta.getAttaUrl());
response1 = httpClient.execute(httpGet);
entity = response1.getEntity();
data = EntityUtils.toByteArray(entity);
entry = new ZipArchiveEntry(fileAtta.getEmpName() + fileAtta.getEmpIdcard() + ".png");
zipOutput.putArchiveEntry(entry);
zipOutput.write(data);
zipOutput.closeArchiveEntry();
}
}
zipOutput.finish();
} catch (Exception e) {
log.error("C端项目人员签字附件下载打包异常:",e);
}
}
} catch (IOException e) {
log.error("C端项目人员签字附件下载异常:",e);
}finally {
if (Common.isNotNull(handles)){
handles.clear();
}
}
}
private void getFilesInfo(List<TAttaInfoVo> handles) {
URL url;
// 获取其他附件以外的附件如身份证正反面
if (Common.isNotNull(handles)) {
for (TAttaInfoVo atta : handles) {
if (CommonConstants.TWENTY_THREE_STRING.equals(atta.getRelationType())) {
url = ossUtil.getObjectUrl(null, atta.getAttaSrc());
atta.setAttaUrl(url.toString().replace("http", "https"));
}
}
}
}
}
......@@ -88,7 +88,7 @@
</springProfile>
<springProfile name="test">
<!-- Level: FATAL 0 ERROR 3 WARN 4 INFO 6 DEBUG 7 -->
<root level="error">
<root level="debug">
<appender-ref ref="console"/>
<appender-ref ref="debug"/>
<appender-ref ref="error"/>
......
......@@ -134,5 +134,32 @@
<delete id="deleteByDomainIdAndOther">
delete from t_atta_info where domain_id=#{domainId} and relation_type not in ('0','2','26','27')
</delete>
<select id="getAttInfoByParam" resultType="com.yifu.cloud.plus.v1.yifu.archives.vo.TAttaInfoVo">
SELECT
b.id,
b.atta_name,
b.atta_src,
b.atta_size,
b.atta_type,
b.create_by,
b.create_time,
b.relation_type,
b.domain_id, a.EMP_NAME,a.EMP_IDCARD
from (select id,EMP_NAME,EMP_IDCARD from t_pre_emp_main where `STATUS`='4' and SOUR_TYPE='0'
and DEPT_NO=#{departNo}
and AUDIT_TIME >= #{startDate}
and AUDIT_TIME <![CDATA[ <= ]]> #{endDate}) a
LEFT JOIN (select * from t_atta_info where RELATION_TYPE ='23' GROUP BY DOMAIN_ID ) b on a.id=b.DOMAIN_ID
where b.DOMAIN_ID is not null
</select>
<select id="getAttInfoCountByParam" resultType="java.lang.Integer">
SELECT
count(1)
from (select id from t_pre_emp_main where `STATUS`='4' and SOUR_TYPE='0'
and DEPT_NO = #{departNo}
and AUDIT_TIME >= #{startDate}
and AUDIT_TIME <![CDATA[ <= ]]> #{endDate}) a
LEFT JOIN (select * from t_atta_info where RELATION_TYPE ='23' GROUP BY DOMAIN_ID ) b on a.id=b.DOMAIN_ID
where b.DOMAIN_ID is not null
</select>
</mapper>
......@@ -57,6 +57,7 @@
<result property="fundStatus" column="FUND_STATUS"/>
<result property="contractStatus" column="CONTRACT_STATUS"/>
<result property="empLabel" column="EMP_LABEL"/>
<result property="isComplete" column="IS_COMPLETE"/>
</resultMap>
<resultMap id="tEmployeeProjectExportMap" type="com.yifu.cloud.plus.v1.yifu.archives.vo.EmployeeProjectExportVO">
......@@ -122,6 +123,7 @@
<result property="contactCity" column="CONTACT_CITY"/>
<result property="contactTown" column="CONTACT_TOWN"/>
<result property="contactAddress" column="contact_address"/>
<result property="isComplete" column="IS_COMPLETE"/>
</resultMap>
<sql id="Base_Column_List">
......@@ -176,7 +178,8 @@
a.SOCIAL_CITY,
a.SOCIAL_TOWN,
a.SALARY_STATUS,
a.EMP_LABEL
a.EMP_LABEL,
a.IS_COMPLETE
</sql>
<sql id="Base_Export_List">
......@@ -235,13 +238,23 @@
b.ADMISSION_DATE,
b.GRADUTION_DATE,
b.REMARK,
case b.FILE_SOURCE
when 1 then '派单'
when 2 then '薪酬'
when 3 then '商险'
when 4 then '档案新建'
when 5 then '批量导入'
when 6 then '电子签'
when 7 then '预入职'
else '-' end FILE_SOURCE,
if(a.STATUS='0','草稿',IF(a.PROJECT_STATUS=1,'已减项','已审核')) PROJECT_STATUS,
a.CREATE_NAME,
a.CREATE_TIME,
b.EMP_EMAIL,
b.EMP_NATRUE AS PROEMP_NATRUE,
a.EMP_LABEL,
t.CONTRACT_PARTY
t.CONTRACT_PARTY,
if(ifnull(a.IS_COMPLETE,'1')='0','是','否') IS_COMPLETE
</sql>
......@@ -442,6 +455,9 @@
<if test="tEmployeeProject.createTimeEnd != null">
AND a.CREATE_TIME <![CDATA[ <= ]]> #{tEmployeeProject.createTimeEnd}
</if>
<if test="tEmployeeProject.isComplete != null and tEmployeeProject.isComplete.trim() != ''">
AND a.IS_COMPLETE = #{tEmployeeProject.isComplete}
</if>
</if>
</sql>
......@@ -612,6 +628,9 @@
AND a.CREATE_TIME <![CDATA[ <= ]]> #{tEmployeeProject.createTimeEnd}
</if>
<if test="tEmployeeProject.isComplete != null and tEmployeeProject.isComplete.trim() != ''">
AND a.IS_COMPLETE = #{tEmployeeProject.isComplete}
</if>
</if>
</sql>
......
......@@ -94,6 +94,12 @@
<result property="firstIndicatorBelong" column="FIRST_INDICATOR_BELONG"/>
<result property="secondIndicatorBelong" column="SECOND_INDICATOR_BELONG"/>
<result property="lineType" column="LINE_TYPE"/>
<!-- 2025-01-10 FXJ V1.7.5 -->
<result property="hasContainRisks" column="HAS_CONTAIN_RISKS"/>
<result property="newLine" column="NEW_LINE"/>
<result property="division" column="DIVISION"/>
<result property="issueStatus" column="ISSUE_STATUS"/>
</resultMap>
......@@ -178,7 +184,10 @@
a.ISSUE_STATUS,
a.FIRST_INDICATOR_BELONG,
a.SECOND_INDICATOR_BELONG,
a.LINE_TYPE
a.LINE_TYPE,
a.HAS_CONTAIN_RISKS,
a.NEW_LINE,
a.DIVISION
</sql>
<resultMap id="tSettleDomainSelectVoMap" type="com.yifu.cloud.plus.v1.yifu.archives.vo.TSettleDomainSelectVo">
......@@ -209,6 +218,11 @@
<result property="commitUserName" column="COMMIT_USER_NAME"/>
<result property="stopFlag" column="STOP_FLAG"/>
<result property="bpoFlag" column="BPO_FLAG"/>
<!-- 2025-01-10 FXJ V1.7.5 -->
<result property="hasContainRisks" column="HAS_CONTAIN_RISKS"/>
<result property="newLine" column="NEW_LINE"/>
<result property="division" column="DIVISION"/>
</resultMap>
<select id="getPage" resultMap="tSettleDomainMap">
......@@ -217,8 +231,20 @@
FROM t_settle_domain a
WHERE 1=1
<if test="tSettleDomain != null">
<if test="tSettleDomain.serverItem != null and tSettleDomain.serverItem.trim() != ''">
and a.SERVER_ITEM like concat('%',#{tSettleDomain.serverItem},'%')
</if>
<if test="tSettleDomain.hasContainRisks != null and tSettleDomain.hasContainRisks.trim() != ''">
and a.HAS_CONTAIN_RISKS = #{tSettleDomain.hasContainRisks}
</if>
<if test="tSettleDomain.newLine != null and tSettleDomain.newLine.trim() != ''">
and a.NEW_LINE like concat('%',#{tSettleDomain.newLine},'%')
</if>
<if test="tSettleDomain.division != null and tSettleDomain.division.trim() != ''">
and a.DIVISION like concat('%',#{tSettleDomain.division},'%')
</if>
<if test="tSettleDomain.departName != null and tSettleDomain.departName.trim() != ''">
and a.DEPART_NAME like concat('%', #{tSettleDomain.departName} ,'%')
and a.DEPART_NAME like concat('%',#{tSettleDomain.departName} ,'%')
</if>
<if test="tSettleDomain.departNo != null and tSettleDomain.departNo.trim() != ''">
and a.DEPART_NO = #{tSettleDomain.departNo}
......@@ -316,7 +342,85 @@
<select id="getPagePerMission" resultMap="tSettleDomainMap">
SELECT
<include refid="Base_Column_List"/>
a.ID,
a.DEPART_NO,
a.DEPART_NAME,
a.IS_NEW,
a.NEW_REMARK,
a.DELETE_FLAG,
a.DP_AUDIT_FLAG,
a.OLD_ID,
a.BELONG_CONTRACT,
a.DP_AUDIT_OPINION,
a.DP_AUDIT_MAN,
a.DP_AUDIT_MAN_NAME,
a.LAST_AUDIT_DATE,
a.SERVER_ITEM,
a.INCOME_BELONG,
a.INCOME_BELONG_SUB,
a.CUSTOMER_ID,
a.CREATE_USER_NAME,
a.COMMIT_USER,
a.COMMIT_USER_NAME,
a.BALANCE,
a.INVOICE_BALANCE,
a.FIRST_PASS_FLAG,
a.FIRST_PASS_TIME,
a.PROVINCE,
a.CITY,
a.TOWN,
a.STOP_FLAG,
a.employee_num,
a.STOP_DATE,
a.STOP_REASON,
a.STOP_USER,
a.STOP_USER_NAME,
a.TYPE,
a.BUSINESS_PRIMARY_TYPE,
a.BUSINESS_SECOND_TYPE,
a.BUSINESS_THIRD_TYPE,
a.MANAGER_AUDIT_OPINION,
a.MANAGER_AUDIT_MAN,
a.MANAGER_AUDIT_MAN_NAME,
a.AUDIT_TIME,
a.MANAGER_AUDIT_TIME,
a.CREATE_TYPE,
a.RELATE_FLAG,
a.EXCEPTION_REMARK,
a.EXIST_ADVANCE_PAYMENT,
a.BACK_PAY_CYCLE,
a.CREATE_BY,
a.CREATE_NAME,
a.CREATE_TIME,
a.UPDATE_BY,
a.UPDATE_TIME,
a.SOCIAL_TYPE,
a.INSURANCE_SETTLE_TYPE,
a.CUSTOMER_NO,
a.CUSTOMER_NAME,
a.UNIT_OF_OUR_COMPANY,
a.INVOICE_TITLE_SALARY,
a.INVOICE_TITLE_INSURANCE,
a.FUND_TYPE,
a.MR_SETTLE_TYPE,
a.MANAGEMENT_TAG,
a.MANAGEMENT_FEE,
a.MANAGEMENT_TYPE,
a.RISK_FUND_TAG,
a.RISK_FUND_FEE,
a.RISK_FUND_TYPE,
a.MANAGE_SERVER_ITEM,
a.RISK_SERVER_ITEM,
a.UNIT_SERIOUS_ILLNESS_PROP,
a.BPO_FLAG,
a.BU_BELONG,
a.ISSUE_STATUS,
a.FIRST_INDICATOR_BELONG,
a.SECOND_INDICATOR_BELONG,
a.LINE_TYPE,
if(a.HAS_CONTAIN_RISKS = '是','0',if(a.HAS_CONTAIN_RISKS = '否','1','')) HAS_CONTAIN_RISKS,
a.NEW_LINE,
a.DIVISION
FROM
t_settle_domain a
<if test="userId != null and userId.trim() != '-999'">
......
package com.yifu.cloud.plus.v1.yifu.auth.config;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
import java.util.Collections;
/**
* Description: 允许跨域以
* CORS资源共享配置
*
* @author fxju
* @since JDK 1.8
*/
@Slf4j
@Configuration
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
//是否发送Cookie
.allowCredentials(true)
//放行哪些原始域
.allowedOriginPatterns("*")
.allowedMethods(new String[]{"GET", "POST", "PUT", "DELETE"})
.allowedHeaders("*")
.exposedHeaders("*");
}
public class CorsConfig {
@Bean
public FilterRegistrationBean filterRegistrationBean() {
CorsConfiguration corsConfiguration = new CorsConfiguration();
//1.允许任何来源
corsConfiguration.setAllowedOriginPatterns(Collections.singletonList("*"));
//2.允许任何请求头
corsConfiguration.addAllowedHeader(CorsConfiguration.ALL);
//3.允许任何方法
corsConfiguration.addAllowedMethod(CorsConfiguration.ALL);
//4.允许凭证
corsConfiguration.setAllowCredentials(true);
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", corsConfiguration);
CorsFilter corsFilter = new CorsFilter(source);
FilterRegistrationBean<CorsFilter> filterRegistrationBean=new FilterRegistrationBean<>(corsFilter);
// 前Spring Security 过滤器是通过 SecurityFilterAutoConfiguration 的 DelegatingFilterProxyRegistrationBean 注册到 servletContext上下文,其中过滤器的顺序属性 Order 读取的 是 SecurityProperties 的默认配置也就是 -100;
filterRegistrationBean.setOrder(-101); // 小于 SpringSecurity Filter的 Order(-100) 即可
return filterRegistrationBean;
}
}
......@@ -18,13 +18,17 @@ package com.yifu.cloud.plus.v1.yifu.auth.config;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.yifu.cloud.plus.v1.yifu.auth.filter.PasswordDecoderFilter;
import com.yifu.cloud.plus.v1.yifu.auth.filter.WxLoginAuthenticationFilter;
import com.yifu.cloud.plus.v1.yifu.auth.handler.YifuAuthenticationFailureHandlerImpl;
import com.yifu.cloud.plus.v1.yifu.auth.handler.YifuClientLoginSuccessHandler;
import com.yifu.cloud.plus.v1.yifu.auth.handler.YifuWxLoginSuccessHandler;
import com.yifu.cloud.plus.v1.yifu.common.security.component.CasAuthenticationProvider;
import com.yifu.cloud.plus.v1.yifu.common.security.component.WxAuthenticationProvider;
import com.yifu.cloud.plus.v1.yifu.common.security.component.YifuDaoAuthenticationProvider;
import com.yifu.cloud.plus.v1.yifu.common.security.grant.CustomAppAuthenticationProvider;
import com.yifu.cloud.plus.v1.yifu.common.security.handler.FormAuthenticationFailureHandler;
import com.yifu.cloud.plus.v1.yifu.common.security.handler.SsoLogoutSuccessHandler;
import com.yifu.cloud.plus.v1.yifu.common.security.service.WxUserDetailService;
import com.yifu.cloud.plus.v1.yifu.common.security.service.YifuUserDetailsServiceImpl;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
......@@ -67,7 +71,8 @@ public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
@Lazy
@Autowired
private AuthorizationServerTokenServices defaultAuthorizationServerTokenServices;
@Autowired
private WxUserDetailService wxUserDetailService;
@Autowired
private CacheManager cacheManager;
......@@ -81,11 +86,11 @@ public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
@SneakyThrows
protected void configure(HttpSecurity http) {
http.addFilterBefore(getPasswordDecoderFilter(),PasswordDecoderFilter.class)
.formLogin().loginPage("/token/login").loginProcessingUrl("/token/form")
.failureHandler(authenticationFailureHandler()).and().logout()
.logoutSuccessHandler(logoutSuccessHandler()).deleteCookies("JSESSIONID").invalidateHttpSession(true)
.and()
.authorizeRequests().antMatchers("/**/login","/token/**", "/actuator/**", "/mobile/**", "/oauth/token","/weixin/callback").permitAll()
//.formLogin().loginPage("/token/login").loginProcessingUrl("/token/form")
//.failureHandler(authenticationFailureHandler()).and().logout()
//.logoutSuccessHandler(logoutSuccessHandler()).deleteCookies("JSESSIONID").invalidateHttpSession(true)
//.and()
.authorizeRequests().antMatchers("/**/login","/token/**", "/actuator/**", "/mobile/**", "/oauth/token","/weixin/callback","/oauth/**", "/wxLogin").permitAll()
.anyRequest().authenticated().and().csrf().disable();
}
......@@ -103,8 +108,17 @@ public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
// 自定义的认证模式
auth.authenticationProvider(new CustomAppAuthenticationProvider());
auth.authenticationProvider(casAuthenticationProvider());
auth.authenticationProvider(wxAuthenticationProvider());
}
@Bean
public WxAuthenticationProvider wxAuthenticationProvider() {
WxAuthenticationProvider provider = new WxAuthenticationProvider();
// 设置userDetailsService
provider.setUserDetailsService(wxUserDetailService);
// 禁止隐藏用户未找到异常
provider.setHideUserNotFoundExceptions(false);
return provider;
}
@Bean
@Override
@SneakyThrows
......@@ -174,11 +188,38 @@ public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
return filter;
}
/**
* @param
* @Author: fxj
* @Date: 2025-01-10
* @Description: 微信登录
**/
@Bean
public WxLoginAuthenticationFilter wxLoginAuthenticationFilter() {
WxLoginAuthenticationFilter filter = new WxLoginAuthenticationFilter();
try {
filter.setAuthenticationManager(this.authenticationManagerBean());
} catch (Exception e) {
log.error("WebSecurityConfigurer>>>>",e);
}
filter.setAuthenticationSuccessHandler(authenticationSuccessHandler());
filter.setAuthenticationFailureHandler(yifuAuthenticationFailureHandler());
return filter;
}
private AuthenticationFailureHandler yifuAuthenticationFailureHandler() {
return YifuAuthenticationFailureHandlerImpl.builder()
.objectMapper(objectMapper).build();
}
private AuthenticationSuccessHandler authenticationSuccessHandler() {
return YifuWxLoginSuccessHandler.builder()
.objectMapper(objectMapper)
.clientDetailsService(clientDetailsService)
.passwordEncoder(passwordEncoder())
.cacheManager(cacheManager)
.tokenStore(tokenStore)
.defaultAuthorizationServerTokenServices(defaultAuthorizationServerTokenServices).build();
}
private AuthenticationSuccessHandler yifuClientLoginSuccessHandler() {
return YifuClientLoginSuccessHandler.builder()
.objectMapper(objectMapper)
......
package com.yifu.cloud.plus.v1.yifu.auth.filter;
import com.alibaba.fastjson.JSONObject;
import com.yifu.cloud.plus.v1.yifu.auth.config.WxConfig;
import com.yifu.cloud.plus.v1.yifu.common.core.constant.SecurityConstants;
import com.yifu.cloud.plus.v1.yifu.common.core.util.Common;
import com.yifu.cloud.plus.v1.yifu.common.security.token.WxAuthenticationToken;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AbstractAuthenticationToken;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.web.client.RestTemplate;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* @param
* @Author: wangan
* @Date: 2020/7/20
* @Description: 微信登录
* @return:
**/
@Slf4j
public class WxLoginAuthenticationFilter extends AbstractAuthenticationProcessingFilter {
private static final String SPRING_SECURITY_RESTFUL_LOGIN_URL = "/oauth/wxLogin";
private boolean postOnly = true;
private RestTemplate restTemplate = new RestTemplate();
@Autowired
private WxConfig wxConfig;
public WxLoginAuthenticationFilter() {
super(new AntPathRequestMatcher(SPRING_SECURITY_RESTFUL_LOGIN_URL, "POST"));
}
/**
*
* @Author pwang
* @Date 2021-07-23 16:37
* code 对应的code 必传
* cleintType 应用类型 非必传applets表示小程序不传调公众号号接口
* @return agentId 对应的agentId 非必传 不传查配置的默认应用信息(合同审批)
**/
@Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
if (postOnly && !request.getMethod().equals("POST")) {
throw new AuthenticationServiceException(
"Authentication method not supported: " + request.getMethod());
}
AbstractAuthenticationToken authRequest;
String code = obtainParameter(request, "code");
if (Common.isEmpty(code)) {
throw new AuthenticationServiceException("未获取到授权码:"+code);
}
// String result = restTemplate.getForObject(String.format(SecurityConstants.WX_GET_ACCOSS_TOKEN, wxConfig.getCorpid(), wxConfig.getCorpsecret()), String.class);
// if (Common.isEmpty(result)) {
// throw new AuthenticationServiceException("微信授权失败");
// }
// String access_token = JSONObject.parseObject(result).getString("access_token");
// if (Common.isEmpty(access_token)) {
// throw new AuthenticationServiceException("微信授权失败");
// }
String agentId = obtainParameter(request, "agentId");
String access_token = null;
if (Common.isNotNull(agentId)) {
//根据agentId确定corpsecret
access_token = wxConfig.getAccessToken(restTemplate,agentId);
}else{
//兼容老版本写法取默认的corpsecret
access_token = wxConfig.getAccessToken(restTemplate);
}
// log.info("access_token={}", access_token);
String cleintType = obtainParameter(request, "cleintType");
String userResult = null;
if(Common.isNotNull(cleintType)){
//指定应用类型按参数判断
if(cleintType.equals(SecurityConstants.WX_APPLETS_KEY)){
//小程序
userResult = restTemplate.getForObject(SecurityConstants.WX_APPLETS_GET_USER_ID, String.class, access_token, code);
}else{
throw new AuthenticationServiceException("无此应用类型");
}
}else{
//兼容老逻辑 查公众号接口
userResult = restTemplate.getForObject(SecurityConstants.WX_GET_USER_ID, String.class, access_token, code);
}
if (Common.isEmpty(userResult)) {
log.info(userResult);
throw new AuthenticationServiceException("获取企业微信用户失败");
}
//log.error(JSONObject.toJSONString(userResult));
JSONObject jsonObject = JSONObject.parseObject(userResult);
if (StringUtils.equals(wxConfig.getAccossTokenInvliad(), jsonObject.getString(wxConfig.getErrcode()))) {
wxConfig.removeAccessToken(agentId);
log.info(userResult);
throw new AuthenticationServiceException("无效的微信accoss_token");
}else if(!StringUtils.equals(wxConfig.getAccossTokenSuccess(), jsonObject.getString(wxConfig.getErrcode()))){
wxConfig.removeAccessToken(agentId);
log.info(userResult);
throw new AuthenticationServiceException("企业微信认证错误,企业微信返回错误码:"+jsonObject.getString(wxConfig.getErrcode())+"(错误码地址:https://work.weixin.qq.com/api/doc/90001/90148/90455)");
}
String UserId = null;
if(Common.isNotNull(cleintType)){
//指定应用类型按参数判断
if(cleintType.equals(SecurityConstants.WX_APPLETS_KEY)){
//小程序
UserId = jsonObject.getString("userid");
}else{
throw new AuthenticationServiceException("无此应用类型");
}
}else{
//兼容老逻辑 查公众号接口
UserId = jsonObject.getString("UserId");
}
if (Common.isEmpty(UserId)) {
throw new AuthenticationServiceException("微信用户匹配失败");
}
log.info("获取企业微信用户====UserId={}", UserId);
String principal;
String credentials = null;
String wxUserId = UserId; //企业微信账号
principal = wxUserId;
principal = principal.trim();
authRequest = new WxAuthenticationToken(principal, credentials);
// Allow subclasses to set the "details" property
setDetails(request, authRequest);
Authentication authenticate = this.getAuthenticationManager().authenticate(authRequest);
return authenticate;
}
private void setDetails(HttpServletRequest request,
AbstractAuthenticationToken authRequest) {
authRequest.setDetails(authenticationDetailsSource.buildDetails(request));
}
private String obtainParameter(HttpServletRequest request, String parameter) {
String result = request.getParameter(parameter);
return result == null ? "" : result;
}
}
// //企业微信登录
// String wxUserId="1111";
// principal = wxUserId;
// credentials = null;
// authRequest = new WxAuthenticationToken(principal, credentials);
//人力云调用企业微信进行网页授权
// String result = restTemplate.getForObject("https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=wwbcb090af0dfe50e5&corpsecret=R0nKkvsY-oF41fuQvUXZ-kFG3_g_Ce0bpZt6mByx524", String.class);
// if (Common.isEmpty(result)) {
// throw new AuthenticationServiceException("微信授权失败");
// }
// String access_token = JSONObject.parseObject(result).getString("access_token");
// if(Common.isEmpty(access_token)){
// throw new AuthenticationServiceException("微信授权失败");
// }
// String userResult = restTemplate.getForObject("https://qyapi.weixin.qq.com/cgi-bin/user/getuserinfo?access_token={ACCESS_TOKEN}&code=CODE", String.class, access_token);
//// if (Common.isEmpty(userResult)) {
//// throw new AuthenticationServiceException("获取企业微信用户失败");
//// }
//// String UserId = JSONObject.parseObject(userResult).getString("UserId");
// String UserId="1111";
// if(Common.isEmpty(UserId)){
// throw new AuthenticationServiceException("未查询到企业微信用户对应的hr系统用户");
// }
// R<SysUser> remoteSysUerR = remoteUserService.getSimpleUserByWxUserId(UserId, SecurityConstants.FROM_IN);
// if (remoteSysUerR == null) {
// throw new RuntimeException("调用用户服务失败");
// }
// if (CommonConstants.SUCCESS != remoteSysUerR.getCode()) {
// throw new RuntimeException("调用用户服务返回失败");
// }
// SysUser sysUser = remoteSysUerR.getData();
// if (sysUser == null) {
// throw new RuntimeException("未查询到用户信息");
// }
// //获取用户信息
// principal = sysUser.getUsername().trim();
// authRequest = new QrAuthenticationToken(principal, null);
//
// // Allow subclasses to set the "details" property
// setDetails(request, authRequest);
// return this.getAuthenticationManager().authenticate(authRequest);
......@@ -2,6 +2,7 @@ package com.yifu.cloud.plus.v1.yifu.auth.handler;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.http.HttpStatus;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.yifu.cloud.plus.v1.yifu.auth.constants.SecurityConstants;
......@@ -164,6 +165,7 @@ public class YifuClientLoginSuccessHandler implements AuthenticationSuccessHandl
private void backResult(HttpServletResponse response, R result) throws IOException {
response.setCharacterEncoding(CharsetUtil.UTF_8);
response.setContentType(CommonConstants.CONTENT_TYPE);
response.setStatus(HttpStatus.HTTP_OK);
PrintWriter printWriter = response.getWriter();
printWriter.append(objectMapper.writeValueAsString(result));
}
......
package com.yifu.cloud.plus.v1.yifu.auth.handler;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.http.HttpStatus;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.yifu.cloud.plus.v1.yifu.auth.constants.SecurityConstants;
import com.yifu.cloud.plus.v1.yifu.common.core.constant.CommonConstants;
import com.yifu.cloud.plus.v1.yifu.common.core.util.Common;
import com.yifu.cloud.plus.v1.yifu.common.core.util.R;
import com.yifu.cloud.plus.v1.yifu.common.core.util.WebUtils;
import com.yifu.cloud.plus.v1.yifu.common.core.vo.YifuUser;
import com.yifu.cloud.plus.v1.yifu.common.security.exception.InvalidException;
import com.yifu.cloud.plus.v1.yifu.common.security.util.AuthUtils;
import com.yifu.cloud.plus.v1.yifu.common.security.vo.UserAndToke;
import lombok.Builder;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.MarkerFactory;
import org.springframework.cache.CacheManager;
import org.springframework.http.HttpHeaders;
import org.springframework.security.core.Authentication;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.common.exceptions.InvalidClientException;
import org.springframework.security.oauth2.provider.*;
import org.springframework.security.oauth2.provider.request.DefaultOAuth2RequestValidator;
import org.springframework.security.oauth2.provider.token.AuthorizationServerTokenServices;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Map;
/**
* @author fxj * @date 2022年05月30日 14:55 @description
*/
@Slf4j
@Builder
public class YifuWxLoginSuccessHandler implements AuthenticationSuccessHandler {
private ObjectMapper objectMapper;
private PasswordEncoder passwordEncoder;
private ClientDetailsService clientDetailsService;
private AuthorizationServerTokenServices defaultAuthorizationServerTokenServices;
private TokenStore tokenStore;
private final CacheManager cacheManager;
@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
/*String header = request.getHeader(SecurityConstants.CLIENT_HEADER_KEY_NEW);
if(Common.isEmpty(header)){
header = request.getHeader(SecurityConstants.CLIENT_HEADER_KEY);
//兼容老逻辑
if(Common.isEmpty(header)){
header = request.getHeader(HttpHeaders.AUTHORIZATION);
}
}*/
YifuUser user = null;
try {
user = (YifuUser)authentication.getPrincipal();
/*if (header == null) {
throw new InvalidClientException("请求头中client信息为空");
}
String[] tokens = AuthUtils.extractAndDecodeHeader(header);
assert tokens.length == 2;
String clientId = tokens[0];
ClientDetails clientDetails = clientDetailsService.loadClientByClientId(clientId);
//校验secret
if (!passwordEncoder.matches(tokens[1], clientDetails.getClientSecret())) {
throw new InvalidClientException("请求头中client信息验证异常");
}*/
//TokenRequest tokenRequest = new TokenRequest(MapUtil.newHashMap(), clientId, clientDetails.getScope(), "password");
Collection<String> scope = new ArrayList<>();
scope.add("server");
TokenRequest tokenRequest = new TokenRequest(MapUtil.newHashMap(), "auth",scope, "password");
//校验scope
ClientDetails clientDetails = clientDetailsService.loadClientByClientId("auth");
new DefaultOAuth2RequestValidator().validateScope(tokenRequest, clientDetails);
OAuth2Request oAuth2Request = tokenRequest.createOAuth2Request(clientDetails);
OAuth2Authentication oAuth2Authentication = new OAuth2Authentication(oAuth2Request, authentication);
OAuth2AccessToken oAuth2AccessToken = null;
oAuth2AccessToken = defaultAuthorizationServerTokenServices.getAccessToken(oAuth2Authentication);
if(null == oAuth2AccessToken){
oAuth2AccessToken = defaultAuthorizationServerTokenServices.createAccessToken(oAuth2Authentication);
}else{
Map<String, Object> additionalInformation = clientDetails.getAdditionalInformation();
if(null != additionalInformation && null != additionalInformation.get(SecurityConstants.MUTUALLY_EXCLUSIVE_LOGIN)){
//单点刷新老的token生成新token
tokenStore.removeAccessToken(oAuth2AccessToken);
oAuth2AccessToken = defaultAuthorizationServerTokenServices.createAccessToken(oAuth2Authentication);
}
}
log.info("获取token 成功:{}", oAuth2AccessToken.getValue());
R<UserAndToke> result = new R<>(new UserAndToke(oAuth2AccessToken,user));
backResult(response, result);
} catch (Exception e) {
if (e instanceof InvalidException){
throw (InvalidException)e ;
}else if(e instanceof InvalidClientException){
String ip = WebUtils.getIP(request);
if( null != ip && !ip.startsWith("127") && !ip.startsWith("192.168")){
log.error(MarkerFactory.getMarker("MAIL"),"{}({})登录错误(触发黑名单逻辑)ip:{},头部信息为:{}",null==user?"":user.getUsername(),null==user?"":user.getUsername(),ip, JSONObject.toJSON(WebUtils.getHeadersInfo(request)));
}else{
log.error(MarkerFactory.getMarker("MAIL"),"{}({})登录错误ip:{},头部信息为:{}",null==user?"":user.getUsername(),null==user?"":user.getUsername(),ip, JSONObject.toJSON(WebUtils.getHeadersInfo(request)));
}
throw (InvalidClientException)e;
}else{
log.error(MarkerFactory.getMarker("MAIL"),"{}({})登录错误ip:{},头部信息为:{}",null==user?"":user.getUsername(),null==user?"":user.getUsername(),WebUtils.getIP(request), JSONObject.toJSON(WebUtils.getHeadersInfo(request)));
throw new InvalidException("未知异常请联系管理员!",e);
}
}
}
private void backResult(HttpServletResponse response, R result) throws IOException {
response.setCharacterEncoding(CharsetUtil.UTF_8);
response.setContentType(CommonConstants.CONTENT_TYPE);
response.setStatus(HttpStatus.HTTP_OK);
PrintWriter printWriter = response.getWriter();
printWriter.append(objectMapper.writeValueAsString(result));
}
}
......@@ -43,3 +43,8 @@ weixin:
redirectUri: https://www.ngrok.xiaomiqiu.cn/admin/hi
errorUri: /error
callbackUri: https://www.ngrok.xiaomiqiu.cn/oauth/weixin/callback
wx:
corpid: wwbcb090af0dfe50e5
corpsecret: 16kqEL_eU-ARwYyqLgEBWHgxm8gXVnkzv_eJMLy9NpU
agentid: 1000010
authUrl: https://test-wx.worfu.com/yifu-auth/method/oauth/wxLogin
......@@ -37,3 +37,8 @@ spring:
prefer-file-system-access: true
suffix: .ftl
template-loader-path: classpath:/templates/
wx:
corpid: wwbcb090af0dfe50e5
corpsecret: R0nKkvsY-oF41fuQvUXZ-kFG3_g_Ce0bpZt6mByx524
agentid: 1000009
authUrl: https://wx.worfu.com/yifu-auth/method/oauth/wxLogin
\ No newline at end of file
......@@ -48,4 +48,10 @@ spring:
expose-spring-macro-helpers: true
prefer-file-system-access: true
suffix: .ftl
template-loader-path: classpath:/templates/
\ No newline at end of file
template-loader-path: classpath:/templates/
wx:
corpid: wwbcb090af0dfe50e5
corpsecret: 16kqEL_eU-ARwYyqLgEBWHgxm8gXVnkzv_eJMLy9NpU
agentid: 1000010
authUrl: https://test-wx.worfu.com/yifu-auth/method/oauth/wxLogin
\ No newline at end of file
......@@ -108,7 +108,7 @@
</springProfile>
<springProfile name="test">
<!-- Level: FATAL 0 ERROR 3 WARN 4 INFO 6 DEBUG 7 -->
<root level="error">
<root level="debug">
<appender-ref ref="console"/>
<appender-ref ref="debug"/>
<appender-ref ref="error"/>
......
......@@ -42,5 +42,6 @@
<module>yifu-common-swagger</module>
<module>yifu-common-ldap</module>
<module>yifu-common-ekp</module>
<module>yifu-common-process</module>
</modules>
</project>
......@@ -102,6 +102,10 @@ public interface CacheConstants {
**/
String EVERYDAY_SALARY_FORM_CODE = "everyday_salary_form_code";
String EVERYDAY_UNBUY_FORM_CODE = "everyday_unbuy_form_code";
String EVERYDAY_UNBUYINFO_FORM_CODE = "everyday_unbuyinfo_form_code";
/**
* @Description: 派单申请编码
* @Author: fxj
......@@ -178,6 +182,8 @@ public interface CacheConstants {
String EMP_ADD_LOCK ="emp_add_lock";
String UNBUY_ADD_LOCK ="unbuy_add_lock";
String SALARY_ACCOUNT_EXPORT_LOCK ="salary_account_export_lock";
String SALARY_ACCOUNT_AUDIT_EXPORT_LOCK ="salary_account_audit_export_lock";
......@@ -200,4 +206,9 @@ public interface CacheConstants {
* C端发验证码前缀
*/
public static final String MVP_TOC_PHONE_CODE_PREFIX = "MVP_TOC_PHONE_CODE_";
public static final String WX_JSAPI_TICKET = "WX_JSAPI_TICKET";
// 商险不购买审批流分布式锁key InsuranceUnpurchase
public static final String INSURANCEUNPURCHASE_PROCESS_CACHE = ServiceNameConstants.SERVICE_NAME_MVP + "_" + "ProcessCache:InsuranceUnpurchase";
}
......@@ -343,6 +343,8 @@ public interface CommonConstants {
String NO_DATA_TO_HANDLE = "无数据可操作!";
String DATA_TOO_LARGER_FOR_DOWN = "下载数据超出100M,请重新选择下载条件!";
String PLEASE_LOG_IN = "请登录!";
String SEX_MAN = "1";
......@@ -368,6 +370,8 @@ public interface CommonConstants {
String ID = "ID";
String PARAM_IS_NOT_ERROR = "传参异常,请检查参数";
int EXCEL_EXPORT_LIMIT = 60000;
int EXCEL_EXPORT_LIMIT_NEW = 20000;
// 给量大的表导出使用
int EXCEL_EXPORT_LIMIT_3 = 30000;
......@@ -632,6 +636,22 @@ public interface CommonConstants {
List<String> socialInfoStatus = Stream.of("1","3","5","7").collect(Collectors.toList());
List<String> deptList = Stream.of("安徽一册档案管理有限公司","安徽顾合企业管理咨询有限公司","安徽赤道线数字传媒科技有限公司","劳务业务中心","易服智享&研究院").collect(Collectors.toList());
String USER_DIR = "user.dir";
String DOUBLE_LINE = "//";
public static final int THIRTY_INT = 30;
public static final int TWENTY_SEVEN_INT = 27;
/**
*未删除标志
**/
public static final String NOT_DELETE_FLAG = "0";
/**
*已删除标志
**/
public static final String DELETE_FLAG = "1";
//单条数据检索SQL
public static final String SQL_LIMIT_ONE = " limit 1 ";
}
......@@ -22,6 +22,8 @@ public class ResultConstants {
public static final String NO_GETLOCK_DATA = "当前用户操作处理中,请稍后重试!";
public static final String NO_GETLOCK_DATA_SEARCH = "多用户同时请求中,请稍后重试!";
public static final String NO_UNBUY_GETLOCK_DATA = "当前项目编码和不购买类型的数据处理中,请稍后重试!";
public static final String NO_ID = "操作失败,id不能为空!";
public static final String FILE_UPLOADING_DATA = "附件排队上传中,请稍后重试!";
public static final String FILE_DOWN_LOAD_DATA = "导出排队下载中,请稍后重试!";
......
......@@ -147,8 +147,9 @@ public interface SecurityConstants {
* @Description: 企业微信发送消息授权路径
* @return:
* 下面链接中的state参数是和前端进行交互区分的重要参数,如果新增,请不要和以前的前缀相同
* 1,2,3,4 前缀为合同审批待处理、抄送和垫付审批中的待处理、抄送。 5 前缀为突发事件待处理页面的标识
* 1=垫付审批待处理,2=垫付审批抄送,3=合同审批待处理,4=合同审批抄送,5=事件审批待处理
* 第一位标识消息类型:0审批,1抄送
* 第二位标识实体标识:1不购买商险申请
* 01 : 不购买商险申请审批
**/
String WX_GET_MESSAGE_AUTH_URL = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=%s&redirect_uri=%s&response_type=code&scope=snsapi_base&state=%s#wechat_redirect";
......@@ -157,4 +158,42 @@ public interface SecurityConstants {
// 获取审核详情
String WX_GET_APPROVAL_DETAIL = "https://qyapi.weixin.qq.com/cgi-bin/oa/getapprovaldetail?access_token={1}";
/**
* @Author: wangan
* @Date: 2020/7/29
* @Description: 企业微信获取企业的jsapi_ticket 用于签名
* @return:
**/
String WX_JSAPI_TICKET_URL = "https://qyapi.weixin.qq.com/cgi-bin/get_jsapi_ticket?access_token=%s";
/**
* @Author: wangdayu
* @Date: 2024/3/25
* @Description: 判断是否在应用可见范围内
* @return:
**/
String WX_IS_IN_VISIBLE_RANGE= "https://qyapi.weixin.qq.com/cgi-bin/user/get?access_token=%s&userid=%s";
/**
* 微信小程序
* @Author pwang
* @Date 2021-07-23 16:33
* @param null
* @return
**/
String WX_APPLETS_KEY = "applets";
/**
* @Author: pwang
* @Date: 2021/7/23
* @Description: 企业微信小程序获取用户userId
* @return:
**/
String WX_APPLETS_GET_USER_ID = "https://qyapi.weixin.qq.com/cgi-bin/miniprogram/jscode2session?access_token={1}&js_code={2}&grant_type=authorization_code";
/**
* @Author: wangan
* @Date: 2020/7/29
* @Description: 企业微信获取用户userId
* @return:
**/
String WX_GET_USER_ID = "https://qyapi.weixin.qq.com/cgi-bin/user/getuserinfo?access_token={1}&code={2}";
}
......@@ -50,4 +50,6 @@ public interface ServiceNameConstants {
* hr b端Client id
**/
String CLIENT_ID_HR_B = "hrCustomer";
String SERVICE_NAME_MVP = "mvp";
}
......@@ -93,6 +93,37 @@ public class Common {
return false;
}
/**
* 集合不为空
*
* @param collection
* @return
*/
public static boolean isNotKong(Collection collection) {
return null != collection && collection.size() > 0;
}
/**
* obj不是null
*
* @param obj
* @return
* @author: fxj
*/
public static boolean isNotKong(Object obj) {
return null != obj;
}
/**
* 集合为空
*
* @param collection
* @return
*/
public static boolean isEmpty(Collection collection) {
return null == collection || collection.size() == 0;
}
// 金额验证
public static boolean isNumber(String str) {
// 判断小数点后2位的数字的正则表达式
......
package com.yifu.cloud.plus.v1.yifu.common.core.util;
import sun.misc.BASE64Encoder;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
/**
* 采用MD5加密
*
* @author shixc
* @datetime 2016-04-12
*/
public class EncryptUtil {
/***
* MD5加密 生成32位md5码
* @param inStr 待加密字符串
* @return 返回32位md5码
* @throws UnsupportedEncodingException
*/
public static String md5Encode(String inStr) throws UnsupportedEncodingException {
MessageDigest md5 = null;
try {
md5 = MessageDigest.getInstance("MD5");
} catch (Exception e) {
System.out.println(e.toString());
e.printStackTrace();
return "";
}
byte[] byteArray = inStr.getBytes("UTF-8");
byte[] md5Bytes = md5.digest(byteArray);
StringBuffer hexValue = new StringBuffer();
for (int i = 0; i < md5Bytes.length; i++) {
int val = ((int) md5Bytes[i]) & 0xff;
if (val < 16) {
hexValue.append("0");
}
hexValue.append(Integer.toHexString(val));
}
return hexValue.toString();
}
public static String base64Encoder(String src) throws UnsupportedEncodingException {
BASE64Encoder encoder = new BASE64Encoder();
return encoder.encode(src.getBytes("UTF-8"));
}
/**
* 测试主函数
*
* @param args
* @throws Exception
*/
public static void main(String args[]) throws Exception {
String str = new String("");
System.out.println("原始:" + str);
System.out.println("MD5后:" + md5Encode(str));
}
/**
* @param str
* @Author: wangan
* @Date: 2020/7/29
* @Description: sha1加密
* @return: java.lang.String
**/
public static String getSha1(String str) {
if (str == null || str.length() == 0) {
return null;
}
char hexDigits[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
try {
MessageDigest mdTemp = MessageDigest.getInstance("SHA1");
mdTemp.update(str.getBytes("UTF-8"));
byte[] md = mdTemp.digest();
int j = md.length;
char buf[] = new char[j * 2];
int k = 0;
for (int i = 0; i < j; i++) {
byte byte0 = md[i];
buf[k++] = hexDigits[byte0 >>> 4 & 0xf];
buf[k++] = hexDigits[byte0 & 0xf];
}
return new String(buf);
} catch (Exception e) {
return null;
}
}
}
package com.yifu.cloud.plus.v1.yifu.common.core.util.bean;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeanWrapper;
import org.springframework.beans.BeanWrapperImpl;
import java.util.HashSet;
import java.util.Set;
/**
* @auther wangan
* @date 2019/12/3
* bean复制,忽视空串
*/
public class BeanCopyUtils {
public static String[] getNullPropertyNames(Object source) {
final BeanWrapper src = new BeanWrapperImpl(source);
java.beans.PropertyDescriptor[] pds = src.getPropertyDescriptors();
Set<String> emptyNames = new HashSet<>();
for (java.beans.PropertyDescriptor pd : pds) {
Object srcValue = src.getPropertyValue(pd.getName());
if (srcValue == null) {
emptyNames.add(pd.getName());
}
}
String[] result = new String[emptyNames.size()];
return emptyNames.toArray(result);
}
public static void copyProperties(Object src, Object target) {
BeanUtils.copyProperties(src, target, getNullPropertyNames(src));
}
}
......@@ -62,6 +62,18 @@
<version>1.0.0</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.yifu.cloud.plus.v1</groupId>
<artifactId>yifu-process-api</artifactId>
<version>1.0.0</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.yifu.cloud.plus.v1</groupId>
<artifactId>yifu-common-process</artifactId>
<version>1.0.0</version>
<scope>compile</scope>
</dependency>
</dependencies>
<properties>
......@@ -69,4 +81,4 @@
<maven.compiler.target>8</maven.compiler.target>
</properties>
</project>
\ No newline at end of file
</project>
package com.yifu.cloud.plus.v1.yifu.common.dapr.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;
/**
* @author chenyuxi
* @date 2025/01/09
* @version 1.7.5
*/
@Data
@Component
@PropertySource("classpath:daprConfig.properties")
@ConfigurationProperties(value = "dapr.process", ignoreInvalidFields = false)
public class DaprProcessProperties {
String appUrl;
String appId;
String appPort;
String httpPort;
String grpcPort;
String metricsPort;
}
......@@ -13,6 +13,7 @@ import com.yifu.cloud.plus.v1.yifu.common.core.util.Common;
import com.yifu.cloud.plus.v1.yifu.common.core.util.R;
import com.yifu.cloud.plus.v1.yifu.common.core.vo.YifuUser;
import com.yifu.cloud.plus.v1.yifu.common.dapr.config.DaprArchivesProperties;
import com.yifu.cloud.plus.v1.yifu.salary.vo.TInsuranceUnpurchasePersonCardVo;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
......@@ -506,4 +507,15 @@ public class ArchivesDaprUtil {
}
return res;
}
/**
* @Author huyc
* @Description 判断是否存在正常的项目
* @Date 16:38 2025/1/15
* @Param
* @return
**/
public R<Boolean> selectExitEmpProject(TInsuranceUnpurchasePersonCardVo cardVo) {
return HttpDaprUtil.invokeMethodPost(daprArchivesProperties.getAppUrl(),daprArchivesProperties.getAppId(),"/temployeeproject/inner/selectExitEmpProject", JSON.toJSONString(cardVo), Boolean.class, SecurityConstants.FROM_IN);
}
}
......@@ -103,4 +103,14 @@ public class EkpDaprUtils {
public R<EkpSocialPushInfoVo> jobpushRiskInfoToEkp(List<EkpIncomeParamRisk> incomeParam) {
return HttpDaprUtil.invokeMethodPost(daprProperties.getAppUrl(),daprProperties.getAppId(),"/ekpriskinfo/inner/jobPushRiskInfoToEkp", JSON.toJSONString(incomeParam), EkpSocialPushInfoVo.class, SecurityConstants.FROM_IN);
}
/**
* 根据事业部配置条件查找用户账号
* @author chenyuxi
* @date 2025/1/15
* @since 1.7.5
*/
public R<EkpDivisionInfoVo> getDivisionUsernameList(EkpDivisionInfoVo divisionInfoVo) {
return HttpDaprUtil.invokeMethodPost(daprProperties.getAppUrl(),daprProperties.getAppId(),"/ekpShenhepeizhi/inner/getDivisionUsernameList",divisionInfoVo, EkpDivisionInfoVo.class, SecurityConstants.FROM_IN);
}
}
package com.yifu.cloud.plus.v1.yifu.common.dapr.util;
import com.yifu.cloud.plus.v1.yifu.common.core.constant.SecurityConstants;
import com.yifu.cloud.plus.v1.yifu.common.core.util.Common;
import com.yifu.cloud.plus.v1.yifu.common.core.util.R;
import com.yifu.cloud.plus.v1.yifu.common.dapr.config.DaprProcessProperties;
import com.yifu.cloud.plus.v1.yifu.process.vo.ProcessVo;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
/**
* 流程
* @author chenyuxi
* @date 2025-01-10 17:47:32
* @since 1.7.5
*/
@Log4j2
@EnableConfigurationProperties(DaprProcessProperties.class)
public class ProcessDaprUtils {
@Autowired
private DaprProcessProperties daprProcessProperties;
/**
* 根据流程类型查询ProcessVo
* @param processType 流程类型
* @return R<ProcessVo>
* @since mvp1.7.5
**/
public R<ProcessVo> getProcessVoByType(String processType) {
R<ProcessVo> processVoR = HttpDaprUtil.invokeMethodPost(daprProcessProperties.getAppUrl(),daprProcessProperties.getAppId(),"/tprocess/inner/getProcessVoByType", processType, ProcessVo.class, SecurityConstants.FROM_IN);
if (Common.isEmpty(processVoR)){
return R.failed("根据流程类型查询ProcessVo失败!");
}
return processVoR;
}
/**
* 根据流程Id查询ProcessVo
* @param processId 流程ID
* @return R<ProcessVo>
* @since mvp1.7.5
**/
public R<ProcessVo> getProcessVoById(String processId) {
R<ProcessVo> processVoR = HttpDaprUtil.invokeMethodPost(daprProcessProperties.getAppUrl(),daprProcessProperties.getAppId(),"/tprocess/inner/getProcessVoByProcessId", processId, ProcessVo.class, SecurityConstants.FROM_IN);
if (Common.isEmpty(processVoR)){
return R.failed("根据流程ID查询ProcessVo失败!");
}
return processVoR;
}
}
......@@ -7,10 +7,7 @@ import com.yifu.cloud.plus.v1.yifu.common.core.util.R;
import com.yifu.cloud.plus.v1.yifu.common.dapr.config.DaprSocialProperties;
import com.yifu.cloud.plus.v1.yifu.insurances.vo.EkpInsuranceViewVo;
import com.yifu.cloud.plus.v1.yifu.insurances.vo.EkpSocialViewVo;
import com.yifu.cloud.plus.v1.yifu.salary.vo.HaveSalaryNoSocialSearchVo;
import com.yifu.cloud.plus.v1.yifu.salary.vo.HaveSalaryNoSocialVo;
import com.yifu.cloud.plus.v1.yifu.salary.vo.TPaymentVo;
import com.yifu.cloud.plus.v1.yifu.salary.vo.UpdateSocialFoundVo;
import com.yifu.cloud.plus.v1.yifu.salary.vo.*;
import com.yifu.cloud.plus.v1.yifu.social.entity.TIncomeDetail;
import com.yifu.cloud.plus.v1.yifu.social.entity.TPaymentInfo;
import com.yifu.cloud.plus.v1.yifu.social.vo.TIncomeDetailReturnVo;
......@@ -157,4 +154,27 @@ public class SocialDaprUtils {
public R<Boolean> updateIncomeSettleStatus(List<EkpInsuranceViewVo> infoVo) {
return HttpDaprUtil.invokeMethodPost(daprProperties.getAppUrl(),daprProperties.getAppId(),"/tincome/inner/updateIncomeSettleStatus", JSON.toJSONString(infoVo), Boolean.class, SecurityConstants.FROM_IN);
}
/**
* @Author huyc
* @Description 判断是否存在正常的工伤缴费
* @Date 16:38 2025/1/15
* @Param
* @return
**/
public R<Boolean> selectExitSocialInjury(TInsuranceUnpurchasePersonCardVo cardVo) {
return HttpDaprUtil.invokeMethodPost(daprProperties.getAppUrl(),daprProperties.getAppId(),"/tsocialfundinfo/inner/selectExitSocialInjury", JSON.toJSONString(cardVo), Boolean.class, SecurityConstants.FROM_IN);
}
/**
* @Description: 查询社保已购买的身份证
* @Author: hgw
* @Date: 2025/1/15 16:11
* @return: com.yifu.cloud.plus.v1.yifu.common.core.util.R<java.lang.Boolean>
**/
public R<ListStringVo> selectWorkInjuryHandleAll() {
return HttpDaprUtil.invokeMethodPost(daprProperties.getAppUrl(),daprProperties.getAppId()
,"/tsocialfundinfo/inner/selectWorkInjuryHandleAll", null, ListStringVo.class, SecurityConstants.FROM_IN);
}
}
package com.yifu.cloud.plus.v1.yifu.common.dapr.util;
import com.yifu.cloud.plus.v1.yifu.admin.api.entity.SysUser;
import com.yifu.cloud.plus.v1.yifu.admin.api.vo.AllUserNaVo;
import com.yifu.cloud.plus.v1.yifu.admin.api.vo.AreaMap;
import com.yifu.cloud.plus.v1.yifu.admin.api.vo.AreaVo;
import com.yifu.cloud.plus.v1.yifu.admin.api.vo.SysUserListVo;
import com.yifu.cloud.plus.v1.yifu.admin.api.vo.*;
import com.yifu.cloud.plus.v1.yifu.common.core.constant.SecurityConstants;
import com.yifu.cloud.plus.v1.yifu.common.core.util.Common;
import com.yifu.cloud.plus.v1.yifu.common.core.util.R;
......@@ -113,4 +110,23 @@ public class UpmsDaprUtils {
}
return userR;
}
public R<SysUserListVo> getUserByRoleIdForCrm(UserApprovalRoleVO userByApprovalRole) {
R<SysUserListVo> allUserVoR = HttpDaprUtil.invokeMethodPost(daprUpmsProperties.getAppUrl(),daprUpmsProperties.getAppId(),"/user/inner/getUser/getUserByRoleIdForCrm",userByApprovalRole, SysUserListVo.class, SecurityConstants.FROM_IN);
if (Common.isEmpty(allUserVoR)){
return R.failed("查询流程配置审批角色对应的审批人失败!");
}
return allUserVoR;
}
/**
* @Author huyc
* @Description 判断部门是否属于分公司
* @Date 10:38 2025/1/20
* @Param
* @return
**/
public R<Boolean> selectExitDeptCompany(String deptId) {
return HttpDaprUtil.invokeMethodPost(daprUpmsProperties.getAppUrl(),daprUpmsProperties.getAppId(),"/user/inner/selectExitDeptCompany", deptId, Boolean.class, SecurityConstants.FROM_IN);
}
}
......@@ -7,4 +7,5 @@ org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.yifu.cloud.plus.v1.yifu.common.dapr.util.InsuranceDaprUtil,\
com.yifu.cloud.plus.v1.yifu.common.dapr.util.SalaryDaprUtil,\
com.yifu.cloud.plus.v1.yifu.common.dapr.util.EkpDaprUtils,\
com.yifu.cloud.plus.v1.yifu.common.dapr.util.PermissionDaprUtil
com.yifu.cloud.plus.v1.yifu.common.dapr.util.PermissionDaprUtil,\
com.yifu.cloud.plus.v1.yifu.common.dapr.util.ProcessDaprUtils
......@@ -34,4 +34,7 @@ dapr.permission.appId=yifu-permission
#\u751F\u4EA7
dapr.ekp.appUrl=http://127.0.0.1:3500/v1.0/invoke/
dapr.ekp.appId=yifu-ekp
\ No newline at end of file
dapr.ekp.appId=yifu-ekp
dapr.process.appUrl=http://127.0.0.1:3500/v1.0/invoke/
dapr.process.appId=yifu-process
package com.yifu.cloud.plus.v1.yifu.ekp.vo;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
/**
* @Author chenyuxi
* @Date 2022-8-31 12:02:06
* @Description 事业部审批配置
* @Version 1.0
*/
@Data
public class EkpDivisionInfoVo implements Serializable {
private String newLine;
private String division;
// 指定事业部配置表负责人标识:0事业部条线负责人;1事业部负责人;2分管副总
private String divisionIdentification;
/**
* 查事业部审批人账号列表
**/
private List<String> divisionUsernameList;
}
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.yifu.cloud.plus.v1</groupId>
<artifactId>yifu-common</artifactId>
<version>1.0.0</version>
</parent>
<artifactId>yifu-common-process</artifactId>
<packaging>jar</packaging>
<description>审批流程-工具类</description>
<dependencies>
<!-- core 工具类 -->
<dependency>
<groupId>com.yifu.cloud.plus.v1</groupId>
<artifactId>yifu-common-core</artifactId>
</dependency>
<!--UPMS API-->
<dependency>
<groupId>com.yifu.cloud.plus.v1</groupId>
<artifactId>yifu-upms-api</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot</artifactId>
</dependency>
<!--swagger 注解-->
<dependency>
<groupId>io.swagger.core.v3</groupId>
<artifactId>swagger-annotations</artifactId>
</dependency>
<!--mybatis 依赖-->
<dependency>
<groupId>com.yifu.cloud.plus.v1</groupId>
<artifactId>yifu-common-mybatis</artifactId>
</dependency>
<!-- 编译表达式 -->
<dependency>
<groupId>com.googlecode.aviator</groupId>
<artifactId>aviator</artifactId>
<version>2.0</version>
</dependency>
</dependencies>
</project>
package com.yifu.cloud.plus.v1.yifu.process.constant;
/**
* @author chenyuxi
* @since 1.7.5
*/
public class ProcessConstants {
//审批中心各个节点类型
public static final String PROCESS_NODE_TYPE_CHOICE = "choice";
public static final String PROCESS_NODE_BEGIN = "begin";
public static final String PROCESS_NODE_END = "end";
public static final String PROCESS_NODE_EMBED = "embed";
public static final String PROCESS_NODE_SERVICE = "service";
// 【含风险项目商险不购买申请流程】条件判断审批节点名称
public static final String PROCESS_NODE_INSURANCEUNPURCHASE_REASON_TYPE = "是否为已购买社保";
public static final String PROCESS_NODE_INSURANCEUNPURCHASE_DEPT_PROPERTY = "是否属于子分公司";
}
package com.yifu.cloud.plus.v1.yifu.process.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.extension.activerecord.Model;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.hibernate.validator.constraints.Length;
import javax.validation.constraints.NotBlank;
/**
* 流程处理权限表(允许多个,多个代表有主办和经办)
*
* @author hgw
* @date 2020-07-16 15:44:02
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("t_node_primission")
@Schema(description = "流程处理权限表(允许多个,多个代表有主办和经办)")
public class TNodePrimission extends Model<TNodePrimission> {
private static final long serialVersionUID = 1L;
@TableId(type = IdType.ASSIGN_ID)
@Schema(description = "主键")
private String id;
@Length(max = 255, message = "指定用户处理节点不能超过255个字符")
@Schema(description = "指定用户处理节点")
private String user;
@Length(max = 255, message = "指定权限处理节点不能超过255个字符")
@Schema(description = "指定权限处理节点")
private String role;
@Length(max = 255, message = "指定职位处理节点不能超过255个字符")
@Schema(description = "指定职位处理节点")
private String post;
@Length(max = 255, message = "指定组织处理节点不能超过255个字符")
@Schema(description = "指定组织处理节点")
private String organization;
@NotBlank(message = "与流程申请人关系(0发起人部门主管/1同区域最高级/2所在单位最高级)不能为空")
@Length(max = 1, message = "与流程申请人关系(0发起人部门主管/1同区域最高级/2所在单位最高级)不能超过1个字符")
@Schema(description = "与流程申请人关系(0发起人部门主管/1同区域最高级/2所在单位最高级)")
private String realationCreateUser;
@NotBlank(message = "标识(系统自动生成MD5串)不能为空")
@Length(max = 255, message = "标识(系统自动生成MD5串)不能超过255个字符")
@Schema(description = "标识(系统自动生成MD5串)")
private String logoTitle;
@NotBlank(message = "节点ID不能为空")
@Length(max = 255, message = "节点ID不能超过255个字符")
@Schema(description = "节点ID")
private String nodeId;
@NotBlank(message = "办理类型(0主办/1经办;如果为经办,则必须有主办权限存在)不能为空")
@Length(max = 1, message = "办理类型(0主办/1经办;如果为经办,则必须有主办权限存在)不能超过1个字符")
@Schema(description = "办理类型(0主办/1经办;如果为经办,则必须有主办权限存在)")
private String dealType;
@NotBlank(message = "流程ID不能为空")
@Length(max = 255, message = "流程ID不能超过255个字符")
@Schema(description = "流程ID")
private String processId;
@NotBlank(message = "节点编码不能为空")
@Length(max = 255, message = "节点编码不能超过255个字符")
@Schema(description = "节点编码-关联节点")
private String nodeLogoTitle;
@Length(max = 1, message = "类型:不能超过1个字符")
@Schema(description = "类型:0指定职位;1与申请人关系;2指定权限;3指定用户;4指定组织;5指定角色(crm);6指定事业部配置表")
private Integer type;
@Length(max = 20, message = "指定角色id不能超过20个字符")
@Schema(description = "指定角色id")
private String approvalRole;
@Length(max = 10, message = "指定事业部配置表负责人标识不能超过10个字符")
@Schema(description = "指定事业部配置表负责人标识(0事业部条线负责人;1事业部负责人;2分管副总)")
private String divisionIdentification;
@Length(max = 1, message = "是否允许直接通过不能超过1个字符")
@Schema(description = "是否允许直接通过(0:不允许,1允许)")
private String isPass;
}
package com.yifu.cloud.plus.v1.yifu.process.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.extension.activerecord.Model;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.hibernate.validator.constraints.Length;
import javax.validation.constraints.NotBlank;
/**
* 流程审阅权限表(抄送/仅有查看权限)
*
* @author hgw
* @date 2020-07-16 15:44:02
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("t_node_reader_promission")
@Schema(description = "流程审阅权限表(抄送/仅有查看权限)")
public class TNodeReaderPromission extends Model<TNodeReaderPromission> {
private static final long serialVersionUID = 1L;
@TableId(type = IdType.ASSIGN_ID)
@Schema(description = "主键")
private String id;
@Length(max = 255, message = "指定用户处理节点不能超过255个字符")
@Schema(description = "指定用户处理节点")
private String user;
@Length(max = 255, message = "指定权限处理节点不能超过255个字符")
@Schema(description = "指定权限处理节点")
private String role;
@Length(max = 255, message = "指定职位处理节点不能超过255个字符")
@Schema(description = "指定职位处理节点")
private String post;
@Length(max = 255, message = "指定组织处理节点不能超过255个字符")
@Schema(description = "指定组织处理节点")
private String organization;
@NotBlank(message = "与流程申请人关系(0上级/1同区域最高级/2同部门最高级)不能为空")
@Length(max = 1, message = "与流程申请人关系(0上级/1同区域最高级/2同部门最高级)不能超过1个字符")
@Schema(description = "与流程申请人关系(0上级/1同区域最高级/2同部门最高级)")
private String realationCreateUser;
@NotBlank(message = "标识(系统自动生成MD5串)不能为空")
@Length(max = 255, message = "标识(系统自动生成MD5串)不能超过255个字符")
@Schema(description = "标识(系统自动生成MD5串)")
private String logoTitle;
@NotBlank(message = "节点ID不能为空")
@Length(max = 255, message = "节点ID不能超过255个字符")
@Schema(description = "节点ID")
private String nodeId;
@NotBlank(message = "流程ID不能为空")
@Length(max = 255, message = "流程ID不能超过255个字符")
@Schema(description = "流程ID")
private String processId;
@NotBlank(message = "节点编码不能为空")
@Length(max = 255, message = "节点编码不能超过255个字符")
@Schema(description = "节点编码")
private String nodeLogoTitle;
@Length(max = 1, message = "类型:不能超过1个字符")
@Schema(description = "类型:0指定职位;1与申请人关系;2指定权限;3指定用户;4指定组织;5指定角色(crm)")
private Integer type;
@Length(max = 20, message = "指定角色id不能超过20个字符")
@Schema(description = "指定角色id")
private String approvalRole;
@Length(max = 20, message = "指定使用的代码自定义判断的标识字段不能超过20个字符")
@Schema(description = "指定使用的代码自定义判断的标识字段")
private String customizeField;
@Schema(description = "是否代码自定义")
private String isCustomize;
}
package com.yifu.cloud.plus.v1.yifu.process.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.extension.activerecord.Model;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.hibernate.validator.constraints.Length;
import javax.validation.constraints.NotBlank;
import java.time.LocalDateTime;
import java.util.List;
/**
* 流程路由表(节点与节点之间的路由关系)
*
* @author hgw
* @date 2020-07-16 15:44:02
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("t_node_route")
@Schema(description = "流程路由表(节点与节点之间的路由关系)")
public class TNodeRoute extends Model<TNodeRoute> {
private static final long serialVersionUID = 1L;
@TableId(type = IdType.ASSIGN_ID)
@Schema(description = "主键")
private String id;
@NotBlank(message = "流程ID不能为空")
@Length(max = 255, message = "流程ID不能超过255个字符")
@Schema(description = "流程ID")
private String processId;
@Length(max = 255, message = "前置节点不能超过255个字符")
@Schema(description = "前置节点")
private String prewNode;
@NotBlank(message = "下个节点不能为空")
@Length(max = 255, message = "下个节点不能超过255个字符")
@Schema(description = "下个节点")
private String nextNode;
@Length(max = 1, message = "连线起点位置不能超过1个字符")
@Schema(description = "连线起点位置")
private String preNodeAnchor;
@Length(max = 1, message = "连线终点位置不能超过1个字符")
@Schema(description = "连线终点位置")
private String nextNodeAnchor;
@Length(max = 100, message = "元素的图形:不能超过100个字符")
@Schema(description = "元素的图形")
private String shape;
@Length(max = 255, message = "标识(系统自动生成MD5串)不能超过255个字符")
@Schema(description = "标识(系统自动生成MD5串)")
private String logoTitle;
@NotBlank(message = "创建人不能为空")
@Length(max = 255, message = "创建人不能超过255个字符")
@Schema(description = "创建人")
private String createUser;
@Schema(description = "创建时间")
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern="yyyy-MM-dd HH:mm:ss")
private LocalDateTime createDate;
@Length(max = 255, message = "更新人不能超过255个字符")
@Schema(description = "更新人")
private String updateUser;
@Schema(description = "更新时间")
private LocalDateTime updateDate;
@NotBlank(message = "路由名称(默认为“未命名”,添加时需要保存格式为:前置节点名称(to:下一节点名称))不能为空")
@Length(max = 255, message = "路由名称(默认为“未命名”,添加时需要保存格式为:前置节点名称(to:下一节点名称))不能超过255个字符")
@Schema(description = "路由名称(默认为“未命名”,添加时需要保存格式为:前置节点名称(to:下一节点名称))")
private String name;
@Length(max = 255, message = "描述不能超过255个字符")
@Schema(description = "描述")
private String description;
@Schema(description = "顺序号")
private Integer sequenceNo;
@Length(max = 255, message = "默认意见不能超过255个字符")
@Schema(description = "默认意见")
private String opinion;
@NotBlank(message = "意见是否必填(0是/1否)不能为空")
@Length(max = 1, message = "意见是否必填(0是/1否)不能超过1个字符")
@Schema(description = "意见是否必填(0是/1否)")
private String opinionMustFlag;
@NotBlank(message = "路由类型(1默认路由/2回退路由/3转交(转交不触发活动事件))不能为空")
@Length(max = 1, message = "路由类型(1默认路由/2回退路由/3转交(转交不触发活动事件))不能超过1个字符")
@Schema(description = "路由类型(1默认路由/2回退路由/3转交(转交不触发活动事件))")
private String routeType;
@NotBlank(message = "是否优先(0是/1否:仅在分支/并列下使用,单节点路由不存在优先级)不能为空")
@Length(max = 1, message = "是否优先(0是/1否:仅在分支/并列下使用,单节点路由不存在优先级)不能超过1个字符")
@Schema(description = "是否优先(0是/1否:仅在分支/并列下使用,单节点路由不存在优先级)")
private String priorityFlag;
@NotBlank(message = "活动超时时自动流转(0是/1否)不能为空")
@Length(max = 1, message = "活动超时时自动流转(0是/1否)不能超过1个字符")
@Schema(description = "活动超时时自动流转(0是/1否)")
private String timeoutRoam;
@NotBlank(message = "与上一活动处理人相同时自动流转(0是/1否)不能为空")
@Length(max = 1, message = "与上一活动处理人相同时自动流转(0是/1否)不能超过1个字符")
@Schema(description = "与上一活动处理人相同时自动流转(0是/1否)")
private String sameForPrew;
@TableField(exist = false)
List<TNodeRouteCondition> nodeRouteConditionList;
}
package com.yifu.cloud.plus.v1.yifu.process.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.extension.activerecord.Model;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.hibernate.validator.constraints.Length;
import javax.validation.constraints.NotBlank;
/**
* 流程路由条件
*
* @author hgw
* @date 2020-07-16 15:44:02
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("t_node_route_condition")
@Schema(description = "流程路由条件")
public class TNodeRouteCondition extends Model<TNodeRouteCondition> {
private static final long serialVersionUID = 1L;
@TableId(type = IdType.ASSIGN_ID)
@Schema(description = "主键")
private String id;
@NotBlank(message = "条件字段不能为空")
@Length(max = 255, message = "条件字段不能超过255个字符")
@Schema(description = "条件字段")
private String field;
@NotBlank(message = "判断条件:大于/等于/大于等于/小于/小于等于/不等于/包含/不包含不能为空")
@Length(max = 255, message = "判断条件:大于/等于/大于等于/小于/小于等于/不等于/包含/不包含不能超过255个字符")
@Schema(description = "判断条件:大于/等于/大于等于/小于/小于等于/不等于/包含/不包含")
private String conditions;
@NotBlank(message = "参与判定的值(可能存在类型转换)不能为空")
@Length(max = 255, message = "参与判定的值(可能存在类型转换)不能超过255个字符")
@Schema(description = "参与判定的值(可能存在类型转换)")
private String conditionValue;
@NotBlank(message = "与其他条件之间的关系(0没有关系或单独条件/1或的关系/2并且关系)不能为空")
@Length(max = 1, message = "与其他条件之间的关系(0没有关系或单独条件/1或的关系/2并且关系)不能超过1个字符")
@Schema(description = "与其他条件之间的关系(0没有关系或单独条件/1或的关系/2并且关系)")
private String realation;
@NotBlank(message = "流程路由ID不能为空")
@Length(max = 255, message = "流程路由ID不能超过255个字符")
@Schema(description = "流程路由ID")
private String nodeRouteId;
@NotBlank(message = "类型:1.正常条件 2.正则表达式'不能为空")
@Length(max = 255, message = "类型:1.正常条件 2.正则表达式255个字符")
@Schema(description = "类型:1.正常条件 2.正则表达式")
private String type;
}
package com.yifu.cloud.plus.v1.yifu.process.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.extension.activerecord.Model;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.hibernate.validator.constraints.Length;
import javax.validation.constraints.NotBlank;
/**
* 流程调用配置(子流程调用)
*
* @author hgw
* @date 2020-07-16 15:44:02
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("t_node_transfer_config")
@Schema(description = "流程调用配置(子流程调用)")
public class TNodeTransferConfig extends Model<TNodeTransferConfig> {
private static final long serialVersionUID = 1L;
@TableId(type = IdType.ASSIGN_ID)
@Schema(description = "主键")
private String id;
@NotBlank(message = "流程节点ID不能为空")
@Length(max = 255, message = "流程节点ID不能超过255个字符")
@Schema(description = "流程节点ID")
private String nodeId;
@NotBlank(message = "流程ID不能为空")
@Length(max = 255, message = "流程ID不能超过255个字符")
@Schema(description = "流程ID")
private String processId;
@NotBlank(message = "调用方式(0同步/1异步)不能为空")
@Length(max = 1, message = "调用方式(0同步/1异步)不能超过1个字符")
@Schema(description = "调用方式(0同步/1异步)")
private String transferType;
@NotBlank(message = "是否拷贝数据(0是/1否)不能为空")
@Length(max = 1, message = "是否拷贝数据(0是/1否)不能超过1个字符")
@Schema(description = "是否拷贝数据(0是/1否)")
private String copyData;
@NotBlank(message = "是否拷贝附件(0是/1否)不能为空")
@Length(max = 1, message = "是否拷贝附件(0是/1否)不能超过1个字符")
@Schema(description = "是否拷贝附件(0是/1否)")
private String copyAtta;
@NotBlank(message = "启动者(0当前流程的启动者/1上一个活动的处理人/2指定一个启动者)不能为空")
@Length(max = 1, message = "启动者(0当前流程的启动者/1上一个活动的处理人/2指定一个启动者)不能超过1个字符")
@Schema(description = "启动者(0当前流程的启动者/1上一个活动的处理人/2指定一个启动者)")
private String starterType;
@Length(max = 255, message = "启动者(STARTER_TYPE 为2时启用)不能超过255个字符")
@Schema(description = "启动者(STARTER_TYPE 为2时启用)")
private String starter;
}
package com.yifu.cloud.plus.v1.yifu.process.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.extension.activerecord.Model;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.hibernate.validator.constraints.Length;
import javax.validation.constraints.NotBlank;
import java.util.ArrayList;
import java.util.List;
/**
* 流程节点表
*
* @author hgw
* @date 2020-07-16 15:44:02
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("t_process_node")
@Schema(description = "流程节点表")
public class TProcessNode extends Model<TProcessNode> {
private static final long serialVersionUID = 1L;
@TableId(type = IdType.ASSIGN_ID)
@Schema(description = "主键")
private String id;
/**
* 类型:{
* begin:开始
* end:结束
* cancel:取消
* choice:选择
* split:拆分
* parallel:并行
* merge:合并
* embed:流程调用
* delay:定时
* invoke:服务调用
* service:服务
* agent:脚本
* }
*/
@NotBlank(message = "类型:不能为空")
@Length(max = 20, message = "类型:不能超过20个字符")
@Schema(description = "类型")
private String type;
@NotBlank(message = "标识(自动生成MD5串)不能为空")
@Length(max = 255, message = "标识(自动生成MD5串)不能超过255个字符")
@Schema(description = "标识(自动生成MD5串)")
private String logoTitle;
@NotBlank(message = "节点名称不能为空")
@Length(max = 255, message = "节点名称不能超过255个字符")
@Schema(description = "节点名称")
private String name;
@Length(max = 255, message = "节点描述不能超过255个字符")
@Schema(description = "节点描述")
private String description;
@Length(max = 255, message = "表单ID不能超过255个字符")
@Schema(description = "表单ID", name = "form")
private String form;
@NotBlank(message = "是否允许调度(0是/1否)不能为空")
@Length(max = 1, message = "是否允许调度(0是/1否)不能超过1个字符")
@Schema(description = "是否允许调度(0是/1否)")
private String allowDispatch;
@NotBlank(message = "是否允许调度到此活动不能为空")
@Length(max = 1, message = "是否允许调度到此活动不能超过1个字符")
@Schema(description = "是否允许调度到此活动")
private String allowThis;
@NotBlank(message = "流程ID不能为空")
@Length(max = 255, message = "流程ID不能超过255个字符")
@Schema(description = "流程ID")
private String processId;
@NotBlank(message = "经办人是否允许办理完成后进入下一步(0允许/1不允许)不能为空")
@Length(max = 1, message = "经办人是否允许办理完成后进入下一步(0允许/1不允许)不能超过1个字符")
@Schema(description = "经办人是否允许办理完成后进入下一步(0允许/1不允许)")
private String handleAllowNext;
@NotBlank(message = "会签方式(0允许会签/1强制会签/2禁止会签)不能为空")
@Length(max = 1, message = "会签方式(0允许会签/1强制会签/2禁止会签)不能超过1个字符")
@Schema(description = "会签方式(0允许会签/1强制会签/2禁止会签)")
private String countersign;
@NotBlank(message = "回退方式(0不允许/1回退上一步/2回退至起点)不能为空")
@Length(max = 1, message = "回退方式(0不允许/1回退上一步/2回退至起点)不能超过1个字符")
@Schema(description = "回退方式(0不允许/1回退上一步/2回退至起点)")
private String backType;
@Length(max = 100, message = "元素的图形:不能超过100个字符")
@Schema(description = "元素的图形")
private String shape;
@Length(max = 100, message = "节点大小:不能超过100个字符")
@Schema(description = "节点大小")
private String size;
@Length(max = 20, message = "X坐标:不能超过20个字符")
@Schema(description = "X坐标")
private String coordinatex;
@Length(max = 20, message = "Y坐标:不能超过20个字符")
@Schema(description = "Y坐标")
private String coordinatey;
@Length(max = 50, message = "颜色:不能超过50个字符")
@Schema(description = "颜色")
private String color;
@TableField(exist = false)
private List<TNodePrimission> nodePrimissionList = new ArrayList<>();
@TableField(exist = false)
private List<TNodeReaderPromission> nodeReaderPromissionList = new ArrayList<>();
@TableField(exist = false)
private List<TNodeTransferConfig> nodeTransferConfigs;
@Schema(description = "允许加签")
private String allowAddSign;
/**
* 节点抄送权限列表(流程预览使用,将当前节点的抄送权限绑定在下一个节点上,因为当前的代码逻辑不返回抄送节点,有冲突)
* 【之后优化@TableField注解,不能在实体类里面直接用@TableField,要建一个包装类】
*/
@TableField(exist = false)
private List<TNodeReaderPromission> preNodeReaderPromissionList = new ArrayList<>();
}
package com.yifu.cloud.plus.v1.yifu.process.util;
import com.yifu.cloud.plus.v1.yifu.admin.api.entity.SysUser;
import com.yifu.cloud.plus.v1.yifu.common.core.constant.CommonConstants;
import com.yifu.cloud.plus.v1.yifu.common.core.exception.CheckedException;
import com.yifu.cloud.plus.v1.yifu.common.core.util.Common;
import com.yifu.cloud.plus.v1.yifu.process.entity.TNodePrimission;
import java.util.ArrayList;
import java.util.List;
/**
* @author chenyuxi
* @date 2020/9/22
* 通用流程工具类
*/
public class CommonProcessUserUtil {
private CommonProcessUserUtil() {
}
public static final String FEGIN_USER_FAIL = "调用用户服务失败";
public static final String FEGIN_USER_RETURN_FAIL = "调用用户服务回失败";
}
package com.yifu.cloud.plus.v1.yifu.process.util;
import com.alibaba.fastjson.JSON;
import com.googlecode.aviator.AviatorEvaluator;
import com.yifu.cloud.plus.v1.yifu.common.core.exception.CheckedException;
import lombok.extern.slf4j.Slf4j;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;
/**
* @auther wangan
* @date 2020/9/2
* goole表达式
*/
@Slf4j
public class ExpressionUtil {
private ExpressionUtil() {
}
/**
* @param expression
* @param obj
* @Author: wangan
* @Date: 2020/9/2
* @Description: 根据表达式判断数据大小
* @return: boolean
**/
public static boolean isMatchExpression(String expression, Object obj) {
Map<String, Object> env = new HashMap<>();
if (obj instanceof BigDecimal) {
env.put("x", Double.parseDouble(obj.toString()));
} else {
env.put("x", obj.toString());
}
try {
return (Boolean) AviatorEvaluator.execute(expression, env);
} catch (Exception e) {
log.error("表达式数据{},表达式{}",expression, JSON.toJSONString(env));
log.error("执行异常",e);
throw new CheckedException("表达式执行出错");
}
}
/**
* @param expression
* @param obj1
* @param obj2
* @Author: wangan
* @Date: 2020/9/2
* @Description: 根据表达式判断数据大小
* @return: boolean
**/
public static boolean isMatchExpression(String expression, Object obj1,Object obj2) {
Map<String, Object> env = new HashMap<>();
if (obj1 instanceof BigDecimal) {
env.put("x", Double.parseDouble(obj1.toString()));
} else {
env.put("x", obj1.toString());
}
if (obj2 instanceof BigDecimal) {
env.put("y", Double.parseDouble(obj2.toString()));
} else {
env.put("y", obj2.toString());
}
try {
return (Boolean) AviatorEvaluator.execute(expression, env);
} catch (Exception e) {
log.error("表达式数据{},表达式{}",expression, JSON.toJSONString(env));
log.error("执行异常",e);
throw new CheckedException("表达式执行出错");
}
}
}
package com.yifu.cloud.plus.v1.yifu.process.vo;
import lombok.Getter;
import lombok.Setter;
import java.io.Serializable;
/**
* @Description: 流程需要删除的idsVo
* @Author: hgw
* @Date: 2020-7-27 11:04:13
* @return:
**/
@Getter
@Setter
public class DeleteProcessIdsVo implements Serializable {
private static final long serialVersionUID = 1L;
// 节点ids
private String[] nodeIds;
// 子流程ids
private String[] nodeTransferConfigIds;
// 线ids
private String[] roteIds;
// 线权限ids
private String[] roteConditionIds;
// 权限ids
private String[] primissionIds;
// 抄送ids
private String[] readPrimissionIds;
}
package com.yifu.cloud.plus.v1.yifu.process.vo;
import com.yifu.cloud.plus.v1.yifu.process.entity.TNodeRoute;
import com.yifu.cloud.plus.v1.yifu.process.entity.TProcessNode;
import lombok.Getter;
import lombok.Setter;
import java.io.Serializable;
import java.util.List;
/**
* @Description: 流程Vo
* @Author: hgw
* @Date: 2019/10/23 15:40
* @return:
**/
@Getter
@Setter
public class ProcessVo implements Serializable {
private static final long serialVersionUID = 1L;
// 主流程id
private String processId;
private String name;
// 节点list
private List<TProcessNode> processNodeList;
// 流程路由list
private List<TNodeRoute> nodeRouteList;
// 删除的ids
private DeleteProcessIdsVo deleteIdsVo;
// 标志是否是流程预览 0是 1否
private String isPreview;
}
package com.yifu.cloud.plus.v1.yifu.process.vo;
import com.yifu.cloud.plus.v1.yifu.process.entity.TNodePrimission;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.io.Serializable;
/**
* @program: yifu_cloud
* @description: 流程处理权限vo类
* @author: wangdayu
* @create: 2023-10-23 17:28
* @since:
*/
@Data
public class TNodePrimissionVo extends TNodePrimission implements Serializable {
@Schema(description = "审核人姓名")
private String userName;
}
package com.yifu.cloud.plus.v1.yifu.process.vo;
import com.yifu.cloud.plus.v1.yifu.process.entity.TNodeReaderPromission;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.io.Serializable;
/**
* @program: yifu_cloud
* @description: 抄送权限vo类
* @author: wangdayu
* @create: 2023-10-23 17:30
* @since:
*/
@Data
public class TNodeReaderPromissionVo extends TNodeReaderPromission implements Serializable {
@Schema(description = "审核人姓名")
private String userName;
}
package com.yifu.cloud.plus.v1.yifu.common.security.component;
import com.yifu.cloud.plus.v1.yifu.common.security.token.WxAuthenticationToken;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.authentication.InternalAuthenticationServiceException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
/**
* 手机验证码登陆
*/
@Slf4j
public class WxAuthenticationProvider extends MyAbstractUserDetailsAuthenticationProvider {
private UserDetailsService userDetailsService;
@Override
protected void additionalAuthenticationChecks(UserDetails var1, Authentication authentication) throws AuthenticationException {
// if(authentication.getCredentials() == null) {
// this.logger.debug("Authentication failed: no credentials provided");
// throw new BadCredentialsException(this.messages.getMessage("PhoneAuthenticationProvider.badCredentials", "Bad credentials"));
// }
}
@Override
protected Authentication createSuccessAuthentication(Object principal, Authentication authentication, UserDetails user) {
WxAuthenticationToken result = new WxAuthenticationToken(principal, authentication.getCredentials(), user.getAuthorities());
result.setDetails(authentication.getDetails());
return result;
}
@Override
protected UserDetails retrieveUser(String wxUserName, Authentication authentication) throws AuthenticationException {
UserDetails loadedUser;
// String presentedPassword = authentication.getCredentials().toString();
//
// // 验证码验证,调用公共服务查询 key 为authentication.getPrincipal()的value, 并判断其与验证码是否匹配
// String code = redisUtil.get(wxUserName).toString();
// if(!code.equals(presentedPassword)){
// this.logger.debug("Authentication failed: verifyCode does not match stored value");
// throw new BadCredentialsException(this.messages.getMessage("PhoneAuthenticationProvider.badCredentials", "Bad verifyCode"));
// }
try {
loadedUser = this.getUserDetailsService().loadUserByUsername(wxUserName);
log.error(wxUserName+":"+loadedUser.getUsername());
} catch (UsernameNotFoundException var6) {
throw var6;
} catch (Exception var7) {
log.info("WxAuthenticationProvider>>>>>>",var7);
throw new InternalAuthenticationServiceException(var7.getMessage(), var7);
}
if(loadedUser == null) {
throw new InternalAuthenticationServiceException("UserDetailsService returned null, which is an interface contract violation");
} else {
return loadedUser;
}
}
@Override
public boolean supports(Class<?> authentication) {
return WxAuthenticationToken.class.isAssignableFrom(authentication);
}
public UserDetailsService getUserDetailsService() {
return userDetailsService;
}
public void setUserDetailsService(UserDetailsService userDetailsService) {
this.userDetailsService = userDetailsService;
}
}
package com.yifu.cloud.plus.v1.yifu.common.security.service;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil;
import com.yifu.cloud.plus.v1.yifu.admin.api.dto.UserInfo;
import com.yifu.cloud.plus.v1.yifu.admin.api.entity.SysUser;
import com.yifu.cloud.plus.v1.yifu.common.core.constant.CommonConstants;
import com.yifu.cloud.plus.v1.yifu.common.core.constant.SecurityConstants;
import com.yifu.cloud.plus.v1.yifu.common.core.constant.ServiceNameConstants;
import com.yifu.cloud.plus.v1.yifu.common.core.exception.CheckedException;
import com.yifu.cloud.plus.v1.yifu.common.core.util.R;
import com.yifu.cloud.plus.v1.yifu.common.core.vo.YifuUser;
import com.yifu.cloud.plus.v1.yifu.common.dapr.config.DaprUpmsProperties;
import com.yifu.cloud.plus.v1.yifu.common.dapr.util.HttpDaprUtil;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
/**
* 手机验证码登录()
*/
@Slf4j
@EnableConfigurationProperties(DaprUpmsProperties.class)
@Service
@AllArgsConstructor
public class WxUserDetailService implements UserDetailsService {
private CacheManager cacheManager;
private final DaprUpmsProperties daprUpmsProperties;
/**
* 手机验证码登录
*
* @param wxUserName 微信用户名
* @return
* @throws UsernameNotFoundException
*/
@Override
public UserDetails loadUserByUsername(String wxUserName) throws UsernameNotFoundException {
Cache cache = cacheManager.getCache(ServiceNameConstants.UMPS_SERVICE + "_user_details_wx");
if (null != cache && null != cache.get(wxUserName)) {
return (YifuUser) cache.get(wxUserName).get();
}
//根据手机号获取用户
R<UserInfo> result = HttpDaprUtil.invokeMethodGet(daprUpmsProperties.getAppUrl(),daprUpmsProperties.getAppId(), "/user/getInfoByWxUsername", "?username="+wxUserName, UserInfo.class, SecurityConstants.FROM_IN);
UserDetails userDetails = getUserDetails(result);
if (cache == null) {
throw new CheckedException("缓存为空");
}
cache.put(wxUserName, userDetails);
return userDetails;
}
/**
* 构建userdetails
*
* @param result 用户信息
* @return
*/
private UserDetails getUserDetails(R<UserInfo> result) {
if (result == null || result.getData() == null) {
throw new UsernameNotFoundException("用户不存在");
}
UserInfo info = result.getData();
Set<String> dbAuthsSet = new HashSet<>();
if (ArrayUtil.isNotEmpty(info.getRoles())) {
// 获取角色
Arrays.stream(info.getRoles()).forEach(role -> dbAuthsSet.add(SecurityConstants.ROLE + role));
// 获取资源
dbAuthsSet.addAll(Arrays.asList(info.getPermissions()));
}
Collection<? extends GrantedAuthority> authorities = AuthorityUtils
.createAuthorityList(dbAuthsSet.toArray(new String[0]));
SysUser user = info.getSysUser();
// 构造security用户
return new YifuUser(user.getUserId(), user.getDeptId(),user.getDeptName(), user.getUsername(),
user.getNickname(),user.getSystemFlag(), SecurityConstants.BCRYPT + user.getPassword(),
user.getPhone(), true, true, true,
StrUtil.equals(user.getLockFlag(), CommonConstants.STATUS_NORMAL),
user.getUserGroup(),authorities, user.getLdapDn(),info.getClientRoleMap(),
info.getSettleIdList(),user.getType());
}
}
package com.yifu.cloud.plus.v1.yifu.common.security.token;
import org.springframework.security.core.GrantedAuthority;
import java.util.Collection;
/**
* 手机验证码token
*/
public class WxAuthenticationToken extends MyAuthenticationToken {
public WxAuthenticationToken(Object principal, Object credentials) {
super(principal, credentials);
}
public WxAuthenticationToken(Object principal, Object credentials, Collection<? extends GrantedAuthority> authorities) {
super(principal, credentials, authorities);
}
}
......@@ -5,5 +5,6 @@ org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.yifu.cloud.plus.v1.yifu.common.security.component.YifuTokenStoreAutoConfiguration,\
com.yifu.cloud.plus.v1.yifu.common.security.component.YifuTokenStoreAutoCleanSchedule,\
com.yifu.cloud.plus.v1.yifu.common.security.component.YifuSecurityMessageSourceConfiguration,\
com.yifu.cloud.plus.v1.yifu.common.security.service.WxUserDetailService,\
com.yifu.cloud.plus.v1.yifu.common.security.exception.GlobalExceptionHandler
package com.yifu.cloud.plus.v1.ekp.entity;
import com.alibaba.excel.annotation.ExcelProperty;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* 事业部审批配置
* @author chenyuxi
* @date 2025/1/15
* @since 1.7.5
*/
@Data
@TableName("ekp_shenhepeizhi_table")
@EqualsAndHashCode()
@Schema(description = "事业部审批配置")
public class EkpShenhepeizhi {
@TableId(type = IdType.ASSIGN_ID)
@Schema(description = "主键")
private String fdId;
private String fdShiyebu;
private String fdTiaoxian;
}
package com.yifu.cloud.plus.v1.ekp.controller;
import com.yifu.cloud.plus.v1.ekp.service.EkpSalaryInfoService;
import com.yifu.cloud.plus.v1.ekp.service.EkpShenhepeizhiService;
import com.yifu.cloud.plus.v1.yifu.common.core.constant.CommonConstants;
import com.yifu.cloud.plus.v1.yifu.common.core.util.Common;
import com.yifu.cloud.plus.v1.yifu.common.core.util.ErrorMessage;
import com.yifu.cloud.plus.v1.yifu.common.core.util.R;
import com.yifu.cloud.plus.v1.yifu.common.core.vo.YifuUser;
import com.yifu.cloud.plus.v1.yifu.common.log.annotation.SysLog;
import com.yifu.cloud.plus.v1.yifu.common.security.annotation.Inner;
import com.yifu.cloud.plus.v1.yifu.common.security.util.SecurityUtils;
import com.yifu.cloud.plus.v1.yifu.ekp.vo.EkpDivisionInfoVo;
import com.yifu.cloud.plus.v1.yifu.ekp.vo.EkpSalaryParam;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
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.RestController;
import org.springframework.web.multipart.MultipartFile;
import java.util.List;
/**
* 事业部审批配置
* @author chenyuxi
* @date 2025/1/15
* @since 1.7.5
*/
@RestController
@RequiredArgsConstructor
@RequestMapping("/ekpShenhepeizhi" )
@Tag(name = "事业部审批配置")
public class TEkpShenhepeizhiController {
private final EkpShenhepeizhiService shenhepeizhiService;
@Inner
@PostMapping("/inner/getDivisionUsernameList")
public EkpDivisionInfoVo getDivisionUsernameList(@RequestBody EkpDivisionInfoVo divisionInfoVo) {
return shenhepeizhiService.getDivisionUsernameList(divisionInfoVo);
}
}
package com.yifu.cloud.plus.v1.ekp.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.yifu.cloud.plus.v1.ekp.entity.EkpShenhepeizhi;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* 事业部审批配置
* @author chenyuxi
* @date 2025/1/15
* @since 1.7.5
*/
@Mapper
public interface EkpShenhepeizhiMapper extends BaseMapper<EkpShenhepeizhi> {
// 查事业部负责人
List<String> getDivisionLoginNameList(@Param("line") String line, @Param("division") String division);
// 查分管副总
List<String> getFuLoginNameList(@Param("line") String line, @Param("division") String division);
// 查条线人
List<String> getLineLoginNameList(@Param("line") String line, @Param("division") String division);
}
package com.yifu.cloud.plus.v1.ekp.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.yifu.cloud.plus.v1.ekp.entity.EkpSalaryInfo;
import com.yifu.cloud.plus.v1.ekp.entity.EkpShenhepeizhi;
import com.yifu.cloud.plus.v1.yifu.common.core.util.ErrorMessage;
import com.yifu.cloud.plus.v1.yifu.common.core.util.R;
import com.yifu.cloud.plus.v1.yifu.ekp.vo.EkpDivisionInfoVo;
import com.yifu.cloud.plus.v1.yifu.ekp.vo.EkpSalaryParam;
import org.springframework.transaction.annotation.Transactional;
import java.io.InputStream;
import java.util.List;
/**
* 事业部审批配置
* @author chenyuxi
* @date 2025/1/15
* @since 1.7.5
*/
public interface EkpShenhepeizhiService extends IService<EkpShenhepeizhi> {
EkpDivisionInfoVo getDivisionUsernameList(EkpDivisionInfoVo divisionInfoVo);
}
......@@ -67,6 +67,9 @@ public class EkpFundInfoServiceImpl extends ServiceImpl<EkpFundInfoMapper, EkpFu
//项目信息
deptInfo = map.get(fundInfo.getFd_3adfe8c70d3fd4());
if (Common.isEmpty(deptInfo)) {
continue;
}
fundInfo.setFd_3b16e37baa5650_text(deptInfo.getDeptName());
fundInfo.setFd_3b16e37baa5650(deptInfo.getFdId());
//实际结算月份
......
......@@ -38,7 +38,9 @@ public class EkpManagerInfoServiceImpl extends ServiceImpl<EkpManagerInfoMapper,
//根据项目编码获取ekp所有项目信息
EkpDeptInfoVo deptInfo = baseMapper.getEkpDeptInfoByNo(incomeParam.getFd_3adfef5e5b9d34());
if (null == deptInfo) {
return null;
}
EkpManagerInfo managerInfoCount;
try {
//去重 防止重复推送
......
......@@ -37,7 +37,9 @@ public class EkpRiskInfoServiceImpl extends ServiceImpl<EkpRiskInfoMapper, EkpRi
public EkpIncomePushInfoVo pushRiskInfoToEkp(EkpIncomeParamRisk incomeParam) {
//根据项目编码获取ekp所有项目信息
EkpDeptInfoVo deptInfo = baseMapper.getEkpDeptInfoByNo(incomeParam.getFd_3adfef5e5b9d34());
if (null == deptInfo) {
return null;
}
EkpRiskInfo riskInfoCount;
try {
//去重 防止重复推送
......
......@@ -74,6 +74,9 @@ EkpSalaryInfoServiceImpl extends ServiceImpl<EkpSalaryInfoMapper, EkpSalaryInfo>
//项目信息
deptInfo = map.get(salaryInfo.getFd_3adfedf98ccba2());
if (Common.isEmpty(deptInfo)) {
continue;
}
salaryInfo.setFd_3b16e418905f52_text(deptInfo.getDeptName());
salaryInfo.setFd_3b16e418905f52(deptInfo.getFdId());
//实际结算月份
......
package com.yifu.cloud.plus.v1.ekp.service.impl;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.read.listener.ReadListener;
import com.alibaba.excel.read.metadata.holder.ReadRowHolder;
import com.alibaba.excel.util.ListUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yifu.cloud.plus.v1.ekp.entity.EkpSalaryInfo;
import com.yifu.cloud.plus.v1.ekp.entity.EkpShenhepeizhi;
import com.yifu.cloud.plus.v1.ekp.mapper.EkpSalaryInfoMapper;
import com.yifu.cloud.plus.v1.ekp.mapper.EkpShenhepeizhiMapper;
import com.yifu.cloud.plus.v1.ekp.service.EkpSalaryInfoService;
import com.yifu.cloud.plus.v1.ekp.service.EkpShenhepeizhiService;
import com.yifu.cloud.plus.v1.ekp.vo.ClaimInfotVO;
import com.yifu.cloud.plus.v1.ekp.vo.ClaimRebackInfotVO;
import com.yifu.cloud.plus.v1.ekp.vo.EkpDeptInfoVo;
import com.yifu.cloud.plus.v1.yifu.common.core.constant.CommonConstants;
import com.yifu.cloud.plus.v1.yifu.common.core.util.*;
import com.yifu.cloud.plus.v1.yifu.ekp.vo.EkpDivisionInfoVo;
import com.yifu.cloud.plus.v1.yifu.ekp.vo.EkpSalaryParam;
import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.io.InputStream;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;
/**
//工资明细表
*
//@author huyc
//@date 2024-03-11 11:21:56
*/
@Log4j2
@Service
@RequiredArgsConstructor
public class EkpShenhepeizhiServiceImpl extends ServiceImpl<EkpShenhepeizhiMapper, EkpShenhepeizhi> implements EkpShenhepeizhiService {
@Override
public EkpDivisionInfoVo getDivisionUsernameList(EkpDivisionInfoVo divisionInfoVo) {
EkpDivisionInfoVo divisionInfoVoRes = new EkpDivisionInfoVo();
List<String> divisionUsernameList = new ArrayList<>();
// 指定事业部配置表负责人标识:0事业部条线负责人;1事业部负责人;2分管副总
if(CommonConstants.ZERO_STRING.equals(divisionInfoVo.getDivisionIdentification())){
divisionUsernameList = baseMapper.getLineLoginNameList(divisionInfoVo.getNewLine(), divisionInfoVo.getDivision());
}
if(CommonConstants.ONE_STRING.equals(divisionInfoVo.getDivisionIdentification())){
divisionUsernameList = baseMapper.getDivisionLoginNameList(divisionInfoVo.getNewLine(), divisionInfoVo.getDivision());
}
if(CommonConstants.TWO_STRING.equals(divisionInfoVo.getDivisionIdentification())){
divisionUsernameList = baseMapper.getFuLoginNameList(divisionInfoVo.getNewLine(), divisionInfoVo.getDivision());
}
divisionInfoVoRes.setDivisionUsernameList(divisionUsernameList);
return divisionInfoVoRes;
}
}
......@@ -68,9 +68,11 @@ public class EkpSocialInfoServiceImpl extends ServiceImpl<EkpSocialInfoMapper, E
EkpSocialInfo socialInfo = new EkpSocialInfo();
//对象信息赋值
copySocialProperties(socialParam, socialInfo);
//项目信息
deptInfo = map.get(socialInfo.getFd_3adfe8c70d3fd4());
if (Common.isEmpty(deptInfo)) {
continue;
}
socialInfo.setFd_3b16e2f436ff98_text(deptInfo.getDeptName());
socialInfo.setFd_3b16e2f436ff98(deptInfo.getFdId());
//实际结算月份
......
<?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.yifu.cloud.plus.v1.ekp.mapper.EkpShenhepeizhiMapper">
<!--查询项目信息-->
<select id="getDivisionLoginNameList" resultType="string">
select du.fd_login_name as loginName from ekp_shenhepeizhi_table a
LEFT JOIN ekporg_1927fe1d4d35e2548a3e d on d.fd_parent_id = a.fd_id
LEFT JOIN sys_org_person du on du.fd_id = d.sys_org_person_id
where a.fd_tiaoxian = #{line} and a.fd_shiyebu = #{division}
</select>
<!--查询项目信息-->
<select id="getFuLoginNameList" resultType="string">
select fu.fd_login_name as loginName from ekp_shenhepeizhi_table a
LEFT JOIN ekporg_1927fe509c6554968429 f on f.fd_parent_id = a.fd_id
LEFT JOIN sys_org_person fu on fu.fd_id = f.sys_org_person_id
where a.fd_tiaoxian = #{line} and a.fd_shiyebu = #{division}
</select>
<!--查询项目信息-->
<select id="getLineLoginNameList" resultType="string">
select lu.fd_login_name as loginName from ekp_shenhepeizhi_table a
LEFT JOIN ekporg_1927fe1d4d389080b7a7 l on l.fd_parent_id = a.fd_id
LEFT JOIN sys_org_person lu on lu.fd_id = l.sys_org_person_id
where a.fd_tiaoxian = #{line} and a.fd_shiyebu = #{division}
</select>
</mapper>
......@@ -16,6 +16,8 @@ import com.yifu.cloud.plus.v1.yifu.insurances.constants.InsurancesConstants;
import com.yifu.cloud.plus.v1.yifu.insurances.entity.TInsuranceOperate;
import com.yifu.cloud.plus.v1.yifu.insurances.service.insurance.TInsuranceDetailService;
import com.yifu.cloud.plus.v1.yifu.insurances.vo.*;
import com.yifu.cloud.plus.v1.yifu.salary.entity.TSalaryAccount;
import com.yifu.cloud.plus.v1.yifu.salary.vo.SalaryRiskListVo;
import com.yifu.cloud.plus.v1.yifu.social.vo.ChangeDeptVo;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
......@@ -162,7 +164,7 @@ public class TInsuranceDetailController {
/**
* 通过id删除
*
*
* @author licancan
* @param id
* @return {@link R<String>}
......@@ -811,4 +813,18 @@ public class TInsuranceDetailController {
public void updateSettleStatus() {
tInsuranceDetailService.updateSettleStatus();
}
/**
* 重新更新结算状态同步失败的数据
*
* @author licancan
* @param
* @return void
*/
@SysLog("重新更新结算状态同步失败的数据")
@Inner
@PostMapping("/inner/getRiskByIdCard")
public SalaryRiskListVo getRiskByIdCard(@RequestBody List<TSalaryAccount> idCardList) {
return tInsuranceDetailService.getRiskByIdCard(idCardList);
}
}
......@@ -284,6 +284,15 @@ public interface TInsuranceDetailMapper extends BaseMapper<TInsuranceDetail> {
List<TInsuranceDetail> selectByIdCardList(@Param("idCardList") List<String> idCardList
, @Param("idList") List<String> idList);
/**
* @param idCardList
* @Description: 根据身份证列表,查找所有商险
* @Author: hgw
* @Date: 2022/11/23 15:17
* @return: java.util.List<com.yifu.cloud.plus.v1.yifu.insurances.entity.TInsuranceDetail>
**/
List<TInsuranceDetail> selectInUseByIdCardList(@Param("idCardList") List<String> idCardList);
/**
* @param ids
* @Description: 根据id查找所有商险
......
......@@ -10,6 +10,8 @@ import com.yifu.cloud.plus.v1.yifu.common.core.vo.YifuUser;
import com.yifu.cloud.plus.v1.yifu.insurances.entity.TInsuranceDetail;
import com.yifu.cloud.plus.v1.yifu.insurances.entity.TInsuranceOperate;
import com.yifu.cloud.plus.v1.yifu.insurances.vo.*;
import com.yifu.cloud.plus.v1.yifu.salary.entity.TSalaryAccount;
import com.yifu.cloud.plus.v1.yifu.salary.vo.SalaryRiskListVo;
import com.yifu.cloud.plus.v1.yifu.social.vo.ChangeDeptVo;
import javax.servlet.http.HttpServletResponse;
......@@ -540,4 +542,14 @@ public interface TInsuranceDetailService extends IService<TInsuranceDetail> {
void exportInsurancesWarn(InsuranceSearchVo vo, HttpServletResponse response, List<String> exportFields, String idstr);
R<Object> expireRemark(TBusinessInsuranceVo vo);
/**
* @param idCardList 身份证
* @Description: 获取商险是否在保
* @Author: hgw
* @Date: 2025/1/14 16:00
* @return: com.yifu.cloud.plus.v1.yifu.salary.vo.SalaryRiskListVo
**/
SalaryRiskListVo getRiskByIdCard(List<TSalaryAccount> idCardList);
}
......@@ -42,6 +42,9 @@ import com.yifu.cloud.plus.v1.yifu.insurances.service.insurance.*;
import com.yifu.cloud.plus.v1.yifu.insurances.util.BigDecimalUtils;
import com.yifu.cloud.plus.v1.yifu.insurances.util.*;
import com.yifu.cloud.plus.v1.yifu.insurances.vo.*;
import com.yifu.cloud.plus.v1.yifu.salary.entity.TSalaryAccount;
import com.yifu.cloud.plus.v1.yifu.salary.vo.SalaryRiskListVo;
import com.yifu.cloud.plus.v1.yifu.salary.vo.SalaryRiskVo;
import com.yifu.cloud.plus.v1.yifu.social.entity.TIncomeDetail;
import com.yifu.cloud.plus.v1.yifu.social.vo.ChangeDeptDetailVo;
import com.yifu.cloud.plus.v1.yifu.social.vo.ChangeDeptVo;
......@@ -8195,4 +8198,43 @@ public class TInsuranceDetailServiceImpl extends ServiceImpl<TInsuranceDetailMap
}
return false;
}
/**
* @param idCardList 身份证
* @Description: 获取商险是否在保
* @Author: hgw
* @Date: 2025/1/15 9:25
* @return: com.yifu.cloud.plus.v1.yifu.salary.vo.SalaryRiskListVo
**/
@Override
public SalaryRiskListVo getRiskByIdCard(List<TSalaryAccount> idCardList) {
SalaryRiskListVo returnVo = new SalaryRiskListVo();
if (idCardList != null && !idCardList.isEmpty()) {
List<String> cardList = new ArrayList<>();
for (TSalaryAccount a : idCardList) {
cardList.add(a.getEmpIdcard());
}
List<TInsuranceDetail> detailList = baseMapper.selectInUseByIdCardList(cardList);
List<SalaryRiskVo> list = new ArrayList<>();
SalaryRiskVo riskVo;
Map<String, String> idMap = new HashMap<>();
if (detailList != null && !detailList.isEmpty()) {
for (TInsuranceDetail d : detailList) {
idMap.put(d.getEmpIdcardNo(), d.getEmpName());
}
}
for (TSalaryAccount s : idCardList) {
if (idMap.get(s.getEmpIdcard()) == null) {
riskVo = new SalaryRiskVo();
riskVo.setEmpIdCard(s.getEmpIdcard());
riskVo.setEmpName(s.getEmpName());
riskVo.setMsg("不存在商险");
list.add(riskVo);
}
}
returnVo.setList(list);
}
return returnVo;
}
}
......@@ -34,4 +34,6 @@ ekp:
fdFlowId: '18267f206233f29cbd3c5ee425c9408a'
docStatus: '20'
LoginName: 'admin'
docSubject : '接口发起流程'
\ No newline at end of file
docSubject : '接口发起流程'
......@@ -1447,7 +1447,6 @@
</foreach>
</update>
<!--查询所有商险,如果idList 不为空,则不含被替换的本身。 用来改变档案状态-->
<select id="selectByIdCardList" resultMap="BaseResultMap">
SELECT
......@@ -1470,6 +1469,29 @@
</if>
</select>
<!--查询所有在途商险,判断是否买了商险:【1待投保 2投保中】 或 【3已投保 且 有效】-->
<select id="selectInUseByIdCardList" resultMap="BaseResultMap">
SELECT
ID,
EMP_NAME,
EMP_IDCARD_NO
FROM t_insurance_detail d
where DELETE_FLAG = 0
and (d.BUY_HANDLE_STATUS in (1,2) or (d.BUY_HANDLE_STATUS = 3 and d.IS_EFFECT = 0
and d.POLICY_EFFECT <![CDATA[ <= ]]> NOW() and d.POLICY_END >= NOW()
))
<if test="idCardList != null and idCardList.size > 0">
AND EMP_IDCARD_NO in
<foreach item="item" index="index" collection="idCardList" open="(" separator="," close=")">
#{item}
</foreach>
</if>
<if test="idCardList == null">
and 1=2
</if>
</select>
<select id="selectByIds" resultMap="UpdateMap">
SELECT
a.ID,
......
......@@ -140,5 +140,16 @@ public class SalaryTask {
log.info("------------定时生成【前12月平均工资】-定时任务结束------------");
}
/**
* @Author hgw
* @Description 定时任务刷新【不购买商险申请明细】里的社保状态
* @Date 2025-1-15 16:58:10
**/
public void doSocialWorkInjuryHandleAll() {
log.info("------------定时任务刷新不购买里的社保状态-定时任务开始------------");
HttpDaprUtil.invokeMethodPost(daprSalarylProperties.getAppUrl(),daprSalarylProperties.getAppId(),"/tinsuranceunpurchaseperson/inner/doSocialWorkInjuryHandleAll","", Object.class, SecurityConstants.FROM_IN);
log.info("------------定时任务刷新不购买里的社保状态-定时任务结束------------");
}
}
\ No newline at end of file
# 忽略匹配下列规则的Git 提交 V2.1.0
### gradle ###
.gradle
/build/
!gradle/wrapper/gradle-wrapper.jar
### STS ###
.settings/
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
bin/
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
*.lock
rebel.xml
### NetBeans ###
nbproject/private/
build/
nbbuild/
nbdist/
.nb-gradle/
### maven ###
target/
*.war
*.ear
*.zip
*.tar
*.tar.gz
### logs ####
/logs/
*.log
### temp ignore ###
*.cache
*.diff
*.patch
*.tmp
*.java~
*.properties~
*.xml~
### system ignore ###
.DS_Store
Thumbs.db
Servers
.metadata
upload
gen_code
### node ###
node_modules
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>yifu</artifactId>
<groupId>com.yifu.cloud.plus.v1</groupId>
<version>1.0.0</version>
</parent>
<artifactId>yifu-process</artifactId>
<description>审批流程</description>
<packaging>pom</packaging>
<!--项目子模块-->
<modules>
<module>yifu-process-api</module>
<module>yifu-process-biz</module>
</modules>
</project>
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>yifu</artifactId>
<groupId>com.yifu.cloud.plus.v1</groupId>
<version>1.0.0</version>
</parent>
<artifactId>yifu-process-api</artifactId>
<packaging>jar</packaging>
<description>审批流程服务 接口模块</description>
<dependencies>
<!-- core 工具类 -->
<dependency>
<groupId>com.yifu.cloud.plus.v1</groupId>
<artifactId>yifu-common-core</artifactId>
</dependency>
<!--swagger 注解-->
<dependency>
<groupId>io.swagger.core.v3</groupId>
<artifactId>swagger-annotations</artifactId>
</dependency>
<!--mybatis 依赖-->
<dependency>
<groupId>com.yifu.cloud.plus.v1</groupId>
<artifactId>yifu-common-mybatis</artifactId>
</dependency>
</dependencies>
</project>
package com.yifu.cloud.plus.v1.yifu.process.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.extension.activerecord.Model;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.hibernate.validator.constraints.Length;
import javax.validation.constraints.NotBlank;
import java.time.LocalDateTime;
/**
* 定时流程节点配置
*
* @author hgw
* @date 2020-07-16 17:48:52
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("t_delay_node_config")
@Schema(description = "定时流程节点配置")
public class TDelayNodeConfig extends Model<TDelayNodeConfig> {
private static final long serialVersionUID = 1L;
@TableId(type = IdType.ASSIGN_ID)
@Schema(description = "主键")
private String id;
@NotBlank(message = "定时方式(0延时指定的分钟后执行/1指定一个时间点执行)不能为空")
@Length(max = 1, message = "定时方式(0延时指定的分钟后执行/1指定一个时间点执行)不能超过1个字符")
@Schema(description = "定时方式(0延时指定的分钟后执行/1指定一个时间点执行)")
private String delayType;
@Schema(description = "分钟")
private Integer minutes;
@Schema(description = "时间")
private LocalDateTime time;
@NotBlank(message = "流程节点ID不能为空")
@Length(max = 255, message = "流程节点ID不能超过255个字符")
@Schema(description = "流程节点ID")
private String nodeId;
}
package com.yifu.cloud.plus.v1.yifu.process.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.extension.activerecord.Model;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.hibernate.validator.constraints.Length;
import javax.validation.constraints.NotBlank;
/**
* 流程节点配置表(规则配置)
*
* @author hgw
* @date 2020-07-16 15:44:02
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("t_node_config")
@Schema(description = "流程节点配置表(规则配置)")
public class TNodeConfig extends Model<TNodeConfig> {
private static final long serialVersionUID = 1L;
@TableId(type = IdType.ASSIGN_ID)
@Schema(description = "主键")
private String id;
@NotBlank(message = "是否允许撤回(0是/1否)不能为空")
@Length(max = 1, message = "是否允许撤回(0是/1否)不能超过1个字符")
@Schema(description = "是否允许撤回(0是/1否)")
private String allowWithdraw;
@NotBlank(message = "是否允许流程回溯(0是/1否)不能为空")
@Length(max = 1, message = "是否允许流程回溯(0是/1否)不能超过1个字符")
@Schema(description = "是否允许流程回溯(0是/1否)")
private String allowBacktrack;
@NotBlank(message = "是否发起处理提醒(0是/1否;提醒会在站内和移动端提醒)不能为空")
@Length(max = 1, message = "是否发起处理提醒(0是/1否;提醒会在站内和移动端提醒)不能超过1个字符")
@Schema(description = "是否发起处理提醒(0是/1否;提醒会在站内和移动端提醒)")
private String allowDealRemind;
@NotBlank(message = "节点ID不能为空")
@Length(max = 255, message = "节点ID不能超过255个字符")
@Schema(description = "节点ID")
private String nodeId;
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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