Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
Y
yd-csf
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
xingmin
yd-csf
Commits
0ac1d533
Commit
0ac1d533
authored
Oct 23, 2026
by
jianan
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
转介人门户:OIDC 登录与行级隔离,新增仪表盘/保单/在途佣金/月结单/待办接口
parent
b81c107f
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
27 changed files
with
1280 additions
and
0 deletions
+1280
-0
yd-csf-api/src/main/java/com/yd/csf/api/controller/ReferrerDashboardController.java
+34
-0
yd-csf-api/src/main/java/com/yd/csf/api/controller/ReferrerPipelineController.java
+36
-0
yd-csf-api/src/main/java/com/yd/csf/api/controller/ReferrerPolicyController.java
+46
-0
yd-csf-api/src/main/java/com/yd/csf/api/controller/ReferrerStatementController.java
+47
-0
yd-csf-api/src/main/java/com/yd/csf/api/controller/ReferrerTodoController.java
+35
-0
yd-csf-api/src/main/java/com/yd/csf/api/dto/ReferrerTodoNotifyRequest.java
+19
-0
yd-csf-api/src/main/java/com/yd/csf/api/security/ReferrerIdentityContext.java
+57
-0
yd-csf-api/src/main/java/com/yd/csf/api/security/ReferrerIdentityFilter.java
+145
-0
yd-csf-api/src/main/java/com/yd/csf/api/security/ReferrerOidcProperties.java
+53
-0
yd-csf-api/src/main/java/com/yd/csf/api/security/ReferrerPortalSecurityConfig.java
+94
-0
yd-csf-service/src/main/java/com/yd/csf/service/dao/ReferrerTodoMapper.java
+11
-0
yd-csf-service/src/main/java/com/yd/csf/service/enums/ReferrerCommissionStage.java
+38
-0
yd-csf-service/src/main/java/com/yd/csf/service/model/ReferrerTodo.java
+47
-0
yd-csf-service/src/main/java/com/yd/csf/service/service/IReferrerPortalService.java
+50
-0
yd-csf-service/src/main/java/com/yd/csf/service/service/IReferrerTodoService.java
+20
-0
yd-csf-service/src/main/java/com/yd/csf/service/service/impl/ReferrerPortalServiceImpl.java
+0
-0
yd-csf-service/src/main/java/com/yd/csf/service/service/impl/ReferrerTodoServiceImpl.java
+35
-0
yd-csf-service/src/main/java/com/yd/csf/service/vo/ReferrerDashboardVO.java
+41
-0
yd-csf-service/src/main/java/com/yd/csf/service/vo/ReferrerPipelineVO.java
+59
-0
yd-csf-service/src/main/java/com/yd/csf/service/vo/ReferrerPolicyCommissionItemVO.java
+62
-0
yd-csf-service/src/main/java/com/yd/csf/service/vo/ReferrerPolicyCommissionVO.java
+36
-0
yd-csf-service/src/main/java/com/yd/csf/service/vo/ReferrerPolicyListVO.java
+26
-0
yd-csf-service/src/main/java/com/yd/csf/service/vo/ReferrerPolicyVO.java
+66
-0
yd-csf-service/src/main/java/com/yd/csf/service/vo/ReferrerStatementDetailVO.java
+75
-0
yd-csf-service/src/main/java/com/yd/csf/service/vo/ReferrerStatementItemVO.java
+71
-0
yd-csf-service/src/main/java/com/yd/csf/service/vo/ReferrerStatementVO.java
+59
-0
yd-csf-service/src/main/resources/sql/referrer_todo.sql
+18
-0
No files found.
yd-csf-api/src/main/java/com/yd/csf/api/controller/ReferrerDashboardController.java
0 → 100644
View file @
0ac1d533
package
com
.
yd
.
csf
.
api
.
controller
;
import
com.yd.common.result.Result
;
import
com.yd.csf.api.security.ReferrerIdentityContext
;
import
com.yd.csf.service.service.IReferrerPortalService
;
import
com.yd.csf.service.vo.ReferrerDashboardVO
;
import
org.springframework.web.bind.annotation.GetMapping
;
import
org.springframework.web.bind.annotation.RequestMapping
;
import
org.springframework.web.bind.annotation.RestController
;
import
javax.annotation.Resource
;
/**
* 转介人门户 - 首页指标。
*
* <p>容器内路径 {@code /c/dashboard/**},对外经 context-path 暴露为
* {@code /csf/api/c/dashboard/**},走转介人门户独立安全链。</p>
*/
@RestController
@RequestMapping
(
"/c/dashboard"
)
public
class
ReferrerDashboardController
{
@Resource
private
IReferrerPortalService
referrerPortalService
;
/**
* 首页指标:本月已发 / 本课税年度累计已发 / 在途佣金 / 生效件数 / 首年 FYP。
*/
@GetMapping
(
"/summary"
)
public
Result
<
ReferrerDashboardVO
>
summary
()
{
String
brokerBizId
=
ReferrerIdentityContext
.
requireBrokerBizId
();
return
Result
.
success
(
referrerPortalService
.
getDashboard
(
brokerBizId
));
}
}
yd-csf-api/src/main/java/com/yd/csf/api/controller/ReferrerPipelineController.java
0 → 100644
View file @
0ac1d533
package
com
.
yd
.
csf
.
api
.
controller
;
import
com.yd.common.result.Result
;
import
com.yd.csf.api.security.ReferrerIdentityContext
;
import
com.yd.csf.service.service.IReferrerPortalService
;
import
com.yd.csf.service.vo.ReferrerPipelineVO
;
import
org.springframework.web.bind.annotation.GetMapping
;
import
org.springframework.web.bind.annotation.RequestMapping
;
import
org.springframework.web.bind.annotation.RestController
;
import
javax.annotation.Resource
;
import
java.util.List
;
/**
* 转介人门户 - 在途佣金。
*
* <p>容器内路径 {@code /c/pipeline/**},对外经 context-path 暴露为
* {@code /csf/api/c/pipeline/**},走转介人门户独立安全链。
* 展示待出账的预计发佣及预计到账日;保留/失效翻译为可读文案。</p>
*/
@RestController
@RequestMapping
(
"/c/pipeline"
)
public
class
ReferrerPipelineController
{
@Resource
private
IReferrerPortalService
referrerPortalService
;
/**
* 在途佣金列表:含预计到账日,按 payout_date 升序。
*/
@GetMapping
(
"/list"
)
public
Result
<
List
<
ReferrerPipelineVO
>>
list
()
{
String
brokerBizId
=
ReferrerIdentityContext
.
requireBrokerBizId
();
return
Result
.
success
(
referrerPortalService
.
listPipeline
(
brokerBizId
));
}
}
yd-csf-api/src/main/java/com/yd/csf/api/controller/ReferrerPolicyController.java
0 → 100644
View file @
0ac1d533
package
com
.
yd
.
csf
.
api
.
controller
;
import
com.yd.common.result.Result
;
import
com.yd.csf.api.security.ReferrerIdentityContext
;
import
com.yd.csf.service.service.IReferrerPortalService
;
import
com.yd.csf.service.vo.ReferrerPolicyCommissionVO
;
import
com.yd.csf.service.vo.ReferrerPolicyListVO
;
import
org.springframework.web.bind.annotation.GetMapping
;
import
org.springframework.web.bind.annotation.PathVariable
;
import
org.springframework.web.bind.annotation.RequestMapping
;
import
org.springframework.web.bind.annotation.RestController
;
import
javax.annotation.Resource
;
/**
* 转介人门户 - 我的保单。
*
* <p>容器内路径 {@code /c/policy/**},对外经 context-path 暴露为
* {@code /csf/api/c/policy/**},走转介人门户独立安全链。
* 生效保单整单展示;退保/失效/拒保分组可见不计件。</p>
*/
@RestController
@RequestMapping
(
"/c/policy"
)
public
class
ReferrerPolicyController
{
@Resource
private
IReferrerPortalService
referrerPortalService
;
/**
* 我的保单:生效 / 未生效失效两组。
*/
@GetMapping
(
"/list"
)
public
Result
<
ReferrerPolicyListVO
>
list
()
{
String
brokerBizId
=
ReferrerIdentityContext
.
requireBrokerBizId
();
return
Result
.
success
(
referrerPortalService
.
listPolicies
(
brokerBizId
));
}
/**
* 保单各年度佣金钻取:首年(FYP/FYC)与续期(RYP/RYC)分列。
*/
@GetMapping
(
"/{policyNo}/commission"
)
public
Result
<
ReferrerPolicyCommissionVO
>
commission
(
@PathVariable
String
policyNo
)
{
String
brokerBizId
=
ReferrerIdentityContext
.
requireBrokerBizId
();
return
Result
.
success
(
referrerPortalService
.
getPolicyCommission
(
brokerBizId
,
policyNo
));
}
}
yd-csf-api/src/main/java/com/yd/csf/api/controller/ReferrerStatementController.java
0 → 100644
View file @
0ac1d533
package
com
.
yd
.
csf
.
api
.
controller
;
import
com.yd.common.result.Result
;
import
com.yd.csf.api.security.ReferrerIdentityContext
;
import
com.yd.csf.service.service.IReferrerPortalService
;
import
com.yd.csf.service.vo.ReferrerStatementDetailVO
;
import
com.yd.csf.service.vo.ReferrerStatementVO
;
import
org.springframework.web.bind.annotation.GetMapping
;
import
org.springframework.web.bind.annotation.PathVariable
;
import
org.springframework.web.bind.annotation.RequestMapping
;
import
org.springframework.web.bind.annotation.RestController
;
import
javax.annotation.Resource
;
import
java.util.List
;
/**
* 转介人门户 - 月结单。
*
* <p>容器内路径 {@code /c/statement/**},对外经 context-path 暴露为
* {@code /csf/api/c/statement/**},走转介人门户独立安全链。
* 仅展示已推送(salary.status=5)的薪资单;头部与逐笔明细各自忠实呈现,不强制二者相等。</p>
*/
@RestController
@RequestMapping
(
"/c/statement"
)
public
class
ReferrerStatementController
{
@Resource
private
IReferrerPortalService
referrerPortalService
;
/**
* 月结单列表:仅已推送,按月份降序。
*/
@GetMapping
(
"/list"
)
public
Result
<
List
<
ReferrerStatementVO
>>
list
()
{
String
brokerBizId
=
ReferrerIdentityContext
.
requireBrokerBizId
();
return
Result
.
success
(
referrerPortalService
.
listStatements
(
brokerBizId
));
}
/**
* 月结单详情:头部应发/MPF/其他调整/实发/发放日/银行尾号 + 逐笔保单发佣明细。
*/
@GetMapping
(
"/{salaryBizId}"
)
public
Result
<
ReferrerStatementDetailVO
>
detail
(
@PathVariable
String
salaryBizId
)
{
String
brokerBizId
=
ReferrerIdentityContext
.
requireBrokerBizId
();
return
Result
.
success
(
referrerPortalService
.
getStatementDetail
(
brokerBizId
,
salaryBizId
));
}
}
yd-csf-api/src/main/java/com/yd/csf/api/controller/ReferrerTodoController.java
0 → 100644
View file @
0ac1d533
package
com
.
yd
.
csf
.
api
.
controller
;
import
com.yd.common.result.Result
;
import
com.yd.csf.api.dto.ReferrerTodoNotifyRequest
;
import
com.yd.csf.api.security.ReferrerIdentityContext
;
import
com.yd.csf.service.service.IReferrerTodoService
;
import
org.springframework.validation.annotation.Validated
;
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
javax.annotation.Resource
;
/**
* 转介人待办通知留痕接口
*/
@RestController
@RequestMapping
(
"/c/todo"
)
public
class
ReferrerTodoController
{
@Resource
private
IReferrerTodoService
referrerTodoService
;
/**
* 已通知 / 处理留痕
*/
@PostMapping
(
"/notify"
)
public
Result
<
Boolean
>
notify
(
@Validated
@RequestBody
ReferrerTodoNotifyRequest
request
)
{
String
clientUserBizId
=
ReferrerIdentityContext
.
requireClientUserBizId
();
referrerTodoService
.
recordNotify
(
clientUserBizId
,
request
.
getPolicyNo
(),
request
.
getTodoType
());
return
Result
.
success
(
Boolean
.
TRUE
);
}
}
\ No newline at end of file
yd-csf-api/src/main/java/com/yd/csf/api/dto/ReferrerTodoNotifyRequest.java
0 → 100644
View file @
0ac1d533
package
com
.
yd
.
csf
.
api
.
dto
;
import
lombok.Data
;
import
javax.validation.constraints.NotBlank
;
/**
* 待办通知留痕请求
*/
@Data
public
class
ReferrerTodoNotifyRequest
{
@NotBlank
(
message
=
"保单号不能为空"
)
private
String
policyNo
;
@NotBlank
(
message
=
"待办类型不能为空"
)
private
String
todoType
;
}
\ No newline at end of file
yd-csf-api/src/main/java/com/yd/csf/api/security/ReferrerIdentityContext.java
0 → 100644
View file @
0ac1d533
package
com
.
yd
.
csf
.
api
.
security
;
import
com.yd.common.exception.BusinessException
;
/**
* 当前转介人登录身份上下文。
*
* <p>业务接口只从本类取登录身份,不接收前端身份入参。</p>
*
* <p>身份说明:csf 库的 {@code broker_biz_id}(policy_broker / salary / fortune /
* expected_fortune 等行级归属字段)与 IAM 的 {@code clientUserBizId} 是<b>同一个 ID、
* 同一命名空间</b>,并非两套主键。依据:{@code policy_broker.broker_biz_id} 实际落值为
* {@code client_user_xxx};预计发佣生成逻辑中直接
* {@code resDto.setClientUserBizId(brokerDto.getBrokerBizId())},
* {@code ConditionConfigMapper} 亦以 {@code agent_id AS brokerBizId}。
* 因此行级数据查询直接用登录 {@code clientUserBizId} 作为 {@code brokerBizId},
* 无需任何映射表或手机号反查。</p>
*/
public
final
class
ReferrerIdentityContext
{
private
static
final
ThreadLocal
<
String
>
CLIENT_USER_BIZ_ID
=
new
ThreadLocal
<>();
private
ReferrerIdentityContext
()
{
}
public
static
void
setClientUserBizId
(
String
clientUserBizId
)
{
CLIENT_USER_BIZ_ID
.
set
(
clientUserBizId
);
}
public
static
String
getClientUserBizId
()
{
return
CLIENT_USER_BIZ_ID
.
get
();
}
public
static
String
requireClientUserBizId
()
{
String
clientUserBizId
=
CLIENT_USER_BIZ_ID
.
get
();
if
(
clientUserBizId
==
null
||
clientUserBizId
.
trim
().
isEmpty
())
{
throw
new
BusinessException
(
"缺失转介人登录身份"
);
}
return
clientUserBizId
;
}
/**
* 当前登录转介人在 csf 行级数据上使用的 {@code brokerBizId}。
*
* <p>当前与 {@link #requireClientUserBizId()} 同值(恒等),语义化方法:
* Controller 取行级归属 ID 应调用本方法,而非直接拿 clientUserBizId。
* 若将来出现独立 broker 命名空间,只需在此桥接一处。</p>
*/
public
static
String
requireBrokerBizId
()
{
return
requireClientUserBizId
();
}
public
static
void
clear
()
{
CLIENT_USER_BIZ_ID
.
remove
();
}
}
\ No newline at end of file
yd-csf-api/src/main/java/com/yd/csf/api/security/ReferrerIdentityFilter.java
0 → 100644
View file @
0ac1d533
package
com
.
yd
.
csf
.
api
.
security
;
import
com.yd.common.enums.CommonEnum
;
import
com.yd.common.result.Result
;
import
com.yd.user.feign.client.clientuser.ApiClientUserFeignClient
;
import
com.yd.user.feign.response.clientuser.ApiClientUserIdpLoginResponse
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.security.authentication.UsernamePasswordAuthenticationToken
;
import
org.springframework.security.core.context.SecurityContextHolder
;
import
org.springframework.security.oauth2.jwt.Jwt
;
import
org.springframework.security.oauth2.jwt.JwtDecoder
;
import
org.springframework.security.oauth2.jwt.JwtException
;
import
org.springframework.util.StringUtils
;
import
org.springframework.web.filter.OncePerRequestFilter
;
import
javax.servlet.FilterChain
;
import
javax.servlet.ServletException
;
import
javax.servlet.http.HttpServletRequest
;
import
javax.servlet.http.HttpServletResponse
;
import
java.io.IOException
;
import
java.util.Collections
;
import
java.util.Objects
;
/**
* 转介人门户身份过滤器。
*
* <p>两种身份来源,按优先级:</p>
* <ol>
* <li>请求携带 {@code Authorization: Bearer} 且配置了 JWKS:用 {@link JwtDecoder} 校验
* RS256 + iss + aud,取 {@code sub} 调 yd-user 解析客户端用户,
* 并强制 {@code status=1 && approval_status=CG} 门禁;</li>
* <li>未携带 token 但配置了 {@code referrer.oidc.mock-client-user-biz-id}:注入固定身份,
* 仅供开发期联调(生产不得配置)。</li>
* </ol>
*
* <p>无法建立身份时不写入 SecurityContext,由链内授权规则返回 401。</p>
*/
@Slf4j
public
class
ReferrerIdentityFilter
extends
OncePerRequestFilter
{
private
static
final
String
BEARER_PREFIX
=
"Bearer "
;
private
final
ReferrerOidcProperties
properties
;
private
final
ApiClientUserFeignClient
clientUserFeignClient
;
private
final
JwtDecoder
jwtDecoder
;
public
ReferrerIdentityFilter
(
ReferrerOidcProperties
properties
,
ApiClientUserFeignClient
clientUserFeignClient
,
JwtDecoder
jwtDecoder
)
{
this
.
properties
=
properties
;
this
.
clientUserFeignClient
=
clientUserFeignClient
;
this
.
jwtDecoder
=
jwtDecoder
;
}
@Override
protected
void
doFilterInternal
(
HttpServletRequest
request
,
HttpServletResponse
response
,
FilterChain
filterChain
)
throws
ServletException
,
IOException
{
boolean
authenticated
=
false
;
String
token
=
resolveBearerToken
(
request
);
if
(
StringUtils
.
hasText
(
token
)
&&
jwtDecoder
!=
null
)
{
authenticated
=
authenticateWithJwt
(
token
);
}
else
if
(
StringUtils
.
hasText
(
token
))
{
log
.
warn
(
"收到 Bearer token 但 JwtDecoder 未初始化:referrer.oidc.jwk-set-uri 是否配置?"
);
}
else
if
(
StringUtils
.
hasText
(
properties
.
getMockClientUserBizId
()))
{
applyIdentity
(
properties
.
getMockClientUserBizId
());
authenticated
=
true
;
}
else
{
log
.
debug
(
"请求未携带 Bearer token,且未配置 mock 身份"
);
}
if
(!
authenticated
)
{
filterChain
.
doFilter
(
request
,
response
);
return
;
}
try
{
filterChain
.
doFilter
(
request
,
response
);
}
finally
{
ReferrerIdentityContext
.
clear
();
}
}
/**
* 验签并按 sub 解析转介人身份;任何校验失败返回 false(不抛错、不泄露原因)。
*/
private
boolean
authenticateWithJwt
(
String
token
)
{
Jwt
jwt
;
try
{
jwt
=
jwtDecoder
.
decode
(
token
);
}
catch
(
JwtException
|
IllegalArgumentException
e
)
{
log
.
warn
(
"JWT 验签/校验失败:{}"
,
e
.
getMessage
());
return
false
;
}
String
sub
=
jwt
.
getSubject
();
if
(!
StringUtils
.
hasText
(
sub
))
{
log
.
warn
(
"JWT 缺少 sub claim"
);
return
false
;
}
Result
<
ApiClientUserIdpLoginResponse
>
result
=
clientUserFeignClient
.
getByIdpSub
(
properties
.
getTenantBizId
(),
sub
);
if
(
Objects
.
isNull
(
result
))
{
log
.
warn
(
"调用 yd-user getByIdpSub 失败(Feign 降级返回 null),tenantBizId={} sub={}"
,
properties
.
getTenantBizId
(),
sub
);
return
false
;
}
if
(
Objects
.
isNull
(
result
.
getData
()))
{
log
.
warn
(
"IdP 身份未绑定 client_user 或租户不匹配,tenantBizId={} sub={} code={} msg={}"
,
properties
.
getTenantBizId
(),
sub
,
result
.
getCode
(),
result
.
getMsg
());
return
false
;
}
ApiClientUserIdpLoginResponse
login
=
result
.
getData
();
if
(!
Integer
.
valueOf
(
1
).
equals
(
login
.
getStatus
()))
{
log
.
warn
(
"转介人账号已停用 status={} clientUserBizId={}"
,
login
.
getStatus
(),
login
.
getClientUserBizId
());
return
false
;
}
if
(!
CommonEnum
.
APPROVAL_STATUS_CG
.
getCode
().
equals
(
login
.
getApprovalStatus
()))
{
log
.
warn
(
"转介人审批状态不可登录 approvalStatus={} clientUserBizId={}"
,
login
.
getApprovalStatus
(),
login
.
getClientUserBizId
());
return
false
;
}
applyIdentity
(
login
.
getClientUserBizId
());
return
true
;
}
private
void
applyIdentity
(
String
clientUserBizId
)
{
ReferrerIdentityContext
.
setClientUserBizId
(
clientUserBizId
);
UsernamePasswordAuthenticationToken
authentication
=
new
UsernamePasswordAuthenticationToken
(
clientUserBizId
,
null
,
Collections
.
emptyList
());
SecurityContextHolder
.
getContext
().
setAuthentication
(
authentication
);
}
private
String
resolveBearerToken
(
HttpServletRequest
request
)
{
String
header
=
request
.
getHeader
(
"Authorization"
);
if
(
StringUtils
.
hasText
(
header
)
&&
header
.
startsWith
(
BEARER_PREFIX
))
{
return
header
.
substring
(
BEARER_PREFIX
.
length
()).
trim
();
}
return
null
;
}
}
yd-csf-api/src/main/java/com/yd/csf/api/security/ReferrerOidcProperties.java
0 → 100644
View file @
0ac1d533
package
com
.
yd
.
csf
.
api
.
security
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.context.annotation.Configuration
;
import
org.springframework.stereotype.Component
;
/**
* 转介人门户 OIDC 配置占位。
*
* <p>真实值由 Nacos 提供,开发期可只配置 {@code mockClientUserBizId} 跑通数据接口。</p>
*/
@Configuration
public
class
ReferrerOidcProperties
{
@Value
(
"${referrer.oidc.jwk-set-uri:}"
)
private
String
jwkSetUri
;
@Value
(
"${referrer.oidc.issuer:}"
)
private
String
issuer
;
@Value
(
"${referrer.oidc.audience:}"
)
private
String
audience
;
/**
* 转介人所属租户业务ID(csf 当前为单租户部署,认证时身份解析限定该租户)
*/
@Value
(
"${referrer.oidc.tenant-biz-id:}"
)
private
String
tenantBizId
;
@Value
(
"${referrer.oidc.mock-client-user-biz-id:}"
)
private
String
mockClientUserBizId
;
public
String
getJwkSetUri
()
{
return
jwkSetUri
;
}
public
String
getIssuer
()
{
return
issuer
;
}
public
String
getAudience
()
{
return
audience
;
}
public
String
getTenantBizId
()
{
return
tenantBizId
;
}
public
String
getMockClientUserBizId
()
{
return
mockClientUserBizId
;
}
}
\ No newline at end of file
yd-csf-api/src/main/java/com/yd/csf/api/security/ReferrerPortalSecurityConfig.java
0 → 100644
View file @
0ac1d533
package
com
.
yd
.
csf
.
api
.
security
;
import
com.yd.user.feign.client.clientuser.ApiClientUserFeignClient
;
import
org.springframework.context.annotation.Configuration
;
import
org.springframework.core.annotation.Order
;
import
org.springframework.http.HttpStatus
;
import
org.springframework.security.config.annotation.web.builders.HttpSecurity
;
import
org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter
;
import
org.springframework.security.config.http.SessionCreationPolicy
;
import
org.springframework.security.oauth2.core.OAuth2TokenValidator
;
import
org.springframework.security.oauth2.jwt.Jwt
;
import
org.springframework.security.oauth2.jwt.JwtClaimValidator
;
import
org.springframework.security.oauth2.jwt.JwtDecoder
;
import
org.springframework.security.oauth2.jwt.JwtIssuerValidator
;
import
org.springframework.security.oauth2.jwt.JwtTimestampValidator
;
import
org.springframework.security.oauth2.jwt.NimbusJwtDecoder
;
import
org.springframework.security.oauth2.core.DelegatingOAuth2TokenValidator
;
import
org.springframework.security.oauth2.jose.jws.SignatureAlgorithm
;
import
org.springframework.security.web.authentication.HttpStatusEntryPoint
;
import
org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter
;
import
org.springframework.util.StringUtils
;
import
java.util.ArrayList
;
import
java.util.Collection
;
import
java.util.List
;
/**
* 转介人门户独立安全链。
*
* <p>必须沿用 {@link WebSecurityConfigurerAdapter} 老式风格:yd-auth-core 的后台链也是
* Adapter 风格,Spring Security 5.6 不允许 Adapter 与 {@code SecurityFilterChain} Bean 混用,
* 否则启动报 “Found WebSecurityConfigurerAdapter as well as SecurityFilterChain”。</p>
*
* <p>多个 Adapter 凭 {@link Order} 共存:本链 {@code @Order(1)} 优先匹配容器内
* {@code /c/**}(对外 {@code /csf/api/c/**}),其余请求落老链(兜底 {@code /**})。</p>
*/
@Configuration
@Order
(
1
)
public
class
ReferrerPortalSecurityConfig
extends
WebSecurityConfigurerAdapter
{
private
final
ReferrerOidcProperties
properties
;
private
final
ApiClientUserFeignClient
clientUserFeignClient
;
public
ReferrerPortalSecurityConfig
(
ReferrerOidcProperties
properties
,
ApiClientUserFeignClient
clientUserFeignClient
)
{
this
.
properties
=
properties
;
this
.
clientUserFeignClient
=
clientUserFeignClient
;
}
@Override
protected
void
configure
(
HttpSecurity
http
)
throws
Exception
{
http
.
antMatcher
(
"/c/**"
)
.
csrf
().
disable
()
.
sessionManagement
().
sessionCreationPolicy
(
SessionCreationPolicy
.
STATELESS
)
.
and
()
.
exceptionHandling
()
// 未携带有效身份时直接 401,避免落到默认 403/登录页
.
authenticationEntryPoint
(
new
HttpStatusEntryPoint
(
HttpStatus
.
UNAUTHORIZED
))
.
and
()
.
authorizeRequests
()
.
anyRequest
().
authenticated
()
.
and
()
// 链内手动 new:不加 @Component,避免被 Boot 注册成容器级 Filter 污染老后台 /** 链
.
addFilterBefore
(
new
ReferrerIdentityFilter
(
properties
,
clientUserFeignClient
,
buildJwtDecoder
()),
UsernamePasswordAuthenticationFilter
.
class
);
}
/**
* 构建 RS256 JWKS 解码器,校验时间戳 + iss + aud(aud 为数组时要求包含配置 audience)。
* 未配置 jwk-set-uri 时返回 null,过滤器退化为开发期 mock 身份。
*/
private
JwtDecoder
buildJwtDecoder
()
{
if
(!
StringUtils
.
hasText
(
properties
.
getJwkSetUri
()))
{
return
null
;
}
NimbusJwtDecoder
decoder
=
NimbusJwtDecoder
.
withJwkSetUri
(
properties
.
getJwkSetUri
())
.
jwsAlgorithm
(
SignatureAlgorithm
.
RS256
)
.
build
();
List
<
OAuth2TokenValidator
<
Jwt
>>
validators
=
new
ArrayList
<>();
validators
.
add
(
new
JwtTimestampValidator
());
if
(
StringUtils
.
hasText
(
properties
.
getIssuer
()))
{
validators
.
add
(
new
JwtIssuerValidator
(
properties
.
getIssuer
()));
}
if
(
StringUtils
.
hasText
(
properties
.
getAudience
()))
{
String
audience
=
properties
.
getAudience
();
validators
.
add
(
new
JwtClaimValidator
<
Collection
<?>>(
"aud"
,
aud
->
aud
!=
null
&&
aud
.
contains
(
audience
)));
}
decoder
.
setJwtValidator
(
new
DelegatingOAuth2TokenValidator
<>(
validators
));
return
decoder
;
}
}
yd-csf-service/src/main/java/com/yd/csf/service/dao/ReferrerTodoMapper.java
0 → 100644
View file @
0ac1d533
package
com
.
yd
.
csf
.
service
.
dao
;
import
com.baomidou.mybatisplus.core.mapper.BaseMapper
;
import
com.yd.csf.service.model.ReferrerTodo
;
/**
* 转介人待办通知留痕表 Mapper
*/
public
interface
ReferrerTodoMapper
extends
BaseMapper
<
ReferrerTodo
>
{
}
\ No newline at end of file
yd-csf-service/src/main/java/com/yd/csf/service/enums/ReferrerCommissionStage.java
0 → 100644
View file @
0ac1d533
package
com
.
yd
.
csf
.
service
.
enums
;
/**
* 转介人门户佣金四态(design D4.1)。
*
* <p>系统内部出账状态(expected_fortune/fortune 0–7、salary 1–6)不直接对外,
* 统一收敛为转介人语言的四个「钱的位置」。守恒式(互斥且闭合):
* {@code 应得 = 已发 + 在途 + 保留 + 失效}。</p>
*/
public
enum
ReferrerCommissionStage
{
/** 已发:已完成出账、已到手。 */
PAID
,
/** 在途:钱会来、尚未到(待出账、部分出账的未付段、分期未到期、未找到来佣 7)。 */
PIPELINE
,
/** 保留:暂扣、未说不给。 */
RETAINED
,
/** 失效:这笔没了。 */
LAPSED
;
/**
* expected_fortune 整行状态 -> 四态(用于只展示剩余待发的在途列表)。
* 不产生 {@link #PAID}:全额出账无独立状态码,已发须按 paid/unpaid 金额判定。
*/
public
static
ReferrerCommissionStage
fromExpectedStatus
(
String
status
)
{
if
(
"4"
.
equals
(
status
))
{
return
RETAINED
;
}
if
(
"5"
.
equals
(
status
))
{
return
LAPSED
;
}
// 0/1/2/3/6/7 均按在途;7(未找到来佣)遵 D4.1 归在途,不得判失效。
return
PIPELINE
;
}
}
yd-csf-service/src/main/java/com/yd/csf/service/model/ReferrerTodo.java
0 → 100644
View file @
0ac1d533
package
com
.
yd
.
csf
.
service
.
model
;
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
lombok.Getter
;
import
lombok.Setter
;
import
java.io.Serializable
;
import
java.time.LocalDateTime
;
/**
* 转介人待办通知留痕表
*/
@Getter
@Setter
@TableName
(
"referrer_todo"
)
public
class
ReferrerTodo
implements
Serializable
{
private
static
final
long
serialVersionUID
=
1L
;
@TableId
(
value
=
"id"
,
type
=
IdType
.
AUTO
)
private
Long
id
;
@TableField
(
"todo_biz_id"
)
private
String
todoBizId
;
@TableField
(
"broker_biz_id"
)
private
String
brokerBizId
;
@TableField
(
"policy_no"
)
private
String
policyNo
;
@TableField
(
"todo_type"
)
private
String
todoType
;
@TableField
(
"notify_time"
)
private
LocalDateTime
notifyTime
;
@TableField
(
"create_time"
)
private
LocalDateTime
createTime
;
@TableField
(
"update_time"
)
private
LocalDateTime
updateTime
;
}
\ No newline at end of file
yd-csf-service/src/main/java/com/yd/csf/service/service/IReferrerPortalService.java
0 → 100644
View file @
0ac1d533
package
com
.
yd
.
csf
.
service
.
service
;
import
com.yd.csf.service.vo.ReferrerDashboardVO
;
import
com.yd.csf.service.vo.ReferrerPipelineVO
;
import
com.yd.csf.service.vo.ReferrerPolicyCommissionVO
;
import
com.yd.csf.service.vo.ReferrerPolicyListVO
;
import
com.yd.csf.service.vo.ReferrerStatementDetailVO
;
import
com.yd.csf.service.vo.ReferrerStatementVO
;
import
java.util.List
;
/**
* 转介人门户只读数据服务。
*
* <p>所有方法均要求调用方传入已解析的转介人 {@code brokerBizId},
* 服务层不接收任何前端身份入参。</p>
*/
public
interface
IReferrerPortalService
{
/**
* 首页指标。
*/
ReferrerDashboardVO
getDashboard
(
String
brokerBizId
);
/**
* 月结单列表(仅已推送,按月份降序)。
*/
List
<
ReferrerStatementVO
>
listStatements
(
String
brokerBizId
);
/**
* 月结单详情。
*/
ReferrerStatementDetailVO
getStatementDetail
(
String
brokerBizId
,
String
salaryBizId
);
/**
* 我的保单(生效 / 未生效失效分组)。
*/
ReferrerPolicyListVO
listPolicies
(
String
brokerBizId
);
/**
* 保单各年度佣金钻取。
*/
ReferrerPolicyCommissionVO
getPolicyCommission
(
String
brokerBizId
,
String
policyNo
);
/**
* 在途佣金列表。
*/
List
<
ReferrerPipelineVO
>
listPipeline
(
String
brokerBizId
);
}
\ No newline at end of file
yd-csf-service/src/main/java/com/yd/csf/service/service/IReferrerTodoService.java
0 → 100644
View file @
0ac1d533
package
com
.
yd
.
csf
.
service
.
service
;
import
com.baomidou.mybatisplus.extension.service.IService
;
import
com.yd.csf.service.model.ReferrerTodo
;
/**
* 转介人待办通知留痕服务
*/
public
interface
IReferrerTodoService
extends
IService
<
ReferrerTodo
>
{
/**
* 记录一次「已通知」留痕。
*
* @param brokerBizId 登录态转介人业务 ID
* @param policyNo 保单号
* @param todoType 待办类型
*/
void
recordNotify
(
String
brokerBizId
,
String
policyNo
,
String
todoType
);
}
\ No newline at end of file
yd-csf-service/src/main/java/com/yd/csf/service/service/impl/ReferrerPortalServiceImpl.java
0 → 100644
View file @
0ac1d533
This diff is collapsed.
Click to expand it.
yd-csf-service/src/main/java/com/yd/csf/service/service/impl/ReferrerTodoServiceImpl.java
0 → 100644
View file @
0ac1d533
package
com
.
yd
.
csf
.
service
.
service
.
impl
;
import
com.baomidou.mybatisplus.extension.service.impl.ServiceImpl
;
import
com.yd.csf.service.dao.ReferrerTodoMapper
;
import
com.yd.csf.service.model.ReferrerTodo
;
import
com.yd.csf.service.service.IReferrerTodoService
;
import
org.springframework.stereotype.Service
;
import
org.springframework.transaction.annotation.Transactional
;
import
java.time.LocalDateTime
;
import
java.util.UUID
;
/**
* 转介人待办通知留痕服务实现
*/
@Service
public
class
ReferrerTodoServiceImpl
extends
ServiceImpl
<
ReferrerTodoMapper
,
ReferrerTodo
>
implements
IReferrerTodoService
{
@Override
@Transactional
(
rollbackFor
=
Exception
.
class
)
public
void
recordNotify
(
String
brokerBizId
,
String
policyNo
,
String
todoType
)
{
LocalDateTime
now
=
LocalDateTime
.
now
();
ReferrerTodo
todo
=
new
ReferrerTodo
();
todo
.
setTodoBizId
(
UUID
.
randomUUID
().
toString
().
replace
(
"-"
,
""
));
todo
.
setBrokerBizId
(
brokerBizId
);
todo
.
setPolicyNo
(
policyNo
);
todo
.
setTodoType
(
todoType
);
todo
.
setNotifyTime
(
now
);
todo
.
setCreateTime
(
now
);
todo
.
setUpdateTime
(
now
);
this
.
save
(
todo
);
}
}
\ No newline at end of file
yd-csf-service/src/main/java/com/yd/csf/service/vo/ReferrerDashboardVO.java
0 → 100644
View file @
0ac1d533
package
com
.
yd
.
csf
.
service
.
vo
;
import
lombok.Data
;
import
java.io.Serializable
;
import
java.math.BigDecimal
;
/**
* 转介人首页指标。
*/
@Data
public
class
ReferrerDashboardVO
implements
Serializable
{
private
static
final
long
serialVersionUID
=
1L
;
/**
* 本月已发佣金(HKD)
*/
private
BigDecimal
monthPaidCommission
;
/**
* 本课税年度累计已发佣金(HKD)
*/
private
BigDecimal
taxYearPaidCommission
;
/**
* 在途佣金(HKD,不含失效/未找到来佣)
*/
private
BigDecimal
pipelineCommission
;
/**
* 生效件数
*/
private
Long
effectivePolicyCount
;
/**
* 首年业绩 FYP(HKD,按本人占比折算)
*/
private
BigDecimal
firstYearFyp
;
}
\ No newline at end of file
yd-csf-service/src/main/java/com/yd/csf/service/vo/ReferrerPipelineVO.java
0 → 100644
View file @
0ac1d533
package
com
.
yd
.
csf
.
service
.
vo
;
import
com.fasterxml.jackson.annotation.JsonFormat
;
import
lombok.Data
;
import
java.io.Serializable
;
import
java.math.BigDecimal
;
import
java.time.LocalDate
;
/**
* 转介人在途佣金项。
*/
@Data
public
class
ReferrerPipelineVO
implements
Serializable
{
private
static
final
long
serialVersionUID
=
1L
;
/**
* 预计发佣业务ID
*/
private
String
expectedFortuneBizId
;
/**
* 保单号
*/
private
String
policyNo
;
/**
* 产品名称
*/
private
String
productName
;
/**
* 发佣期数(1=第一年...)
*/
private
Integer
fortunePeriod
;
/**
* 发佣名称
*/
private
String
fortuneName
;
/**
* 预计出账日期
*/
@JsonFormat
(
pattern
=
"yyyy-MM-dd"
,
timezone
=
"GMT+8"
)
private
LocalDate
payoutDate
;
/**
* 语义状态码:PAID / PIPELINE / RETAINED / LAPSED(D4.1)
*/
private
String
stage
;
/**
* 在途金额(剩余发放折合港币)
*/
private
BigDecimal
hkdAmount
;
}
\ No newline at end of file
yd-csf-service/src/main/java/com/yd/csf/service/vo/ReferrerPolicyCommissionItemVO.java
0 → 100644
View file @
0ac1d533
package
com
.
yd
.
csf
.
service
.
vo
;
import
com.fasterxml.jackson.annotation.JsonFormat
;
import
lombok.Data
;
import
java.io.Serializable
;
import
java.math.BigDecimal
;
import
java.time.LocalDate
;
/**
* 转介人保单佣金段:一个保单年度的钱按「钱的位置」(D4.1) 拆分后的一段。
*
* <p>部分出账的年度会产出两段:{@code PAID(已出账金额)} + {@code PIPELINE(待出账金额)},
* 保证各段金额相加恒等于该年度应得。</p>
*/
@Data
public
class
ReferrerPolicyCommissionItemVO
implements
Serializable
{
private
static
final
long
serialVersionUID
=
1L
;
/**
* 语义状态码:PAID / PIPELINE / RETAINED / LAPSED
*/
private
String
stage
;
/**
* 发佣期数(1=第一年...)
*/
private
Integer
fortunePeriod
;
/**
* 年度文案:首年 / 第2年 / 第3年...
*/
private
String
periodLabel
;
/**
* 发佣名称
*/
private
String
fortuneName
;
/**
* 保留/失效原因(财务登记,未登记时为空,前端不臆造)
*/
private
String
statusDesc
;
/**
* 该段金额(HKD)
*/
private
BigDecimal
amount
;
/**
* 预计出账日
*/
@JsonFormat
(
pattern
=
"yyyy-MM-dd"
,
timezone
=
"GMT+8"
)
private
LocalDate
payoutDate
;
/**
* 实际出账日
*/
@JsonFormat
(
pattern
=
"yyyy-MM-dd"
,
timezone
=
"GMT+8"
)
private
LocalDate
actualPayoutDate
;
}
yd-csf-service/src/main/java/com/yd/csf/service/vo/ReferrerPolicyCommissionVO.java
0 → 100644
View file @
0ac1d533
package
com
.
yd
.
csf
.
service
.
vo
;
import
lombok.Data
;
import
java.io.Serializable
;
import
java.util.List
;
/**
* 转介人保单佣金钻取结果。
*/
@Data
public
class
ReferrerPolicyCommissionVO
implements
Serializable
{
private
static
final
long
serialVersionUID
=
1L
;
/**
* 保单号
*/
private
String
policyNo
;
/**
* 首年佣金(FYC,HKD)
*/
private
java
.
math
.
BigDecimal
firstYearCommission
;
/**
* 续期佣金(RYC,HKD)
*/
private
java
.
math
.
BigDecimal
renewalCommission
;
/**
* 各年度佣金明细
*/
private
List
<
ReferrerPolicyCommissionItemVO
>
items
;
}
\ No newline at end of file
yd-csf-service/src/main/java/com/yd/csf/service/vo/ReferrerPolicyListVO.java
0 → 100644
View file @
0ac1d533
package
com
.
yd
.
csf
.
service
.
vo
;
import
lombok.Data
;
import
java.io.Serializable
;
import
java.util.List
;
/**
* 转介人名下保单分组。
*/
@Data
public
class
ReferrerPolicyListVO
implements
Serializable
{
private
static
final
long
serialVersionUID
=
1L
;
/**
* 生效保单(计件计业绩)
*/
private
List
<
ReferrerPolicyVO
>
effectivePolicies
;
/**
* 未生效/已失效保单(可见不计件计业绩)
*/
private
List
<
ReferrerPolicyVO
>
inactivePolicies
;
}
\ No newline at end of file
yd-csf-service/src/main/java/com/yd/csf/service/vo/ReferrerPolicyVO.java
0 → 100644
View file @
0ac1d533
package
com
.
yd
.
csf
.
service
.
vo
;
import
lombok.Data
;
import
java.io.Serializable
;
import
java.math.BigDecimal
;
/**
* 转介人名下保单。
*/
@Data
public
class
ReferrerPolicyVO
implements
Serializable
{
private
static
final
long
serialVersionUID
=
1L
;
/**
* 保单号
*/
private
String
policyNo
;
/**
* 保單持有人
*/
private
String
policyHolder
;
/**
* 受保人
*/
private
String
insured
;
/**
* 产品名称
*/
private
String
productName
;
/**
* 保险公司
*/
private
String
insuranceCompany
;
/**
* 保单币种
*/
private
String
currency
;
/**
* 全额保费(承保规模,原币)
*/
private
BigDecimal
fullPremium
;
/**
* 全额保费(HKD)
*/
private
BigDecimal
fullPremiumHkd
;
/**
* 我的介绍费占比
*/
private
String
myRatio
;
/**
* 保单状态
*/
private
String
status
;
}
\ No newline at end of file
yd-csf-service/src/main/java/com/yd/csf/service/vo/ReferrerStatementDetailVO.java
0 → 100644
View file @
0ac1d533
package
com
.
yd
.
csf
.
service
.
vo
;
import
com.fasterxml.jackson.annotation.JsonFormat
;
import
lombok.Data
;
import
java.io.Serializable
;
import
java.math.BigDecimal
;
import
java.time.LocalDate
;
import
java.util.List
;
/**
* 转介人月结单详情。
*/
@Data
public
class
ReferrerStatementDetailVO
implements
Serializable
{
private
static
final
long
serialVersionUID
=
1L
;
/**
* 薪资单业务ID
*/
private
String
salaryBizId
;
/**
* 薪资月份 yyyyMM
*/
private
String
month
;
/**
* 发放编号
*/
private
String
salaryNo
;
/**
* 应发总金额(HKD)
*/
private
BigDecimal
grossAmount
;
/**
* MPF事项总金额(HKD)
*/
private
BigDecimal
mpfAmount
;
/**
* 其他调整总金额(HKD)
*/
private
BigDecimal
otherAmount
;
/**
* 实发总金额(HKD)
*/
private
BigDecimal
paidAmount
;
/**
* 发放日
*/
@JsonFormat
(
pattern
=
"yyyy-MM-dd"
,
timezone
=
"GMT+8"
)
private
LocalDate
payoutDate
;
/**
* 收款银行名称
*/
private
String
bankName
;
/**
* 账户尾号
*/
private
String
accountEndNo
;
/**
* 逐笔保单明细
*/
private
List
<
ReferrerStatementItemVO
>
items
;
}
\ No newline at end of file
yd-csf-service/src/main/java/com/yd/csf/service/vo/ReferrerStatementItemVO.java
0 → 100644
View file @
0ac1d533
package
com
.
yd
.
csf
.
service
.
vo
;
import
lombok.Data
;
import
java.io.Serializable
;
import
java.math.BigDecimal
;
/**
* 转介人月结单逐笔明细项。
*/
@Data
public
class
ReferrerStatementItemVO
implements
Serializable
{
private
static
final
long
serialVersionUID
=
1L
;
/**
* 保单号
*/
private
String
policyNo
;
/**
* 保單持有人
*/
private
String
policyHolder
;
/**
* 保险公司
*/
private
String
insuranceCompany
;
/**
* 产品名称
*/
private
String
productName
;
/**
* 发佣期数(1=第一年...)
*/
private
Integer
fortunePeriod
;
/**
* 发佣名称
*/
private
String
fortuneName
;
/**
* 转介人介绍费占比
*/
private
String
brokerRatio
;
/**
* 原币种
*/
private
String
originalCurrency
;
/**
* 原币种金额
*/
private
BigDecimal
originalAmount
;
/**
* 原币种→港币汇率
*/
private
BigDecimal
originalToHkdRate
;
/**
* 折算港币金额
*/
private
BigDecimal
hkdAmount
;
}
\ No newline at end of file
yd-csf-service/src/main/java/com/yd/csf/service/vo/ReferrerStatementVO.java
0 → 100644
View file @
0ac1d533
package
com
.
yd
.
csf
.
service
.
vo
;
import
com.fasterxml.jackson.annotation.JsonFormat
;
import
lombok.Data
;
import
java.io.Serializable
;
import
java.math.BigDecimal
;
import
java.time.LocalDate
;
/**
* 转介人月结单列表项。
*/
@Data
public
class
ReferrerStatementVO
implements
Serializable
{
private
static
final
long
serialVersionUID
=
1L
;
/**
* 薪资单业务ID
*/
private
String
salaryBizId
;
/**
* 薪资月份 yyyyMM
*/
private
String
month
;
/**
* 发放编号
*/
private
String
salaryNo
;
/**
* 应发总金额(HKD)
*/
private
BigDecimal
grossAmount
;
/**
* MPF事项总金额(HKD)
*/
private
BigDecimal
mpfAmount
;
/**
* 其他调整总金额(HKD)
*/
private
BigDecimal
otherAmount
;
/**
* 实发总金额(HKD)
*/
private
BigDecimal
paidAmount
;
/**
* 发放日(取当月已出账头日期)
*/
@JsonFormat
(
pattern
=
"yyyy-MM-dd"
,
timezone
=
"GMT+8"
)
private
LocalDate
payoutDate
;
}
\ No newline at end of file
yd-csf-service/src/main/resources/sql/referrer_todo.sql
0 → 100644
View file @
0ac1d533
-- 转介人待办通知留痕表 DDL
-- 执行前确认数据库名称
CREATE
TABLE
IF
NOT
EXISTS
`referrer_todo`
(
`id`
BIGINT
NOT
NULL
AUTO_INCREMENT
COMMENT
'主键'
,
`todo_biz_id`
VARCHAR
(
64
)
NOT
NULL
COMMENT
'待办留痕业务ID'
,
`broker_biz_id`
VARCHAR
(
64
)
NOT
NULL
COMMENT
'转介人业务ID(登录态注入)'
,
`policy_no`
VARCHAR
(
64
)
NOT
NULL
COMMENT
'保单号快照'
,
`todo_type`
VARCHAR
(
32
)
NOT
NULL
COMMENT
'待办类型:续期/失效/生日'
,
`notify_time`
DATETIME
COMMENT
'通知时间'
,
`create_time`
DATETIME
DEFAULT
CURRENT_TIMESTAMP
COMMENT
'创建时间'
,
`update_time`
DATETIME
DEFAULT
CURRENT_TIMESTAMP
ON
UPDATE
CURRENT_TIMESTAMP
COMMENT
'更新时间'
,
PRIMARY
KEY
(
`id`
),
INDEX
`idx_todo_biz_id`
(
`todo_biz_id`
),
INDEX
`idx_broker_biz_id`
(
`broker_biz_id`
),
INDEX
`idx_policy_no`
(
`policy_no`
)
)
ENGINE
=
InnoDB
DEFAULT
CHARSET
=
utf8mb4
COMMENT
=
'转介人待办通知留痕表'
;
\ No newline at end of file
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment