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
bf7d94c2
Commit
bf7d94c2
authored
Sep 17, 2026
by
jianan
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
保费到期提醒23-保单邮件逐条通知
parent
15a970a0
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
89 additions
and
72 deletions
+89
-72
yd-csf-api/src/main/java/com/yd/csf/api/service/ApiPolicyFollowExportService.java
+1
-1
yd-csf-api/src/main/java/com/yd/csf/api/service/impl/RenewalDispatchServiceImpl.java
+4
-3
yd-csf-service/src/main/java/com/yd/csf/service/component/renewal/RenewalDueDateCalculator.java
+1
-1
yd-csf-service/src/main/java/com/yd/csf/service/component/renewal/RenewalDuePolicy.java
+1
-1
yd-csf-service/src/main/java/com/yd/csf/service/component/renewal/RenewalPolicyMailBuilder.java
+71
-55
yd-csf-service/src/main/java/com/yd/csf/service/component/renewal/RenewalPolicyReportService.java
+2
-3
yd-csf-service/src/main/java/com/yd/csf/service/component/renewal/RenewalPremiumUtils.java
+1
-1
yd-csf-service/src/main/java/com/yd/csf/service/component/renewal/RenewalReminderData.java
+1
-1
yd-csf-service/src/main/java/com/yd/csf/service/service/RenewalReminderQueryService.java
+1
-1
yd-csf-service/src/main/java/com/yd/csf/service/service/impl/RenewalReminderQueryServiceImpl.java
+3
-3
yd-csf-service/src/main/java/com/yd/csf/service/vo/RenewalPolicyExportDTO.java
+3
-2
No files found.
yd-csf-api/src/main/java/com/yd/csf/api/service/ApiPolicyFollowExportService.java
View file @
bf7d94c2
...
...
@@ -10,7 +10,7 @@ import com.yd.csf.service.component.TemplateStyleStrategy;
import
com.yd.csf.service.dto.PolicyFollowQueryRequest
;
import
com.yd.csf.service.model.PolicyFollow
;
import
com.yd.csf.service.service.PolicyFollowService
;
import
com.yd.csf.service.
utils
.RenewalDueDateCalculator
;
import
com.yd.csf.service.
component.renewal
.RenewalDueDateCalculator
;
import
com.yd.csf.service.utils.SimpleDateUtils
;
import
com.yd.csf.service.vo.RenewalPolicyExportDTO
;
import
lombok.extern.slf4j.Slf4j
;
...
...
yd-csf-api/src/main/java/com/yd/csf/api/service/impl/RenewalDispatchServiceImpl.java
View file @
bf7d94c2
...
...
@@ -4,9 +4,10 @@ import com.yd.common.exception.BusinessException;
import
com.yd.common.utils.RandomStringGenerator
;
import
com.yd.csf.api.service.RenewalDispatchService
;
import
com.yd.csf.api.service.RenewalMailService
;
import
com.yd.csf.service.component.RenewalPolicyReportService
;
import
com.yd.csf.service.dto.RenewalDuePolicy
;
import
com.yd.csf.service.dto.RenewalReminderData
;
import
com.yd.csf.service.component.renewal.RenewalPolicyMailBuilder
;
import
com.yd.csf.service.component.renewal.RenewalPolicyReportService
;
import
com.yd.csf.service.component.renewal.RenewalDuePolicy
;
import
com.yd.csf.service.component.renewal.RenewalReminderData
;
import
com.yd.csf.service.enums.RenewalMailTypeEnum
;
import
com.yd.csf.service.enums.RenewalRemindStatusEnum
;
import
com.yd.csf.service.model.RenewalRemindBatch
;
...
...
yd-csf-service/src/main/java/com/yd/csf/service/
utils
/RenewalDueDateCalculator.java
→
yd-csf-service/src/main/java/com/yd/csf/service/
component/renewal
/RenewalDueDateCalculator.java
View file @
bf7d94c2
package
com
.
yd
.
csf
.
service
.
utils
;
package
com
.
yd
.
csf
.
service
.
component
.
renewal
;
import
com.yd.csf.feign.enums.PaymentFrequencyEnum
;
import
lombok.Getter
;
...
...
yd-csf-service/src/main/java/com/yd/csf/service/
dto
/RenewalDuePolicy.java
→
yd-csf-service/src/main/java/com/yd/csf/service/
component/renewal
/RenewalDuePolicy.java
View file @
bf7d94c2
package
com
.
yd
.
csf
.
service
.
dto
;
package
com
.
yd
.
csf
.
service
.
component
.
renewal
;
import
com.yd.csf.service.model.PolicyFollow
;
import
lombok.AllArgsConstructor
;
...
...
yd-csf-
api/src/main/java/com/yd/csf/api/service/imp
l/RenewalPolicyMailBuilder.java
→
yd-csf-
service/src/main/java/com/yd/csf/service/component/renewa
l/RenewalPolicyMailBuilder.java
View file @
bf7d94c2
package
com
.
yd
.
csf
.
api
.
service
.
imp
l
;
package
com
.
yd
.
csf
.
service
.
component
.
renewa
l
;
import
com.yd.csf.service.dto.RenewalDuePolicy
;
import
com.yd.csf.service.enums.RenewalMailTypeEnum
;
import
com.yd.csf.service.model.PolicyFollow
;
import
com.yd.csf.service.utils.RenewalPremiumUtils
;
import
com.yd.csf.service.utils.SimpleDateUtils
;
import
lombok.AllArgsConstructor
;
import
lombok.Getter
;
...
...
@@ -19,6 +17,7 @@ import java.util.concurrent.atomic.AtomicInteger;
/**
* 逐单续期保费通知邮件构建器:简繁双语 HTML(内联 CSS、无图片无外链)。
* 版式按需求稿:字段单列、开场句日期加粗下划线、应缴总保费与备注红色、底部日期加粗下划线。
* 静态标签简体段/繁体段各一份,数据值原样填充不做简繁转换,全部做 HTML 转义。
*/
@Component
...
...
@@ -29,6 +28,14 @@ public class RenewalPolicyMailBuilder {
private
static
final
String
FONT
=
"'Microsoft YaHei','PingFang SC',Arial,sans-serif"
;
private
static
final
DateTimeFormatter
DATE_FMT
=
DateTimeFormatter
.
ofPattern
(
"yyyy年MM月dd日"
);
private
static
final
DecimalFormat
MONEY_FMT
=
new
DecimalFormat
(
"#,##0.00"
);
/**
* 需求稿强调色:应缴总保费、备注整行红色
*/
private
static
final
String
EMPHASIS_RED
=
"#FF0000"
;
/**
* 标签对齐宽度(全角字符数,含冒号);最长标签「保单持有人:」为 6
*/
private
static
final
int
LABEL_WIDTH
=
6
;
/**
* grace_period 缺失时括注中的默认天数,与筛选侧同源配置
...
...
@@ -72,15 +79,15 @@ public class RenewalPolicyMailBuilder {
String
effectiveText
=
effectiveDate
==
null
?
null
:
effectiveDate
.
format
(
DATE_FMT
);
String
graceNoteSc
=
item
.
isGraceFallback
()
?
"(宽限天数待核对(按默认 "
+
resolveDefaultGraceDays
()
+
" 天估算))"
:
"(
保费到期日起计 "
+
item
.
getGraceDays
()
+
"
天)"
;
:
"(
获取保费到期日起计"
+
item
.
getGraceDays
()
+
"
天)"
;
String
graceNoteTc
=
item
.
isGraceFallback
()
?
"(寬限天數待核對(按預設 "
+
resolveDefaultGraceDays
()
+
" 天估算))"
:
"(
保費到期日起計 "
+
item
.
getGraceDays
()
+
"
天)"
;
:
"(
获取保费到期日起计"
+
item
.
getGraceDays
()
+
"
天)"
;
String
subject
=
(
type
==
RenewalMailTypeEnum
.
R2
?
"【宽限期跟进】"
:
""
)
+
"续期保费通知-
"
+
policyNo
;
+
"续期保费通知-
【"
+
policyNo
+
"】"
;
String
html
=
"<div style=\"font-family:"
+
FONT
+
";font-size:14px;color:#
333333
;line-height:1.9;\">"
String
html
=
"<div style=\"font-family:"
+
FONT
+
";font-size:14px;color:#
000000
;line-height:1.9;\">"
+
segment
(
Labels
.
SC
,
MISSING_SC
,
type
,
company
,
product
,
esc
(
policyNo
),
holder
,
insured
,
money
,
effectiveText
,
dueDateText
,
graceEndText
,
graceNoteSc
)
+
"<hr style=\"border:none;border-top:1px solid #dddddd;margin:18px 0;\">"
...
...
@@ -104,55 +111,63 @@ public class RenewalPolicyMailBuilder {
String
money
,
String
effectiveText
,
String
dueDateText
,
String
graceEndText
,
String
graceNote
)
{
String
opening
;
String
boldDue
=
boldUnderline
(
dueDateText
);
if
(
type
==
RenewalMailTypeEnum
.
R2
)
{
opening
=
l
.
openingR2Prefix
+
dueDateText
+
l
.
openingR2Middle
+
graceEndText
+
l
.
openingR2Suffix
;
opening
=
l
.
openingR2Prefix
+
boldDue
+
l
.
openingR2Middle
+
boldUnderline
(
graceEndText
)
+
l
.
openingR2Suffix
;
}
else
{
opening
=
l
.
openingR1Prefix
+
dueDateText
+
l
.
openingR1Suffix
;
opening
=
l
.
openingR1Prefix
+
boldDue
+
l
.
openingR1Suffix
;
}
String
companyV
=
markOrValue
(
company
,
missingMark
);
String
productV
=
markOrValue
(
product
,
missingMark
);
String
holderV
=
markOrValue
(
holder
,
missingMark
);
String
insuredV
=
markOrValue
(
insured
,
missingMark
);
String
moneyV
=
markOrValue
(
money
,
missingMark
);
String
effectiveV
=
markOrValue
(
effectiveText
,
missingMark
);
StringBuilder
sb
=
new
StringBuilder
();
sb
.
append
(
"<p style=\"margin:0 0 6px 0;font-weight:bold;\">"
).
append
(
l
.
segmentTitle
).
append
(
"</p>"
);
sb
.
append
(
"<p style=\"margin:0 0 12px 0;\">"
).
append
(
opening
).
append
(
"</p>"
);
sb
.
append
(
"<table cellspacing=\"0\" cellpadding=\"4\" style=\"border-collapse:collapse;font-size:14px;\">"
);
sb
.
append
(
row4
(
l
.
company
,
companyV
,
l
.
product
,
productV
));
sb
.
append
(
row4
(
l
.
policyNo
,
policyNo
,
l
.
effectiveDate
,
effectiveV
));
sb
.
append
(
row4
(
l
.
holder
,
holderV
,
l
.
insured
,
insuredV
));
sb
.
append
(
row1
(
l
.
premiumAndLevy
,
moneyV
,
false
));
sb
.
append
(
row1
(
l
.
totalPremium
,
moneyV
,
true
));
sb
.
append
(
"</table>"
);
sb
.
append
(
"<p style=\"margin:10px 0 0 0;\">"
).
append
(
l
.
remark
).
append
(
"</p>"
);
sb
.
append
(
"<p style=\"margin:6px 0 0 0;\">"
)
.
append
(
l
.
dueDateLabel
).
append
(
":<span style=\"font-weight:bold;text-decoration:underline;\">"
)
.
append
(
dueDateText
).
append
(
"</span></p>"
);
sb
.
append
(
"<p style=\"margin:6px 0 0 0;\">"
)
.
append
(
l
.
graceEndLabel
).
append
(
":<span style=\"font-weight:bold;text-decoration:underline;\">"
)
.
append
(
graceEndText
).
append
(
"</span>"
).
append
(
graceNote
).
append
(
"</p>"
);
sb
.
append
(
"<p style=\"margin:0 0 8px 0;font-weight:bold;\">"
).
append
(
l
.
segmentTitle
).
append
(
"</p>"
);
sb
.
append
(
"<p style=\"margin:0 0 10px 0;\">"
).
append
(
opening
).
append
(
"</p>"
);
// 保单资料:每字段单独一行,标签全角补齐对齐
sb
.
append
(
"<div style=\"line-height:2;\">"
);
sb
.
append
(
fieldLine
(
l
.
company
,
markOrValue
(
company
,
missingMark
)));
sb
.
append
(
fieldLine
(
l
.
product
,
markOrValue
(
product
,
missingMark
)));
sb
.
append
(
fieldLine
(
l
.
policyNo
,
policyNo
));
sb
.
append
(
fieldLine
(
l
.
holder
,
markOrValue
(
holder
,
missingMark
)));
sb
.
append
(
fieldLine
(
l
.
insured
,
markOrValue
(
insured
,
missingMark
)));
sb
.
append
(
fieldLine
(
l
.
premiumAndLevy
,
markOrValue
(
money
,
missingMark
)));
sb
.
append
(
fieldLine
(
l
.
effectiveDate
,
markOrValue
(
effectiveText
,
missingMark
)));
sb
.
append
(
"</div>"
);
// 应缴总保费:标签+金额整行红色加粗
sb
.
append
(
"<div style=\"margin-top:14px;color:"
).
append
(
EMPHASIS_RED
)
.
append
(
";font-weight:bold;\">"
)
.
append
(
l
.
totalPremium
).
append
(
":"
).
append
(
markOrValue
(
money
,
missingMark
))
.
append
(
"</div>"
);
// 备注:整行红色、常规字重(繁体段文案按需求稿原文)
sb
.
append
(
"<div style=\"margin-top:4px;color:"
).
append
(
EMPHASIS_RED
).
append
(
";\">"
)
.
append
(
l
.
remark
).
append
(
"</div>"
);
// 到期日区域与备注间空一行
sb
.
append
(
"<div style=\"margin-top:22px;\">"
)
.
append
(
l
.
dueDateLabel
).
append
(
":"
).
append
(
boldDue
)
.
append
(
"</div>"
);
sb
.
append
(
"<div style=\"margin-top:6px;\">"
)
.
append
(
l
.
graceEndLabel
).
append
(
":"
).
append
(
boldUnderline
(
graceEndText
))
.
append
(
" "
).
append
(
graceNote
)
.
append
(
"</div>"
);
return
sb
.
toString
();
}
private
String
row4
(
String
label1
,
String
value1
,
String
label2
,
String
value2
)
{
return
"<tr>"
+
"<td style=\"white-space:nowrap;color:#666666;\">"
+
label1
+
":</td>"
+
"<td style=\"padding-right:24px;\">"
+
value1
+
"</td>"
+
"<td style=\"white-space:nowrap;color:#666666;\">"
+
label2
+
":</td>"
+
"<td>"
+
value2
+
"</td>"
+
"</tr>"
;
private
String
fieldLine
(
String
label
,
String
value
)
{
return
"<div>"
+
padLabel
(
label
)
+
value
+
"</div>"
;
}
private
String
boldUnderline
(
String
text
)
{
return
"<span style=\"font-weight:bold;text-decoration:underline;\">"
+
text
+
"</span>"
;
}
private
String
row1
(
String
label
,
String
value
,
boolean
total
)
{
String
valueStyle
=
total
?
"<span style=\"color:#D90000;font-weight:bold;\">"
+
value
+
"</span>"
:
value
;
return
"<tr>"
+
"<td style=\"white-space:nowrap;color:#666666;\">"
+
label
+
":</td>"
+
"<td colspan=\"3\">"
+
valueStyle
+
"</td>"
+
"</tr>"
;
/**
* 标签(含全角冒号)右侧补全角空格到固定宽度,使各字段值纵向对齐
*/
private
String
padLabel
(
String
labelWithColon
)
{
StringBuilder
sb
=
new
StringBuilder
(
labelWithColon
);
while
(
sb
.
length
()
<
LABEL_WIDTH
)
{
sb
.
append
(
' '
);
}
return
sb
.
toString
();
}
/**
...
...
@@ -284,19 +299,20 @@ public class RenewalPolicyMailBuilder {
}
private
static
final
Labels
SC
=
new
Labels
(
"【简体】"
,
"产品公司
"
,
"计划名称"
,
"保单号码"
,
"保单生效日
"
,
"保单持有人
"
,
"受保人"
,
"保费及征费
"
,
"应缴总保费"
,
"【简体】"
,
"产品公司
:"
,
"计划名称:"
,
"保单号码:"
,
"保单生效日:
"
,
"保单持有人
:"
,
"受保人:"
,
"保费及征费:
"
,
"应缴总保费"
,
"备注:此金额未计入保费优惠,保费优惠待确认后通知客户。"
,
"保费到期日"
,
"宽限期到期日"
,
"以下保单的保费将于
"
,
" 到期,请在此日期前缴付应缴保费。
"
,
"以下保单的保费已于
"
,
" 到期,宽限期将于 "
,
" 届满,请尽快跟进确认缴费情况。
"
);
"以下保单的保费将于
"
,
"到期,请在此日期前缴付应缴保费。保单资料如下:
"
,
"以下保单的保费已于
"
,
"到期,宽限期将于"
,
"届满,请尽快跟进确认缴费情况。保单资料如下:
"
);
private
static
final
Labels
TC
=
new
Labels
(
"【繁體】"
,
"產品公司"
,
"計劃名稱"
,
"保單號碼"
,
"保單生效日"
,
"保單持有人"
,
"受保人"
,
"保費及征費"
,
"應繳總保費"
,
"備註:此金額未計入保費優惠,保費優惠待確認後通知客戶。"
,
"【繁體】"
,
"產品公司:"
,
"計劃名稱:"
,
"保單號碼:"
,
"保單生效日:"
,
"保單持有人:"
,
"受保人:"
,
"保費及征費:"
,
"應繳總保費"
,
// 繁体段备注按需求稿原文(「备注」「客户」保留稿中用字)
"备注:此金額未計入保費優惠,保費優惠待確認後通知客户。"
,
"保費到期日"
,
"寬限期到期日"
,
"以下保單的保費將於
"
,
" 到期,請在此日期前繳付應繳保費。
"
,
"以下保單的保費已於
"
,
" 到期,寬限期將於 "
,
" 屆滿,請盡快跟進確認繳費情況。
"
);
"以下保單的保費將於
"
,
"到期,請在此日期前繳付應繳保費。保單資料如下:
"
,
"以下保單的保費已於
"
,
"到期,寬限期將於"
,
"屆滿,請盡快跟進確認繳費情況。保單資料如下:
"
);
}
}
yd-csf-service/src/main/java/com/yd/csf/service/component/RenewalPolicyReportService.java
→
yd-csf-service/src/main/java/com/yd/csf/service/component/
renewal/
RenewalPolicyReportService.java
View file @
bf7d94c2
package
com
.
yd
.
csf
.
service
.
component
;
package
com
.
yd
.
csf
.
service
.
component
.
renewal
;
import
com.alibaba.excel.EasyExcel
;
import
com.yd.csf.service.dto.RenewalDuePolicy
;
import
com.yd.csf.service.dto.RenewalReminderData
;
import
com.yd.csf.service.component.TemplateStyleStrategy
;
import
com.yd.csf.service.vo.RenewalPolicyExportDTO
;
import
org.apache.commons.collections4.CollectionUtils
;
import
org.springframework.stereotype.Component
;
...
...
yd-csf-service/src/main/java/com/yd/csf/service/
utils
/RenewalPremiumUtils.java
→
yd-csf-service/src/main/java/com/yd/csf/service/
component/renewal
/RenewalPremiumUtils.java
View file @
bf7d94c2
package
com
.
yd
.
csf
.
service
.
utils
;
package
com
.
yd
.
csf
.
service
.
component
.
renewal
;
import
com.yd.csf.service.model.PolicyFollow
;
import
org.apache.commons.lang3.StringUtils
;
...
...
yd-csf-service/src/main/java/com/yd/csf/service/
dto
/RenewalReminderData.java
→
yd-csf-service/src/main/java/com/yd/csf/service/
component/renewal
/RenewalReminderData.java
View file @
bf7d94c2
package
com
.
yd
.
csf
.
service
.
dto
;
package
com
.
yd
.
csf
.
service
.
component
.
renewal
;
import
lombok.AllArgsConstructor
;
import
lombok.Data
;
...
...
yd-csf-service/src/main/java/com/yd/csf/service/service/RenewalReminderQueryService.java
View file @
bf7d94c2
package
com
.
yd
.
csf
.
service
.
service
;
import
com.yd.csf.service.
dto
.RenewalReminderData
;
import
com.yd.csf.service.
component.renewal
.RenewalReminderData
;
import
java.time.LocalDate
;
import
java.time.YearMonth
;
...
...
yd-csf-service/src/main/java/com/yd/csf/service/service/impl/RenewalReminderQueryServiceImpl.java
View file @
bf7d94c2
...
...
@@ -2,12 +2,12 @@ package com.yd.csf.service.service.impl;
import
com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper
;
import
com.yd.csf.service.dao.PolicyFollowMapper
;
import
com.yd.csf.service.
dto
.RenewalDuePolicy
;
import
com.yd.csf.service.
dto
.RenewalReminderData
;
import
com.yd.csf.service.
component.renewal
.RenewalDuePolicy
;
import
com.yd.csf.service.
component.renewal
.RenewalReminderData
;
import
com.yd.csf.service.enums.PolicyFollowStatusEnum
;
import
com.yd.csf.service.model.PolicyFollow
;
import
com.yd.csf.service.service.RenewalReminderQueryService
;
import
com.yd.csf.service.
utils
.RenewalDueDateCalculator
;
import
com.yd.csf.service.
component.renewal
.RenewalDueDateCalculator
;
import
com.yd.csf.service.utils.SimpleDateUtils
;
import
lombok.extern.slf4j.Slf4j
;
import
org.apache.commons.collections4.CollectionUtils
;
...
...
yd-csf-service/src/main/java/com/yd/csf/service/vo/RenewalPolicyExportDTO.java
View file @
bf7d94c2
...
...
@@ -2,6 +2,7 @@ package com.yd.csf.service.vo;
import
com.alibaba.excel.annotation.ExcelProperty
;
import
com.alibaba.excel.annotation.format.DateTimeFormat
;
import
com.yd.csf.service.component.renewal.RenewalPremiumUtils
;
import
com.yd.csf.service.model.PolicyFollow
;
import
lombok.Data
;
...
...
@@ -152,10 +153,10 @@ public class RenewalPolicyExportDTO {
/**
* 总保费及征费 = 期交保费 + 保单征费;两者均无值时留空,征费为空或非数字按 0 处理。
* 口径与逐单邮件共用 {@link
com.yd.csf.service.utils.
RenewalPremiumUtils}。
* 口径与逐单邮件共用 {@link RenewalPremiumUtils}。
*/
private
static
String
buildTotalPremiumAndLevy
(
PolicyFollow
p
)
{
BigDecimal
total
=
com
.
yd
.
csf
.
service
.
utils
.
RenewalPremiumUtils
.
totalPremiumAndLevy
(
p
);
BigDecimal
total
=
RenewalPremiumUtils
.
totalPremiumAndLevy
(
p
);
return
total
==
null
?
null
:
total
.
toPlainString
();
}
}
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