{"id":58795,"date":"2025-08-16T15:40:34","date_gmt":"2025-08-16T07:40:34","guid":{"rendered":"https:\/\/www.wsisp.com\/helps\/58795.html"},"modified":"2025-08-16T15:40:34","modified_gmt":"2025-08-16T07:40:34","slug":"%e4%bc%81%e4%b8%9a%e7%ba%a7java%e9%a1%b9%e7%9b%ae%e9%87%91%e8%9e%8d%e5%ba%94%e7%94%a8%e9%a2%86%e5%9f%9f-%e9%93%b6%e8%a1%8c%e7%b3%bb%e7%bb%9f","status":"publish","type":"post","link":"https:\/\/www.wsisp.com\/helps\/58795.html","title":{"rendered":"\u4f01\u4e1a\u7ea7Java\u9879\u76ee\u91d1\u878d\u5e94\u7528\u9886\u57df\u2014\u2014\u94f6\u884c\u7cfb\u7edf"},"content":{"rendered":"<h3>\u94f6\u884c\u7cfb\u7edf<\/h3>\n<p>\u540e\u7aef<\/p>\n<ul>\n<li>\n<p>\u6838\u5fc3\u6846\u67b6: Spring Boot\/Spring Cloud (\u5fae\u670d\u52a1\u67b6\u6784)<\/p>\n<\/li>\n<li>\n<p>\u6301\u4e45\u5c42: MyBatis\/JPA, Hibernate<\/p>\n<\/li>\n<li>\n<p>\u6570\u636e\u5e93: Oracle\/MySQL (\u4e3b\u4ece\u590d\u5236), Redis (\u7f13\u5b58)<\/p>\n<\/li>\n<li>\n<p>\u6d88\u606f\u961f\u5217: RabbitMQ\/Kafka (\u5f02\u6b65\u5904\u7406)<\/p>\n<\/li>\n<li>\n<p>API\u63a5\u53e3: RESTful API, Swagger\u6587\u6863<\/p>\n<\/li>\n<li>\n<p>\u5b89\u5168\u6846\u67b6: Spring Security, OAuth2\/JWT<\/p>\n<\/li>\n<li>\n<p>\u5206\u5e03\u5f0f\u4e8b\u52a1: Seata<\/p>\n<\/li>\n<li>\n<p>\u641c\u7d22\u5f15\u64ce: Elasticsearch (\u4ea4\u6613\u67e5\u8be2)<\/p>\n<\/li>\n<li>\n<p>\u6279\u5904\u7406: Spring Batch<\/p>\n<\/li>\n<\/ul>\n<p>\u524d\u7aef<\/p>\n<ul>\n<li>\n<p>Web\u6846\u67b6: Vue.js\/React &#043; Element UI\/Ant Design<\/p>\n<\/li>\n<li>\n<p>\u79fb\u52a8\u7aef: \u539f\u751fAPP\u6216React Native\/Flutter<\/p>\n<\/li>\n<li>\n<p>\u56fe\u8868\u5e93: ECharts\/D3.js (\u6570\u636e\u53ef\u89c6\u5316)<\/p>\n<\/li>\n<\/ul>\n<p>**\u5176\u4ed6&#xff1a;**\u5206\u5e03\u5f0f\u9501: Redisson   \u5206\u5e03\u5f0fID\u751f\u6210: Snowflake\u7b97\u6cd5  \u6587\u4ef6\u5904\u7406: Apache POI (Excel), PDFBox  \u5de5\u4f5c\u6d41\u5f15\u64ce: Activiti\/Camunda<\/p>\n<ul>\n<li>\n<p>\u5bb9\u5668\u5316: Docker &#043; Kubernetes<\/p>\n<\/li>\n<li>\n<p>\u670d\u52a1\u53d1\u73b0: Nacos\/Eureka<\/p>\n<\/li>\n<li>\n<p>\u914d\u7f6e\u4e2d\u5fc3: Apollo\/Nacos<\/p>\n<\/li>\n<li>\n<p>\u7f51\u5173: Spring Cloud Gateway<\/p>\n<\/li>\n<li>\n<p>\u76d1\u63a7: Prometheus &#043; Grafana<\/p>\n<\/li>\n<li>\n<p>\u65e5\u5fd7: ELK Stack (Elasticsearch, Logstash, Kibana)<\/p>\n<\/li>\n<li>\n<p>CI\/CD: Jenkins\/<\/p>\n<\/li>\n<li>\n<p>GitLab CI<\/p>\n<\/li>\n<\/ul>\n<p>1. \u8d26\u6237\u7ba1\u7406<\/p>\n<p>\u8d26\u6237\u5f00\u6237\/\u9500\u6237<\/p>\n<p>\u8d26\u6237\u4fe1\u606f\u7ef4\u62a4<\/p>\n<p>\u8d26\u6237\u72b6\u6001\u7ba1\u7406(\u51bb\u7ed3\/\u89e3\u51bb)<\/p>\n<p>\u8d26\u6237\u4f59\u989d\u67e5\u8be2<\/p>\n<p>\u8d26\u6237\u5206\u7ea7\u7ba1\u7406(\u4e2a\u4eba\/\u4f01\u4e1a)<\/p>\n<p><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>dependencies<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><br \/>\n    <span class=\"token comment\">&lt;!&#8211; Spring Boot Starter &#8211;&gt;<\/span><br \/>\n    <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>dependency<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><br \/>\n        <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>groupId<\/span><span class=\"token punctuation\">&gt;<\/span><\/span>org.springframework.boot<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>groupId<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><br \/>\n        <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>artifactId<\/span><span class=\"token punctuation\">&gt;<\/span><\/span>spring-boot-starter-web<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>artifactId<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><br \/>\n    <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>dependency<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><br \/>\n    <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>dependency<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><br \/>\n        <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>groupId<\/span><span class=\"token punctuation\">&gt;<\/span><\/span>org.springframework.boot<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>groupId<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><br \/>\n        <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>artifactId<\/span><span class=\"token punctuation\">&gt;<\/span><\/span>spring-boot-starter-data-jpa<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>artifactId<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><br \/>\n    <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>dependency<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><br \/>\n    <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>dependency<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><br \/>\n        <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>groupId<\/span><span class=\"token punctuation\">&gt;<\/span><\/span>org.springframework.boot<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>groupId<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><br \/>\n        <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>artifactId<\/span><span class=\"token punctuation\">&gt;<\/span><\/span>spring-boot-starter-validation<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>artifactId<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><br \/>\n    <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>dependency<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><\/p>\n<p>    <span class=\"token comment\">&lt;!&#8211; Database &#8211;&gt;<\/span><br \/>\n    <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>dependency<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><br \/>\n        <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>groupId<\/span><span class=\"token punctuation\">&gt;<\/span><\/span>mysql<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>groupId<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><br \/>\n        <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>artifactId<\/span><span class=\"token punctuation\">&gt;<\/span><\/span>mysql-connector-java<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>artifactId<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><br \/>\n        <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>scope<\/span><span class=\"token punctuation\">&gt;<\/span><\/span>runtime<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>scope<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><br \/>\n    <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>dependency<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><br \/>\n    <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>dependency<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><br \/>\n        <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>groupId<\/span><span class=\"token punctuation\">&gt;<\/span><\/span>com.h2database<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>groupId<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><br \/>\n        <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>artifactId<\/span><span class=\"token punctuation\">&gt;<\/span><\/span>h2<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>artifactId<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><br \/>\n        <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>scope<\/span><span class=\"token punctuation\">&gt;<\/span><\/span>test<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>scope<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><br \/>\n    <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>dependency<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><\/p>\n<p>    <span class=\"token comment\">&lt;!&#8211; Lombok &#8211;&gt;<\/span><br \/>\n    <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>dependency<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><br \/>\n        <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>groupId<\/span><span class=\"token punctuation\">&gt;<\/span><\/span>org.projectlombok<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>groupId<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><br \/>\n        <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>artifactId<\/span><span class=\"token punctuation\">&gt;<\/span><\/span>lombok<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>artifactId<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><br \/>\n        <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>optional<\/span><span class=\"token punctuation\">&gt;<\/span><\/span>true<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>optional<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><br \/>\n    <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>dependency<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><br \/>\n    <span class=\"token comment\">&lt;!&#8211; Spring Security &#8211;&gt;<\/span><br \/>\n    <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>dependency<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><br \/>\n        <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>groupId<\/span><span class=\"token punctuation\">&gt;<\/span><\/span>org.springframework.boot<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>groupId<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><br \/>\n        <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>artifactId<\/span><span class=\"token punctuation\">&gt;<\/span><\/span>spring-boot-starter-security<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>artifactId<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><br \/>\n    <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>dependency<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><\/p>\n<p>    <span class=\"token comment\">&lt;!&#8211; JWT\u652f\u6301 &#8211;&gt;<\/span><br \/>\n    <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>dependency<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><br \/>\n        <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>groupId<\/span><span class=\"token punctuation\">&gt;<\/span><\/span>io.jsonwebtoken<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>groupId<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><br \/>\n        <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>artifactId<\/span><span class=\"token punctuation\">&gt;<\/span><\/span>jjwt-api<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>artifactId<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><br \/>\n        <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>version<\/span><span class=\"token punctuation\">&gt;<\/span><\/span>0.11.5<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>version<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><br \/>\n    <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>dependency<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><br \/>\n    <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>dependency<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><br \/>\n        <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>groupId<\/span><span class=\"token punctuation\">&gt;<\/span><\/span>io.jsonwebtoken<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>groupId<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><br \/>\n        <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>artifactId<\/span><span class=\"token punctuation\">&gt;<\/span><\/span>jjwt-impl<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>artifactId<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><br \/>\n        <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>version<\/span><span class=\"token punctuation\">&gt;<\/span><\/span>0.11.5<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>version<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><br \/>\n        <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>scope<\/span><span class=\"token punctuation\">&gt;<\/span><\/span>runtime<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>scope<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><br \/>\n    <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>dependency<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><br \/>\n    <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>dependency<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><br \/>\n        <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>groupId<\/span><span class=\"token punctuation\">&gt;<\/span><\/span>io.jsonwebtoken<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>groupId<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><br \/>\n        <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>artifactId<\/span><span class=\"token punctuation\">&gt;<\/span><\/span>jjwt-jackson<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>artifactId<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><br \/>\n        <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>version<\/span><span class=\"token punctuation\">&gt;<\/span><\/span>0.11.5<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>version<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><br \/>\n        <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>scope<\/span><span class=\"token punctuation\">&gt;<\/span><\/span>runtime<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>scope<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><br \/>\n    <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>dependency<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><\/p>\n<p>    <span class=\"token comment\">&lt;!&#8211; \u6570\u636e\u52a0\u5bc6 &#8211;&gt;<\/span><br \/>\n    <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>dependency<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><br \/>\n        <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>groupId<\/span><span class=\"token punctuation\">&gt;<\/span><\/span>org.bouncycastle<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>groupId<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><br \/>\n        <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>artifactId<\/span><span class=\"token punctuation\">&gt;<\/span><\/span>bcpkix-jdk15on<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>artifactId<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><br \/>\n        <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>version<\/span><span class=\"token punctuation\">&gt;<\/span><\/span>1.70<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>version<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><br \/>\n    <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>dependency<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><\/p>\n<p>    <span class=\"token comment\">&lt;!&#8211; \u9632XSS &#8211;&gt;<\/span><br \/>\n    <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>dependency<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><br \/>\n        <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>groupId<\/span><span class=\"token punctuation\">&gt;<\/span><\/span>org.apache.commons<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>groupId<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><br \/>\n        <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>artifactId<\/span><span class=\"token punctuation\">&gt;<\/span><\/span>commons-text<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>artifactId<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><br \/>\n        <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>version<\/span><span class=\"token punctuation\">&gt;<\/span><\/span>1.10.0<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>version<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><br \/>\n    <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>dependency<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><\/p>\n<p>    <span class=\"token comment\">&lt;!&#8211; \u9650\u6d41 &#8211;&gt;<\/span><br \/>\n    <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>dependency<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><br \/>\n        <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>groupId<\/span><span class=\"token punctuation\">&gt;<\/span><\/span>com.github.vladimir-bukhtoyarov<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>groupId<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><br \/>\n        <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>artifactId<\/span><span class=\"token punctuation\">&gt;<\/span><\/span>bucket4j-core<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>artifactId<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><br \/>\n        <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>version<\/span><span class=\"token punctuation\">&gt;<\/span><\/span>7.6.0<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>version<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><br \/>\n    <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>dependency<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><br \/>\n    <span class=\"token comment\">&lt;!&#8211; Other &#8211;&gt;<\/span><br \/>\n    <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>dependency<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><br \/>\n        <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>groupId<\/span><span class=\"token punctuation\">&gt;<\/span><\/span>org.springdoc<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>groupId<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><br \/>\n        <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>artifactId<\/span><span class=\"token punctuation\">&gt;<\/span><\/span>springdoc-openapi-ui<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>artifactId<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><br \/>\n        <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>version<\/span><span class=\"token punctuation\">&gt;<\/span><\/span>1.6.14<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>version<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><br \/>\n    <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>dependency<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><br \/>\n<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>dependencies<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><\/p>\n<p><span class=\"token key atrule\">spring<\/span><span class=\"token punctuation\">:<\/span><br \/>\n  <span class=\"token key atrule\">datasource<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    <span class=\"token key atrule\">url<\/span><span class=\"token punctuation\">:<\/span> jdbc<span class=\"token punctuation\">:<\/span>mysql<span class=\"token punctuation\">:<\/span>\/\/localhost<span class=\"token punctuation\">:<\/span>3306\/bank_account_db<span class=\"token punctuation\">?<\/span>useSSL&#061;false<span class=\"token important\">&amp;serverTimezone&#061;UTC<\/span><br \/>\n    <span class=\"token key atrule\">username<\/span><span class=\"token punctuation\">:<\/span> root<br \/>\n    <span class=\"token key atrule\">password<\/span><span class=\"token punctuation\">:<\/span> password<br \/>\n    <span class=\"token key atrule\">driver-class-name<\/span><span class=\"token punctuation\">:<\/span> com.mysql.cj.jdbc.Driver<br \/>\n  <span class=\"token key atrule\">jpa<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    <span class=\"token key atrule\">hibernate<\/span><span class=\"token punctuation\">:<\/span><br \/>\n      <span class=\"token key atrule\">ddl-auto<\/span><span class=\"token punctuation\">:<\/span> update<br \/>\n    <span class=\"token key atrule\">show-sql<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token boolean important\">true<\/span><br \/>\n    <span class=\"token key atrule\">properties<\/span><span class=\"token punctuation\">:<\/span><br \/>\n      <span class=\"token key atrule\">hibernate<\/span><span class=\"token punctuation\">:<\/span><br \/>\n        <span class=\"token key atrule\">format_sql<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token boolean important\">true<\/span><br \/>\n        <span class=\"token key atrule\">dialect<\/span><span class=\"token punctuation\">:<\/span> org.hibernate.dialect.MySQL8Dialect<\/p>\n<p><span class=\"token key atrule\">server<\/span><span class=\"token punctuation\">:<\/span><br \/>\n  <span class=\"token key atrule\">port<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token number\">8080<\/span><\/p>\n<p><span class=\"token key atrule\">logging<\/span><span class=\"token punctuation\">:<\/span><br \/>\n  <span class=\"token key atrule\">level<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    <span class=\"token key atrule\">com.bank.account<\/span><span class=\"token punctuation\">:<\/span> DEBUG<br \/>\n<span class=\"token key atrule\">security<\/span><span class=\"token punctuation\">:<\/span><br \/>\n  <span class=\"token key atrule\">jwt<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    <span class=\"token key atrule\">secret-key<\/span><span class=\"token punctuation\">:<\/span> your<span class=\"token punctuation\">&#8211;<\/span>256<span class=\"token punctuation\">&#8211;<\/span>bit<span class=\"token punctuation\">&#8211;<\/span>secret<span class=\"token punctuation\">&#8211;<\/span>key<span class=\"token punctuation\">&#8211;<\/span>change<span class=\"token punctuation\">&#8211;<\/span>this<span class=\"token punctuation\">&#8211;<\/span>to<span class=\"token punctuation\">&#8211;<\/span>something<span class=\"token punctuation\">&#8211;<\/span>secure<br \/>\n    <span class=\"token key atrule\">expiration<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token number\">86400000<\/span> <span class=\"token comment\"># 24 hours in milliseconds<\/span><br \/>\n    <span class=\"token key atrule\">refresh-token.expiration<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token number\">604800000<\/span> <span class=\"token comment\"># 7 days in milliseconds<\/span><br \/>\n  <span class=\"token key atrule\">encryption<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    <span class=\"token key atrule\">key<\/span><span class=\"token punctuation\">:<\/span> your<span class=\"token punctuation\">&#8211;<\/span>encryption<span class=\"token punctuation\">&#8211;<\/span>key<span class=\"token punctuation\">&#8211;<\/span>32bytes<br \/>\n    <span class=\"token key atrule\">iv<\/span><span class=\"token punctuation\">:<\/span> your<span class=\"token punctuation\">&#8211;<\/span>initialization<span class=\"token punctuation\">&#8211;<\/span>vector<span class=\"token punctuation\">&#8211;<\/span>16bytes<br \/>\n  <span class=\"token key atrule\">rate-limit<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    <span class=\"token key atrule\">enabled<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token boolean important\">true<\/span><br \/>\n    <span class=\"token key atrule\">capacity<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token number\">100<\/span><br \/>\n    <span class=\"token key atrule\">refill-rate<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token number\">100<\/span><br \/>\n    <span class=\"token key atrule\">refill-time<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token number\">1<\/span> <span class=\"token comment\"># minutes<\/span><\/p>\n<p><span class=\"token annotation punctuation\">&#064;Entity<\/span><br \/>\n<span class=\"token annotation punctuation\">&#064;Table<\/span><span class=\"token punctuation\">(<\/span>name<span class=\"token operator\">&#061;<\/span><span class=\"token string\">&#034;bank_account&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n<span class=\"token annotation punctuation\">&#064;Data<\/span><br \/>\n<span class=\"token keyword\">public<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token class-name\">Account<\/span><span class=\"token punctuation\">{<\/span><\/p>\n<p><span class=\"token annotation punctuation\">&#064;Id<\/span><br \/>\n<span class=\"token annotation punctuation\">&#064;GeneratedValue<\/span><span class=\"token punctuation\">(<\/span>strategy<span class=\"token operator\">&#061;<\/span><span class=\"token class-name\">GenerationType<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">IDENTITY<\/span><span class=\"token punctuation\">)<\/span><br \/>\n<span class=\"token keyword\">private<\/span> <span class=\"token class-name\">Long<\/span> id<span class=\"token punctuation\">;<\/span><\/p>\n<p><span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>unique<span class=\"token operator\">&#061;<\/span><span class=\"token boolean\">true<\/span><span class=\"token punctuation\">,<\/span>nullable<span class=\"token operator\">&#061;<\/span><span class=\"token boolean\">false<\/span><span class=\"token punctuation\">)<\/span><br \/>\n<span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> accountNumber<span class=\"token punctuation\">;<\/span><\/p>\n<p><span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>nullable <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">Long<\/span> customerId<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Enumerated<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">EnumType<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">STRING<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>nullable <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">AccountType<\/span> accountType<span class=\"token punctuation\">;<\/span><span class=\"token comment\">\/\/\u679a\u4e3e\u7c7b\u578b&#xff1a;\u4e2a\u4eba\u50a8\u84c4\/\u6d3b\u671f,\u4f01\u4e1a\u6d3b\u671f\/\u8d37\u6b3e,\u4fe1\u7528\u5361<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Enumerated<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">EnumType<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">STRING<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>nullable <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">AccountStatus<\/span> status<span class=\"token punctuation\">;<\/span><span class=\"token comment\">\/\/\u679a\u4e3e\u72b6\u6001&#xff1a;\u6d3b\u8dc3\u3001\u4e0d\u6d3b\u8dc3\u3001\u51bb\u7ed3\u3001\u5df2\u5173\u95ed\u3001\u4f11\u7720<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>nullable <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">,<\/span> precision <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">19<\/span><span class=\"token punctuation\">,<\/span> scale <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">4<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">BigDecimal<\/span> balance <span class=\"token operator\">&#061;<\/span> <span class=\"token class-name\">BigDecimal<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">ZERO<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>nullable <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">,<\/span> precision <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">19<\/span><span class=\"token punctuation\">,<\/span> scale <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">4<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">BigDecimal<\/span> availableBalance <span class=\"token operator\">&#061;<\/span> <span class=\"token class-name\">BigDecimal<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">ZERO<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>nullable <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> currency <span class=\"token operator\">&#061;<\/span> <span class=\"token string\">&#034;CNY&#034;<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;CreationTimestamp<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">Date<\/span> createdAt<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;UpdateTimestamp<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">Date<\/span> updatedAt<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Version<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">Long<\/span> version<span class=\"token punctuation\">;<\/span> <span class=\"token comment\">\/\/ \u4e50\u89c2\u9501\u7248\u672c\u53f7<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token comment\">\/**<br \/>\n\u5b89\u5168\u76f8\u5173\u7684\u5b9e\u4f53<br \/>\n*\/<\/span><br \/>\n<span class=\"token annotation punctuation\">&#064;Data<\/span><br \/>\n<span class=\"token annotation punctuation\">&#064;Builder<\/span><br \/>\n<span class=\"token annotation punctuation\">&#064;NoArgsConstructor<\/span><br \/>\n<span class=\"token annotation punctuation\">&#064;AllArgsConstructor<\/span><br \/>\n<span class=\"token annotation punctuation\">&#064;Entity<\/span><br \/>\n<span class=\"token annotation punctuation\">&#064;Table<\/span><span class=\"token punctuation\">(<\/span>name <span class=\"token operator\">&#061;<\/span> <span class=\"token string\">&#034;users&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n<span class=\"token keyword\">public<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token class-name\">User<\/span> <span class=\"token keyword\">implements<\/span> <span class=\"token class-name\">UserDetails<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token annotation punctuation\">&#064;Id<\/span><br \/>\n    <span class=\"token annotation punctuation\">&#064;GeneratedValue<\/span><span class=\"token punctuation\">(<\/span>strategy <span class=\"token operator\">&#061;<\/span> <span class=\"token class-name\">GenerationType<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">IDENTITY<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">Long<\/span> id<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>nullable <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">,<\/span> unique <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">true<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> username<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>nullable <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> password<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Enumerated<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">EnumType<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">STRING<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">Role<\/span> role<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Override<\/span><br \/>\n    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">Collection<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token operator\">?<\/span> <span class=\"token keyword\">extends<\/span> <span class=\"token class-name\">GrantedAuthority<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> <span class=\"token function\">getAuthorities<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> <span class=\"token class-name\">List<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">of<\/span><span class=\"token punctuation\">(<\/span><span class=\"token keyword\">new<\/span> <span class=\"token class-name\">SimpleGrantedAuthority<\/span><span class=\"token punctuation\">(<\/span>role<span class=\"token punctuation\">.<\/span><span class=\"token function\">name<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Override<\/span><br \/>\n    <span class=\"token keyword\">public<\/span> <span class=\"token keyword\">boolean<\/span> <span class=\"token function\">isAccountNonExpired<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> <span class=\"token boolean\">true<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Override<\/span><br \/>\n    <span class=\"token keyword\">public<\/span> <span class=\"token keyword\">boolean<\/span> <span class=\"token function\">isAccountNonLocked<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> <span class=\"token boolean\">true<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Override<\/span><br \/>\n    <span class=\"token keyword\">public<\/span> <span class=\"token keyword\">boolean<\/span> <span class=\"token function\">isCredentialsNonExpired<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> <span class=\"token boolean\">true<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Override<\/span><br \/>\n    <span class=\"token keyword\">public<\/span> <span class=\"token keyword\">boolean<\/span> <span class=\"token function\">isEnabled<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> <span class=\"token boolean\">true<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token keyword\">public<\/span> <span class=\"token keyword\">enum<\/span> <span class=\"token class-name\">Role<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token constant\">CUSTOMER<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token constant\">TELLER<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token constant\">MANAGER<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token constant\">ADMIN<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token annotation punctuation\">&#064;Data<\/span><br \/>\n<span class=\"token annotation punctuation\">&#064;Builder<\/span><br \/>\n<span class=\"token annotation punctuation\">&#064;AllArgsConstructor<\/span><br \/>\n<span class=\"token annotation punctuation\">&#064;NoArgsConstructor<\/span><br \/>\n<span class=\"token keyword\">public<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token class-name\">AuthenticationRequest<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> username<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> password<span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token annotation punctuation\">&#064;Data<\/span><br \/>\n<span class=\"token annotation punctuation\">&#064;Builder<\/span><br \/>\n<span class=\"token annotation punctuation\">&#064;AllArgsConstructor<\/span><br \/>\n<span class=\"token annotation punctuation\">&#064;NoArgsConstructor<\/span><br \/>\n<span class=\"token keyword\">public<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token class-name\">AuthenticationResponse<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> token<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> refreshToken<span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token keyword\">public<\/span> <span class=\"token keyword\">enum<\/span> <span class=\"token class-name\">AccountType<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token constant\">PERSONAL_SAVINGS<\/span><span class=\"token punctuation\">,<\/span>    <span class=\"token comment\">\/\/ \u4e2a\u4eba\u50a8\u84c4\u8d26\u6237<\/span><br \/>\n    <span class=\"token constant\">PERSONAL_CURRENT<\/span><span class=\"token punctuation\">,<\/span>    <span class=\"token comment\">\/\/ \u4e2a\u4eba\u6d3b\u671f\u8d26\u6237<\/span><br \/>\n    <span class=\"token constant\">CORPORATE_CURRENT<\/span><span class=\"token punctuation\">,<\/span>   <span class=\"token comment\">\/\/ \u4f01\u4e1a\u6d3b\u671f\u8d26\u6237<\/span><br \/>\n    <span class=\"token constant\">CORPORATE_LOAN<\/span><span class=\"token punctuation\">,<\/span>      <span class=\"token comment\">\/\/ \u4f01\u4e1a\u8d37\u6b3e\u8d26\u6237<\/span><br \/>\n    <span class=\"token constant\">CREDIT_CARD<\/span>          <span class=\"token comment\">\/\/ \u4fe1\u7528\u5361\u8d26\u6237<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token keyword\">public<\/span> <span class=\"token keyword\">enum<\/span> <span class=\"token class-name\">AccountStatus<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token constant\">ACTIVE<\/span><span class=\"token punctuation\">,<\/span>         <span class=\"token comment\">\/\/ \u6d3b\u8dc3<\/span><br \/>\n    <span class=\"token constant\">INACTIVE<\/span><span class=\"token punctuation\">,<\/span>       <span class=\"token comment\">\/\/ \u4e0d\u6d3b\u8dc3<\/span><br \/>\n    <span class=\"token constant\">FROZEN<\/span><span class=\"token punctuation\">,<\/span>         <span class=\"token comment\">\/\/ \u51bb\u7ed3<\/span><br \/>\n    <span class=\"token constant\">CLOSED<\/span><span class=\"token punctuation\">,<\/span>         <span class=\"token comment\">\/\/ \u5df2\u5173\u95ed<\/span><br \/>\n    <span class=\"token constant\">DORMANT<\/span>         <span class=\"token comment\">\/\/ \u4f11\u7720<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token annotation punctuation\">&#064;Data<\/span><br \/>\n<span class=\"token keyword\">public<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token class-name\">AccountDTO<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">Long<\/span> id<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> accountNumber<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">Long<\/span> customerId<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">AccountType<\/span> accountType<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">AccountStatus<\/span> status<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">BigDecimal<\/span> balance<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">BigDecimal<\/span> availableBalance<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> currency<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">Date<\/span> createdAt<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">Date<\/span> updatedAt<span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token annotation punctuation\">&#064;Data<\/span><br \/>\n<span class=\"token keyword\">public<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token class-name\">CreateAccountRequest<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token annotation punctuation\">&#064;NotNull<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">Long<\/span> customerId<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;NotNull<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">AccountType<\/span> accountType<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> currency <span class=\"token operator\">&#061;<\/span> <span class=\"token string\">&#034;CNY&#034;<\/span><span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token annotation punctuation\">&#064;Data<\/span><br \/>\n<span class=\"token keyword\">public<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token class-name\">AccountOperationResponse<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">boolean<\/span> success<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> message<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> accountNumber<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">BigDecimal<\/span> newBalance<span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token annotation punctuation\">&#064;Getter<\/span><br \/>\n<span class=\"token keyword\">public<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token class-name\">AccountException<\/span> <span class=\"token keyword\">extends<\/span> <span class=\"token class-name\">RuntimeException<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">final<\/span> <span class=\"token class-name\">ErrorCode<\/span> errorCode<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">AccountException<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">ErrorCode<\/span> errorCode<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">super<\/span><span class=\"token punctuation\">(<\/span>errorCode<span class=\"token punctuation\">.<\/span><span class=\"token function\">getMessage<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token keyword\">this<\/span><span class=\"token punctuation\">.<\/span>errorCode <span class=\"token operator\">&#061;<\/span> errorCode<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token annotation punctuation\">&#064;Getter<\/span><br \/>\n<span class=\"token keyword\">public<\/span> <span class=\"token keyword\">enum<\/span> <span class=\"token class-name\">ErrorCode<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token function\">ACCOUNT_NOT_FOUND<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">404<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;Account not found&#034;<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token function\">ACCOUNT_NOT_ACTIVE<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">400<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;Account is not active&#034;<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token function\">ACCOUNT_ALREADY_FROZEN<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">400<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;Account is already frozen&#034;<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token function\">ACCOUNT_NOT_FROZEN<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">400<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;Account is not frozen&#034;<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token function\">ACCOUNT_ALREADY_CLOSED<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">400<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;Account is already closed&#034;<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token function\">ACCOUNT_BALANCE_NOT_ZERO<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">400<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;Account balance is not zero&#034;<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token function\">INSUFFICIENT_BALANCE<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">400<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;Insufficient balance&#034;<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token function\">INVALID_AMOUNT<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">400<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;Amount must be positive&#034;<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">final<\/span> <span class=\"token keyword\">int<\/span> status<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">final<\/span> <span class=\"token class-name\">String<\/span> message<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token class-name\">ErrorCode<\/span><span class=\"token punctuation\">(<\/span><span class=\"token keyword\">int<\/span> status<span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">String<\/span> message<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">this<\/span><span class=\"token punctuation\">.<\/span>status <span class=\"token operator\">&#061;<\/span> status<span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token keyword\">this<\/span><span class=\"token punctuation\">.<\/span>message <span class=\"token operator\">&#061;<\/span> message<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token annotation punctuation\">&#064;RestControllerAdvice<\/span><br \/>\n<span class=\"token keyword\">public<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token class-name\">GlobalExceptionHandler<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token annotation punctuation\">&#064;ExceptionHandler<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">AccountException<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">class<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">ResponseEntity<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">ErrorResponse<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> <span class=\"token function\">handleAccountException<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">AccountException<\/span> e<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token class-name\">ErrorCode<\/span> errorCode <span class=\"token operator\">&#061;<\/span> e<span class=\"token punctuation\">.<\/span><span class=\"token function\">getErrorCode<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> <span class=\"token class-name\">ResponseEntity<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">status<\/span><span class=\"token punctuation\">(<\/span>errorCode<span class=\"token punctuation\">.<\/span><span class=\"token function\">getStatus<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">body<\/span><span class=\"token punctuation\">(<\/span><span class=\"token keyword\">new<\/span> <span class=\"token class-name\">ErrorResponse<\/span><span class=\"token punctuation\">(<\/span>errorCode<span class=\"token punctuation\">.<\/span><span class=\"token function\">getStatus<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span> errorCode<span class=\"token punctuation\">.<\/span><span class=\"token function\">getMessage<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p>\u5b89\u5168\u914d\u7f6e\u7c7b\u548c\u9650\u6d41\u914d\u7f6e\u7c7b<\/p>\n<p><span class=\"token annotation punctuation\">&#064;Configuration<\/span><br \/>\n<span class=\"token annotation punctuation\">&#064;EnableWebSecurity<\/span><br \/>\n<span class=\"token annotation punctuation\">&#064;EnableMethodSecurity<\/span><span class=\"token punctuation\">(<\/span>prePostEnabled <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">true<\/span><span class=\"token punctuation\">)<\/span><br \/>\n<span class=\"token annotation punctuation\">&#064;RequiredArgsConstructor<\/span><br \/>\n<span class=\"token keyword\">public<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token class-name\">SecurityConfig<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">final<\/span> <span class=\"token class-name\">JwtAuthenticationFilter<\/span> jwtAuthFilter<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">final<\/span> <span class=\"token class-name\">AuthenticationProvider<\/span> authenticationProvider<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Bean<\/span><br \/>\n    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">SecurityFilterChain<\/span> <span class=\"token function\">securityFilterChain<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">HttpSecurity<\/span> http<span class=\"token punctuation\">)<\/span> <span class=\"token keyword\">throws<\/span> <span class=\"token class-name\">Exception<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        http<br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token function\">cors<\/span><span class=\"token punctuation\">(<\/span>cors <span class=\"token operator\">-&gt;<\/span> cors<span class=\"token punctuation\">.<\/span><span class=\"token function\">configurationSource<\/span><span class=\"token punctuation\">(<\/span><span class=\"token function\">corsConfigurationSource<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token function\">csrf<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">AbstractHttpConfigurer<\/span><span class=\"token operator\">::<\/span><span class=\"token function\">disable<\/span><span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token function\">authorizeHttpRequests<\/span><span class=\"token punctuation\">(<\/span>auth <span class=\"token operator\">-&gt;<\/span> auth<br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">requestMatchers<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                    <span class=\"token string\">&#034;\/api\/auth\/**&#034;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                    <span class=\"token string\">&#034;\/v3\/api-docs\/**&#034;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                    <span class=\"token string\">&#034;\/swagger-ui\/**&#034;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                    <span class=\"token string\">&#034;\/swagger-ui.html&#034;<\/span><br \/>\n                <span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">permitAll<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">anyRequest<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">authenticated<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token function\">sessionManagement<\/span><span class=\"token punctuation\">(<\/span>sess <span class=\"token operator\">-&gt;<\/span> sess<span class=\"token punctuation\">.<\/span><span class=\"token function\">sessionCreationPolicy<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">SessionCreationPolicy<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">STATELESS<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token function\">authenticationProvider<\/span><span class=\"token punctuation\">(<\/span>authenticationProvider<span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token function\">addFilterBefore<\/span><span class=\"token punctuation\">(<\/span>jwtAuthFilter<span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">UsernamePasswordAuthenticationFilter<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">class<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">return<\/span> http<span class=\"token punctuation\">.<\/span><span class=\"token function\">build<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Bean<\/span><br \/>\n    <span class=\"token class-name\">CorsConfigurationSource<\/span> <span class=\"token function\">corsConfigurationSource<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token class-name\">CorsConfiguration<\/span> configuration <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">CorsConfiguration<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        configuration<span class=\"token punctuation\">.<\/span><span class=\"token function\">setAllowedOrigins<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">List<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">of<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;https:\/\/bank.com&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;https:\/\/admin.bank.com&#034;<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        configuration<span class=\"token punctuation\">.<\/span><span class=\"token function\">setAllowedMethods<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">Arrays<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">asList<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;GET&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;POST&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;PUT&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;DELETE&#034;<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        configuration<span class=\"token punctuation\">.<\/span><span class=\"token function\">setAllowedHeaders<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">List<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">of<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;*&#034;<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        configuration<span class=\"token punctuation\">.<\/span><span class=\"token function\">setExposedHeaders<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">List<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">of<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;X-Rate-Limit-Remaining&#034;<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token class-name\">UrlBasedCorsConfigurationSource<\/span> source <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">UrlBasedCorsConfigurationSource<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        source<span class=\"token punctuation\">.<\/span><span class=\"token function\">registerCorsConfiguration<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;\/**&#034;<\/span><span class=\"token punctuation\">,<\/span> configuration<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> source<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token annotation punctuation\">&#064;Configuration<\/span><br \/>\n<span class=\"token annotation punctuation\">&#064;EnableCaching<\/span><br \/>\n<span class=\"token keyword\">public<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token class-name\">RateLimitConfig<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token annotation punctuation\">&#064;Bean<\/span><br \/>\n    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">CacheManager<\/span> <span class=\"token function\">cacheManager<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token class-name\">CacheManager<\/span> cacheManager <span class=\"token operator\">&#061;<\/span> <span class=\"token class-name\">Caching<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">getCachingProvider<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">getCacheManager<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token class-name\">MutableConfiguration<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">String<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token keyword\">byte<\/span><span class=\"token punctuation\">[<\/span><span class=\"token punctuation\">]<\/span><span class=\"token operator\">&gt;<\/span> config <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">MutableConfiguration<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        cacheManager<span class=\"token punctuation\">.<\/span><span class=\"token function\">createCache<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;rate-limit-buckets&#034;<\/span><span class=\"token punctuation\">,<\/span> config<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> cacheManager<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Bean<\/span><br \/>\n    <span class=\"token class-name\">ProxyManager<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">String<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> <span class=\"token function\">proxyManager<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">CacheManager<\/span> cacheManager<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">JCacheProxyManager<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><span class=\"token punctuation\">(<\/span>cacheManager<span class=\"token punctuation\">.<\/span><span class=\"token function\">getCache<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;rate-limit-buckets&#034;<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Bean<\/span><br \/>\n    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">BucketConfiguration<\/span> <span class=\"token function\">bucketConfiguration<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> <span class=\"token class-name\">BucketConfiguration<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">builder<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">addLimit<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">Bandwidth<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">classic<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">100<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">Refill<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">intervally<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">100<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">Duration<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">ofMinutes<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">1<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">build<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Bean<\/span><br \/>\n    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">Bucket<\/span> <span class=\"token function\">bucket<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">ProxyManager<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">String<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> proxyManager<span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">BucketConfiguration<\/span> bucketConfiguration<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> proxyManager<span class=\"token punctuation\">.<\/span><span class=\"token function\">builder<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">build<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;global-limit&#034;<\/span><span class=\"token punctuation\">,<\/span> bucketConfiguration<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p>JWT\u8ba4\u8bc1\u5b9e\u73b0<\/p>\n<p><span class=\"token annotation punctuation\">&#064;Service<\/span><br \/>\n<span class=\"token keyword\">public<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token class-name\">JwtService<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token annotation punctuation\">&#064;Value<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;${security.jwt.secret-key}&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> secretKey<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Value<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;${security.jwt.expiration}&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">long<\/span> jwtExpiration<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Value<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;${security.jwt.refresh-token.expiration}&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">long<\/span> refreshExpiration<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">String<\/span> <span class=\"token function\">extractUsername<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">String<\/span> token<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> <span class=\"token function\">extractClaim<\/span><span class=\"token punctuation\">(<\/span>token<span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">Claims<\/span><span class=\"token operator\">::<\/span><span class=\"token function\">getSubject<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token keyword\">public<\/span> <span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">T<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> <span class=\"token class-name\">T<\/span> <span class=\"token function\">extractClaim<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">String<\/span> token<span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">Function<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">Claims<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">T<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> claimsResolver<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">final<\/span> <span class=\"token class-name\">Claims<\/span> claims <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">extractAllClaims<\/span><span class=\"token punctuation\">(<\/span>token<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> claimsResolver<span class=\"token punctuation\">.<\/span><span class=\"token function\">apply<\/span><span class=\"token punctuation\">(<\/span>claims<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">String<\/span> <span class=\"token function\">generateToken<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">UserDetails<\/span> userDetails<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> <span class=\"token function\">generateToken<\/span><span class=\"token punctuation\">(<\/span><span class=\"token keyword\">new<\/span> <span class=\"token class-name\">HashMap<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span> userDetails<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">String<\/span> <span class=\"token function\">generateToken<\/span><span class=\"token punctuation\">(<\/span><br \/>\n            <span class=\"token class-name\">Map<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">String<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">Object<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> extraClaims<span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token class-name\">UserDetails<\/span> userDetails<br \/>\n    <span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> <span class=\"token function\">buildToken<\/span><span class=\"token punctuation\">(<\/span>extraClaims<span class=\"token punctuation\">,<\/span> userDetails<span class=\"token punctuation\">,<\/span> jwtExpiration<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">String<\/span> <span class=\"token function\">generateRefreshToken<\/span><span class=\"token punctuation\">(<\/span><br \/>\n            <span class=\"token class-name\">UserDetails<\/span> userDetails<br \/>\n    <span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> <span class=\"token function\">buildToken<\/span><span class=\"token punctuation\">(<\/span><span class=\"token keyword\">new<\/span> <span class=\"token class-name\">HashMap<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span> userDetails<span class=\"token punctuation\">,<\/span> refreshExpiration<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> <span class=\"token function\">buildToken<\/span><span class=\"token punctuation\">(<\/span><br \/>\n            <span class=\"token class-name\">Map<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">String<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">Object<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> extraClaims<span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token class-name\">UserDetails<\/span> userDetails<span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token keyword\">long<\/span> expiration<br \/>\n    <span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> <span class=\"token class-name\">Jwts<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">builder<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">setClaims<\/span><span class=\"token punctuation\">(<\/span>extraClaims<span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">setSubject<\/span><span class=\"token punctuation\">(<\/span>userDetails<span class=\"token punctuation\">.<\/span><span class=\"token function\">getUsername<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">setIssuedAt<\/span><span class=\"token punctuation\">(<\/span><span class=\"token keyword\">new<\/span> <span class=\"token class-name\">Date<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">System<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">currentTimeMillis<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">setExpiration<\/span><span class=\"token punctuation\">(<\/span><span class=\"token keyword\">new<\/span> <span class=\"token class-name\">Date<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">System<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">currentTimeMillis<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#043;<\/span> expiration<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">signWith<\/span><span class=\"token punctuation\">(<\/span><span class=\"token function\">getSignInKey<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">SignatureAlgorithm<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">HS256<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">compact<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token keyword\">public<\/span> <span class=\"token keyword\">boolean<\/span> <span class=\"token function\">isTokenValid<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">String<\/span> token<span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">UserDetails<\/span> userDetails<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">final<\/span> <span class=\"token class-name\">String<\/span> username <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">extractUsername<\/span><span class=\"token punctuation\">(<\/span>token<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> <span class=\"token punctuation\">(<\/span>username<span class=\"token punctuation\">.<\/span><span class=\"token function\">equals<\/span><span class=\"token punctuation\">(<\/span>userDetails<span class=\"token punctuation\">.<\/span><span class=\"token function\">getUsername<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&amp;&amp;<\/span> <span class=\"token operator\">!<\/span><span class=\"token function\">isTokenExpired<\/span><span class=\"token punctuation\">(<\/span>token<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">boolean<\/span> <span class=\"token function\">isTokenExpired<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">String<\/span> token<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> <span class=\"token function\">extractExpiration<\/span><span class=\"token punctuation\">(<\/span>token<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">before<\/span><span class=\"token punctuation\">(<\/span><span class=\"token keyword\">new<\/span> <span class=\"token class-name\">Date<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">Date<\/span> <span class=\"token function\">extractExpiration<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">String<\/span> token<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> <span class=\"token function\">extractClaim<\/span><span class=\"token punctuation\">(<\/span>token<span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">Claims<\/span><span class=\"token operator\">::<\/span><span class=\"token function\">getExpiration<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">Claims<\/span> <span class=\"token function\">extractAllClaims<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">String<\/span> token<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> <span class=\"token class-name\">Jwts<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">parserBuilder<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">setSigningKey<\/span><span class=\"token punctuation\">(<\/span><span class=\"token function\">getSignInKey<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">build<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">parseClaimsJws<\/span><span class=\"token punctuation\">(<\/span>token<span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">getBody<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">Key<\/span> <span class=\"token function\">getSignInKey<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">byte<\/span><span class=\"token punctuation\">[<\/span><span class=\"token punctuation\">]<\/span> keyBytes <span class=\"token operator\">&#061;<\/span> <span class=\"token class-name\">Decoders<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">BASE64<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">decode<\/span><span class=\"token punctuation\">(<\/span>secretKey<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> <span class=\"token class-name\">Keys<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">hmacShaKeyFor<\/span><span class=\"token punctuation\">(<\/span>keyBytes<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p>\u5de5\u5177\u7c7b<\/p>\n<p><span class=\"token comment\">\/**<br \/>\n\u8d26\u53f7\u751f\u6210\u5de5\u5177<br \/>\n*\/<\/span><br \/>\n<span class=\"token annotation punctuation\">&#064;Component<\/span><br \/>\n<span class=\"token keyword\">public<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token class-name\">AccountNumberGenerator<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">static<\/span> <span class=\"token keyword\">final<\/span> <span class=\"token class-name\">String<\/span> <span class=\"token constant\">BANK_CODE<\/span> <span class=\"token operator\">&#061;<\/span> <span class=\"token string\">&#034;888&#034;<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">final<\/span> <span class=\"token class-name\">AtomicLong<\/span> sequence <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">AtomicLong<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">1<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">String<\/span> <span class=\"token function\">generate<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">AccountType<\/span> accountType<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">long<\/span> seq <span class=\"token operator\">&#061;<\/span> sequence<span class=\"token punctuation\">.<\/span><span class=\"token function\">getAndIncrement<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token class-name\">String<\/span> prefix <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">getAccountPrefix<\/span><span class=\"token punctuation\">(<\/span>accountType<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token class-name\">String<\/span> seqStr <span class=\"token operator\">&#061;<\/span> <span class=\"token class-name\">String<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">format<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;%010d&#034;<\/span><span class=\"token punctuation\">,<\/span> seq<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u7b80\u5355\u6821\u9a8c\u7801\u8ba1\u7b97<\/span><br \/>\n        <span class=\"token class-name\">String<\/span> rawNumber <span class=\"token operator\">&#061;<\/span> <span class=\"token constant\">BANK_CODE<\/span> <span class=\"token operator\">&#043;<\/span> prefix <span class=\"token operator\">&#043;<\/span> seqStr<span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token keyword\">int<\/span> checkDigit <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">calculateCheckDigit<\/span><span class=\"token punctuation\">(<\/span>rawNumber<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">return<\/span> rawNumber <span class=\"token operator\">&#043;<\/span> checkDigit<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> <span class=\"token function\">getAccountPrefix<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">AccountType<\/span> accountType<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> <span class=\"token keyword\">switch<\/span> <span class=\"token punctuation\">(<\/span>accountType<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">case<\/span> <span class=\"token constant\">PERSONAL_SAVINGS<\/span> <span class=\"token operator\">-&gt;<\/span> <span class=\"token string\">&#034;10&#034;<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            <span class=\"token keyword\">case<\/span> <span class=\"token constant\">PERSONAL_CURRENT<\/span> <span class=\"token operator\">-&gt;<\/span> <span class=\"token string\">&#034;11&#034;<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            <span class=\"token keyword\">case<\/span> <span class=\"token constant\">CORPORATE_CURRENT<\/span> <span class=\"token operator\">-&gt;<\/span> <span class=\"token string\">&#034;20&#034;<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            <span class=\"token keyword\">case<\/span> <span class=\"token constant\">CORPORATE_LOAN<\/span> <span class=\"token operator\">-&gt;<\/span> <span class=\"token string\">&#034;21&#034;<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            <span class=\"token keyword\">case<\/span> <span class=\"token constant\">CREDIT_CARD<\/span> <span class=\"token operator\">-&gt;<\/span> <span class=\"token string\">&#034;30&#034;<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">int<\/span> <span class=\"token function\">calculateCheckDigit<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">String<\/span> number<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">int<\/span> sum <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">0<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token keyword\">for<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token keyword\">int<\/span> i <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">0<\/span><span class=\"token punctuation\">;<\/span> i <span class=\"token operator\">&lt;<\/span> number<span class=\"token punctuation\">.<\/span><span class=\"token function\">length<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span> i<span class=\"token operator\">&#043;&#043;<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">int<\/span> digit <span class=\"token operator\">&#061;<\/span> <span class=\"token class-name\">Character<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">getNumericValue<\/span><span class=\"token punctuation\">(<\/span>number<span class=\"token punctuation\">.<\/span><span class=\"token function\">charAt<\/span><span class=\"token punctuation\">(<\/span>i<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            sum <span class=\"token operator\">&#043;&#061;<\/span> <span class=\"token punctuation\">(<\/span>i <span class=\"token operator\">%<\/span> <span class=\"token number\">2<\/span> <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token number\">0<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">?<\/span> digit <span class=\"token operator\">*<\/span> <span class=\"token number\">1<\/span> <span class=\"token operator\">:<\/span> digit <span class=\"token operator\">*<\/span> <span class=\"token number\">3<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token number\">10<\/span> <span class=\"token operator\">&#8211;<\/span> <span class=\"token punctuation\">(<\/span>sum <span class=\"token operator\">%<\/span> <span class=\"token number\">10<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">%<\/span> <span class=\"token number\">10<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token comment\">\/**<br \/>\n\u6570\u636e\u52a0\u5bc6\u5de5\u5177<br \/>\n*\/<\/span><br \/>\n<span class=\"token annotation punctuation\">&#064;Component<\/span><br \/>\n<span class=\"token keyword\">public<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token class-name\">EncryptionUtil<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token annotation punctuation\">&#064;Value<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;${security.encryption.key}&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> encryptionKey<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Value<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;${security.encryption.iv}&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> iv<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token keyword\">static<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token class-name\">Security<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">addProvider<\/span><span class=\"token punctuation\">(<\/span><span class=\"token keyword\">new<\/span> <span class=\"token class-name\">BouncyCastleProvider<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">String<\/span> <span class=\"token function\">encrypt<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">String<\/span> data<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">try<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token class-name\">IvParameterSpec<\/span> ivSpec <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">IvParameterSpec<\/span><span class=\"token punctuation\">(<\/span>iv<span class=\"token punctuation\">.<\/span><span class=\"token function\">getBytes<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">StandardCharsets<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">UTF_8<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            <span class=\"token class-name\">SecretKeySpec<\/span> keySpec <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">SecretKeySpec<\/span><span class=\"token punctuation\">(<\/span>encryptionKey<span class=\"token punctuation\">.<\/span><span class=\"token function\">getBytes<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">StandardCharsets<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">UTF_8<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;AES&#034;<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>            <span class=\"token class-name\">Cipher<\/span> cipher <span class=\"token operator\">&#061;<\/span> <span class=\"token class-name\">Cipher<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">getInstance<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;AES\/CBC\/PKCS7Padding&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;BC&#034;<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            cipher<span class=\"token punctuation\">.<\/span><span class=\"token function\">init<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">Cipher<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">ENCRYPT_MODE<\/span><span class=\"token punctuation\">,<\/span> keySpec<span class=\"token punctuation\">,<\/span> ivSpec<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>            <span class=\"token keyword\">byte<\/span><span class=\"token punctuation\">[<\/span><span class=\"token punctuation\">]<\/span> encrypted <span class=\"token operator\">&#061;<\/span> cipher<span class=\"token punctuation\">.<\/span><span class=\"token function\">doFinal<\/span><span class=\"token punctuation\">(<\/span>data<span class=\"token punctuation\">.<\/span><span class=\"token function\">getBytes<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">StandardCharsets<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">UTF_8<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            <span class=\"token keyword\">return<\/span> <span class=\"token class-name\">Base64<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">getEncoder<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">encodeToString<\/span><span class=\"token punctuation\">(<\/span>encrypted<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">catch<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token class-name\">Exception<\/span> e<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">throw<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">RuntimeException<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;Encryption failed&#034;<\/span><span class=\"token punctuation\">,<\/span> e<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">String<\/span> <span class=\"token function\">decrypt<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">String<\/span> encryptedData<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">try<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token class-name\">IvParameterSpec<\/span> ivSpec <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">IvParameterSpec<\/span><span class=\"token punctuation\">(<\/span>iv<span class=\"token punctuation\">.<\/span><span class=\"token function\">getBytes<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">StandardCharsets<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">UTF_8<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            <span class=\"token class-name\">SecretKeySpec<\/span> keySpec <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">SecretKeySpec<\/span><span class=\"token punctuation\">(<\/span>encryptionKey<span class=\"token punctuation\">.<\/span><span class=\"token function\">getBytes<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">StandardCharsets<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">UTF_8<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;AES&#034;<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>            <span class=\"token class-name\">Cipher<\/span> cipher <span class=\"token operator\">&#061;<\/span> <span class=\"token class-name\">Cipher<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">getInstance<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;AES\/CBC\/PKCS7Padding&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;BC&#034;<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            cipher<span class=\"token punctuation\">.<\/span><span class=\"token function\">init<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">Cipher<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">DECRYPT_MODE<\/span><span class=\"token punctuation\">,<\/span> keySpec<span class=\"token punctuation\">,<\/span> ivSpec<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>            <span class=\"token keyword\">byte<\/span><span class=\"token punctuation\">[<\/span><span class=\"token punctuation\">]<\/span> decoded <span class=\"token operator\">&#061;<\/span> <span class=\"token class-name\">Base64<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">getDecoder<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">decode<\/span><span class=\"token punctuation\">(<\/span>encryptedData<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            <span class=\"token keyword\">byte<\/span><span class=\"token punctuation\">[<\/span><span class=\"token punctuation\">]<\/span> decrypted <span class=\"token operator\">&#061;<\/span> cipher<span class=\"token punctuation\">.<\/span><span class=\"token function\">doFinal<\/span><span class=\"token punctuation\">(<\/span>decoded<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            <span class=\"token keyword\">return<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">String<\/span><span class=\"token punctuation\">(<\/span>decrypted<span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">StandardCharsets<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">UTF_8<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">catch<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token class-name\">Exception<\/span> e<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">throw<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">RuntimeException<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;Decryption failed&#034;<\/span><span class=\"token punctuation\">,<\/span> e<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p>\u9632XSS\u8fc7\u6ee4\u5668<\/p>\n<p><span class=\"token annotation punctuation\">&#064;Component<\/span><br \/>\n<span class=\"token keyword\">public<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token class-name\">XSSFilter<\/span> <span class=\"token keyword\">extends<\/span> <span class=\"token class-name\">OncePerRequestFilter<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token annotation punctuation\">&#064;Override<\/span><br \/>\n    <span class=\"token keyword\">protected<\/span> <span class=\"token keyword\">void<\/span> <span class=\"token function\">doFilterInternal<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">HttpServletRequest<\/span> request<span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">HttpServletResponse<\/span> response<span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token class-name\">FilterChain<\/span> filterChain<span class=\"token punctuation\">)<\/span> <span class=\"token keyword\">throws<\/span> <span class=\"token class-name\">ServletException<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">IOException<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        filterChain<span class=\"token punctuation\">.<\/span><span class=\"token function\">doFilter<\/span><span class=\"token punctuation\">(<\/span><span class=\"token keyword\">new<\/span> <span class=\"token class-name\">XSSRequestWrapper<\/span><span class=\"token punctuation\">(<\/span>request<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span> response<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">static<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token class-name\">XSSRequestWrapper<\/span> <span class=\"token keyword\">extends<\/span> <span class=\"token class-name\">HttpServletRequestWrapper<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">final<\/span> <span class=\"token class-name\">Map<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">String<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">String<\/span><span class=\"token punctuation\">[<\/span><span class=\"token punctuation\">]<\/span><span class=\"token operator\">&gt;<\/span> escapedParameterValuesMap <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">ConcurrentHashMap<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">XSSRequestWrapper<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">HttpServletRequest<\/span> request<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">super<\/span><span class=\"token punctuation\">(<\/span>request<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><\/p>\n<p>        <span class=\"token annotation punctuation\">&#064;Override<\/span><br \/>\n        <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">String<\/span> <span class=\"token function\">getParameter<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">String<\/span> name<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token class-name\">String<\/span> parameter <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">super<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">getParameter<\/span><span class=\"token punctuation\">(<\/span>name<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            <span class=\"token keyword\">return<\/span> parameter <span class=\"token operator\">!&#061;<\/span> <span class=\"token keyword\">null<\/span> <span class=\"token operator\">?<\/span> <span class=\"token class-name\">StringEscapeUtils<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">escapeHtml4<\/span><span class=\"token punctuation\">(<\/span>parameter<span class=\"token punctuation\">)<\/span> <span class=\"token operator\">:<\/span> <span class=\"token keyword\">null<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><\/p>\n<p>        <span class=\"token annotation punctuation\">&#064;Override<\/span><br \/>\n        <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">String<\/span><span class=\"token punctuation\">[<\/span><span class=\"token punctuation\">]<\/span> <span class=\"token function\">getParameterValues<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">String<\/span> name<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token class-name\">String<\/span><span class=\"token punctuation\">[<\/span><span class=\"token punctuation\">]<\/span> parameterValues <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">super<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">getParameterValues<\/span><span class=\"token punctuation\">(<\/span>name<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>parameterValues <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token keyword\">null<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                <span class=\"token keyword\">return<\/span> <span class=\"token keyword\">null<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><\/p>\n<p>            <span class=\"token keyword\">return<\/span> escapedParameterValuesMap<span class=\"token punctuation\">.<\/span><span class=\"token function\">computeIfAbsent<\/span><span class=\"token punctuation\">(<\/span>name<span class=\"token punctuation\">,<\/span> k <span class=\"token operator\">-&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                <span class=\"token class-name\">String<\/span><span class=\"token punctuation\">[<\/span><span class=\"token punctuation\">]<\/span> escapedValues <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">String<\/span><span class=\"token punctuation\">[<\/span>parameterValues<span class=\"token punctuation\">.<\/span>length<span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">;<\/span><br \/>\n                <span class=\"token keyword\">for<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token keyword\">int<\/span> i <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">0<\/span><span class=\"token punctuation\">;<\/span> i <span class=\"token operator\">&lt;<\/span> parameterValues<span class=\"token punctuation\">.<\/span>length<span class=\"token punctuation\">;<\/span> i<span class=\"token operator\">&#043;&#043;<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                    escapedValues<span class=\"token punctuation\">[<\/span>i<span class=\"token punctuation\">]<\/span> <span class=\"token operator\">&#061;<\/span> <span class=\"token class-name\">StringEscapeUtils<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">escapeHtml4<\/span><span class=\"token punctuation\">(<\/span>parameterValues<span class=\"token punctuation\">[<\/span>i<span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n                <span class=\"token punctuation\">}<\/span><br \/>\n                <span class=\"token keyword\">return<\/span> escapedValues<span class=\"token punctuation\">;<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><\/p>\n<p>        <span class=\"token annotation punctuation\">&#064;Override<\/span><br \/>\n        <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">Map<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">String<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">String<\/span><span class=\"token punctuation\">[<\/span><span class=\"token punctuation\">]<\/span><span class=\"token operator\">&gt;<\/span> <span class=\"token function\">getParameterMap<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token class-name\">Map<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">String<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">String<\/span><span class=\"token punctuation\">[<\/span><span class=\"token punctuation\">]<\/span><span class=\"token operator\">&gt;<\/span> parameterMap <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">super<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">getParameterMap<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            <span class=\"token class-name\">Map<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">String<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">String<\/span><span class=\"token punctuation\">[<\/span><span class=\"token punctuation\">]<\/span><span class=\"token operator\">&gt;<\/span> escapedParameterMap <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">ConcurrentHashMap<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>            <span class=\"token keyword\">for<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token class-name\">Map<span class=\"token punctuation\">.<\/span>Entry<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token class-name\">String<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">String<\/span><span class=\"token punctuation\">[<\/span><span class=\"token punctuation\">]<\/span><span class=\"token operator\">&gt;<\/span> entry <span class=\"token operator\">:<\/span> parameterMap<span class=\"token punctuation\">.<\/span><span class=\"token function\">entrySet<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                escapedParameterMap<span class=\"token punctuation\">.<\/span><span class=\"token function\">put<\/span><span class=\"token punctuation\">(<\/span>entry<span class=\"token punctuation\">.<\/span><span class=\"token function\">getKey<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token function\">getParameterValues<\/span><span class=\"token punctuation\">(<\/span>entry<span class=\"token punctuation\">.<\/span><span class=\"token function\">getKey<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><\/p>\n<p>            <span class=\"token keyword\">return<\/span> escapedParameterMap<span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><\/p>\n<p>        <span class=\"token annotation punctuation\">&#064;Override<\/span><br \/>\n        <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">Enumeration<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">String<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> <span class=\"token function\">getParameterNames<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">return<\/span> <span class=\"token class-name\">Collections<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">enumeration<\/span><span class=\"token punctuation\">(<\/span><span class=\"token function\">getParameterMap<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">keySet<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p>Controller\u5c42<\/p>\n<p><span class=\"token annotation punctuation\">&#064;RestController<\/span><br \/>\n<span class=\"token annotation punctuation\">&#064;RequestMapping<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;\/api\/accounts&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n<span class=\"token annotation punctuation\">&#064;RequiredArgsConstructor<\/span><br \/>\n<span class=\"token keyword\">public<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token class-name\">AccountController<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">final<\/span> <span class=\"token class-name\">AccountService<\/span> accountService<span class=\"token punctuation\">;<\/span><\/p>\n<p><span class=\"token annotation punctuation\">&#064;PostMapping<\/span><br \/>\n<span class=\"token keyword\">public<\/span> <span class=\"token class-name\">ResponseEntity<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">AccountDTO<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> <span class=\"token function\">createAccount<\/span><span class=\"token punctuation\">(<\/span><span class=\"token annotation punctuation\">&#064;Valid<\/span> <span class=\"token annotation punctuation\">&#064;RequestBody<\/span> <span class=\"token class-name\">CreateAccountRequest<\/span> request<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">{<\/span><br \/>\n<span class=\"token class-name\">AccountDTO<\/span> account <span class=\"token operator\">&#061;<\/span> accountService<span class=\"token punctuation\">.<\/span><span class=\"token function\">createAccount<\/span><span class=\"token punctuation\">(<\/span>request<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> <span class=\"token class-name\">ResponseEntity<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">ok<\/span><span class=\"token punctuation\">(<\/span>account<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token annotation punctuation\">&#064;GetMapping<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;\/{accountNumber}&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">ResponseEntity<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">AccountDTO<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> <span class=\"token function\">getAccount<\/span><span class=\"token punctuation\">(<\/span><span class=\"token annotation punctuation\">&#064;PathVariable<\/span> <span class=\"token class-name\">String<\/span> accountNumber<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token class-name\">AccountDTO<\/span> account <span class=\"token operator\">&#061;<\/span> accountService<span class=\"token punctuation\">.<\/span><span class=\"token function\">getAccount<\/span><span class=\"token punctuation\">(<\/span>accountNumber<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> <span class=\"token class-name\">ResponseEntity<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">ok<\/span><span class=\"token punctuation\">(<\/span>account<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;PostMapping<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;\/{accountNumber}\/deposit&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">ResponseEntity<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">AccountOperationResponse<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> <span class=\"token function\">deposit<\/span><span class=\"token punctuation\">(<\/span><br \/>\n            <span class=\"token annotation punctuation\">&#064;PathVariable<\/span> <span class=\"token class-name\">String<\/span> accountNumber<span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token annotation punctuation\">&#064;RequestParam<\/span> <span class=\"token class-name\">BigDecimal<\/span> amount<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token class-name\">AccountOperationResponse<\/span> response <span class=\"token operator\">&#061;<\/span> accountService<span class=\"token punctuation\">.<\/span><span class=\"token function\">deposit<\/span><span class=\"token punctuation\">(<\/span>accountNumber<span class=\"token punctuation\">,<\/span> amount<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> <span class=\"token class-name\">ResponseEntity<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">ok<\/span><span class=\"token punctuation\">(<\/span>response<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;PostMapping<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;\/{accountNumber}\/withdraw&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">ResponseEntity<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">AccountOperationResponse<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> <span class=\"token function\">withdraw<\/span><span class=\"token punctuation\">(<\/span><br \/>\n            <span class=\"token annotation punctuation\">&#064;PathVariable<\/span> <span class=\"token class-name\">String<\/span> accountNumber<span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token annotation punctuation\">&#064;RequestParam<\/span> <span class=\"token class-name\">BigDecimal<\/span> amount<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token class-name\">AccountOperationResponse<\/span> response <span class=\"token operator\">&#061;<\/span> accountService<span class=\"token punctuation\">.<\/span><span class=\"token function\">withdraw<\/span><span class=\"token punctuation\">(<\/span>accountNumber<span class=\"token punctuation\">,<\/span> amount<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> <span class=\"token class-name\">ResponseEntity<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">ok<\/span><span class=\"token punctuation\">(<\/span>response<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;PostMapping<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;\/{accountNumber}\/freeze&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">ResponseEntity<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">AccountOperationResponse<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> <span class=\"token function\">freezeAccount<\/span><span class=\"token punctuation\">(<\/span><span class=\"token annotation punctuation\">&#064;PathVariable<\/span> <span class=\"token class-name\">String<\/span> accountNumber<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token class-name\">AccountOperationResponse<\/span> response <span class=\"token operator\">&#061;<\/span> accountService<span class=\"token punctuation\">.<\/span><span class=\"token function\">freezeAccount<\/span><span class=\"token punctuation\">(<\/span>accountNumber<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> <span class=\"token class-name\">ResponseEntity<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">ok<\/span><span class=\"token punctuation\">(<\/span>response<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;PostMapping<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;\/{accountNumber}\/unfreeze&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">ResponseEntity<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">AccountOperationResponse<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> <span class=\"token function\">unfreezeAccount<\/span><span class=\"token punctuation\">(<\/span><span class=\"token annotation punctuation\">&#064;PathVariable<\/span> <span class=\"token class-name\">String<\/span> accountNumber<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token class-name\">AccountOperationResponse<\/span> response <span class=\"token operator\">&#061;<\/span> accountService<span class=\"token punctuation\">.<\/span><span class=\"token function\">unfreezeAccount<\/span><span class=\"token punctuation\">(<\/span>accountNumber<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> <span class=\"token class-name\">ResponseEntity<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">ok<\/span><span class=\"token punctuation\">(<\/span>response<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;PostMapping<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;\/{accountNumber}\/close&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">ResponseEntity<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">AccountOperationResponse<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> <span class=\"token function\">closeAccount<\/span><span class=\"token punctuation\">(<\/span><span class=\"token annotation punctuation\">&#064;PathVariable<\/span> <span class=\"token class-name\">String<\/span> accountNumber<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token class-name\">AccountOperationResponse<\/span> response <span class=\"token operator\">&#061;<\/span> accountService<span class=\"token punctuation\">.<\/span><span class=\"token function\">closeAccount<\/span><span class=\"token punctuation\">(<\/span>accountNumber<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> <span class=\"token class-name\">ResponseEntity<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">ok<\/span><span class=\"token punctuation\">(<\/span>response<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token annotation punctuation\">&#064;RestController<\/span><br \/>\n<span class=\"token annotation punctuation\">&#064;RequestMapping<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;\/api\/auth&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n<span class=\"token annotation punctuation\">&#064;RequiredArgsConstructor<\/span><br \/>\n<span class=\"token keyword\">public<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token class-name\">AuthenticationController<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">final<\/span> <span class=\"token class-name\">AuthenticationService<\/span> authenticationService<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;PostMapping<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;\/register\/customer&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">ResponseEntity<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">AuthenticationResponse<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> <span class=\"token function\">registerCustomer<\/span><span class=\"token punctuation\">(<\/span><br \/>\n            <span class=\"token annotation punctuation\">&#064;RequestBody<\/span> <span class=\"token class-name\">AuthenticationRequest<\/span> request<br \/>\n    <span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> <span class=\"token class-name\">ResponseEntity<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">ok<\/span><span class=\"token punctuation\">(<\/span>authenticationService<span class=\"token punctuation\">.<\/span><span class=\"token function\">register<\/span><span class=\"token punctuation\">(<\/span>request<span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">Role<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">CUSTOMER<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;PostMapping<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;\/register\/teller&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">ResponseEntity<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">AuthenticationResponse<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> <span class=\"token function\">registerTeller<\/span><span class=\"token punctuation\">(<\/span><br \/>\n            <span class=\"token annotation punctuation\">&#064;RequestBody<\/span> <span class=\"token class-name\">AuthenticationRequest<\/span> request<br \/>\n    <span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> <span class=\"token class-name\">ResponseEntity<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">ok<\/span><span class=\"token punctuation\">(<\/span>authenticationService<span class=\"token punctuation\">.<\/span><span class=\"token function\">register<\/span><span class=\"token punctuation\">(<\/span>request<span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">Role<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">TELLER<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;PostMapping<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;\/authenticate&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">ResponseEntity<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">AuthenticationResponse<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> <span class=\"token function\">authenticate<\/span><span class=\"token punctuation\">(<\/span><br \/>\n            <span class=\"token annotation punctuation\">&#064;RequestBody<\/span> <span class=\"token class-name\">AuthenticationRequest<\/span> request<br \/>\n    <span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> <span class=\"token class-name\">ResponseEntity<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">ok<\/span><span class=\"token punctuation\">(<\/span>authenticationService<span class=\"token punctuation\">.<\/span><span class=\"token function\">authenticate<\/span><span class=\"token punctuation\">(<\/span>request<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p>Service\u5c42<\/p>\n<p><span class=\"token annotation punctuation\">&#064;Service<\/span><br \/>\n<span class=\"token annotation punctuation\">&#064;RequiredArgsConstructor<\/span><br \/>\n<span class=\"token annotation punctuation\">&#064;Slf4j<\/span><br \/>\n<span class=\"token keyword\">public<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token class-name\">AccountService<\/span><span class=\"token punctuation\">{<\/span><\/p>\n<p><span class=\"token keyword\">private<\/span> <span class=\"token keyword\">final<\/span> <span class=\"token class-name\">AccountRepository<\/span> accountRepository<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">final<\/span> <span class=\"token class-name\">AccountNumberGenerator<\/span> accountNumberGenerator<span class=\"token punctuation\">;<\/span><\/p>\n<p><span class=\"token keyword\">private<\/span> <span class=\"token keyword\">final<\/span> <span class=\"token class-name\">EncryptionUtil<\/span> encryptionUtil<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">final<\/span> <span class=\"token class-name\">RateLimitConfig<\/span> rateLimitConfig<span class=\"token punctuation\">;<\/span><\/p>\n<p><span class=\"token annotation punctuation\">&#064;Transactional<\/span><br \/>\n<span class=\"token keyword\">public<\/span> <span class=\"token class-name\">AccountDTO<\/span> <span class=\"token function\">createAccount<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">CreateAccountRequest<\/span> request<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">{<\/span><\/p>\n<p><span class=\"token class-name\">String<\/span> accountNumber <span class=\"token operator\">&#061;<\/span> accountNumberGenerator<span class=\"token punctuation\">.<\/span><span class=\"token function\">generate<\/span><span class=\"token punctuation\">(<\/span>request<span class=\"token punctuation\">.<\/span><span class=\"token function\">getAccountType<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token class-name\">Account<\/span> account <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">Account<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        account<span class=\"token punctuation\">.<\/span><span class=\"token function\">setAccountNumber<\/span><span class=\"token punctuation\">(<\/span>accountNumber<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        account<span class=\"token punctuation\">.<\/span><span class=\"token function\">setCustomerId<\/span><span class=\"token punctuation\">(<\/span>request<span class=\"token punctuation\">.<\/span><span class=\"token function\">getCustomerId<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        account<span class=\"token punctuation\">.<\/span><span class=\"token function\">setAccountType<\/span><span class=\"token punctuation\">(<\/span>request<span class=\"token punctuation\">.<\/span><span class=\"token function\">getAccountType<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        account<span class=\"token punctuation\">.<\/span><span class=\"token function\">setStatus<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">AccountStatus<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">ACTIVE<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        account<span class=\"token punctuation\">.<\/span><span class=\"token function\">setCurrency<\/span><span class=\"token punctuation\">(<\/span>request<span class=\"token punctuation\">.<\/span><span class=\"token function\">getCurrency<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token class-name\">Account<\/span> savedAccount <span class=\"token operator\">&#061;<\/span> accountRepository<span class=\"token punctuation\">.<\/span><span class=\"token function\">save<\/span><span class=\"token punctuation\">(<\/span>account<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        log<span class=\"token punctuation\">.<\/span><span class=\"token function\">info<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;Account created: {}&#034;<\/span><span class=\"token punctuation\">,<\/span> accountNumber<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">return<\/span> <span class=\"token function\">convertToDTO<\/span><span class=\"token punctuation\">(<\/span>savedAccount<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token annotation punctuation\">&#064;Transactional<\/span><span class=\"token punctuation\">(<\/span>readOnly <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">true<\/span><span class=\"token punctuation\">)<\/span><br \/>\n<span class=\"token annotation punctuation\">&#064;PreAuthorize<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;hasAnyRole(&#039;TELLER&#039;, &#039;MANAGER&#039;, &#039;ADMIN&#039;) || &#034;<\/span><br \/>\n            <span class=\"token operator\">&#043;<\/span> <span class=\"token string\">&#034;(hasRole(&#039;CUSTOMER&#039;) &amp;&amp; &#064;accountSecurityService.isAccountOwner(authentication, #accountNumber))&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">AccountDTO<\/span> <span class=\"token function\">getAccount<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">String<\/span> accountNumber<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><\/p>\n<p><span class=\"token comment\">\/\/ \u9650\u6d41\u68c0\u67e5<\/span><br \/>\n        <span class=\"token class-name\">Bucket<\/span> bucket <span class=\"token operator\">&#061;<\/span> rateLimitConfig<span class=\"token punctuation\">.<\/span><span class=\"token function\">bucket<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token operator\">!<\/span>bucket<span class=\"token punctuation\">.<\/span><span class=\"token function\">tryConsume<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">1<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">throw<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">AccountException<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">ErrorCode<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">TOO_MANY_REQUESTS<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><br \/>\n        <span class=\"token class-name\">Account<\/span> account <span class=\"token operator\">&#061;<\/span> accountRepository<span class=\"token punctuation\">.<\/span><span class=\"token function\">findByAccountNumber<\/span><span class=\"token punctuation\">(<\/span>accountNumber<span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">orElseThrow<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">-&gt;<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">AccountException<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">ErrorCode<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">ACCOUNT_NOT_FOUND<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/\u654f\u611f\u6570\u636e\u52a0\u5bc6<\/span><br \/>\n        <span class=\"token class-name\">AccountDTO<\/span> dto <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">convertToDto<\/span><span class=\"token punctuation\">(<\/span>account<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        dto<span class=\"token punctuation\">.<\/span><span class=\"token function\">setAccountNumber<\/span><span class=\"token punctuation\">(<\/span>encryptionUtil<span class=\"token punctuation\">.<\/span><span class=\"token function\">encrypt<\/span><span class=\"token punctuation\">(<\/span>dto<span class=\"token punctuation\">.<\/span><span class=\"token function\">getAccountNumber<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> dto<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Transactional<\/span><br \/>\n    <span class=\"token annotation punctuation\">&#064;PreAuthorize<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;hasAnyRole(&#039;TELLER&#039;, &#039;MANAGER&#039;, &#039;ADMIN&#039;)&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">AccountOperationResponse<\/span> <span class=\"token function\">deposit<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">String<\/span> accountNumber<span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">BigDecimal<\/span> amount<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/\u89e3\u5bc6\u8d26\u53f7<\/span><br \/>\n        <span class=\"token class-name\">String<\/span> decryptedAccountNumber <span class=\"token operator\">&#061;<\/span> encryptionUtil<span class=\"token punctuation\">.<\/span><span class=\"token function\">decrypt<\/span><span class=\"token punctuation\">(<\/span>accountNumber<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>amount<span class=\"token punctuation\">.<\/span><span class=\"token function\">compareTo<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">BigDecimal<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">ZERO<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&lt;&#061;<\/span> <span class=\"token number\">0<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">throw<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">AccountException<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">ErrorCode<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">INVALID_AMOUNT<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><\/p>\n<p>        <span class=\"token class-name\">Account<\/span> account <span class=\"token operator\">&#061;<\/span> accountRepository<span class=\"token punctuation\">.<\/span><span class=\"token function\">findByAccountNumberForUpdate<\/span><span class=\"token punctuation\">(<\/span>accountNumber<span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">orElseThrow<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">-&gt;<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">AccountException<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">ErrorCode<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">ACCOUNT_NOT_FOUND<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>account<span class=\"token punctuation\">.<\/span><span class=\"token function\">getStatus<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">!&#061;<\/span> <span class=\"token class-name\">AccountStatus<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">ACTIVE<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">throw<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">AccountException<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">ErrorCode<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">ACCOUNT_NOT_ACTIVE<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><\/p>\n<p>        <span class=\"token class-name\">BigDecimal<\/span> newBalance <span class=\"token operator\">&#061;<\/span> account<span class=\"token punctuation\">.<\/span><span class=\"token function\">getBalance<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">add<\/span><span class=\"token punctuation\">(<\/span>amount<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        account<span class=\"token punctuation\">.<\/span><span class=\"token function\">setBalance<\/span><span class=\"token punctuation\">(<\/span>newBalance<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        account<span class=\"token punctuation\">.<\/span><span class=\"token function\">setAvailableBalance<\/span><span class=\"token punctuation\">(<\/span>newBalance<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        accountRepository<span class=\"token punctuation\">.<\/span><span class=\"token function\">save<\/span><span class=\"token punctuation\">(<\/span>account<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        log<span class=\"token punctuation\">.<\/span><span class=\"token function\">info<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;Deposit {} to account {}&#034;<\/span><span class=\"token punctuation\">,<\/span> amount<span class=\"token punctuation\">,<\/span> accountNumber<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u5ba1\u8ba1\u65e5\u5fd7<\/span><br \/>\n        <span class=\"token function\">logSecurityEvent<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;DEPOSIT&#034;<\/span><span class=\"token punctuation\">,<\/span> decryptedAccountNumber<span class=\"token punctuation\">,<\/span> amount<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">return<\/span> <span class=\"token function\">buildSuccessResponse<\/span><span class=\"token punctuation\">(<\/span>accountNumber<span class=\"token punctuation\">,<\/span> newBalance<span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;Deposit successful&#034;<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Transactional<\/span><br \/>\n    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">AccountOperationResponse<\/span> <span class=\"token function\">withdraw<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">String<\/span> accountNumber<span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">BigDecimal<\/span> amount<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>amount<span class=\"token punctuation\">.<\/span><span class=\"token function\">compareTo<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">BigDecimal<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">ZERO<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&lt;&#061;<\/span> <span class=\"token number\">0<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">throw<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">AccountException<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">ErrorCode<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">INVALID_AMOUNT<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><\/p>\n<p>        <span class=\"token class-name\">Account<\/span> account <span class=\"token operator\">&#061;<\/span> accountRepository<span class=\"token punctuation\">.<\/span><span class=\"token function\">findByAccountNumberForUpdate<\/span><span class=\"token punctuation\">(<\/span>accountNumber<span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">orElseThrow<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">-&gt;<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">AccountException<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">ErrorCode<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">ACCOUNT_NOT_FOUND<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>account<span class=\"token punctuation\">.<\/span><span class=\"token function\">getStatus<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">!&#061;<\/span> <span class=\"token class-name\">AccountStatus<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">ACTIVE<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">throw<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">AccountException<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">ErrorCode<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">ACCOUNT_NOT_ACTIVE<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><\/p>\n<p>        <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>account<span class=\"token punctuation\">.<\/span><span class=\"token function\">getAvailableBalance<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">compareTo<\/span><span class=\"token punctuation\">(<\/span>amount<span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&lt;<\/span> <span class=\"token number\">0<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">throw<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">AccountException<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">ErrorCode<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">INSUFFICIENT_BALANCE<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><\/p>\n<p>        <span class=\"token class-name\">BigDecimal<\/span> newBalance <span class=\"token operator\">&#061;<\/span> account<span class=\"token punctuation\">.<\/span><span class=\"token function\">getBalance<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">subtract<\/span><span class=\"token punctuation\">(<\/span>amount<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        account<span class=\"token punctuation\">.<\/span><span class=\"token function\">setBalance<\/span><span class=\"token punctuation\">(<\/span>newBalance<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        account<span class=\"token punctuation\">.<\/span><span class=\"token function\">setAvailableBalance<\/span><span class=\"token punctuation\">(<\/span>newBalance<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        accountRepository<span class=\"token punctuation\">.<\/span><span class=\"token function\">save<\/span><span class=\"token punctuation\">(<\/span>account<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        log<span class=\"token punctuation\">.<\/span><span class=\"token function\">info<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;Withdraw {} from account {}&#034;<\/span><span class=\"token punctuation\">,<\/span> amount<span class=\"token punctuation\">,<\/span> accountNumber<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">return<\/span> <span class=\"token function\">buildSuccessResponse<\/span><span class=\"token punctuation\">(<\/span>accountNumber<span class=\"token punctuation\">,<\/span> newBalance<span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;Withdrawal successful&#034;<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Transactional<\/span><br \/>\n    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">AccountOperationResponse<\/span> <span class=\"token function\">freezeAccount<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">String<\/span> accountNumber<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token class-name\">Account<\/span> account <span class=\"token operator\">&#061;<\/span> accountRepository<span class=\"token punctuation\">.<\/span><span class=\"token function\">findByAccountNumberForUpdate<\/span><span class=\"token punctuation\">(<\/span>accountNumber<span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">orElseThrow<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">-&gt;<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">AccountException<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">ErrorCode<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">ACCOUNT_NOT_FOUND<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>account<span class=\"token punctuation\">.<\/span><span class=\"token function\">getStatus<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token class-name\">AccountStatus<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">FROZEN<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">throw<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">AccountException<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">ErrorCode<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">ACCOUNT_ALREADY_FROZEN<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><\/p>\n<p>        account<span class=\"token punctuation\">.<\/span><span class=\"token function\">setStatus<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">AccountStatus<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">FROZEN<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        accountRepository<span class=\"token punctuation\">.<\/span><span class=\"token function\">save<\/span><span class=\"token punctuation\">(<\/span>account<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        log<span class=\"token punctuation\">.<\/span><span class=\"token function\">info<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;Account {} frozen&#034;<\/span><span class=\"token punctuation\">,<\/span> accountNumber<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">return<\/span> <span class=\"token function\">buildSuccessResponse<\/span><span class=\"token punctuation\">(<\/span>accountNumber<span class=\"token punctuation\">,<\/span> account<span class=\"token punctuation\">.<\/span><span class=\"token function\">getBalance<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;Account frozen successfully&#034;<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Transactional<\/span><br \/>\n    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">AccountOperationResponse<\/span> <span class=\"token function\">unfreezeAccount<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">String<\/span> accountNumber<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token class-name\">Account<\/span> account <span class=\"token operator\">&#061;<\/span> accountRepository<span class=\"token punctuation\">.<\/span><span class=\"token function\">findByAccountNumberForUpdate<\/span><span class=\"token punctuation\">(<\/span>accountNumber<span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">orElseThrow<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">-&gt;<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">AccountException<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">ErrorCode<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">ACCOUNT_NOT_FOUND<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>account<span class=\"token punctuation\">.<\/span><span class=\"token function\">getStatus<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">!&#061;<\/span> <span class=\"token class-name\">AccountStatus<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">FROZEN<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">throw<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">AccountException<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">ErrorCode<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">ACCOUNT_NOT_FROZEN<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><\/p>\n<p>        account<span class=\"token punctuation\">.<\/span><span class=\"token function\">setStatus<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">AccountStatus<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">ACTIVE<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        accountRepository<span class=\"token punctuation\">.<\/span><span class=\"token function\">save<\/span><span class=\"token punctuation\">(<\/span>account<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        log<span class=\"token punctuation\">.<\/span><span class=\"token function\">info<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;Account {} unfrozen&#034;<\/span><span class=\"token punctuation\">,<\/span> accountNumber<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">return<\/span> <span class=\"token function\">buildSuccessResponse<\/span><span class=\"token punctuation\">(<\/span>accountNumber<span class=\"token punctuation\">,<\/span> account<span class=\"token punctuation\">.<\/span><span class=\"token function\">getBalance<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;Account unfrozen successfully&#034;<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Transactional<\/span><br \/>\n    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">AccountOperationResponse<\/span> <span class=\"token function\">closeAccount<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">String<\/span> accountNumber<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token class-name\">Account<\/span> account <span class=\"token operator\">&#061;<\/span> accountRepository<span class=\"token punctuation\">.<\/span><span class=\"token function\">findByAccountNumberForUpdate<\/span><span class=\"token punctuation\">(<\/span>accountNumber<span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">orElseThrow<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">-&gt;<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">AccountException<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">ErrorCode<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">ACCOUNT_NOT_FOUND<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>account<span class=\"token punctuation\">.<\/span><span class=\"token function\">getStatus<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token class-name\">AccountStatus<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">CLOSED<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">throw<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">AccountException<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">ErrorCode<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">ACCOUNT_ALREADY_CLOSED<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><\/p>\n<p>        <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>account<span class=\"token punctuation\">.<\/span><span class=\"token function\">getBalance<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">compareTo<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">BigDecimal<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">ZERO<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">!&#061;<\/span> <span class=\"token number\">0<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">throw<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">AccountException<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">ErrorCode<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">ACCOUNT_BALANCE_NOT_ZERO<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><\/p>\n<p>        account<span class=\"token punctuation\">.<\/span><span class=\"token function\">setStatus<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">AccountStatus<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">CLOSED<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        accountRepository<span class=\"token punctuation\">.<\/span><span class=\"token function\">save<\/span><span class=\"token punctuation\">(<\/span>account<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        log<span class=\"token punctuation\">.<\/span><span class=\"token function\">info<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;Account {} closed&#034;<\/span><span class=\"token punctuation\">,<\/span> accountNumber<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">return<\/span> <span class=\"token function\">buildSuccessResponse<\/span><span class=\"token punctuation\">(<\/span>accountNumber<span class=\"token punctuation\">,<\/span> account<span class=\"token punctuation\">.<\/span><span class=\"token function\">getBalance<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;Account closed successfully&#034;<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">AccountDTO<\/span> <span class=\"token function\">convertToDTO<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">Account<\/span> account<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token class-name\">AccountDTO<\/span> dto <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">AccountDTO<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        dto<span class=\"token punctuation\">.<\/span><span class=\"token function\">setId<\/span><span class=\"token punctuation\">(<\/span>account<span class=\"token punctuation\">.<\/span><span class=\"token function\">getId<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        dto<span class=\"token punctuation\">.<\/span><span class=\"token function\">setAccountNumber<\/span><span class=\"token punctuation\">(<\/span>account<span class=\"token punctuation\">.<\/span><span class=\"token function\">getAccountNumber<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        dto<span class=\"token punctuation\">.<\/span><span class=\"token function\">setCustomerId<\/span><span class=\"token punctuation\">(<\/span>account<span class=\"token punctuation\">.<\/span><span class=\"token function\">getCustomerId<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        dto<span class=\"token punctuation\">.<\/span><span class=\"token function\">setAccountType<\/span><span class=\"token punctuation\">(<\/span>account<span class=\"token punctuation\">.<\/span><span class=\"token function\">getAccountType<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        dto<span class=\"token punctuation\">.<\/span><span class=\"token function\">setStatus<\/span><span class=\"token punctuation\">(<\/span>account<span class=\"token punctuation\">.<\/span><span class=\"token function\">getStatus<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        dto<span class=\"token punctuation\">.<\/span><span class=\"token function\">setBalance<\/span><span class=\"token punctuation\">(<\/span>account<span class=\"token punctuation\">.<\/span><span class=\"token function\">getBalance<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        dto<span class=\"token punctuation\">.<\/span><span class=\"token function\">setAvailableBalance<\/span><span class=\"token punctuation\">(<\/span>account<span class=\"token punctuation\">.<\/span><span class=\"token function\">getAvailableBalance<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        dto<span class=\"token punctuation\">.<\/span><span class=\"token function\">setCurrency<\/span><span class=\"token punctuation\">(<\/span>account<span class=\"token punctuation\">.<\/span><span class=\"token function\">getCurrency<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        dto<span class=\"token punctuation\">.<\/span><span class=\"token function\">setCreatedAt<\/span><span class=\"token punctuation\">(<\/span>account<span class=\"token punctuation\">.<\/span><span class=\"token function\">getCreatedAt<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        dto<span class=\"token punctuation\">.<\/span><span class=\"token function\">setUpdatedAt<\/span><span class=\"token punctuation\">(<\/span>account<span class=\"token punctuation\">.<\/span><span class=\"token function\">getUpdatedAt<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> dto<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">AccountOperationResponse<\/span> <span class=\"token function\">buildSuccessResponse<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">String<\/span> accountNumber<span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">BigDecimal<\/span> newBalance<span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">String<\/span> message<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token class-name\">AccountOperationResponse<\/span> response <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">AccountOperationResponse<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        response<span class=\"token punctuation\">.<\/span><span class=\"token function\">setSuccess<\/span><span class=\"token punctuation\">(<\/span><span class=\"token boolean\">true<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        response<span class=\"token punctuation\">.<\/span><span class=\"token function\">setMessage<\/span><span class=\"token punctuation\">(<\/span>message<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        response<span class=\"token punctuation\">.<\/span><span class=\"token function\">setAccountNumber<\/span><span class=\"token punctuation\">(<\/span>accountNumber<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        response<span class=\"token punctuation\">.<\/span><span class=\"token function\">setNewBalance<\/span><span class=\"token punctuation\">(<\/span>newBalance<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> response<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token comment\">\/**<br \/>\n\u5b89\u5168\u670d\u52a1<br \/>\n*\/<\/span><br \/>\n<span class=\"token annotation punctuation\">&#064;Service<\/span><br \/>\n<span class=\"token annotation punctuation\">&#064;RequiredArgsConstructor<\/span><br \/>\n<span class=\"token keyword\">public<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token class-name\">AuthenticationService<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">final<\/span> <span class=\"token class-name\">UserRepository<\/span> userRepository<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">final<\/span> <span class=\"token class-name\">PasswordEncoder<\/span> passwordEncoder<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">final<\/span> <span class=\"token class-name\">JwtService<\/span> jwtService<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">final<\/span> <span class=\"token class-name\">AuthenticationManager<\/span> authenticationManager<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">AuthenticationResponse<\/span> <span class=\"token function\">register<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">AuthenticationRequest<\/span> request<span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">Role<\/span> role<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">var<\/span> user <span class=\"token operator\">&#061;<\/span> <span class=\"token class-name\">User<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">builder<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">username<\/span><span class=\"token punctuation\">(<\/span>request<span class=\"token punctuation\">.<\/span><span class=\"token function\">getUsername<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">password<\/span><span class=\"token punctuation\">(<\/span>passwordEncoder<span class=\"token punctuation\">.<\/span><span class=\"token function\">encode<\/span><span class=\"token punctuation\">(<\/span>request<span class=\"token punctuation\">.<\/span><span class=\"token function\">getPassword<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">role<\/span><span class=\"token punctuation\">(<\/span>role<span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">build<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        userRepository<span class=\"token punctuation\">.<\/span><span class=\"token function\">save<\/span><span class=\"token punctuation\">(<\/span>user<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">var<\/span> jwtToken <span class=\"token operator\">&#061;<\/span> jwtService<span class=\"token punctuation\">.<\/span><span class=\"token function\">generateToken<\/span><span class=\"token punctuation\">(<\/span>user<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token keyword\">var<\/span> refreshToken <span class=\"token operator\">&#061;<\/span> jwtService<span class=\"token punctuation\">.<\/span><span class=\"token function\">generateRefreshToken<\/span><span class=\"token punctuation\">(<\/span>user<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">return<\/span> <span class=\"token class-name\">AuthenticationResponse<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">builder<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">token<\/span><span class=\"token punctuation\">(<\/span>jwtToken<span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">refreshToken<\/span><span class=\"token punctuation\">(<\/span>refreshToken<span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">build<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">AuthenticationResponse<\/span> <span class=\"token function\">authenticate<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">AuthenticationRequest<\/span> request<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        authenticationManager<span class=\"token punctuation\">.<\/span><span class=\"token function\">authenticate<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">UsernamePasswordAuthenticationToken<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                        request<span class=\"token punctuation\">.<\/span><span class=\"token function\">getUsername<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                        request<span class=\"token punctuation\">.<\/span><span class=\"token function\">getPassword<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">)<\/span><br \/>\n        <span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">var<\/span> user <span class=\"token operator\">&#061;<\/span> userRepository<span class=\"token punctuation\">.<\/span><span class=\"token function\">findByUsername<\/span><span class=\"token punctuation\">(<\/span>request<span class=\"token punctuation\">.<\/span><span class=\"token function\">getUsername<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">orElseThrow<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">var<\/span> jwtToken <span class=\"token operator\">&#061;<\/span> jwtService<span class=\"token punctuation\">.<\/span><span class=\"token function\">generateToken<\/span><span class=\"token punctuation\">(<\/span>user<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token keyword\">var<\/span> refreshToken <span class=\"token operator\">&#061;<\/span> jwtService<span class=\"token punctuation\">.<\/span><span class=\"token function\">generateRefreshToken<\/span><span class=\"token punctuation\">(<\/span>user<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">return<\/span> <span class=\"token class-name\">AuthenticationResponse<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">builder<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">token<\/span><span class=\"token punctuation\">(<\/span>jwtToken<span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">refreshToken<\/span><span class=\"token punctuation\">(<\/span>refreshToken<span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">build<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p>Repository\u5c42<\/p>\n<p><span class=\"token keyword\">public<\/span> <span class=\"token keyword\">interface<\/span> <span class=\"token class-name\">AccountRepository<\/span> <span class=\"token keyword\">extends<\/span> <span class=\"token class-name\">JpaRepository<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">Account<\/span><span class=\"token punctuation\">,<\/span><span class=\"token class-name\">Long<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><span class=\"token punctuation\">{<\/span><\/p>\n<p><span class=\"token class-name\">Optional<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">Account<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> <span class=\"token function\">findByAccountNumber<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">String<\/span> accountNumber<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p><span class=\"token annotation punctuation\">&#064;Lock<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">LockModeType<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">PESSIMISTIC_WRITE<\/span><span class=\"token punctuation\">)<\/span><br \/>\n<span class=\"token annotation punctuation\">&#064;Query<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;SELECT a FROM Account a WHERE a.accountNumber &#061; :accountNumber&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token class-name\">Optional<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">Account<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> <span class=\"token function\">findByAccountNumberForUpdate<\/span><span class=\"token punctuation\">(<\/span><span class=\"token annotation punctuation\">&#064;Param<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;accountNumber&#034;<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token class-name\">String<\/span> accountNumber<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p><span class=\"token keyword\">boolean<\/span> <span class=\"token function\">existsByAccountNumber<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">String<\/span> accountNumber<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p>2. \u4ea4\u6613\u5904\u7406<\/p>\n<p>\u5b58\u6b3e\/\u53d6\u6b3e<\/p>\n<p>\u8f6c\u8d26(\u540c\u884c\/\u8de8\u884c)<\/p>\n<p>\u6279\u91cf\u4ea4\u6613\u5904\u7406<\/p>\n<p>\u4ea4\u6613\u6d41\u6c34\u8bb0\u5f55<\/p>\n<p>\u4ea4\u6613\u9650\u989d\u7ba1\u7406<\/p>\n<p><span class=\"token comment\"># \u5728\u539f\u6709\u914d\u7f6e\u57fa\u7840\u4e0a\u6dfb\u52a0<\/span><br \/>\n<span class=\"token key atrule\">service<\/span><span class=\"token punctuation\">:<\/span><br \/>\n  <span class=\"token key atrule\">account<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    <span class=\"token key atrule\">url<\/span><span class=\"token punctuation\">:<\/span> http<span class=\"token punctuation\">:<\/span>\/\/account<span class=\"token punctuation\">&#8211;<\/span>service<span class=\"token punctuation\">:<\/span><span class=\"token number\">8080<\/span><\/p>\n<p><span class=\"token key atrule\">security<\/span><span class=\"token punctuation\">:<\/span><br \/>\n  <span class=\"token key atrule\">transaction<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    <span class=\"token key atrule\">max-retry-attempts<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token number\">3<\/span><br \/>\n    <span class=\"token key atrule\">retry-delay<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token number\">1000<\/span> <span class=\"token comment\"># ms<\/span><\/p>\n<p><span class=\"token annotation punctuation\">&#064;Entity<\/span><br \/>\n<span class=\"token annotation punctuation\">&#064;Table<\/span><span class=\"token punctuation\">(<\/span>name <span class=\"token operator\">&#061;<\/span> <span class=\"token string\">&#034;transaction&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n<span class=\"token annotation punctuation\">&#064;Data<\/span><br \/>\n<span class=\"token keyword\">public<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token class-name\">Transaction<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token annotation punctuation\">&#064;Id<\/span><br \/>\n    <span class=\"token annotation punctuation\">&#064;GeneratedValue<\/span><span class=\"token punctuation\">(<\/span>strategy <span class=\"token operator\">&#061;<\/span> <span class=\"token class-name\">GenerationType<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">IDENTITY<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">Long<\/span> id<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>nullable <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">,<\/span> unique <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">true<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> transactionId<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>nullable <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> accountNumber<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> counterpartyAccountNumber<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Enumerated<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">EnumType<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">STRING<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>nullable <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">TransactionType<\/span> transactionType<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Enumerated<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">EnumType<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">STRING<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>nullable <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">TransactionStatus<\/span> status<span class=\"token punctuation\">;<\/span><span class=\"token comment\">\/\/\u5904\u7406\u4e2d\u3001\u5df2\u5b8c\u6210\u3001\u5931\u8d25\u3001\u5df2\u51b2\u6b63\u3001\u5df2\u53d6\u6d88<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>nullable <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">,<\/span> precision <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">19<\/span><span class=\"token punctuation\">,<\/span> scale <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">4<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">BigDecimal<\/span> amount<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>precision <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">19<\/span><span class=\"token punctuation\">,<\/span> scale <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">4<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">BigDecimal<\/span> fee<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>nullable <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> currency <span class=\"token operator\">&#061;<\/span> <span class=\"token string\">&#034;CNY&#034;<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> description<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>nullable <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> reference<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;CreationTimestamp<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">LocalDateTime<\/span> createdAt<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;UpdateTimestamp<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">LocalDateTime<\/span> updatedAt<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Version<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">Long<\/span> version<span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token annotation punctuation\">&#064;Entity<\/span><br \/>\n<span class=\"token annotation punctuation\">&#064;Table<\/span><span class=\"token punctuation\">(<\/span>name <span class=\"token operator\">&#061;<\/span> <span class=\"token string\">&#034;transaction_limit&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n<span class=\"token annotation punctuation\">&#064;Data<\/span><br \/>\n<span class=\"token keyword\">public<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token class-name\">TransactionLimit<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token annotation punctuation\">&#064;Id<\/span><br \/>\n    <span class=\"token annotation punctuation\">&#064;GeneratedValue<\/span><span class=\"token punctuation\">(<\/span>strategy <span class=\"token operator\">&#061;<\/span> <span class=\"token class-name\">GenerationType<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">IDENTITY<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">Long<\/span> id<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Enumerated<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">EnumType<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">STRING<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>nullable <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">TransactionType<\/span> transactionType<span class=\"token punctuation\">;<\/span><span class=\"token comment\">\/\/\u5b58\u6b3e\u3001\u53d6\u6b3e\u3001\u8f6c\u8d26\u3001\u8d26\u5355\u652f\u4ed8\u3001\u8d37\u6b3e\u8fd8\u6b3e\u3001\u8d39\u7528\u6536\u53d6<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>nullable <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> accountType<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>nullable <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">,<\/span> precision <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">19<\/span><span class=\"token punctuation\">,<\/span> scale <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">4<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">BigDecimal<\/span> dailyLimit<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>nullable <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">,<\/span> precision <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">19<\/span><span class=\"token punctuation\">,<\/span> scale <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">4<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">BigDecimal<\/span> perTransactionLimit<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>nullable <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">Integer<\/span> dailyCountLimit<span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token annotation punctuation\">&#064;Data<\/span><br \/>\n<span class=\"token keyword\">public<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token class-name\">TransactionDTO<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> transactionId<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> accountNumber<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> counterpartyAccountNumber<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">TransactionType<\/span> transactionType<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">TransactionStatus<\/span> status<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">BigDecimal<\/span> amount<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">BigDecimal<\/span> fee<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> currency<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> description<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> reference<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">LocalDateTime<\/span> createdAt<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">LocalDateTime<\/span> updatedAt<span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token annotation punctuation\">&#064;Data<\/span><br \/>\n<span class=\"token keyword\">public<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token class-name\">DepositRequest<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token annotation punctuation\">&#064;NotNull<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> accountNumber<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;NotNull<\/span><br \/>\n    <span class=\"token annotation punctuation\">&#064;Positive<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">BigDecimal<\/span> amount<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> description<span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token annotation punctuation\">&#064;Data<\/span><br \/>\n<span class=\"token keyword\">public<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token class-name\">WithdrawalRequest<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token annotation punctuation\">&#064;NotNull<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> accountNumber<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;NotNull<\/span><br \/>\n    <span class=\"token annotation punctuation\">&#064;Positive<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">BigDecimal<\/span> amount<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> description<span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token annotation punctuation\">&#064;Data<\/span><br \/>\n<span class=\"token keyword\">public<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token class-name\">TransferRequest<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token annotation punctuation\">&#064;NotNull<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> fromAccountNumber<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;NotNull<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> toAccountNumber<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;NotNull<\/span><br \/>\n    <span class=\"token annotation punctuation\">&#064;Positive<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">BigDecimal<\/span> amount<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> description<span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token annotation punctuation\">&#064;Data<\/span><br \/>\n<span class=\"token keyword\">public<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token class-name\">BatchTransactionRequest<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token annotation punctuation\">&#064;NotEmpty<\/span><br \/>\n    <span class=\"token annotation punctuation\">&#064;Valid<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">List<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">TransferRequest<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> transactions<span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p>\u5f02\u5e38<\/p>\n<p><span class=\"token annotation punctuation\">&#064;Getter<\/span><br \/>\n<span class=\"token keyword\">public<\/span> <span class=\"token keyword\">enum<\/span> <span class=\"token class-name\">ErrorCode<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token comment\">\/\/ \u539f\u6709\u9519\u8bef\u7801&#8230;<\/span><br \/>\n    <span class=\"token function\">TRANSACTION_LIMIT_NOT_FOUND<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">400<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;Transaction limit not found&#034;<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token function\">EXCEED_PER_TRANSACTION_LIMIT<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">400<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;Exceed per transaction limit&#034;<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token function\">EXCEED_DAILY_LIMIT<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">400<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;Exceed daily limit&#034;<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token function\">EXCEED_DAILY_COUNT_LIMIT<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">400<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;Exceed daily count limit&#034;<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token function\">DEPOSIT_FAILED<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">400<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;Deposit failed&#034;<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token function\">WITHDRAWAL_FAILED<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">400<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;Withdrawal failed&#034;<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token function\">TRANSFER_FAILED<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">400<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;Transfer failed&#034;<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token function\">ACCOUNT_SERVICE_UNAVAILABLE<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">503<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;Account service unavailable&#034;<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token function\">TRANSACTION_SERVICE_UNAVAILABLE<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">503<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;Transaction service unavailable&#034;<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">final<\/span> <span class=\"token keyword\">int<\/span> status<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">final<\/span> <span class=\"token class-name\">String<\/span> message<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token class-name\">ErrorCode<\/span><span class=\"token punctuation\">(<\/span><span class=\"token keyword\">int<\/span> status<span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">String<\/span> message<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">this<\/span><span class=\"token punctuation\">.<\/span>status <span class=\"token operator\">&#061;<\/span> status<span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token keyword\">this<\/span><span class=\"token punctuation\">.<\/span>message <span class=\"token operator\">&#061;<\/span> message<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p>\u5de5\u5177\u7c7b<\/p>\n<p><span class=\"token annotation punctuation\">&#064;Component<\/span><br \/>\n<span class=\"token keyword\">public<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token class-name\">TransactionIdGenerator<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">static<\/span> <span class=\"token keyword\">final<\/span> <span class=\"token class-name\">String<\/span> <span class=\"token constant\">BANK_CODE<\/span> <span class=\"token operator\">&#061;<\/span> <span class=\"token string\">&#034;888&#034;<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">final<\/span> <span class=\"token class-name\">AtomicLong<\/span> sequence <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">AtomicLong<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">1<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">String<\/span> <span class=\"token function\">generate<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">long<\/span> timestamp <span class=\"token operator\">&#061;<\/span> <span class=\"token class-name\">Instant<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">now<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">toEpochMilli<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token keyword\">long<\/span> seq <span class=\"token operator\">&#061;<\/span> sequence<span class=\"token punctuation\">.<\/span><span class=\"token function\">getAndIncrement<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> <span class=\"token class-name\">String<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">format<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;%s-TRX-%d-%06d&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token constant\">BANK_CODE<\/span><span class=\"token punctuation\">,<\/span> timestamp<span class=\"token punctuation\">,<\/span> seq<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p>Controller\u5c42<\/p>\n<p><span class=\"token annotation punctuation\">&#064;Controller<\/span><br \/>\n<span class=\"token annotation punctuation\">&#064;RequestMapping<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;\/api\/transactions&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n<span class=\"token annotation punctuation\">&#064;RequiredArgsConstructor<\/span><br \/>\n<span class=\"token keyword\">public<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token class-name\">TransactionController<\/span><span class=\"token punctuation\">{<\/span><\/p>\n<p><span class=\"token keyword\">private<\/span> <span class=\"token keyword\">final<\/span> <span class=\"token class-name\">TransactionService<\/span> transactionService<span class=\"token punctuation\">;<\/span><\/p>\n<p><span class=\"token annotation punctuation\">&#064;PostMapping<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;\/deposit&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n<span class=\"token annotation punctuation\">&#064;PreAuthorize<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;hasAnyRole(&#039;TELLER&#039;, &#039;MANAGER&#039;, &#039;ADMIN&#039;)&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n<span class=\"token keyword\">public<\/span> <span class=\"token class-name\">ResponseEntity<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">TransactionDTO<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> <span class=\"token function\">deposit<\/span><span class=\"token punctuation\">(<\/span><span class=\"token annotation punctuation\">&#064;Valid<\/span> <span class=\"token annotation punctuation\">&#064;RequestBody<\/span> <span class=\"token class-name\">DepositRequest<\/span> request<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> <span class=\"token class-name\">ResponseEntity<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">ok<\/span><span class=\"token punctuation\">(<\/span>transactionService<span class=\"token punctuation\">.<\/span><span class=\"token function\">deposit<\/span><span class=\"token punctuation\">(<\/span>request<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token annotation punctuation\">&#064;PostMapping<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;\/withdraw&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">ResponseEntity<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">TransactionDTO<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> <span class=\"token function\">withdraw<\/span><span class=\"token punctuation\">(<\/span><span class=\"token annotation punctuation\">&#064;Valid<\/span> <span class=\"token annotation punctuation\">&#064;RequestBody<\/span> <span class=\"token class-name\">WithdrawalRequest<\/span> request<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> <span class=\"token class-name\">ResponseEntity<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">ok<\/span><span class=\"token punctuation\">(<\/span>transactionService<span class=\"token punctuation\">.<\/span><span class=\"token function\">withdraw<\/span><span class=\"token punctuation\">(<\/span>request<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;PostMapping<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;\/transfer&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">ResponseEntity<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">TransactionDTO<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> <span class=\"token function\">transfer<\/span><span class=\"token punctuation\">(<\/span><span class=\"token annotation punctuation\">&#064;Valid<\/span> <span class=\"token annotation punctuation\">&#064;RequestBody<\/span> <span class=\"token class-name\">TransferRequest<\/span> request<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> <span class=\"token class-name\">ResponseEntity<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">ok<\/span><span class=\"token punctuation\">(<\/span>transactionService<span class=\"token punctuation\">.<\/span><span class=\"token function\">transfer<\/span><span class=\"token punctuation\">(<\/span>request<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;PostMapping<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;\/batch-transfer&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token annotation punctuation\">&#064;PreAuthorize<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;hasAnyRole(&#039;TELLER&#039;, &#039;MANAGER&#039;, &#039;ADMIN&#039;)&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">ResponseEntity<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">List<\/span><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">TransactionDTO<\/span><span class=\"token punctuation\">&gt;<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> <span class=\"token function\">batchTransfer<\/span><span class=\"token punctuation\">(<\/span><span class=\"token annotation punctuation\">&#064;Valid<\/span> <span class=\"token annotation punctuation\">&#064;RequestBody<\/span> <span class=\"token class-name\">BatchTransactionRequest<\/span> request<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> <span class=\"token class-name\">ResponseEntity<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">ok<\/span><span class=\"token punctuation\">(<\/span>transactionService<span class=\"token punctuation\">.<\/span><span class=\"token function\">batchTransfer<\/span><span class=\"token punctuation\">(<\/span>request<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;GetMapping<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;\/history&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">ResponseEntity<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">List<\/span><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">TransactionDTO<\/span><span class=\"token punctuation\">&gt;<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> <span class=\"token function\">getTransactionHistory<\/span><span class=\"token punctuation\">(<\/span><br \/>\n            <span class=\"token annotation punctuation\">&#064;RequestParam<\/span> <span class=\"token class-name\">String<\/span> accountNumber<span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token annotation punctuation\">&#064;RequestParam<\/span> <span class=\"token annotation punctuation\">&#064;DateTimeFormat<\/span><span class=\"token punctuation\">(<\/span>iso <span class=\"token operator\">&#061;<\/span> <span class=\"token class-name\">DateTimeFormat<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">ISO<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">DATE<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token class-name\">LocalDate<\/span> startDate<span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token annotation punctuation\">&#064;RequestParam<\/span> <span class=\"token annotation punctuation\">&#064;DateTimeFormat<\/span><span class=\"token punctuation\">(<\/span>iso <span class=\"token operator\">&#061;<\/span> <span class=\"token class-name\">DateTimeFormat<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">ISO<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">DATE<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token class-name\">LocalDate<\/span> endDate<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> <span class=\"token class-name\">ResponseEntity<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">ok<\/span><span class=\"token punctuation\">(<\/span>transactionService<span class=\"token punctuation\">.<\/span><span class=\"token function\">getTransactionHistory<\/span><span class=\"token punctuation\">(<\/span>accountNumber<span class=\"token punctuation\">,<\/span> startDate<span class=\"token punctuation\">,<\/span> endDate<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token punctuation\">}<\/span><\/p>\n<p>Service\u5c42<\/p>\n<p><span class=\"token annotation punctuation\">&#064;Service<\/span><br \/>\n<span class=\"token annotation punctuation\">&#064;RequiredArgsConstructor<\/span><br \/>\n<span class=\"token annotation punctuation\">&#064;Slf4j<\/span><br \/>\n<span class=\"token keyword\">public<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token class-name\">TransactionService<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">final<\/span> <span class=\"token class-name\">TransactionRepository<\/span> transactionRepository<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">final<\/span> <span class=\"token class-name\">TransactionLimitRepository<\/span> limitRepository<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">final<\/span> <span class=\"token class-name\">AccountClientService<\/span> accountClientService<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">final<\/span> <span class=\"token class-name\">TransactionIdGenerator<\/span> idGenerator<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">final<\/span> <span class=\"token class-name\">EncryptionUtil<\/span> encryptionUtil<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Transactional<\/span><br \/>\n    <span class=\"token annotation punctuation\">&#064;PreAuthorize<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;hasAnyRole(&#039;TELLER&#039;, &#039;MANAGER&#039;, &#039;ADMIN&#039;)&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">TransactionDTO<\/span> <span class=\"token function\">deposit<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">DepositRequest<\/span> request<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token comment\">\/\/ \u89e3\u5bc6\u8d26\u53f7<\/span><br \/>\n        <span class=\"token class-name\">String<\/span> decryptedAccountNumber <span class=\"token operator\">&#061;<\/span> encryptionUtil<span class=\"token punctuation\">.<\/span><span class=\"token function\">decrypt<\/span><span class=\"token punctuation\">(<\/span>request<span class=\"token punctuation\">.<\/span><span class=\"token function\">getAccountNumber<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u9a8c\u8bc1\u91d1\u989d<\/span><br \/>\n        <span class=\"token function\">validateAmount<\/span><span class=\"token punctuation\">(<\/span>request<span class=\"token punctuation\">.<\/span><span class=\"token function\">getAmount<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u68c0\u67e5\u8d26\u6237\u72b6\u6001<\/span><br \/>\n        <span class=\"token function\">checkAccountStatus<\/span><span class=\"token punctuation\">(<\/span>decryptedAccountNumber<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u6267\u884c\u5b58\u6b3e<\/span><br \/>\n        <span class=\"token class-name\">BigDecimal<\/span> newBalance <span class=\"token operator\">&#061;<\/span> accountClientService<span class=\"token punctuation\">.<\/span><span class=\"token function\">deposit<\/span><span class=\"token punctuation\">(<\/span>decryptedAccountNumber<span class=\"token punctuation\">,<\/span> request<span class=\"token punctuation\">.<\/span><span class=\"token function\">getAmount<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u8bb0\u5f55\u4ea4\u6613<\/span><br \/>\n        <span class=\"token class-name\">Transaction<\/span> transaction <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">Transaction<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        transaction<span class=\"token punctuation\">.<\/span><span class=\"token function\">setTransactionId<\/span><span class=\"token punctuation\">(<\/span>idGenerator<span class=\"token punctuation\">.<\/span><span class=\"token function\">generate<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        transaction<span class=\"token punctuation\">.<\/span><span class=\"token function\">setAccountNumber<\/span><span class=\"token punctuation\">(<\/span>decryptedAccountNumber<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        transaction<span class=\"token punctuation\">.<\/span><span class=\"token function\">setTransactionType<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">TransactionType<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">DEPOSIT<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        transaction<span class=\"token punctuation\">.<\/span><span class=\"token function\">setStatus<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">TransactionStatus<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">COMPLETED<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        transaction<span class=\"token punctuation\">.<\/span><span class=\"token function\">setAmount<\/span><span class=\"token punctuation\">(<\/span>request<span class=\"token punctuation\">.<\/span><span class=\"token function\">getAmount<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        transaction<span class=\"token punctuation\">.<\/span><span class=\"token function\">setCurrency<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;CNY&#034;<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        transaction<span class=\"token punctuation\">.<\/span><span class=\"token function\">setDescription<\/span><span class=\"token punctuation\">(<\/span>request<span class=\"token punctuation\">.<\/span><span class=\"token function\">getDescription<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        transaction<span class=\"token punctuation\">.<\/span><span class=\"token function\">setReference<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;DEP-&#034;<\/span> <span class=\"token operator\">&#043;<\/span> <span class=\"token class-name\">System<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">currentTimeMillis<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token class-name\">Transaction<\/span> saved <span class=\"token operator\">&#061;<\/span> transactionRepository<span class=\"token punctuation\">.<\/span><span class=\"token function\">save<\/span><span class=\"token punctuation\">(<\/span>transaction<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        log<span class=\"token punctuation\">.<\/span><span class=\"token function\">info<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;Deposit completed: {}&#034;<\/span><span class=\"token punctuation\">,<\/span> saved<span class=\"token punctuation\">.<\/span><span class=\"token function\">getTransactionId<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">return<\/span> <span class=\"token function\">convertToDTO<\/span><span class=\"token punctuation\">(<\/span>saved<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Transactional<\/span><br \/>\n    <span class=\"token annotation punctuation\">&#064;PreAuthorize<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;hasAnyRole(&#039;TELLER&#039;, &#039;MANAGER&#039;, &#039;ADMIN&#039;) || &#034;<\/span><br \/>\n            <span class=\"token operator\">&#043;<\/span> <span class=\"token string\">&#034;(hasRole(&#039;CUSTOMER&#039;) &amp;&amp; &#064;accountSecurityService.isAccountOwner(authentication, #request.accountNumber))&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">TransactionDTO<\/span> <span class=\"token function\">withdraw<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">WithdrawalRequest<\/span> request<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token comment\">\/\/ \u89e3\u5bc6\u8d26\u53f7<\/span><br \/>\n        <span class=\"token class-name\">String<\/span> decryptedAccountNumber <span class=\"token operator\">&#061;<\/span> encryptionUtil<span class=\"token punctuation\">.<\/span><span class=\"token function\">decrypt<\/span><span class=\"token punctuation\">(<\/span>request<span class=\"token punctuation\">.<\/span><span class=\"token function\">getAccountNumber<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u9a8c\u8bc1\u91d1\u989d<\/span><br \/>\n        <span class=\"token function\">validateAmount<\/span><span class=\"token punctuation\">(<\/span>request<span class=\"token punctuation\">.<\/span><span class=\"token function\">getAmount<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u68c0\u67e5\u8d26\u6237\u72b6\u6001<\/span><br \/>\n        <span class=\"token function\">checkAccountStatus<\/span><span class=\"token punctuation\">(<\/span>decryptedAccountNumber<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u68c0\u67e5\u4ea4\u6613\u9650\u989d<\/span><br \/>\n        <span class=\"token function\">checkWithdrawalLimit<\/span><span class=\"token punctuation\">(<\/span>decryptedAccountNumber<span class=\"token punctuation\">,<\/span> request<span class=\"token punctuation\">.<\/span><span class=\"token function\">getAmount<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u6267\u884c\u53d6\u6b3e<\/span><br \/>\n        <span class=\"token class-name\">BigDecimal<\/span> newBalance <span class=\"token operator\">&#061;<\/span> accountClientService<span class=\"token punctuation\">.<\/span><span class=\"token function\">withdraw<\/span><span class=\"token punctuation\">(<\/span>decryptedAccountNumber<span class=\"token punctuation\">,<\/span> request<span class=\"token punctuation\">.<\/span><span class=\"token function\">getAmount<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u8bb0\u5f55\u4ea4\u6613<\/span><br \/>\n        <span class=\"token class-name\">Transaction<\/span> transaction <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">Transaction<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        transaction<span class=\"token punctuation\">.<\/span><span class=\"token function\">setTransactionId<\/span><span class=\"token punctuation\">(<\/span>idGenerator<span class=\"token punctuation\">.<\/span><span class=\"token function\">generate<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        transaction<span class=\"token punctuation\">.<\/span><span class=\"token function\">setAccountNumber<\/span><span class=\"token punctuation\">(<\/span>decryptedAccountNumber<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        transaction<span class=\"token punctuation\">.<\/span><span class=\"token function\">setTransactionType<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">TransactionType<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">WITHDRAWAL<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        transaction<span class=\"token punctuation\">.<\/span><span class=\"token function\">setStatus<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">TransactionStatus<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">COMPLETED<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        transaction<span class=\"token punctuation\">.<\/span><span class=\"token function\">setAmount<\/span><span class=\"token punctuation\">(<\/span>request<span class=\"token punctuation\">.<\/span><span class=\"token function\">getAmount<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">negate<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        transaction<span class=\"token punctuation\">.<\/span><span class=\"token function\">setCurrency<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;CNY&#034;<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        transaction<span class=\"token punctuation\">.<\/span><span class=\"token function\">setDescription<\/span><span class=\"token punctuation\">(<\/span>request<span class=\"token punctuation\">.<\/span><span class=\"token function\">getDescription<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        transaction<span class=\"token punctuation\">.<\/span><span class=\"token function\">setReference<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;WTH-&#034;<\/span> <span class=\"token operator\">&#043;<\/span> <span class=\"token class-name\">System<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">currentTimeMillis<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token class-name\">Transaction<\/span> saved <span class=\"token operator\">&#061;<\/span> transactionRepository<span class=\"token punctuation\">.<\/span><span class=\"token function\">save<\/span><span class=\"token punctuation\">(<\/span>transaction<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        log<span class=\"token punctuation\">.<\/span><span class=\"token function\">info<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;Withdrawal completed: {}&#034;<\/span><span class=\"token punctuation\">,<\/span> saved<span class=\"token punctuation\">.<\/span><span class=\"token function\">getTransactionId<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">return<\/span> <span class=\"token function\">convertToDTO<\/span><span class=\"token punctuation\">(<\/span>saved<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Transactional<\/span><br \/>\n    <span class=\"token annotation punctuation\">&#064;PreAuthorize<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;hasAnyRole(&#039;TELLER&#039;, &#039;MANAGER&#039;, &#039;ADMIN&#039;) || &#034;<\/span><br \/>\n            <span class=\"token operator\">&#043;<\/span> <span class=\"token string\">&#034;(hasRole(&#039;CUSTOMER&#039;) &amp;&amp; &#064;accountSecurityService.isAccountOwner(authentication, #request.fromAccountNumber))&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">TransactionDTO<\/span> <span class=\"token function\">transfer<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">TransferRequest<\/span> request<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token comment\">\/\/ \u89e3\u5bc6\u8d26\u53f7<\/span><br \/>\n        <span class=\"token class-name\">String<\/span> decryptedFromAccount <span class=\"token operator\">&#061;<\/span> encryptionUtil<span class=\"token punctuation\">.<\/span><span class=\"token function\">decrypt<\/span><span class=\"token punctuation\">(<\/span>request<span class=\"token punctuation\">.<\/span><span class=\"token function\">getFromAccountNumber<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token class-name\">String<\/span> decryptedToAccount <span class=\"token operator\">&#061;<\/span> encryptionUtil<span class=\"token punctuation\">.<\/span><span class=\"token function\">decrypt<\/span><span class=\"token punctuation\">(<\/span>request<span class=\"token punctuation\">.<\/span><span class=\"token function\">getToAccountNumber<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u9a8c\u8bc1\u91d1\u989d<\/span><br \/>\n        <span class=\"token function\">validateAmount<\/span><span class=\"token punctuation\">(<\/span>request<span class=\"token punctuation\">.<\/span><span class=\"token function\">getAmount<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u68c0\u67e5\u8d26\u6237\u72b6\u6001<\/span><br \/>\n        <span class=\"token function\">checkAccountStatus<\/span><span class=\"token punctuation\">(<\/span>decryptedFromAccount<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token function\">checkAccountStatus<\/span><span class=\"token punctuation\">(<\/span>decryptedToAccount<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u68c0\u67e5\u8f6c\u8d26\u9650\u989d<\/span><br \/>\n        <span class=\"token function\">checkTransferLimit<\/span><span class=\"token punctuation\">(<\/span>decryptedFromAccount<span class=\"token punctuation\">,<\/span> request<span class=\"token punctuation\">.<\/span><span class=\"token function\">getAmount<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u6267\u884c\u8f6c\u8d26<\/span><br \/>\n        <span class=\"token class-name\">BigDecimal<\/span> fromNewBalance <span class=\"token operator\">&#061;<\/span> accountClientService<span class=\"token punctuation\">.<\/span><span class=\"token function\">withdraw<\/span><span class=\"token punctuation\">(<\/span>decryptedFromAccount<span class=\"token punctuation\">,<\/span> request<span class=\"token punctuation\">.<\/span><span class=\"token function\">getAmount<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token class-name\">BigDecimal<\/span> toNewBalance <span class=\"token operator\">&#061;<\/span> accountClientService<span class=\"token punctuation\">.<\/span><span class=\"token function\">deposit<\/span><span class=\"token punctuation\">(<\/span>decryptedToAccount<span class=\"token punctuation\">,<\/span> request<span class=\"token punctuation\">.<\/span><span class=\"token function\">getAmount<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u8bb0\u5f55\u4ea4\u6613(\u501f\u65b9)<\/span><br \/>\n        <span class=\"token class-name\">Transaction<\/span> debitTransaction <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">Transaction<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        debitTransaction<span class=\"token punctuation\">.<\/span><span class=\"token function\">setTransactionId<\/span><span class=\"token punctuation\">(<\/span>idGenerator<span class=\"token punctuation\">.<\/span><span class=\"token function\">generate<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        debitTransaction<span class=\"token punctuation\">.<\/span><span class=\"token function\">setAccountNumber<\/span><span class=\"token punctuation\">(<\/span>decryptedFromAccount<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        debitTransaction<span class=\"token punctuation\">.<\/span><span class=\"token function\">setCounterpartyAccountNumber<\/span><span class=\"token punctuation\">(<\/span>decryptedToAccount<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        debitTransaction<span class=\"token punctuation\">.<\/span><span class=\"token function\">setTransactionType<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">TransactionType<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">TRANSFER<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        debitTransaction<span class=\"token punctuation\">.<\/span><span class=\"token function\">setStatus<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">TransactionStatus<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">COMPLETED<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        debitTransaction<span class=\"token punctuation\">.<\/span><span class=\"token function\">setAmount<\/span><span class=\"token punctuation\">(<\/span>request<span class=\"token punctuation\">.<\/span><span class=\"token function\">getAmount<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">negate<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        debitTransaction<span class=\"token punctuation\">.<\/span><span class=\"token function\">setCurrency<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;CNY&#034;<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        debitTransaction<span class=\"token punctuation\">.<\/span><span class=\"token function\">setDescription<\/span><span class=\"token punctuation\">(<\/span>request<span class=\"token punctuation\">.<\/span><span class=\"token function\">getDescription<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        debitTransaction<span class=\"token punctuation\">.<\/span><span class=\"token function\">setReference<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;TFR-DEBIT-&#034;<\/span> <span class=\"token operator\">&#043;<\/span> <span class=\"token class-name\">System<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">currentTimeMillis<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u8bb0\u5f55\u4ea4\u6613(\u8d37\u65b9)<\/span><br \/>\n        <span class=\"token class-name\">Transaction<\/span> creditTransaction <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">Transaction<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        creditTransaction<span class=\"token punctuation\">.<\/span><span class=\"token function\">setTransactionId<\/span><span class=\"token punctuation\">(<\/span>idGenerator<span class=\"token punctuation\">.<\/span><span class=\"token function\">generate<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        creditTransaction<span class=\"token punctuation\">.<\/span><span class=\"token function\">setAccountNumber<\/span><span class=\"token punctuation\">(<\/span>decryptedToAccount<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        creditTransaction<span class=\"token punctuation\">.<\/span><span class=\"token function\">setCounterpartyAccountNumber<\/span><span class=\"token punctuation\">(<\/span>decryptedFromAccount<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        creditTransaction<span class=\"token punctuation\">.<\/span><span class=\"token function\">setTransactionType<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">TransactionType<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">TRANSFER<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        creditTransaction<span class=\"token punctuation\">.<\/span><span class=\"token function\">setStatus<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">TransactionStatus<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">COMPLETED<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        creditTransaction<span class=\"token punctuation\">.<\/span><span class=\"token function\">setAmount<\/span><span class=\"token punctuation\">(<\/span>request<span class=\"token punctuation\">.<\/span><span class=\"token function\">getAmount<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        creditTransaction<span class=\"token punctuation\">.<\/span><span class=\"token function\">setCurrency<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;CNY&#034;<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        creditTransaction<span class=\"token punctuation\">.<\/span><span class=\"token function\">setDescription<\/span><span class=\"token punctuation\">(<\/span>request<span class=\"token punctuation\">.<\/span><span class=\"token function\">getDescription<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        creditTransaction<span class=\"token punctuation\">.<\/span><span class=\"token function\">setReference<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;TFR-CREDIT-&#034;<\/span> <span class=\"token operator\">&#043;<\/span> <span class=\"token class-name\">System<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">currentTimeMillis<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        transactionRepository<span class=\"token punctuation\">.<\/span><span class=\"token function\">save<\/span><span class=\"token punctuation\">(<\/span>debitTransaction<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        transactionRepository<span class=\"token punctuation\">.<\/span><span class=\"token function\">save<\/span><span class=\"token punctuation\">(<\/span>creditTransaction<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        log<span class=\"token punctuation\">.<\/span><span class=\"token function\">info<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;Transfer completed: {} -&gt; {}&#034;<\/span><span class=\"token punctuation\">,<\/span> debitTransaction<span class=\"token punctuation\">.<\/span><span class=\"token function\">getTransactionId<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span> creditTransaction<span class=\"token punctuation\">.<\/span><span class=\"token function\">getTransactionId<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">return<\/span> <span class=\"token function\">convertToDTO<\/span><span class=\"token punctuation\">(<\/span>debitTransaction<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Transactional<\/span><br \/>\n    <span class=\"token annotation punctuation\">&#064;PreAuthorize<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;hasAnyRole(&#039;TELLER&#039;, &#039;MANAGER&#039;, &#039;ADMIN&#039;)&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">List<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">TransactionDTO<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> <span class=\"token function\">batchTransfer<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">BatchTransactionRequest<\/span> request<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> request<span class=\"token punctuation\">.<\/span><span class=\"token function\">getTransactions<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">stream<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">map<\/span><span class=\"token punctuation\">(<\/span><span class=\"token keyword\">this<\/span><span class=\"token operator\">::<\/span><span class=\"token function\">transfer<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">collect<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">Collectors<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">toList<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Transactional<\/span><span class=\"token punctuation\">(<\/span>readOnly <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">true<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token annotation punctuation\">&#064;PreAuthorize<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;hasAnyRole(&#039;TELLER&#039;, &#039;MANAGER&#039;, &#039;ADMIN&#039;) || &#034;<\/span><br \/>\n            <span class=\"token operator\">&#043;<\/span> <span class=\"token string\">&#034;(hasRole(&#039;CUSTOMER&#039;) &amp;&amp; &#064;accountSecurityService.isAccountOwner(authentication, #accountNumber))&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">List<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">TransactionDTO<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> <span class=\"token function\">getTransactionHistory<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">String<\/span> accountNumber<span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">LocalDate<\/span> startDate<span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">LocalDate<\/span> endDate<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token class-name\">String<\/span> decryptedAccountNumber <span class=\"token operator\">&#061;<\/span> encryptionUtil<span class=\"token punctuation\">.<\/span><span class=\"token function\">decrypt<\/span><span class=\"token punctuation\">(<\/span>accountNumber<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token class-name\">LocalDateTime<\/span> start <span class=\"token operator\">&#061;<\/span> startDate<span class=\"token punctuation\">.<\/span><span class=\"token function\">atStartOfDay<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token class-name\">LocalDateTime<\/span> end <span class=\"token operator\">&#061;<\/span> endDate<span class=\"token punctuation\">.<\/span><span class=\"token function\">atTime<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">LocalTime<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">MAX<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">return<\/span> transactionRepository<br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">findByAccountNumberAndCreatedAtBetween<\/span><span class=\"token punctuation\">(<\/span>decryptedAccountNumber<span class=\"token punctuation\">,<\/span> start<span class=\"token punctuation\">,<\/span> end<span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">stream<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">map<\/span><span class=\"token punctuation\">(<\/span><span class=\"token keyword\">this<\/span><span class=\"token operator\">::<\/span><span class=\"token function\">convertToDTO<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">peek<\/span><span class=\"token punctuation\">(<\/span>dto <span class=\"token operator\">-&gt;<\/span> dto<span class=\"token punctuation\">.<\/span><span class=\"token function\">setAccountNumber<\/span><span class=\"token punctuation\">(<\/span>encryptionUtil<span class=\"token punctuation\">.<\/span><span class=\"token function\">encrypt<\/span><span class=\"token punctuation\">(<\/span>dto<span class=\"token punctuation\">.<\/span><span class=\"token function\">getAccountNumber<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">peek<\/span><span class=\"token punctuation\">(<\/span>dto <span class=\"token operator\">-&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                    <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>dto<span class=\"token punctuation\">.<\/span><span class=\"token function\">getCounterpartyAccountNumber<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">!&#061;<\/span> <span class=\"token keyword\">null<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                        dto<span class=\"token punctuation\">.<\/span><span class=\"token function\">setCounterpartyAccountNumber<\/span><span class=\"token punctuation\">(<\/span>encryptionUtil<span class=\"token punctuation\">.<\/span><span class=\"token function\">encrypt<\/span><span class=\"token punctuation\">(<\/span>dto<span class=\"token punctuation\">.<\/span><span class=\"token function\">getCounterpartyAccountNumber<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n                    <span class=\"token punctuation\">}<\/span><br \/>\n                <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">collect<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">Collectors<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">toList<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">void<\/span> <span class=\"token function\">validateAmount<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">BigDecimal<\/span> amount<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>amount<span class=\"token punctuation\">.<\/span><span class=\"token function\">compareTo<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">BigDecimal<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">ZERO<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&lt;&#061;<\/span> <span class=\"token number\">0<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">throw<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">AccountException<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">ErrorCode<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">INVALID_AMOUNT<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">void<\/span> <span class=\"token function\">checkAccountStatus<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">String<\/span> accountNumber<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token class-name\">AccountDTO<\/span> account <span class=\"token operator\">&#061;<\/span> accountClientService<span class=\"token punctuation\">.<\/span><span class=\"token function\">getAccount<\/span><span class=\"token punctuation\">(<\/span>accountNumber<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>account<span class=\"token punctuation\">.<\/span><span class=\"token function\">getStatus<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">!&#061;<\/span> <span class=\"token class-name\">AccountStatus<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">ACTIVE<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">throw<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">AccountException<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">ErrorCode<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">ACCOUNT_NOT_ACTIVE<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">void<\/span> <span class=\"token function\">checkWithdrawalLimit<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">String<\/span> accountNumber<span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">BigDecimal<\/span> amount<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token class-name\">AccountDTO<\/span> account <span class=\"token operator\">&#061;<\/span> accountClientService<span class=\"token punctuation\">.<\/span><span class=\"token function\">getAccount<\/span><span class=\"token punctuation\">(<\/span>accountNumber<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token class-name\">TransactionLimit<\/span> limit <span class=\"token operator\">&#061;<\/span> limitRepository<span class=\"token punctuation\">.<\/span><span class=\"token function\">findByTransactionTypeAndAccountType<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                <span class=\"token class-name\">TransactionType<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">WITHDRAWAL<\/span><span class=\"token punctuation\">,<\/span> account<span class=\"token punctuation\">.<\/span><span class=\"token function\">getAccountType<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">name<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">orElseThrow<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">-&gt;<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">AccountException<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">ErrorCode<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">TRANSACTION_LIMIT_NOT_FOUND<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u68c0\u67e5\u5355\u7b14\u9650\u989d<\/span><br \/>\n        <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>amount<span class=\"token punctuation\">.<\/span><span class=\"token function\">compareTo<\/span><span class=\"token punctuation\">(<\/span>limit<span class=\"token punctuation\">.<\/span><span class=\"token function\">getPerTransactionLimit<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&gt;<\/span> <span class=\"token number\">0<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">throw<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">AccountException<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">ErrorCode<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">EXCEED_PER_TRANSACTION_LIMIT<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u68c0\u67e5\u5f53\u65e5\u7d2f\u8ba1\u9650\u989d<\/span><br \/>\n        <span class=\"token class-name\">LocalDateTime<\/span> todayStart <span class=\"token operator\">&#061;<\/span> <span class=\"token class-name\">LocalDate<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">now<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">atStartOfDay<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token class-name\">LocalDateTime<\/span> todayEnd <span class=\"token operator\">&#061;<\/span> <span class=\"token class-name\">LocalDate<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">now<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">atTime<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">LocalTime<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">MAX<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token class-name\">BigDecimal<\/span> todayTotal <span class=\"token operator\">&#061;<\/span> transactionRepository<br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">findByAccountNumberAndCreatedAtBetween<\/span><span class=\"token punctuation\">(<\/span>accountNumber<span class=\"token punctuation\">,<\/span> todayStart<span class=\"token punctuation\">,<\/span> todayEnd<span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">stream<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">filter<\/span><span class=\"token punctuation\">(<\/span>t <span class=\"token operator\">-&gt;<\/span> t<span class=\"token punctuation\">.<\/span><span class=\"token function\">getTransactionType<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token class-name\">TransactionType<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">WITHDRAWAL<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">map<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">Transaction<\/span><span class=\"token operator\">::<\/span><span class=\"token function\">getAmount<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">reduce<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">BigDecimal<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">ZERO<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">BigDecimal<\/span><span class=\"token operator\">::<\/span><span class=\"token function\">add<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">abs<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>todayTotal<span class=\"token punctuation\">.<\/span><span class=\"token function\">add<\/span><span class=\"token punctuation\">(<\/span>amount<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">compareTo<\/span><span class=\"token punctuation\">(<\/span>limit<span class=\"token punctuation\">.<\/span><span class=\"token function\">getDailyLimit<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&gt;<\/span> <span class=\"token number\">0<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">throw<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">AccountException<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">ErrorCode<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">EXCEED_DAILY_LIMIT<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u68c0\u67e5\u5f53\u65e5\u4ea4\u6613\u6b21\u6570<\/span><br \/>\n        <span class=\"token keyword\">long<\/span> todayCount <span class=\"token operator\">&#061;<\/span> transactionRepository<br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">findByAccountNumberAndCreatedAtBetween<\/span><span class=\"token punctuation\">(<\/span>accountNumber<span class=\"token punctuation\">,<\/span> todayStart<span class=\"token punctuation\">,<\/span> todayEnd<span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">stream<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">filter<\/span><span class=\"token punctuation\">(<\/span>t <span class=\"token operator\">-&gt;<\/span> t<span class=\"token punctuation\">.<\/span><span class=\"token function\">getTransactionType<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token class-name\">TransactionType<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">WITHDRAWAL<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">count<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>todayCount <span class=\"token operator\">&gt;&#061;<\/span> limit<span class=\"token punctuation\">.<\/span><span class=\"token function\">getDailyCountLimit<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">throw<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">AccountException<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">ErrorCode<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">EXCEED_DAILY_COUNT_LIMIT<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">void<\/span> <span class=\"token function\">checkTransferLimit<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">String<\/span> accountNumber<span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">BigDecimal<\/span> amount<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token class-name\">AccountDTO<\/span> account <span class=\"token operator\">&#061;<\/span> accountClientService<span class=\"token punctuation\">.<\/span><span class=\"token function\">getAccount<\/span><span class=\"token punctuation\">(<\/span>accountNumber<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token class-name\">TransactionLimit<\/span> limit <span class=\"token operator\">&#061;<\/span> limitRepository<span class=\"token punctuation\">.<\/span><span class=\"token function\">findByTransactionTypeAndAccountType<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                <span class=\"token class-name\">TransactionType<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">TRANSFER<\/span><span class=\"token punctuation\">,<\/span> account<span class=\"token punctuation\">.<\/span><span class=\"token function\">getAccountType<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">name<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">orElseThrow<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">-&gt;<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">AccountException<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">ErrorCode<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">TRANSACTION_LIMIT_NOT_FOUND<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u68c0\u67e5\u5355\u7b14\u9650\u989d<\/span><br \/>\n        <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>amount<span class=\"token punctuation\">.<\/span><span class=\"token function\">compareTo<\/span><span class=\"token punctuation\">(<\/span>limit<span class=\"token punctuation\">.<\/span><span class=\"token function\">getPerTransactionLimit<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&gt;<\/span> <span class=\"token number\">0<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">throw<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">AccountException<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">ErrorCode<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">EXCEED_PER_TRANSACTION_LIMIT<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u68c0\u67e5\u5f53\u65e5\u7d2f\u8ba1\u9650\u989d<\/span><br \/>\n        <span class=\"token class-name\">LocalDateTime<\/span> todayStart <span class=\"token operator\">&#061;<\/span> <span class=\"token class-name\">LocalDate<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">now<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">atStartOfDay<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token class-name\">LocalDateTime<\/span> todayEnd <span class=\"token operator\">&#061;<\/span> <span class=\"token class-name\">LocalDate<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">now<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">atTime<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">LocalTime<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">MAX<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token class-name\">BigDecimal<\/span> todayTotal <span class=\"token operator\">&#061;<\/span> transactionRepository<br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">findByAccountNumberAndCreatedAtBetween<\/span><span class=\"token punctuation\">(<\/span>accountNumber<span class=\"token punctuation\">,<\/span> todayStart<span class=\"token punctuation\">,<\/span> todayEnd<span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">stream<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">filter<\/span><span class=\"token punctuation\">(<\/span>t <span class=\"token operator\">-&gt;<\/span> t<span class=\"token punctuation\">.<\/span><span class=\"token function\">getTransactionType<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token class-name\">TransactionType<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">TRANSFER<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">map<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">Transaction<\/span><span class=\"token operator\">::<\/span><span class=\"token function\">getAmount<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">reduce<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">BigDecimal<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">ZERO<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">BigDecimal<\/span><span class=\"token operator\">::<\/span><span class=\"token function\">add<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">abs<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>todayTotal<span class=\"token punctuation\">.<\/span><span class=\"token function\">add<\/span><span class=\"token punctuation\">(<\/span>amount<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">compareTo<\/span><span class=\"token punctuation\">(<\/span>limit<span class=\"token punctuation\">.<\/span><span class=\"token function\">getDailyLimit<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&gt;<\/span> <span class=\"token number\">0<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">throw<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">AccountException<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">ErrorCode<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">EXCEED_DAILY_LIMIT<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">TransactionDTO<\/span> <span class=\"token function\">convertToDTO<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">Transaction<\/span> transaction<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token class-name\">TransactionDTO<\/span> dto <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">TransactionDTO<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        dto<span class=\"token punctuation\">.<\/span><span class=\"token function\">setTransactionId<\/span><span class=\"token punctuation\">(<\/span>transaction<span class=\"token punctuation\">.<\/span><span class=\"token function\">getTransactionId<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        dto<span class=\"token punctuation\">.<\/span><span class=\"token function\">setAccountNumber<\/span><span class=\"token punctuation\">(<\/span>transaction<span class=\"token punctuation\">.<\/span><span class=\"token function\">getAccountNumber<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        dto<span class=\"token punctuation\">.<\/span><span class=\"token function\">setCounterpartyAccountNumber<\/span><span class=\"token punctuation\">(<\/span>transaction<span class=\"token punctuation\">.<\/span><span class=\"token function\">getCounterpartyAccountNumber<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        dto<span class=\"token punctuation\">.<\/span><span class=\"token function\">setTransactionType<\/span><span class=\"token punctuation\">(<\/span>transaction<span class=\"token punctuation\">.<\/span><span class=\"token function\">getTransactionType<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        dto<span class=\"token punctuation\">.<\/span><span class=\"token function\">setStatus<\/span><span class=\"token punctuation\">(<\/span>transaction<span class=\"token punctuation\">.<\/span><span class=\"token function\">getStatus<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        dto<span class=\"token punctuation\">.<\/span><span class=\"token function\">setAmount<\/span><span class=\"token punctuation\">(<\/span>transaction<span class=\"token punctuation\">.<\/span><span class=\"token function\">getAmount<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        dto<span class=\"token punctuation\">.<\/span><span class=\"token function\">setFee<\/span><span class=\"token punctuation\">(<\/span>transaction<span class=\"token punctuation\">.<\/span><span class=\"token function\">getFee<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        dto<span class=\"token punctuation\">.<\/span><span class=\"token function\">setCurrency<\/span><span class=\"token punctuation\">(<\/span>transaction<span class=\"token punctuation\">.<\/span><span class=\"token function\">getCurrency<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        dto<span class=\"token punctuation\">.<\/span><span class=\"token function\">setDescription<\/span><span class=\"token punctuation\">(<\/span>transaction<span class=\"token punctuation\">.<\/span><span class=\"token function\">getDescription<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        dto<span class=\"token punctuation\">.<\/span><span class=\"token function\">setReference<\/span><span class=\"token punctuation\">(<\/span>transaction<span class=\"token punctuation\">.<\/span><span class=\"token function\">getReference<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        dto<span class=\"token punctuation\">.<\/span><span class=\"token function\">setCreatedAt<\/span><span class=\"token punctuation\">(<\/span>transaction<span class=\"token punctuation\">.<\/span><span class=\"token function\">getCreatedAt<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        dto<span class=\"token punctuation\">.<\/span><span class=\"token function\">setUpdatedAt<\/span><span class=\"token punctuation\">(<\/span>transaction<span class=\"token punctuation\">.<\/span><span class=\"token function\">getUpdatedAt<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> dto<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token annotation punctuation\">&#064;Service<\/span><br \/>\n<span class=\"token annotation punctuation\">&#064;RequiredArgsConstructor<\/span><br \/>\n<span class=\"token keyword\">public<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token class-name\">AccountClientService<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">final<\/span> <span class=\"token class-name\">RestTemplate<\/span> restTemplate<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">final<\/span> <span class=\"token class-name\">EncryptionUtil<\/span> encryptionUtil<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Value<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;${service.account.url}&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> accountServiceUrl<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">AccountDTO<\/span> <span class=\"token function\">getAccount<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">String<\/span> accountNumber<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">try<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token class-name\">String<\/span> encryptedAccountNumber <span class=\"token operator\">&#061;<\/span> encryptionUtil<span class=\"token punctuation\">.<\/span><span class=\"token function\">encrypt<\/span><span class=\"token punctuation\">(<\/span>accountNumber<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>            <span class=\"token class-name\">HttpHeaders<\/span> headers <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">HttpHeaders<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            headers<span class=\"token punctuation\">.<\/span><span class=\"token function\">set<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;X-Internal-Service&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;transaction-service&#034;<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>            <span class=\"token class-name\">ResponseEntity<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">AccountDTO<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> response <span class=\"token operator\">&#061;<\/span> restTemplate<span class=\"token punctuation\">.<\/span><span class=\"token function\">exchange<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                    accountServiceUrl <span class=\"token operator\">&#043;<\/span> <span class=\"token string\">&#034;\/api\/accounts\/&#034;<\/span> <span class=\"token operator\">&#043;<\/span> encryptedAccountNumber<span class=\"token punctuation\">,<\/span><br \/>\n                    <span class=\"token class-name\">HttpMethod<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">GET<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                    <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">HttpEntity<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><span class=\"token punctuation\">(<\/span>headers<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                    <span class=\"token class-name\">AccountDTO<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">class<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>            <span class=\"token class-name\">AccountDTO<\/span> account <span class=\"token operator\">&#061;<\/span> response<span class=\"token punctuation\">.<\/span><span class=\"token function\">getBody<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>account <span class=\"token operator\">!&#061;<\/span> <span class=\"token keyword\">null<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                account<span class=\"token punctuation\">.<\/span><span class=\"token function\">setAccountNumber<\/span><span class=\"token punctuation\">(<\/span>accountNumber<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span> <span class=\"token comment\">\/\/ \u8fd4\u56de\u89e3\u5bc6\u540e\u7684\u8d26\u53f7<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><br \/>\n            <span class=\"token keyword\">return<\/span> account<span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">catch<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token class-name\">HttpClientErrorException<span class=\"token punctuation\">.<\/span>NotFound<\/span> e<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">throw<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">AccountException<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">ErrorCode<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">ACCOUNT_NOT_FOUND<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">catch<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token class-name\">Exception<\/span> e<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">throw<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">AccountException<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">ErrorCode<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">ACCOUNT_SERVICE_UNAVAILABLE<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">BigDecimal<\/span> <span class=\"token function\">deposit<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">String<\/span> accountNumber<span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">BigDecimal<\/span> amount<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">try<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token class-name\">String<\/span> encryptedAccountNumber <span class=\"token operator\">&#061;<\/span> encryptionUtil<span class=\"token punctuation\">.<\/span><span class=\"token function\">encrypt<\/span><span class=\"token punctuation\">(<\/span>accountNumber<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>            <span class=\"token class-name\">HttpHeaders<\/span> headers <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">HttpHeaders<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            headers<span class=\"token punctuation\">.<\/span><span class=\"token function\">set<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;X-Internal-Service&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;transaction-service&#034;<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>            <span class=\"token class-name\">ResponseEntity<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">AccountOperationResponse<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> response <span class=\"token operator\">&#061;<\/span> restTemplate<span class=\"token punctuation\">.<\/span><span class=\"token function\">exchange<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                    accountServiceUrl <span class=\"token operator\">&#043;<\/span> <span class=\"token string\">&#034;\/api\/accounts\/&#034;<\/span> <span class=\"token operator\">&#043;<\/span> encryptedAccountNumber <span class=\"token operator\">&#043;<\/span> <span class=\"token string\">&#034;\/deposit?amount&#061;&#034;<\/span> <span class=\"token operator\">&#043;<\/span> amount<span class=\"token punctuation\">,<\/span><br \/>\n                    <span class=\"token class-name\">HttpMethod<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">POST<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                    <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">HttpEntity<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><span class=\"token punctuation\">(<\/span>headers<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                    <span class=\"token class-name\">AccountOperationResponse<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">class<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>            <span class=\"token class-name\">AccountOperationResponse<\/span> result <span class=\"token operator\">&#061;<\/span> response<span class=\"token punctuation\">.<\/span><span class=\"token function\">getBody<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>result <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token keyword\">null<\/span> <span class=\"token operator\">||<\/span> <span class=\"token operator\">!<\/span>result<span class=\"token punctuation\">.<\/span><span class=\"token function\">isSuccess<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                <span class=\"token keyword\">throw<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">AccountException<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">ErrorCode<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">DEPOSIT_FAILED<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><br \/>\n            <span class=\"token keyword\">return<\/span> result<span class=\"token punctuation\">.<\/span><span class=\"token function\">getNewBalance<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">catch<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token class-name\">Exception<\/span> e<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">throw<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">AccountException<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">ErrorCode<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">ACCOUNT_SERVICE_UNAVAILABLE<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">BigDecimal<\/span> <span class=\"token function\">withdraw<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">String<\/span> accountNumber<span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">BigDecimal<\/span> amount<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">try<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token class-name\">String<\/span> encryptedAccountNumber <span class=\"token operator\">&#061;<\/span> encryptionUtil<span class=\"token punctuation\">.<\/span><span class=\"token function\">encrypt<\/span><span class=\"token punctuation\">(<\/span>accountNumber<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>            <span class=\"token class-name\">HttpHeaders<\/span> headers <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">HttpHeaders<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            headers<span class=\"token punctuation\">.<\/span><span class=\"token function\">set<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;X-Internal-Service&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;transaction-service&#034;<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>            <span class=\"token class-name\">ResponseEntity<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">AccountOperationResponse<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> response <span class=\"token operator\">&#061;<\/span> restTemplate<span class=\"token punctuation\">.<\/span><span class=\"token function\">exchange<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                    accountServiceUrl <span class=\"token operator\">&#043;<\/span> <span class=\"token string\">&#034;\/api\/accounts\/&#034;<\/span> <span class=\"token operator\">&#043;<\/span> encryptedAccountNumber <span class=\"token operator\">&#043;<\/span> <span class=\"token string\">&#034;\/withdraw?amount&#061;&#034;<\/span> <span class=\"token operator\">&#043;<\/span> amount<span class=\"token punctuation\">,<\/span><br \/>\n                    <span class=\"token class-name\">HttpMethod<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">POST<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                    <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">HttpEntity<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><span class=\"token punctuation\">(<\/span>headers<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                    <span class=\"token class-name\">AccountOperationResponse<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">class<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>            <span class=\"token class-name\">AccountOperationResponse<\/span> result <span class=\"token operator\">&#061;<\/span> response<span class=\"token punctuation\">.<\/span><span class=\"token function\">getBody<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>result <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token keyword\">null<\/span> <span class=\"token operator\">||<\/span> <span class=\"token operator\">!<\/span>result<span class=\"token punctuation\">.<\/span><span class=\"token function\">isSuccess<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                <span class=\"token keyword\">throw<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">AccountException<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">ErrorCode<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">WITHDRAWAL_FAILED<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><br \/>\n            <span class=\"token keyword\">return<\/span> result<span class=\"token punctuation\">.<\/span><span class=\"token function\">getNewBalance<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">catch<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token class-name\">Exception<\/span> e<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">throw<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">AccountException<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">ErrorCode<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">ACCOUNT_SERVICE_UNAVAILABLE<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p>Repository\u5c42<\/p>\n<p><span class=\"token keyword\">public<\/span> <span class=\"token keyword\">interface<\/span> <span class=\"token class-name\">TransactionRepository<\/span> <span class=\"token keyword\">extends<\/span> <span class=\"token class-name\">JpaRepository<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">Transaction<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">Long<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token class-name\">Optional<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">Transaction<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> <span class=\"token function\">findByTransactionId<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">String<\/span> transactionId<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token class-name\">List<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">Transaction<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> <span class=\"token function\">findByAccountNumberAndCreatedAtBetween<\/span><span class=\"token punctuation\">(<\/span><br \/>\n            <span class=\"token class-name\">String<\/span> accountNumber<span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">LocalDateTime<\/span> startDate<span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">LocalDateTime<\/span> endDate<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Lock<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">LockModeType<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">PESSIMISTIC_WRITE<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token annotation punctuation\">&#064;Query<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;SELECT t FROM Transaction t WHERE t.transactionId &#061; :transactionId&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token class-name\">Optional<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">Transaction<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> <span class=\"token function\">findByTransactionIdForUpdate<\/span><span class=\"token punctuation\">(<\/span><span class=\"token annotation punctuation\">&#064;Param<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;transactionId&#034;<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token class-name\">String<\/span> transactionId<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token keyword\">public<\/span> <span class=\"token keyword\">interface<\/span> <span class=\"token class-name\">TransactionLimitRepository<\/span> <span class=\"token keyword\">extends<\/span> <span class=\"token class-name\">JpaRepository<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">TransactionLimit<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">Long<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token class-name\">Optional<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">TransactionLimit<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> <span class=\"token function\">findByTransactionTypeAndAccountType<\/span><span class=\"token punctuation\">(<\/span><br \/>\n            <span class=\"token class-name\">TransactionType<\/span> transactionType<span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">String<\/span> accountType<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p>3. \u652f\u4ed8\u7ed3\u7b97<\/p>\n<p>\u652f\u4ed8\u8ba2\u5355\u5904\u7406<\/p>\n<p>\u6e05\u7b97\u5bf9\u8d26<\/p>\n<p>\u624b\u7eed\u8d39\u8ba1\u7b97<\/p>\n<p>\u7b2c\u4e09\u65b9\u652f\u4ed8\u5bf9\u63a5<\/p>\n<p><span class=\"token comment\"># \u5728\u539f\u6709\u914d\u7f6e\u57fa\u7840\u4e0a\u6dfb\u52a0<\/span><br \/>\n<span class=\"token key atrule\">payment<\/span><span class=\"token punctuation\">:<\/span><br \/>\n  <span class=\"token key atrule\">settlement<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    <span class=\"token key atrule\">auto-enabled<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token boolean important\">true<\/span><br \/>\n    <span class=\"token key atrule\">time<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token string\">&#034;02:00&#034;<\/span> <span class=\"token comment\"># \u81ea\u52a8\u7ed3\u7b97\u65f6\u95f4<\/span><br \/>\n  <span class=\"token key atrule\">third-party<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    <span class=\"token key atrule\">timeout<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token number\">5000<\/span> <span class=\"token comment\"># \u7b2c\u4e09\u65b9\u652f\u4ed8\u8d85\u65f6\u65f6\u95f4(ms)<\/span><br \/>\n    <span class=\"token key atrule\">retry-times<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token number\">3<\/span> <span class=\"token comment\"># \u91cd\u8bd5\u6b21\u6570<\/span><\/p>\n<p><span class=\"token annotation punctuation\">&#064;Entity<\/span><br \/>\n<span class=\"token annotation punctuation\">&#064;Table<\/span><span class=\"token punctuation\">(<\/span>name <span class=\"token operator\">&#061;<\/span> <span class=\"token string\">&#034;payment_order&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n<span class=\"token annotation punctuation\">&#064;Data<\/span><br \/>\n<span class=\"token keyword\">public<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token class-name\">PaymentOrder<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token annotation punctuation\">&#064;Id<\/span><br \/>\n    <span class=\"token annotation punctuation\">&#064;GeneratedValue<\/span><span class=\"token punctuation\">(<\/span>strategy <span class=\"token operator\">&#061;<\/span> <span class=\"token class-name\">GenerationType<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">IDENTITY<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">Long<\/span> id<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>nullable <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">,<\/span> unique <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">true<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> orderNo<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>nullable <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> accountNumber<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>nullable <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> merchantCode<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>nullable <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> merchantOrderNo<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Enumerated<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">EnumType<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">STRING<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>nullable <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">PaymentOrderType<\/span> orderType<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Enumerated<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">EnumType<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">STRING<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>nullable <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">PaymentOrderStatus<\/span> status<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>nullable <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">,<\/span> precision <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">19<\/span><span class=\"token punctuation\">,<\/span> scale <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">4<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">BigDecimal<\/span> amount<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>precision <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">19<\/span><span class=\"token punctuation\">,<\/span> scale <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">4<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">BigDecimal<\/span> fee<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>precision <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">19<\/span><span class=\"token punctuation\">,<\/span> scale <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">4<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">BigDecimal<\/span> settlementAmount<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>nullable <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> currency <span class=\"token operator\">&#061;<\/span> <span class=\"token string\">&#034;CNY&#034;<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> description<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> callbackUrl<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> notifyUrl<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> thirdPartyTransactionNo<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">LocalDateTime<\/span> paymentTime<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">LocalDateTime<\/span> settlementTime<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;CreationTimestamp<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">LocalDateTime<\/span> createdAt<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;UpdateTimestamp<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">LocalDateTime<\/span> updatedAt<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Version<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">Long<\/span> version<span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token annotation punctuation\">&#064;Entity<\/span><br \/>\n<span class=\"token annotation punctuation\">&#064;Table<\/span><span class=\"token punctuation\">(<\/span>name <span class=\"token operator\">&#061;<\/span> <span class=\"token string\">&#034;settlement_record&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n<span class=\"token annotation punctuation\">&#064;Data<\/span><br \/>\n<span class=\"token keyword\">public<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token class-name\">SettlementRecord<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token annotation punctuation\">&#064;Id<\/span><br \/>\n    <span class=\"token annotation punctuation\">&#064;GeneratedValue<\/span><span class=\"token punctuation\">(<\/span>strategy <span class=\"token operator\">&#061;<\/span> <span class=\"token class-name\">GenerationType<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">IDENTITY<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">Long<\/span> id<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>nullable <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">,<\/span> unique <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">true<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> settlementNo<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>nullable <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> merchantCode<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>nullable <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">LocalDate<\/span> settlementDate<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>nullable <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">,<\/span> precision <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">19<\/span><span class=\"token punctuation\">,<\/span> scale <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">4<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">BigDecimal<\/span> totalAmount<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>nullable <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">,<\/span> precision <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">19<\/span><span class=\"token punctuation\">,<\/span> scale <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">4<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">BigDecimal<\/span> totalFee<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>nullable <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">,<\/span> precision <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">19<\/span><span class=\"token punctuation\">,<\/span> scale <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">4<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">BigDecimal<\/span> netAmount<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>nullable <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">Integer<\/span> totalCount<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Enumerated<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">EnumType<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">STRING<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>nullable <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">SettlementStatus<\/span> status<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> bankTransactionNo<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">LocalDateTime<\/span> completedTime<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;CreationTimestamp<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">LocalDateTime<\/span> createdAt<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;UpdateTimestamp<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">LocalDateTime<\/span> updatedAt<span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token annotation punctuation\">&#064;Entity<\/span><br \/>\n<span class=\"token annotation punctuation\">&#064;Table<\/span><span class=\"token punctuation\">(<\/span>name <span class=\"token operator\">&#061;<\/span> <span class=\"token string\">&#034;fee_config&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n<span class=\"token annotation punctuation\">&#064;Data<\/span><br \/>\n<span class=\"token keyword\">public<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token class-name\">FeeConfig<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token annotation punctuation\">&#064;Id<\/span><br \/>\n    <span class=\"token annotation punctuation\">&#064;GeneratedValue<\/span><span class=\"token punctuation\">(<\/span>strategy <span class=\"token operator\">&#061;<\/span> <span class=\"token class-name\">GenerationType<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">IDENTITY<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">Long<\/span> id<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>nullable <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> merchantCode<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>nullable <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> paymentType<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Enumerated<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">EnumType<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">STRING<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>nullable <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">FeeCalculateMethod<\/span> calculateMethod<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>precision <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">19<\/span><span class=\"token punctuation\">,<\/span> scale <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">4<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">BigDecimal<\/span> fixedFee<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>precision <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">5<\/span><span class=\"token punctuation\">,<\/span> scale <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">4<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">BigDecimal<\/span> rate<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>precision <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">19<\/span><span class=\"token punctuation\">,<\/span> scale <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">4<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">BigDecimal<\/span> minFee<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>precision <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">19<\/span><span class=\"token punctuation\">,<\/span> scale <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">4<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">BigDecimal<\/span> maxFee<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>nullable <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">Boolean<\/span> active <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">true<\/span><span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token keyword\">public<\/span> <span class=\"token keyword\">enum<\/span> <span class=\"token class-name\">PaymentOrderType<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token constant\">WECHAT_PAY<\/span><span class=\"token punctuation\">,<\/span>     <span class=\"token comment\">\/\/ \u5fae\u4fe1\u652f\u4ed8<\/span><br \/>\n    <span class=\"token constant\">ALI_PAY<\/span><span class=\"token punctuation\">,<\/span>        <span class=\"token comment\">\/\/ \u652f\u4ed8\u5b9d<\/span><br \/>\n    <span class=\"token constant\">UNION_PAY<\/span><span class=\"token punctuation\">,<\/span>      <span class=\"token comment\">\/\/ \u94f6\u8054<\/span><br \/>\n    <span class=\"token constant\">QUICK_PAY<\/span><span class=\"token punctuation\">,<\/span>      <span class=\"token comment\">\/\/ \u5feb\u6377\u652f\u4ed8<\/span><br \/>\n    <span class=\"token constant\">BANK_TRANSFER<\/span>   <span class=\"token comment\">\/\/ \u94f6\u884c\u8f6c\u8d26<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token keyword\">public<\/span> <span class=\"token keyword\">enum<\/span> <span class=\"token class-name\">PaymentOrderStatus<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token constant\">CREATED<\/span><span class=\"token punctuation\">,<\/span>        <span class=\"token comment\">\/\/ \u5df2\u521b\u5efa<\/span><br \/>\n    <span class=\"token constant\">PROCESSING<\/span><span class=\"token punctuation\">,<\/span>     <span class=\"token comment\">\/\/ \u5904\u7406\u4e2d<\/span><br \/>\n    <span class=\"token constant\">SUCCESS<\/span><span class=\"token punctuation\">,<\/span>        <span class=\"token comment\">\/\/ \u652f\u4ed8\u6210\u529f<\/span><br \/>\n    <span class=\"token constant\">FAILED<\/span><span class=\"token punctuation\">,<\/span>         <span class=\"token comment\">\/\/ \u652f\u4ed8\u5931\u8d25<\/span><br \/>\n    <span class=\"token constant\">REFUNDED<\/span><span class=\"token punctuation\">,<\/span>       <span class=\"token comment\">\/\/ \u5df2\u9000\u6b3e<\/span><br \/>\n    <span class=\"token constant\">CLOSED<\/span>          <span class=\"token comment\">\/\/ \u5df2\u5173\u95ed<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token keyword\">public<\/span> <span class=\"token keyword\">enum<\/span> <span class=\"token class-name\">SettlementStatus<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token constant\">PENDING<\/span><span class=\"token punctuation\">,<\/span>        <span class=\"token comment\">\/\/ \u5f85\u7ed3\u7b97<\/span><br \/>\n    <span class=\"token constant\">PROCESSING<\/span><span class=\"token punctuation\">,<\/span>     <span class=\"token comment\">\/\/ \u7ed3\u7b97\u4e2d<\/span><br \/>\n    <span class=\"token constant\">COMPLETED<\/span><span class=\"token punctuation\">,<\/span>      <span class=\"token comment\">\/\/ \u7ed3\u7b97\u5b8c\u6210<\/span><br \/>\n    <span class=\"token constant\">FAILED<\/span>          <span class=\"token comment\">\/\/ \u7ed3\u7b97\u5931\u8d25<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token keyword\">public<\/span> <span class=\"token keyword\">enum<\/span> <span class=\"token class-name\">FeeCalculateMethod<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token constant\">FIXED<\/span><span class=\"token punctuation\">,<\/span>          <span class=\"token comment\">\/\/ \u56fa\u5b9a\u8d39\u7528<\/span><br \/>\n    <span class=\"token constant\">PERCENTAGE<\/span><span class=\"token punctuation\">,<\/span>     <span class=\"token comment\">\/\/ \u767e\u5206\u6bd4<\/span><br \/>\n    <span class=\"token constant\">TIERED<\/span>          <span class=\"token comment\">\/\/ \u9636\u68af\u8d39\u7387<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token annotation punctuation\">&#064;Data<\/span><br \/>\n<span class=\"token keyword\">public<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token class-name\">PaymentRequestDTO<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token annotation punctuation\">&#064;NotBlank<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> accountNumber<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;NotBlank<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> merchantCode<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;NotBlank<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> merchantOrderNo<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;NotNull<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">PaymentOrderType<\/span> orderType<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;NotNull<\/span><br \/>\n    <span class=\"token annotation punctuation\">&#064;Positive<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">BigDecimal<\/span> amount<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;NotBlank<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> currency<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> description<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> callbackUrl<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> notifyUrl<span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token annotation punctuation\">&#064;Data<\/span><br \/>\n<span class=\"token keyword\">public<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token class-name\">PaymentResponseDTO<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> orderNo<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> merchantOrderNo<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">PaymentOrderStatus<\/span> status<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">BigDecimal<\/span> amount<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">BigDecimal<\/span> fee<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">BigDecimal<\/span> settlementAmount<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> currency<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> paymentUrl<span class=\"token punctuation\">;<\/span> <span class=\"token comment\">\/\/ \u7528\u4e8e\u524d\u7aef\u8df3\u8f6c\u652f\u4ed8<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">LocalDateTime<\/span> createdAt<span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token annotation punctuation\">&#064;Data<\/span><br \/>\n<span class=\"token keyword\">public<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token class-name\">SettlementRequestDTO<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token annotation punctuation\">&#064;NotBlank<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> merchantCode<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">LocalDate<\/span> settlementDate<span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token annotation punctuation\">&#064;Data<\/span><br \/>\n<span class=\"token keyword\">public<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token class-name\">SettlementResponseDTO<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> settlementNo<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> merchantCode<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">LocalDate<\/span> settlementDate<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">BigDecimal<\/span> totalAmount<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">BigDecimal<\/span> totalFee<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">BigDecimal<\/span> netAmount<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">Integer<\/span> totalCount<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">SettlementStatus<\/span> status<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">LocalDateTime<\/span> completedTime<span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token annotation punctuation\">&#064;Data<\/span><br \/>\n<span class=\"token keyword\">public<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token class-name\">ThirdPartyPaymentRequest<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> orderNo<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">BigDecimal<\/span> amount<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> currency<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> accountNumber<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> merchantCode<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> paymentType<span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token annotation punctuation\">&#064;Data<\/span><br \/>\n<span class=\"token keyword\">public<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token class-name\">ThirdPartyPaymentResponse<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">boolean<\/span> success<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> transactionNo<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> paymentUrl<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> errorCode<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> errorMessage<span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p>\u5de5\u5177\u7c7b<\/p>\n<p><span class=\"token annotation punctuation\">&#064;Component<\/span><br \/>\n<span class=\"token keyword\">public<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token class-name\">OrderNoGenerator<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">static<\/span> <span class=\"token keyword\">final<\/span> <span class=\"token class-name\">String<\/span> <span class=\"token constant\">BANK_CODE<\/span> <span class=\"token operator\">&#061;<\/span> <span class=\"token string\">&#034;888&#034;<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">final<\/span> <span class=\"token class-name\">AtomicLong<\/span> sequence <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">AtomicLong<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">1<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">String<\/span> <span class=\"token function\">generate<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">long<\/span> timestamp <span class=\"token operator\">&#061;<\/span> <span class=\"token class-name\">Instant<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">now<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">toEpochMilli<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token keyword\">long<\/span> seq <span class=\"token operator\">&#061;<\/span> sequence<span class=\"token punctuation\">.<\/span><span class=\"token function\">getAndIncrement<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> <span class=\"token class-name\">String<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">format<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;%s-PAY-%d-%06d&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token constant\">BANK_CODE<\/span><span class=\"token punctuation\">,<\/span> timestamp<span class=\"token punctuation\">,<\/span> seq<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token annotation punctuation\">&#064;Component<\/span><br \/>\n<span class=\"token keyword\">public<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token class-name\">SettlementNoGenerator<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">static<\/span> <span class=\"token keyword\">final<\/span> <span class=\"token class-name\">String<\/span> <span class=\"token constant\">BANK_CODE<\/span> <span class=\"token operator\">&#061;<\/span> <span class=\"token string\">&#034;888&#034;<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">final<\/span> <span class=\"token class-name\">AtomicLong<\/span> sequence <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">AtomicLong<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">1<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">String<\/span> <span class=\"token function\">generate<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token class-name\">String<\/span> dateStr <span class=\"token operator\">&#061;<\/span> <span class=\"token class-name\">LocalDate<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">now<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">format<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">DateTimeFormatter<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">BASIC_ISO_DATE<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token keyword\">long<\/span> seq <span class=\"token operator\">&#061;<\/span> sequence<span class=\"token punctuation\">.<\/span><span class=\"token function\">getAndIncrement<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> <span class=\"token class-name\">String<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">format<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;%s-STL-%s-%06d&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token constant\">BANK_CODE<\/span><span class=\"token punctuation\">,<\/span> dateStr<span class=\"token punctuation\">,<\/span> seq<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p>Controller\u5c42<\/p>\n<p><span class=\"token annotation punctuation\">&#064;RestController<\/span><br \/>\n<span class=\"token annotation punctuation\">&#064;RequestMapping<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;\/api\/payments&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n<span class=\"token annotation punctuation\">&#064;RequiredArgsConstructor<\/span><br \/>\n<span class=\"token keyword\">public<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token class-name\">PaymentController<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">final<\/span> <span class=\"token class-name\">PaymentService<\/span> paymentService<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">final<\/span> <span class=\"token class-name\">SettlementService<\/span> settlementService<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;PostMapping<\/span><br \/>\n    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">PaymentResponseDTO<\/span> <span class=\"token function\">createPayment<\/span><span class=\"token punctuation\">(<\/span><span class=\"token annotation punctuation\">&#064;Valid<\/span> <span class=\"token annotation punctuation\">&#064;RequestBody<\/span> <span class=\"token class-name\">PaymentRequestDTO<\/span> request<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> paymentService<span class=\"token punctuation\">.<\/span><span class=\"token function\">createPayment<\/span><span class=\"token punctuation\">(<\/span>request<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;GetMapping<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;\/{orderNo}&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">PaymentResponseDTO<\/span> <span class=\"token function\">queryPayment<\/span><span class=\"token punctuation\">(<\/span><span class=\"token annotation punctuation\">&#064;PathVariable<\/span> <span class=\"token class-name\">String<\/span> orderNo<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> paymentService<span class=\"token punctuation\">.<\/span><span class=\"token function\">queryPayment<\/span><span class=\"token punctuation\">(<\/span>orderNo<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;GetMapping<\/span><br \/>\n    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">PaymentResponseDTO<\/span> <span class=\"token function\">queryPaymentByMerchant<\/span><span class=\"token punctuation\">(<\/span><br \/>\n            <span class=\"token annotation punctuation\">&#064;RequestParam<\/span> <span class=\"token class-name\">String<\/span> merchantCode<span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token annotation punctuation\">&#064;RequestParam<\/span> <span class=\"token class-name\">String<\/span> merchantOrderNo<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> paymentService<span class=\"token punctuation\">.<\/span><span class=\"token function\">queryPaymentByMerchant<\/span><span class=\"token punctuation\">(<\/span>merchantCode<span class=\"token punctuation\">,<\/span> merchantOrderNo<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;PostMapping<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;\/settlements&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">SettlementResponseDTO<\/span> <span class=\"token function\">createSettlement<\/span><span class=\"token punctuation\">(<\/span><span class=\"token annotation punctuation\">&#064;Valid<\/span> <span class=\"token annotation punctuation\">&#064;RequestBody<\/span> <span class=\"token class-name\">SettlementRequestDTO<\/span> request<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> settlementService<span class=\"token punctuation\">.<\/span><span class=\"token function\">createSettlement<\/span><span class=\"token punctuation\">(<\/span>request<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;GetMapping<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;\/settlements\/{settlementNo}&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">SettlementResponseDTO<\/span> <span class=\"token function\">querySettlement<\/span><span class=\"token punctuation\">(<\/span><span class=\"token annotation punctuation\">&#064;PathVariable<\/span> <span class=\"token class-name\">String<\/span> settlementNo<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> settlementService<span class=\"token punctuation\">.<\/span><span class=\"token function\">querySettlement<\/span><span class=\"token punctuation\">(<\/span>settlementNo<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p>Service\u5c42<\/p>\n<p><span class=\"token annotation punctuation\">&#064;Service<\/span><br \/>\n<span class=\"token annotation punctuation\">&#064;RequiredArgsConstructor<\/span><br \/>\n<span class=\"token annotation punctuation\">&#064;Slf4j<\/span><br \/>\n<span class=\"token keyword\">public<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token class-name\">PaymentService<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">final<\/span> <span class=\"token class-name\">PaymentOrderRepository<\/span> paymentOrderRepository<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">final<\/span> <span class=\"token class-name\">FeeConfigRepository<\/span> feeConfigRepository<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">final<\/span> <span class=\"token class-name\">TransactionService<\/span> transactionService<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">final<\/span> <span class=\"token class-name\">ThirdPartyPaymentGateway<\/span> paymentGateway<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">final<\/span> <span class=\"token class-name\">OrderNoGenerator<\/span> orderNoGenerator<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">final<\/span> <span class=\"token class-name\">EncryptionUtil<\/span> encryptionUtil<span class=\"token punctuation\">;<\/span><\/p>\n<p><span class=\"token annotation punctuation\">&#064;Transactional<\/span><br \/>\n    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">PaymentResponseDTO<\/span> <span class=\"token function\">createPayment<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">PaymentRequestDTO<\/span> request<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token comment\">\/\/ \u89e3\u5bc6\u8d26\u53f7<\/span><br \/>\n        <span class=\"token class-name\">String<\/span> decryptedAccountNumber <span class=\"token operator\">&#061;<\/span> encryptionUtil<span class=\"token punctuation\">.<\/span><span class=\"token function\">decrypt<\/span><span class=\"token punctuation\">(<\/span>request<span class=\"token punctuation\">.<\/span><span class=\"token function\">getAccountNumber<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u68c0\u67e5\u662f\u5426\u5df2\u5b58\u5728\u76f8\u540c\u5546\u6237\u8ba2\u5355<\/span><br \/>\n        <span class=\"token class-name\">Optional<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">PaymentOrder<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> existingOrder <span class=\"token operator\">&#061;<\/span> paymentOrderRepository<br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">findByMerchantCodeAndMerchantOrderNo<\/span><span class=\"token punctuation\">(<\/span>request<span class=\"token punctuation\">.<\/span><span class=\"token function\">getMerchantCode<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span> request<span class=\"token punctuation\">.<\/span><span class=\"token function\">getMerchantOrderNo<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>existingOrder<span class=\"token punctuation\">.<\/span><span class=\"token function\">isPresent<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">throw<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">AccountException<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">ErrorCode<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">DUPLICATE_MERCHANT_ORDER<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u8ba1\u7b97\u624b\u7eed\u8d39<\/span><br \/>\n        <span class=\"token class-name\">BigDecimal<\/span> fee <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">calculateFee<\/span><span class=\"token punctuation\">(<\/span>request<span class=\"token punctuation\">.<\/span><span class=\"token function\">getMerchantCode<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span> request<span class=\"token punctuation\">.<\/span><span class=\"token function\">getOrderType<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">name<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span> request<span class=\"token punctuation\">.<\/span><span class=\"token function\">getAmount<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token class-name\">BigDecimal<\/span> settlementAmount <span class=\"token operator\">&#061;<\/span> request<span class=\"token punctuation\">.<\/span><span class=\"token function\">getAmount<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">subtract<\/span><span class=\"token punctuation\">(<\/span>fee<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u521b\u5efa\u652f\u4ed8\u8ba2\u5355<\/span><br \/>\n        <span class=\"token class-name\">PaymentOrder<\/span> order <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">PaymentOrder<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        order<span class=\"token punctuation\">.<\/span><span class=\"token function\">setOrderNo<\/span><span class=\"token punctuation\">(<\/span>orderNoGenerator<span class=\"token punctuation\">.<\/span><span class=\"token function\">generate<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        order<span class=\"token punctuation\">.<\/span><span class=\"token function\">setAccountNumber<\/span><span class=\"token punctuation\">(<\/span>decryptedAccountNumber<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        order<span class=\"token punctuation\">.<\/span><span class=\"token function\">setMerchantCode<\/span><span class=\"token punctuation\">(<\/span>request<span class=\"token punctuation\">.<\/span><span class=\"token function\">getMerchantCode<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        order<span class=\"token punctuation\">.<\/span><span class=\"token function\">setMerchantOrderNo<\/span><span class=\"token punctuation\">(<\/span>request<span class=\"token punctuation\">.<\/span><span class=\"token function\">getMerchantOrderNo<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        order<span class=\"token punctuation\">.<\/span><span class=\"token function\">setOrderType<\/span><span class=\"token punctuation\">(<\/span>request<span class=\"token punctuation\">.<\/span><span class=\"token function\">getOrderType<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        order<span class=\"token punctuation\">.<\/span><span class=\"token function\">setStatus<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">PaymentOrderStatus<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">CREATED<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        order<span class=\"token punctuation\">.<\/span><span class=\"token function\">setAmount<\/span><span class=\"token punctuation\">(<\/span>request<span class=\"token punctuation\">.<\/span><span class=\"token function\">getAmount<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        order<span class=\"token punctuation\">.<\/span><span class=\"token function\">setFee<\/span><span class=\"token punctuation\">(<\/span>fee<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        order<span class=\"token punctuation\">.<\/span><span class=\"token function\">setSettlementAmount<\/span><span class=\"token punctuation\">(<\/span>settlementAmount<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        order<span class=\"token punctuation\">.<\/span><span class=\"token function\">setCurrency<\/span><span class=\"token punctuation\">(<\/span>request<span class=\"token punctuation\">.<\/span><span class=\"token function\">getCurrency<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        order<span class=\"token punctuation\">.<\/span><span class=\"token function\">setDescription<\/span><span class=\"token punctuation\">(<\/span>request<span class=\"token punctuation\">.<\/span><span class=\"token function\">getDescription<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        order<span class=\"token punctuation\">.<\/span><span class=\"token function\">setCallbackUrl<\/span><span class=\"token punctuation\">(<\/span>request<span class=\"token punctuation\">.<\/span><span class=\"token function\">getCallbackUrl<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        order<span class=\"token punctuation\">.<\/span><span class=\"token function\">setNotifyUrl<\/span><span class=\"token punctuation\">(<\/span>request<span class=\"token punctuation\">.<\/span><span class=\"token function\">getNotifyUrl<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token class-name\">PaymentOrder<\/span> savedOrder <span class=\"token operator\">&#061;<\/span> paymentOrderRepository<span class=\"token punctuation\">.<\/span><span class=\"token function\">save<\/span><span class=\"token punctuation\">(<\/span>order<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        log<span class=\"token punctuation\">.<\/span><span class=\"token function\">info<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;Payment order created: {}&#034;<\/span><span class=\"token punctuation\">,<\/span> savedOrder<span class=\"token punctuation\">.<\/span><span class=\"token function\">getOrderNo<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u5f02\u6b65\u5904\u7406\u652f\u4ed8<\/span><br \/>\n        <span class=\"token function\">processPaymentAsync<\/span><span class=\"token punctuation\">(<\/span>savedOrder<span class=\"token punctuation\">.<\/span><span class=\"token function\">getOrderNo<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">return<\/span> <span class=\"token function\">convertToPaymentResponse<\/span><span class=\"token punctuation\">(<\/span>savedOrder<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Async<\/span><br \/>\n    <span class=\"token keyword\">public<\/span> <span class=\"token keyword\">void<\/span> <span class=\"token function\">processPaymentAsync<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">String<\/span> orderNo<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">try<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token class-name\">PaymentOrder<\/span> order <span class=\"token operator\">&#061;<\/span> paymentOrderRepository<span class=\"token punctuation\">.<\/span><span class=\"token function\">findByOrderNoForUpdate<\/span><span class=\"token punctuation\">(<\/span>orderNo<span class=\"token punctuation\">)<\/span><br \/>\n                    <span class=\"token punctuation\">.<\/span><span class=\"token function\">orElseThrow<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">-&gt;<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">AccountException<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">ErrorCode<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">ORDER_NOT_FOUND<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>            <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>order<span class=\"token punctuation\">.<\/span><span class=\"token function\">getStatus<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">!&#061;<\/span> <span class=\"token class-name\">PaymentOrderStatus<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">CREATED<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                <span class=\"token keyword\">return<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><\/p>\n<p>            order<span class=\"token punctuation\">.<\/span><span class=\"token function\">setStatus<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">PaymentOrderStatus<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">PROCESSING<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            paymentOrderRepository<span class=\"token punctuation\">.<\/span><span class=\"token function\">save<\/span><span class=\"token punctuation\">(<\/span>order<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>            <span class=\"token comment\">\/\/ \u8c03\u7528\u7b2c\u4e09\u65b9\u652f\u4ed8<\/span><br \/>\n            <span class=\"token class-name\">ThirdPartyPaymentRequest<\/span> paymentRequest <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">ThirdPartyPaymentRequest<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            paymentRequest<span class=\"token punctuation\">.<\/span><span class=\"token function\">setOrderNo<\/span><span class=\"token punctuation\">(<\/span>order<span class=\"token punctuation\">.<\/span><span class=\"token function\">getOrderNo<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            paymentRequest<span class=\"token punctuation\">.<\/span><span class=\"token function\">setAmount<\/span><span class=\"token punctuation\">(<\/span>order<span class=\"token punctuation\">.<\/span><span class=\"token function\">getAmount<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            paymentRequest<span class=\"token punctuation\">.<\/span><span class=\"token function\">setCurrency<\/span><span class=\"token punctuation\">(<\/span>order<span class=\"token punctuation\">.<\/span><span class=\"token function\">getCurrency<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            paymentRequest<span class=\"token punctuation\">.<\/span><span class=\"token function\">setAccountNumber<\/span><span class=\"token punctuation\">(<\/span>order<span class=\"token punctuation\">.<\/span><span class=\"token function\">getAccountNumber<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            paymentRequest<span class=\"token punctuation\">.<\/span><span class=\"token function\">setMerchantCode<\/span><span class=\"token punctuation\">(<\/span>order<span class=\"token punctuation\">.<\/span><span class=\"token function\">getMerchantCode<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            paymentRequest<span class=\"token punctuation\">.<\/span><span class=\"token function\">setPaymentType<\/span><span class=\"token punctuation\">(<\/span>order<span class=\"token punctuation\">.<\/span><span class=\"token function\">getOrderType<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">name<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>            <span class=\"token class-name\">ThirdPartyPaymentResponse<\/span> paymentResponse <span class=\"token operator\">&#061;<\/span> paymentGateway<span class=\"token punctuation\">.<\/span><span class=\"token function\">processPayment<\/span><span class=\"token punctuation\">(<\/span>paymentRequest<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>            <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>paymentResponse<span class=\"token punctuation\">.<\/span><span class=\"token function\">isSuccess<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                order<span class=\"token punctuation\">.<\/span><span class=\"token function\">setStatus<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">PaymentOrderStatus<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">SUCCESS<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n                order<span class=\"token punctuation\">.<\/span><span class=\"token function\">setThirdPartyTransactionNo<\/span><span class=\"token punctuation\">(<\/span>paymentResponse<span class=\"token punctuation\">.<\/span><span class=\"token function\">getTransactionNo<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n                order<span class=\"token punctuation\">.<\/span><span class=\"token function\">setPaymentTime<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">LocalDateTime<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">now<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>                <span class=\"token comment\">\/\/ \u8bb0\u5f55\u4ea4\u6613<\/span><br \/>\n                transactionService<span class=\"token punctuation\">.<\/span><span class=\"token function\">withdraw<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                        order<span class=\"token punctuation\">.<\/span><span class=\"token function\">getAccountNumber<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                        order<span class=\"token punctuation\">.<\/span><span class=\"token function\">getAmount<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                        <span class=\"token string\">&#034;Payment for order: &#034;<\/span> <span class=\"token operator\">&#043;<\/span> order<span class=\"token punctuation\">.<\/span><span class=\"token function\">getOrderNo<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">else<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                order<span class=\"token punctuation\">.<\/span><span class=\"token function\">setStatus<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">PaymentOrderStatus<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">FAILED<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n                log<span class=\"token punctuation\">.<\/span><span class=\"token function\">error<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;Payment failed for order {}: {}&#034;<\/span><span class=\"token punctuation\">,<\/span> orderNo<span class=\"token punctuation\">,<\/span> paymentResponse<span class=\"token punctuation\">.<\/span><span class=\"token function\">getErrorMessage<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><\/p>\n<p>            paymentOrderRepository<span class=\"token punctuation\">.<\/span><span class=\"token function\">save<\/span><span class=\"token punctuation\">(<\/span>order<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>            <span class=\"token comment\">\/\/ \u56de\u8c03\u5546\u6237<\/span><br \/>\n            <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>order<span class=\"token punctuation\">.<\/span><span class=\"token function\">getCallbackUrl<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">!&#061;<\/span> <span class=\"token keyword\">null<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                <span class=\"token function\">notifyMerchant<\/span><span class=\"token punctuation\">(<\/span>order<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><\/p>\n<p>        <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">catch<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token class-name\">Exception<\/span> e<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            log<span class=\"token punctuation\">.<\/span><span class=\"token function\">error<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;Error processing payment for order: &#034;<\/span> <span class=\"token operator\">&#043;<\/span> orderNo<span class=\"token punctuation\">,<\/span> e<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            paymentOrderRepository<span class=\"token punctuation\">.<\/span><span class=\"token function\">findByOrderNo<\/span><span class=\"token punctuation\">(<\/span>orderNo<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">ifPresent<\/span><span class=\"token punctuation\">(<\/span>order <span class=\"token operator\">-&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                order<span class=\"token punctuation\">.<\/span><span class=\"token function\">setStatus<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">PaymentOrderStatus<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">FAILED<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n                paymentOrderRepository<span class=\"token punctuation\">.<\/span><span class=\"token function\">save<\/span><span class=\"token punctuation\">(<\/span>order<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Transactional<\/span><span class=\"token punctuation\">(<\/span>readOnly <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">true<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">PaymentResponseDTO<\/span> <span class=\"token function\">queryPayment<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">String<\/span> orderNo<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token class-name\">PaymentOrder<\/span> order <span class=\"token operator\">&#061;<\/span> paymentOrderRepository<span class=\"token punctuation\">.<\/span><span class=\"token function\">findByOrderNo<\/span><span class=\"token punctuation\">(<\/span>orderNo<span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">orElseThrow<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">-&gt;<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">AccountException<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">ErrorCode<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">ORDER_NOT_FOUND<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">return<\/span> <span class=\"token function\">convertToPaymentResponse<\/span><span class=\"token punctuation\">(<\/span>order<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Transactional<\/span><span class=\"token punctuation\">(<\/span>readOnly <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">true<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">PaymentResponseDTO<\/span> <span class=\"token function\">queryPaymentByMerchant<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">String<\/span> merchantCode<span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">String<\/span> merchantOrderNo<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token class-name\">PaymentOrder<\/span> order <span class=\"token operator\">&#061;<\/span> paymentOrderRepository<span class=\"token punctuation\">.<\/span><span class=\"token function\">findByMerchantCodeAndMerchantOrderNo<\/span><span class=\"token punctuation\">(<\/span>merchantCode<span class=\"token punctuation\">,<\/span> merchantOrderNo<span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">orElseThrow<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">-&gt;<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">AccountException<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">ErrorCode<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">ORDER_NOT_FOUND<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">return<\/span> <span class=\"token function\">convertToPaymentResponse<\/span><span class=\"token punctuation\">(<\/span>order<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">BigDecimal<\/span> <span class=\"token function\">calculateFee<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">String<\/span> merchantCode<span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">String<\/span> paymentType<span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">BigDecimal<\/span> amount<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token class-name\">FeeConfig<\/span> feeConfig <span class=\"token operator\">&#061;<\/span> feeConfigRepository<span class=\"token punctuation\">.<\/span><span class=\"token function\">findByMerchantCodeAndPaymentType<\/span><span class=\"token punctuation\">(<\/span>merchantCode<span class=\"token punctuation\">,<\/span> paymentType<span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">orElseThrow<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">-&gt;<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">AccountException<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">ErrorCode<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">FEE_CONFIG_NOT_FOUND<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">switch<\/span> <span class=\"token punctuation\">(<\/span>feeConfig<span class=\"token punctuation\">.<\/span><span class=\"token function\">getCalculateMethod<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">case<\/span> <span class=\"token constant\">FIXED<\/span><span class=\"token operator\">:<\/span><br \/>\n                <span class=\"token keyword\">return<\/span> feeConfig<span class=\"token punctuation\">.<\/span><span class=\"token function\">getFixedFee<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            <span class=\"token keyword\">case<\/span> <span class=\"token constant\">PERCENTAGE<\/span><span class=\"token operator\">:<\/span><br \/>\n                <span class=\"token class-name\">BigDecimal<\/span> fee <span class=\"token operator\">&#061;<\/span> amount<span class=\"token punctuation\">.<\/span><span class=\"token function\">multiply<\/span><span class=\"token punctuation\">(<\/span>feeConfig<span class=\"token punctuation\">.<\/span><span class=\"token function\">getRate<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n                <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>feeConfig<span class=\"token punctuation\">.<\/span><span class=\"token function\">getMinFee<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">!&#061;<\/span> <span class=\"token keyword\">null<\/span> <span class=\"token operator\">&amp;&amp;<\/span> fee<span class=\"token punctuation\">.<\/span><span class=\"token function\">compareTo<\/span><span class=\"token punctuation\">(<\/span>feeConfig<span class=\"token punctuation\">.<\/span><span class=\"token function\">getMinFee<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&lt;<\/span> <span class=\"token number\">0<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                    <span class=\"token keyword\">return<\/span> feeConfig<span class=\"token punctuation\">.<\/span><span class=\"token function\">getMinFee<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n                <span class=\"token punctuation\">}<\/span><br \/>\n                <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>feeConfig<span class=\"token punctuation\">.<\/span><span class=\"token function\">getMaxFee<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">!&#061;<\/span> <span class=\"token keyword\">null<\/span> <span class=\"token operator\">&amp;&amp;<\/span> fee<span class=\"token punctuation\">.<\/span><span class=\"token function\">compareTo<\/span><span class=\"token punctuation\">(<\/span>feeConfig<span class=\"token punctuation\">.<\/span><span class=\"token function\">getMaxFee<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&gt;<\/span> <span class=\"token number\">0<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                    <span class=\"token keyword\">return<\/span> feeConfig<span class=\"token punctuation\">.<\/span><span class=\"token function\">getMaxFee<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n                <span class=\"token punctuation\">}<\/span><br \/>\n                <span class=\"token keyword\">return<\/span> fee<span class=\"token punctuation\">;<\/span><br \/>\n            <span class=\"token keyword\">case<\/span> <span class=\"token constant\">TIERED<\/span><span class=\"token operator\">:<\/span><br \/>\n                <span class=\"token comment\">\/\/ \u5b9e\u73b0\u9636\u68af\u8d39\u7387\u8ba1\u7b97\u903b\u8f91<\/span><br \/>\n                <span class=\"token keyword\">return<\/span> feeConfig<span class=\"token punctuation\">.<\/span><span class=\"token function\">getFixedFee<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span> <span class=\"token comment\">\/\/ \u7b80\u5316\u5904\u7406<\/span><br \/>\n            <span class=\"token keyword\">default<\/span><span class=\"token operator\">:<\/span><br \/>\n                <span class=\"token keyword\">return<\/span> <span class=\"token class-name\">BigDecimal<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">ZERO<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">void<\/span> <span class=\"token function\">notifyMerchant<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">PaymentOrder<\/span> order<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token comment\">\/\/ \u5b9e\u73b0\u56de\u8c03\u5546\u6237\u903b\u8f91<\/span><br \/>\n        <span class=\"token comment\">\/\/ \u901a\u5e38\u4f7f\u7528HTTP\u8c03\u7528\u5546\u6237\u7684callbackUrl\u6216notifyUrl<\/span><br \/>\n        log<span class=\"token punctuation\">.<\/span><span class=\"token function\">info<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;Notifying merchant for order: {}&#034;<\/span><span class=\"token punctuation\">,<\/span> order<span class=\"token punctuation\">.<\/span><span class=\"token function\">getOrderNo<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">PaymentResponseDTO<\/span> <span class=\"token function\">convertToPaymentResponse<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">PaymentOrder<\/span> order<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token class-name\">PaymentResponseDTO<\/span> response <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">PaymentResponseDTO<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        response<span class=\"token punctuation\">.<\/span><span class=\"token function\">setOrderNo<\/span><span class=\"token punctuation\">(<\/span>order<span class=\"token punctuation\">.<\/span><span class=\"token function\">getOrderNo<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        response<span class=\"token punctuation\">.<\/span><span class=\"token function\">setMerchantOrderNo<\/span><span class=\"token punctuation\">(<\/span>order<span class=\"token punctuation\">.<\/span><span class=\"token function\">getMerchantOrderNo<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        response<span class=\"token punctuation\">.<\/span><span class=\"token function\">setStatus<\/span><span class=\"token punctuation\">(<\/span>order<span class=\"token punctuation\">.<\/span><span class=\"token function\">getStatus<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        response<span class=\"token punctuation\">.<\/span><span class=\"token function\">setAmount<\/span><span class=\"token punctuation\">(<\/span>order<span class=\"token punctuation\">.<\/span><span class=\"token function\">getAmount<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        response<span class=\"token punctuation\">.<\/span><span class=\"token function\">setFee<\/span><span class=\"token punctuation\">(<\/span>order<span class=\"token punctuation\">.<\/span><span class=\"token function\">getFee<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        response<span class=\"token punctuation\">.<\/span><span class=\"token function\">setSettlementAmount<\/span><span class=\"token punctuation\">(<\/span>order<span class=\"token punctuation\">.<\/span><span class=\"token function\">getSettlementAmount<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        response<span class=\"token punctuation\">.<\/span><span class=\"token function\">setCurrency<\/span><span class=\"token punctuation\">(<\/span>order<span class=\"token punctuation\">.<\/span><span class=\"token function\">getCurrency<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        response<span class=\"token punctuation\">.<\/span><span class=\"token function\">setCreatedAt<\/span><span class=\"token punctuation\">(<\/span>order<span class=\"token punctuation\">.<\/span><span class=\"token function\">getCreatedAt<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u52a0\u5bc6\u8d26\u53f7<\/span><br \/>\n        response<span class=\"token punctuation\">.<\/span><span class=\"token function\">setAccountNumber<\/span><span class=\"token punctuation\">(<\/span>encryptionUtil<span class=\"token punctuation\">.<\/span><span class=\"token function\">encrypt<\/span><span class=\"token punctuation\">(<\/span>order<span class=\"token punctuation\">.<\/span><span class=\"token function\">getAccountNumber<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">return<\/span> response<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token comment\">\/**<br \/>\n\u7ed3\u7b97\u670d\u52a1<br \/>\n*\/<\/span><br \/>\n<span class=\"token annotation punctuation\">&#064;Service<\/span><br \/>\n<span class=\"token annotation punctuation\">&#064;RequiredArgsConstructor<\/span><br \/>\n<span class=\"token annotation punctuation\">&#064;Slf4j<\/span><br \/>\n<span class=\"token keyword\">public<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token class-name\">SettlementService<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">final<\/span> <span class=\"token class-name\">PaymentOrderRepository<\/span> paymentOrderRepository<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">final<\/span> <span class=\"token class-name\">SettlementRecordRepository<\/span> settlementRepository<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">final<\/span> <span class=\"token class-name\">TransactionService<\/span> transactionService<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">final<\/span> <span class=\"token class-name\">SettlementNoGenerator<\/span> settlementNoGenerator<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Transactional<\/span><br \/>\n    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">SettlementResponseDTO<\/span> <span class=\"token function\">createSettlement<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">SettlementRequestDTO<\/span> request<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token class-name\">LocalDate<\/span> settlementDate <span class=\"token operator\">&#061;<\/span> request<span class=\"token punctuation\">.<\/span><span class=\"token function\">getSettlementDate<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">!&#061;<\/span> <span class=\"token keyword\">null<\/span> <span class=\"token operator\">?<\/span><br \/>\n                request<span class=\"token punctuation\">.<\/span><span class=\"token function\">getSettlementDate<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">:<\/span> <span class=\"token class-name\">LocalDate<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">now<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">minusDays<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">1<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u68c0\u67e5\u662f\u5426\u5df2\u6709\u7ed3\u7b97\u8bb0\u5f55<\/span><br \/>\n        <span class=\"token class-name\">Optional<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">SettlementRecord<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> existingSettlement <span class=\"token operator\">&#061;<\/span> settlementRepository<br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">findByMerchantCodeAndSettlementDate<\/span><span class=\"token punctuation\">(<\/span>request<span class=\"token punctuation\">.<\/span><span class=\"token function\">getMerchantCode<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span> settlementDate<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>existingSettlement<span class=\"token punctuation\">.<\/span><span class=\"token function\">isPresent<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">throw<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">AccountException<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">ErrorCode<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">SETTLEMENT_ALREADY_EXISTS<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u67e5\u8be2\u5f85\u7ed3\u7b97\u7684\u652f\u4ed8\u8ba2\u5355<\/span><br \/>\n        <span class=\"token class-name\">List<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">PaymentOrder<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> orders <span class=\"token operator\">&#061;<\/span> paymentOrderRepository<br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">findByMerchantCodeAndStatusAndSettlementTimeIsNull<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                        request<span class=\"token punctuation\">.<\/span><span class=\"token function\">getMerchantCode<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                        <span class=\"token class-name\">PaymentOrderStatus<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">SUCCESS<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>orders<span class=\"token punctuation\">.<\/span><span class=\"token function\">isEmpty<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">throw<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">AccountException<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">ErrorCode<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">NO_ORDERS_TO_SETTLE<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u8ba1\u7b97\u7ed3\u7b97\u91d1\u989d<\/span><br \/>\n        <span class=\"token class-name\">BigDecimal<\/span> totalAmount <span class=\"token operator\">&#061;<\/span> orders<span class=\"token punctuation\">.<\/span><span class=\"token function\">stream<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">map<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">PaymentOrder<\/span><span class=\"token operator\">::<\/span><span class=\"token function\">getSettlementAmount<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">reduce<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">BigDecimal<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">ZERO<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">BigDecimal<\/span><span class=\"token operator\">::<\/span><span class=\"token function\">add<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token class-name\">BigDecimal<\/span> totalFee <span class=\"token operator\">&#061;<\/span> orders<span class=\"token punctuation\">.<\/span><span class=\"token function\">stream<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">map<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">PaymentOrder<\/span><span class=\"token operator\">::<\/span><span class=\"token function\">getFee<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">reduce<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">BigDecimal<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">ZERO<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">BigDecimal<\/span><span class=\"token operator\">::<\/span><span class=\"token function\">add<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u521b\u5efa\u7ed3\u7b97\u8bb0\u5f55<\/span><br \/>\n        <span class=\"token class-name\">SettlementRecord<\/span> settlement <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">SettlementRecord<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        settlement<span class=\"token punctuation\">.<\/span><span class=\"token function\">setSettlementNo<\/span><span class=\"token punctuation\">(<\/span>settlementNoGenerator<span class=\"token punctuation\">.<\/span><span class=\"token function\">generate<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        settlement<span class=\"token punctuation\">.<\/span><span class=\"token function\">setMerchantCode<\/span><span class=\"token punctuation\">(<\/span>request<span class=\"token punctuation\">.<\/span><span class=\"token function\">getMerchantCode<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        settlement<span class=\"token punctuation\">.<\/span><span class=\"token function\">setSettlementDate<\/span><span class=\"token punctuation\">(<\/span>settlementDate<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        settlement<span class=\"token punctuation\">.<\/span><span class=\"token function\">setTotalAmount<\/span><span class=\"token punctuation\">(<\/span>totalAmount<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        settlement<span class=\"token punctuation\">.<\/span><span class=\"token function\">setTotalFee<\/span><span class=\"token punctuation\">(<\/span>totalFee<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        settlement<span class=\"token punctuation\">.<\/span><span class=\"token function\">setNetAmount<\/span><span class=\"token punctuation\">(<\/span>totalAmount<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        settlement<span class=\"token punctuation\">.<\/span><span class=\"token function\">setTotalCount<\/span><span class=\"token punctuation\">(<\/span>orders<span class=\"token punctuation\">.<\/span><span class=\"token function\">size<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        settlement<span class=\"token punctuation\">.<\/span><span class=\"token function\">setStatus<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">SettlementStatus<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">PENDING<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token class-name\">SettlementRecord<\/span> savedSettlement <span class=\"token operator\">&#061;<\/span> settlementRepository<span class=\"token punctuation\">.<\/span><span class=\"token function\">save<\/span><span class=\"token punctuation\">(<\/span>settlement<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        log<span class=\"token punctuation\">.<\/span><span class=\"token function\">info<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;Settlement record created: {}&#034;<\/span><span class=\"token punctuation\">,<\/span> savedSettlement<span class=\"token punctuation\">.<\/span><span class=\"token function\">getSettlementNo<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u5f02\u6b65\u5904\u7406\u7ed3\u7b97<\/span><br \/>\n        <span class=\"token function\">processSettlementAsync<\/span><span class=\"token punctuation\">(<\/span>savedSettlement<span class=\"token punctuation\">.<\/span><span class=\"token function\">getSettlementNo<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">return<\/span> <span class=\"token function\">convertToSettlementResponse<\/span><span class=\"token punctuation\">(<\/span>savedSettlement<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Async<\/span><br \/>\n    <span class=\"token keyword\">public<\/span> <span class=\"token keyword\">void<\/span> <span class=\"token function\">processSettlementAsync<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">String<\/span> settlementNo<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">try<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token class-name\">SettlementRecord<\/span> settlement <span class=\"token operator\">&#061;<\/span> settlementRepository<span class=\"token punctuation\">.<\/span><span class=\"token function\">findBySettlementNo<\/span><span class=\"token punctuation\">(<\/span>settlementNo<span class=\"token punctuation\">)<\/span><br \/>\n                    <span class=\"token punctuation\">.<\/span><span class=\"token function\">orElseThrow<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">-&gt;<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">AccountException<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">ErrorCode<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">SETTLEMENT_NOT_FOUND<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>            <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>settlement<span class=\"token punctuation\">.<\/span><span class=\"token function\">getStatus<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">!&#061;<\/span> <span class=\"token class-name\">SettlementStatus<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">PENDING<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                <span class=\"token keyword\">return<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><\/p>\n<p>            settlement<span class=\"token punctuation\">.<\/span><span class=\"token function\">setStatus<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">SettlementStatus<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">PROCESSING<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            settlementRepository<span class=\"token punctuation\">.<\/span><span class=\"token function\">save<\/span><span class=\"token punctuation\">(<\/span>settlement<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>            <span class=\"token comment\">\/\/ \u6267\u884c\u8d44\u91d1\u5212\u62e8<\/span><br \/>\n            transactionService<span class=\"token punctuation\">.<\/span><span class=\"token function\">deposit<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                    <span class=\"token function\">getMerchantAccount<\/span><span class=\"token punctuation\">(<\/span>settlement<span class=\"token punctuation\">.<\/span><span class=\"token function\">getMerchantCode<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                    settlement<span class=\"token punctuation\">.<\/span><span class=\"token function\">getNetAmount<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                    <span class=\"token string\">&#034;Settlement for &#034;<\/span> <span class=\"token operator\">&#043;<\/span> settlement<span class=\"token punctuation\">.<\/span><span class=\"token function\">getSettlementDate<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>            <span class=\"token comment\">\/\/ \u66f4\u65b0\u652f\u4ed8\u8ba2\u5355\u7ed3\u7b97\u72b6\u6001<\/span><br \/>\n            <span class=\"token class-name\">List<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">PaymentOrder<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> orders <span class=\"token operator\">&#061;<\/span> paymentOrderRepository<br \/>\n                    <span class=\"token punctuation\">.<\/span><span class=\"token function\">findByMerchantCodeAndStatusAndSettlementTimeIsNull<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                            settlement<span class=\"token punctuation\">.<\/span><span class=\"token function\">getMerchantCode<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                            <span class=\"token class-name\">PaymentOrderStatus<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">SUCCESS<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>            orders<span class=\"token punctuation\">.<\/span><span class=\"token function\">forEach<\/span><span class=\"token punctuation\">(<\/span>order <span class=\"token operator\">-&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                order<span class=\"token punctuation\">.<\/span><span class=\"token function\">setSettlementTime<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">LocalDateTime<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">now<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n                paymentOrderRepository<span class=\"token punctuation\">.<\/span><span class=\"token function\">save<\/span><span class=\"token punctuation\">(<\/span>order<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>            settlement<span class=\"token punctuation\">.<\/span><span class=\"token function\">setStatus<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">SettlementStatus<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">COMPLETED<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            settlement<span class=\"token punctuation\">.<\/span><span class=\"token function\">setCompletedTime<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">LocalDateTime<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">now<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            settlementRepository<span class=\"token punctuation\">.<\/span><span class=\"token function\">save<\/span><span class=\"token punctuation\">(<\/span>settlement<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>            log<span class=\"token punctuation\">.<\/span><span class=\"token function\">info<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;Settlement completed: {}&#034;<\/span><span class=\"token punctuation\">,<\/span> settlementNo<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">catch<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token class-name\">Exception<\/span> e<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            log<span class=\"token punctuation\">.<\/span><span class=\"token function\">error<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;Error processing settlement: &#034;<\/span> <span class=\"token operator\">&#043;<\/span> settlementNo<span class=\"token punctuation\">,<\/span> e<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            settlementRepository<span class=\"token punctuation\">.<\/span><span class=\"token function\">findBySettlementNo<\/span><span class=\"token punctuation\">(<\/span>settlementNo<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">ifPresent<\/span><span class=\"token punctuation\">(<\/span>s <span class=\"token operator\">-&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                s<span class=\"token punctuation\">.<\/span><span class=\"token function\">setStatus<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">SettlementStatus<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">FAILED<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n                settlementRepository<span class=\"token punctuation\">.<\/span><span class=\"token function\">save<\/span><span class=\"token punctuation\">(<\/span>s<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Scheduled<\/span><span class=\"token punctuation\">(<\/span>cron <span class=\"token operator\">&#061;<\/span> <span class=\"token string\">&#034;0 0 2 * * ?&#034;<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token comment\">\/\/ \u6bcf\u5929\u51cc\u66682\u70b9\u6267\u884c<\/span><br \/>\n    <span class=\"token keyword\">public<\/span> <span class=\"token keyword\">void<\/span> <span class=\"token function\">autoSettlement<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token class-name\">LocalDate<\/span> settlementDate <span class=\"token operator\">&#061;<\/span> <span class=\"token class-name\">LocalDate<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">now<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">minusDays<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">1<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        log<span class=\"token punctuation\">.<\/span><span class=\"token function\">info<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;Starting auto settlement for date: {}&#034;<\/span><span class=\"token punctuation\">,<\/span> settlementDate<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u83b7\u53d6\u6240\u6709\u9700\u8981\u7ed3\u7b97\u7684\u5546\u6237<\/span><br \/>\n        <span class=\"token class-name\">List<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">String<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> merchantCodes <span class=\"token operator\">&#061;<\/span> paymentOrderRepository<br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">findDistinctMerchantCodeByStatusAndSettlementTimeIsNull<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">PaymentOrderStatus<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">SUCCESS<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        merchantCodes<span class=\"token punctuation\">.<\/span><span class=\"token function\">forEach<\/span><span class=\"token punctuation\">(<\/span>merchantCode <span class=\"token operator\">-&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">try<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                <span class=\"token class-name\">SettlementRequestDTO<\/span> request <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">SettlementRequestDTO<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n                request<span class=\"token punctuation\">.<\/span><span class=\"token function\">setMerchantCode<\/span><span class=\"token punctuation\">(<\/span>merchantCode<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n                request<span class=\"token punctuation\">.<\/span><span class=\"token function\">setSettlementDate<\/span><span class=\"token punctuation\">(<\/span>settlementDate<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n                <span class=\"token function\">createSettlement<\/span><span class=\"token punctuation\">(<\/span>request<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">catch<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token class-name\">Exception<\/span> e<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                log<span class=\"token punctuation\">.<\/span><span class=\"token function\">error<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;Auto settlement failed for merchant: &#034;<\/span> <span class=\"token operator\">&#043;<\/span> merchantCode<span class=\"token punctuation\">,<\/span> e<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> <span class=\"token function\">getMerchantAccount<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">String<\/span> merchantCode<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token comment\">\/\/ \u5b9e\u9645\u9879\u76ee\u4e2d\u5e94\u6839\u636e\u5546\u6237\u7f16\u7801\u67e5\u8be2\u5546\u6237\u7684\u7ed3\u7b97\u8d26\u6237<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> <span class=\"token string\">&#034;MERCHANT_&#034;<\/span> <span class=\"token operator\">&#043;<\/span> merchantCode<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">SettlementResponseDTO<\/span> <span class=\"token function\">convertToSettlementResponse<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">SettlementRecord<\/span> settlement<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token class-name\">SettlementResponseDTO<\/span> response <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">SettlementResponseDTO<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        response<span class=\"token punctuation\">.<\/span><span class=\"token function\">setSettlementNo<\/span><span class=\"token punctuation\">(<\/span>settlement<span class=\"token punctuation\">.<\/span><span class=\"token function\">getSettlementNo<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        response<span class=\"token punctuation\">.<\/span><span class=\"token function\">setMerchantCode<\/span><span class=\"token punctuation\">(<\/span>settlement<span class=\"token punctuation\">.<\/span><span class=\"token function\">getMerchantCode<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        response<span class=\"token punctuation\">.<\/span><span class=\"token function\">setSettlementDate<\/span><span class=\"token punctuation\">(<\/span>settlement<span class=\"token punctuation\">.<\/span><span class=\"token function\">getSettlementDate<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        response<span class=\"token punctuation\">.<\/span><span class=\"token function\">setTotalAmount<\/span><span class=\"token punctuation\">(<\/span>settlement<span class=\"token punctuation\">.<\/span><span class=\"token function\">getTotalAmount<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        response<span class=\"token punctuation\">.<\/span><span class=\"token function\">setTotalFee<\/span><span class=\"token punctuation\">(<\/span>settlement<span class=\"token punctuation\">.<\/span><span class=\"token function\">getTotalFee<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        response<span class=\"token punctuation\">.<\/span><span class=\"token function\">setNetAmount<\/span><span class=\"token punctuation\">(<\/span>settlement<span class=\"token punctuation\">.<\/span><span class=\"token function\">getNetAmount<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        response<span class=\"token punctuation\">.<\/span><span class=\"token function\">setTotalCount<\/span><span class=\"token punctuation\">(<\/span>settlement<span class=\"token punctuation\">.<\/span><span class=\"token function\">getTotalCount<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        response<span class=\"token punctuation\">.<\/span><span class=\"token function\">setStatus<\/span><span class=\"token punctuation\">(<\/span>settlement<span class=\"token punctuation\">.<\/span><span class=\"token function\">getStatus<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        response<span class=\"token punctuation\">.<\/span><span class=\"token function\">setCompletedTime<\/span><span class=\"token punctuation\">(<\/span>settlement<span class=\"token punctuation\">.<\/span><span class=\"token function\">getCompletedTime<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> response<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token comment\">\/**<br \/>\n\u7b2c\u4e09\u65b9\u652f\u4ed8\u5bf9\u63a5<br \/>\n*\/<\/span><br \/>\n<span class=\"token annotation punctuation\">&#064;Component<\/span><br \/>\n<span class=\"token keyword\">public<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token class-name\">ThirdPartyPaymentGateway<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">ThirdPartyPaymentResponse<\/span> <span class=\"token function\">processPayment<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">ThirdPartyPaymentRequest<\/span> request<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token comment\">\/\/ \u5b9e\u9645\u9879\u76ee\u4e2d\u8fd9\u91cc\u4f1a\u8c03\u7528\u7b2c\u4e09\u65b9\u652f\u4ed8\u5e73\u53f0\u7684API<\/span><br \/>\n        <span class=\"token comment\">\/\/ \u4ee5\u4e0b\u662f\u6a21\u62df\u5b9e\u73b0<\/span><\/p>\n<p>        <span class=\"token class-name\">ThirdPartyPaymentResponse<\/span> response <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">ThirdPartyPaymentResponse<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">try<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token comment\">\/\/ \u6a21\u62df\u652f\u4ed8\u5904\u7406<\/span><br \/>\n            <span class=\"token class-name\">Thread<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">sleep<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">500<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>            <span class=\"token comment\">\/\/ \u6a21\u62df90%\u6210\u529f\u7387<\/span><br \/>\n            <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token class-name\">Math<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">random<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&gt;<\/span> <span class=\"token number\">0.1<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                response<span class=\"token punctuation\">.<\/span><span class=\"token function\">setSuccess<\/span><span class=\"token punctuation\">(<\/span><span class=\"token boolean\">true<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n                response<span class=\"token punctuation\">.<\/span><span class=\"token function\">setTransactionNo<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;TP&#034;<\/span> <span class=\"token operator\">&#043;<\/span> <span class=\"token class-name\">System<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">currentTimeMillis<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n                response<span class=\"token punctuation\">.<\/span><span class=\"token function\">setPaymentUrl<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;https:\/\/payment-gateway.com\/pay\/&#034;<\/span> <span class=\"token operator\">&#043;<\/span> request<span class=\"token punctuation\">.<\/span><span class=\"token function\">getOrderNo<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">else<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                response<span class=\"token punctuation\">.<\/span><span class=\"token function\">setSuccess<\/span><span class=\"token punctuation\">(<\/span><span class=\"token boolean\">false<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n                response<span class=\"token punctuation\">.<\/span><span class=\"token function\">setErrorCode<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;PAYMENT_FAILED&#034;<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n                response<span class=\"token punctuation\">.<\/span><span class=\"token function\">setErrorMessage<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;Payment processing failed&#034;<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">catch<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token class-name\">Exception<\/span> e<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            response<span class=\"token punctuation\">.<\/span><span class=\"token function\">setSuccess<\/span><span class=\"token punctuation\">(<\/span><span class=\"token boolean\">false<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            response<span class=\"token punctuation\">.<\/span><span class=\"token function\">setErrorCode<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;SYSTEM_ERROR&#034;<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            response<span class=\"token punctuation\">.<\/span><span class=\"token function\">setErrorMessage<\/span><span class=\"token punctuation\">(<\/span>e<span class=\"token punctuation\">.<\/span><span class=\"token function\">getMessage<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><\/p>\n<p>        <span class=\"token keyword\">return<\/span> response<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p>Repository\u5c42<\/p>\n<p><span class=\"token keyword\">public<\/span> <span class=\"token keyword\">interface<\/span> <span class=\"token class-name\">PaymentOrderRepository<\/span> <span class=\"token keyword\">extends<\/span> <span class=\"token class-name\">JpaRepository<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">PaymentOrder<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">Long<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token class-name\">Optional<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">PaymentOrder<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> <span class=\"token function\">findByOrderNo<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">String<\/span> orderNo<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token class-name\">Optional<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">PaymentOrder<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> <span class=\"token function\">findByMerchantCodeAndMerchantOrderNo<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">String<\/span> merchantCode<span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">String<\/span> merchantOrderNo<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token class-name\">List<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">PaymentOrder<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> <span class=\"token function\">findByMerchantCodeAndStatusAndSettlementTimeIsNull<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">String<\/span> merchantCode<span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">PaymentOrderStatus<\/span> status<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Lock<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">LockModeType<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">PESSIMISTIC_WRITE<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token annotation punctuation\">&#064;Query<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;SELECT p FROM PaymentOrder p WHERE p.orderNo &#061; :orderNo&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token class-name\">Optional<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">PaymentOrder<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> <span class=\"token function\">findByOrderNoForUpdate<\/span><span class=\"token punctuation\">(<\/span><span class=\"token annotation punctuation\">&#064;Param<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;orderNo&#034;<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token class-name\">String<\/span> orderNo<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token keyword\">public<\/span> <span class=\"token keyword\">interface<\/span> <span class=\"token class-name\">SettlementRecordRepository<\/span> <span class=\"token keyword\">extends<\/span> <span class=\"token class-name\">JpaRepository<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">SettlementRecord<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">Long<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token class-name\">Optional<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">SettlementRecord<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> <span class=\"token function\">findBySettlementNo<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">String<\/span> settlementNo<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token class-name\">Optional<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">SettlementRecord<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> <span class=\"token function\">findByMerchantCodeAndSettlementDate<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">String<\/span> merchantCode<span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">LocalDate<\/span> settlementDate<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token class-name\">List<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">SettlementRecord<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> <span class=\"token function\">findBySettlementDateAndStatus<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">LocalDate<\/span> settlementDate<span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">SettlementStatus<\/span> status<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token keyword\">public<\/span> <span class=\"token keyword\">interface<\/span> <span class=\"token class-name\">FeeConfigRepository<\/span> <span class=\"token keyword\">extends<\/span> <span class=\"token class-name\">JpaRepository<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">FeeConfig<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">Long<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token class-name\">Optional<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">FeeConfig<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> <span class=\"token function\">findByMerchantCodeAndPaymentType<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">String<\/span> merchantCode<span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">String<\/span> paymentType<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token class-name\">List<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">FeeConfig<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> <span class=\"token function\">findByMerchantCode<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">String<\/span> merchantCode<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p>4. \u8d37\u6b3e\u7ba1\u7406<\/p>\n<p>\u8d37\u6b3e\u7533\u8bf7\u5ba1\u6279<\/p>\n<p>\u8d37\u6b3e\u53d1\u653e<\/p>\n<p>\u8fd8\u6b3e\u8ba1\u5212<\/p>\n<p>\u903e\u671f\u7ba1\u7406<\/p>\n<p>\u5229\u7387\u8c03\u6574<\/p>\n<p><span class=\"token annotation punctuation\">&#064;Entity<\/span><br \/>\n<span class=\"token annotation punctuation\">&#064;Table<\/span><span class=\"token punctuation\">(<\/span>name <span class=\"token operator\">&#061;<\/span> <span class=\"token string\">&#034;loan_application&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n<span class=\"token annotation punctuation\">&#064;Data<\/span><br \/>\n<span class=\"token keyword\">public<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token class-name\">LoanApplication<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token annotation punctuation\">&#064;Id<\/span><br \/>\n    <span class=\"token annotation punctuation\">&#064;GeneratedValue<\/span><span class=\"token punctuation\">(<\/span>strategy <span class=\"token operator\">&#061;<\/span> <span class=\"token class-name\">GenerationType<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">IDENTITY<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">Long<\/span> id<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>nullable <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">,<\/span> unique <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">true<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> applicationNo<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>nullable <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">Long<\/span> customerId<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>nullable <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> accountNumber<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Enumerated<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">EnumType<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">STRING<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>nullable <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">LoanType<\/span> loanType<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>nullable <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">,<\/span> precision <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">19<\/span><span class=\"token punctuation\">,<\/span> scale <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">4<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">BigDecimal<\/span> amount<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>nullable <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">Integer<\/span> term<span class=\"token punctuation\">;<\/span> <span class=\"token comment\">\/\/ in months<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>nullable <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">,<\/span> precision <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">5<\/span><span class=\"token punctuation\">,<\/span> scale <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">4<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">BigDecimal<\/span> interestRate<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>nullable <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> purpose<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Enumerated<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">EnumType<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">STRING<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>nullable <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">LoanStatus<\/span> status<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">Long<\/span> approvedBy<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">LocalDateTime<\/span> approvedAt<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> rejectionReason<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">LocalDate<\/span> disbursementDate<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">LocalDate<\/span> maturityDate<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;CreationTimestamp<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">LocalDateTime<\/span> createdAt<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;UpdateTimestamp<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">LocalDateTime<\/span> updatedAt<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Version<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">Long<\/span> version<span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token annotation punctuation\">&#064;Entity<\/span><br \/>\n<span class=\"token annotation punctuation\">&#064;Table<\/span><span class=\"token punctuation\">(<\/span>name <span class=\"token operator\">&#061;<\/span> <span class=\"token string\">&#034;loan_account&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n<span class=\"token annotation punctuation\">&#064;Data<\/span><br \/>\n<span class=\"token keyword\">public<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token class-name\">LoanAccount<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token annotation punctuation\">&#064;Id<\/span><br \/>\n    <span class=\"token annotation punctuation\">&#064;GeneratedValue<\/span><span class=\"token punctuation\">(<\/span>strategy <span class=\"token operator\">&#061;<\/span> <span class=\"token class-name\">GenerationType<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">IDENTITY<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">Long<\/span> id<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>nullable <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">,<\/span> unique <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">true<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> loanAccountNo<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>nullable <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> applicationNo<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>nullable <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">Long<\/span> customerId<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>nullable <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> accountNumber<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>nullable <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">,<\/span> precision <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">19<\/span><span class=\"token punctuation\">,<\/span> scale <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">4<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">BigDecimal<\/span> originalAmount<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>nullable <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">,<\/span> precision <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">19<\/span><span class=\"token punctuation\">,<\/span> scale <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">4<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">BigDecimal<\/span> outstandingAmount<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>nullable <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">,<\/span> precision <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">19<\/span><span class=\"token punctuation\">,<\/span> scale <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">4<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">BigDecimal<\/span> interestAccrued<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>nullable <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">,<\/span> precision <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">5<\/span><span class=\"token punctuation\">,<\/span> scale <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">4<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">BigDecimal<\/span> interestRate<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>nullable <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">LocalDate<\/span> startDate<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>nullable <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">LocalDate<\/span> maturityDate<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Enumerated<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">EnumType<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">STRING<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>nullable <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">LoanAccountStatus<\/span> status<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;CreationTimestamp<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">LocalDateTime<\/span> createdAt<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;UpdateTimestamp<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">LocalDateTime<\/span> updatedAt<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Version<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">Long<\/span> version<span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token annotation punctuation\">&#064;Entity<\/span><br \/>\n<span class=\"token annotation punctuation\">&#064;Table<\/span><span class=\"token punctuation\">(<\/span>name <span class=\"token operator\">&#061;<\/span> <span class=\"token string\">&#034;repayment_schedule&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n<span class=\"token annotation punctuation\">&#064;Data<\/span><br \/>\n<span class=\"token keyword\">public<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token class-name\">RepaymentSchedule<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token annotation punctuation\">&#064;Id<\/span><br \/>\n    <span class=\"token annotation punctuation\">&#064;GeneratedValue<\/span><span class=\"token punctuation\">(<\/span>strategy <span class=\"token operator\">&#061;<\/span> <span class=\"token class-name\">GenerationType<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">IDENTITY<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">Long<\/span> id<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>nullable <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> loanAccountNo<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>nullable <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">Integer<\/span> installmentNo<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>nullable <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">LocalDate<\/span> dueDate<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>nullable <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">,<\/span> precision <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">19<\/span><span class=\"token punctuation\">,<\/span> scale <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">4<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">BigDecimal<\/span> principalAmount<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>nullable <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">,<\/span> precision <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">19<\/span><span class=\"token punctuation\">,<\/span> scale <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">4<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">BigDecimal<\/span> interestAmount<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>nullable <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">,<\/span> precision <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">19<\/span><span class=\"token punctuation\">,<\/span> scale <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">4<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">BigDecimal<\/span> totalAmount<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>nullable <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">,<\/span> precision <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">19<\/span><span class=\"token punctuation\">,<\/span> scale <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">4<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">BigDecimal<\/span> outstandingPrincipal<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Enumerated<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">EnumType<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">STRING<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>nullable <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">RepaymentStatus<\/span> status<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">LocalDate<\/span> paidDate<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>precision <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">19<\/span><span class=\"token punctuation\">,<\/span> scale <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">4<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">BigDecimal<\/span> paidAmount<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;CreationTimestamp<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">LocalDateTime<\/span> createdAt<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;UpdateTimestamp<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">LocalDateTime<\/span> updatedAt<span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token annotation punctuation\">&#064;Entity<\/span><br \/>\n<span class=\"token annotation punctuation\">&#064;Table<\/span><span class=\"token punctuation\">(<\/span>name <span class=\"token operator\">&#061;<\/span> <span class=\"token string\">&#034;loan_product&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n<span class=\"token annotation punctuation\">&#064;Data<\/span><br \/>\n<span class=\"token keyword\">public<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token class-name\">LoanProduct<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token annotation punctuation\">&#064;Id<\/span><br \/>\n    <span class=\"token annotation punctuation\">&#064;GeneratedValue<\/span><span class=\"token punctuation\">(<\/span>strategy <span class=\"token operator\">&#061;<\/span> <span class=\"token class-name\">GenerationType<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">IDENTITY<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">Long<\/span> id<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>nullable <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">,<\/span> unique <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">true<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> productCode<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>nullable <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> productName<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Enumerated<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">EnumType<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">STRING<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>nullable <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">LoanType<\/span> loanType<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>nullable <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">,<\/span> precision <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">19<\/span><span class=\"token punctuation\">,<\/span> scale <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">4<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">BigDecimal<\/span> minAmount<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>nullable <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">,<\/span> precision <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">19<\/span><span class=\"token punctuation\">,<\/span> scale <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">4<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">BigDecimal<\/span> maxAmount<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>nullable <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">Integer<\/span> minTerm<span class=\"token punctuation\">;<\/span> <span class=\"token comment\">\/\/ in months<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>nullable <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">Integer<\/span> maxTerm<span class=\"token punctuation\">;<\/span> <span class=\"token comment\">\/\/ in months<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>nullable <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">,<\/span> precision <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">5<\/span><span class=\"token punctuation\">,<\/span> scale <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">4<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">BigDecimal<\/span> baseInterestRate<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>nullable <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">Boolean<\/span> active <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">true<\/span><span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token keyword\">public<\/span> <span class=\"token keyword\">enum<\/span> <span class=\"token class-name\">LoanType<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token constant\">PERSONAL_LOAN<\/span><span class=\"token punctuation\">,<\/span>      <span class=\"token comment\">\/\/ \u4e2a\u4eba\u8d37\u6b3e<\/span><br \/>\n    <span class=\"token constant\">MORTGAGE_LOAN<\/span><span class=\"token punctuation\">,<\/span>      <span class=\"token comment\">\/\/ \u62b5\u62bc\u8d37\u6b3e<\/span><br \/>\n    <span class=\"token constant\">AUTO_LOAN<\/span><span class=\"token punctuation\">,<\/span>          <span class=\"token comment\">\/\/ \u6c7d\u8f66\u8d37\u6b3e<\/span><br \/>\n    <span class=\"token constant\">BUSINESS_LOAN<\/span><span class=\"token punctuation\">,<\/span>      <span class=\"token comment\">\/\/ \u5546\u4e1a\u8d37\u6b3e<\/span><br \/>\n    <span class=\"token constant\">CREDIT_LINE<\/span>         <span class=\"token comment\">\/\/ \u4fe1\u7528\u989d\u5ea6<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token keyword\">public<\/span> <span class=\"token keyword\">enum<\/span> <span class=\"token class-name\">LoanStatus<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token constant\">DRAFT<\/span><span class=\"token punctuation\">,<\/span>              <span class=\"token comment\">\/\/ \u8349\u7a3f<\/span><br \/>\n    <span class=\"token constant\">PENDING<\/span><span class=\"token punctuation\">,<\/span>            <span class=\"token comment\">\/\/ \u5f85\u5ba1\u6279<\/span><br \/>\n    <span class=\"token constant\">APPROVED<\/span><span class=\"token punctuation\">,<\/span>           <span class=\"token comment\">\/\/ \u5df2\u6279\u51c6<\/span><br \/>\n    <span class=\"token constant\">REJECTED<\/span><span class=\"token punctuation\">,<\/span>           <span class=\"token comment\">\/\/ \u5df2\u62d2\u7edd<\/span><br \/>\n    <span class=\"token constant\">DISBURSED<\/span><span class=\"token punctuation\">,<\/span>          <span class=\"token comment\">\/\/ \u5df2\u53d1\u653e<\/span><br \/>\n    <span class=\"token constant\">CLOSED<\/span>              <span class=\"token comment\">\/\/ \u5df2\u5173\u95ed<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token keyword\">public<\/span> <span class=\"token keyword\">enum<\/span> <span class=\"token class-name\">LoanAccountStatus<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token constant\">ACTIVE<\/span><span class=\"token punctuation\">,<\/span>             <span class=\"token comment\">\/\/ \u6d3b\u8dc3<\/span><br \/>\n    <span class=\"token constant\">DELINQUENT<\/span><span class=\"token punctuation\">,<\/span>         <span class=\"token comment\">\/\/ \u903e\u671f<\/span><br \/>\n    <span class=\"token constant\">PAID_OFF<\/span><span class=\"token punctuation\">,<\/span>           <span class=\"token comment\">\/\/ \u5df2\u8fd8\u6e05<\/span><br \/>\n    <span class=\"token constant\">WRITTEN_OFF<\/span><span class=\"token punctuation\">,<\/span>        <span class=\"token comment\">\/\/ \u5df2\u6838\u9500<\/span><br \/>\n    <span class=\"token constant\">DEFAULTED<\/span>           <span class=\"token comment\">\/\/ \u8fdd\u7ea6<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token keyword\">public<\/span> <span class=\"token keyword\">enum<\/span> <span class=\"token class-name\">RepaymentStatus<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token constant\">PENDING<\/span><span class=\"token punctuation\">,<\/span>            <span class=\"token comment\">\/\/ \u5f85\u8fd8\u6b3e<\/span><br \/>\n    <span class=\"token constant\">PAID<\/span><span class=\"token punctuation\">,<\/span>               <span class=\"token comment\">\/\/ \u5df2\u8fd8\u6b3e<\/span><br \/>\n    <span class=\"token constant\">PARTIALLY_PAID<\/span><span class=\"token punctuation\">,<\/span>     <span class=\"token comment\">\/\/ \u90e8\u5206\u8fd8\u6b3e<\/span><br \/>\n    <span class=\"token constant\">OVERDUE<\/span><span class=\"token punctuation\">,<\/span>            <span class=\"token comment\">\/\/ \u903e\u671f<\/span><br \/>\n    <span class=\"token constant\">WAIVED<\/span>              <span class=\"token comment\">\/\/ \u5df2\u8c41\u514d<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token annotation punctuation\">&#064;Data<\/span><br \/>\n<span class=\"token keyword\">public<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token class-name\">LoanApplicationDTO<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> applicationNo<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">Long<\/span> customerId<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> accountNumber<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">LoanType<\/span> loanType<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">BigDecimal<\/span> amount<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">Integer<\/span> term<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">BigDecimal<\/span> interestRate<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> purpose<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">LoanStatus<\/span> status<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">Long<\/span> approvedBy<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">LocalDateTime<\/span> approvedAt<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> rejectionReason<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">LocalDate<\/span> disbursementDate<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">LocalDate<\/span> maturityDate<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">LocalDateTime<\/span> createdAt<span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token annotation punctuation\">&#064;Data<\/span><br \/>\n<span class=\"token keyword\">public<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token class-name\">LoanApplicationRequest<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token annotation punctuation\">&#064;NotNull<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">Long<\/span> customerId<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;NotBlank<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> accountNumber<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;NotNull<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">LoanType<\/span> loanType<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;NotNull<\/span><br \/>\n    <span class=\"token annotation punctuation\">&#064;DecimalMin<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;1000.00&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">BigDecimal<\/span> amount<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;NotNull<\/span><br \/>\n    <span class=\"token annotation punctuation\">&#064;Min<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">1<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token annotation punctuation\">&#064;Max<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">360<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">Integer<\/span> term<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;NotBlank<\/span><br \/>\n    <span class=\"token annotation punctuation\">&#064;Size<\/span><span class=\"token punctuation\">(<\/span>min <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">10<\/span><span class=\"token punctuation\">,<\/span> max <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">500<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> purpose<span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token annotation punctuation\">&#064;Data<\/span><br \/>\n<span class=\"token keyword\">public<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token class-name\">LoanApprovalRequest<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token annotation punctuation\">&#064;NotNull<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">Boolean<\/span> approved<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> comments<span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token annotation punctuation\">&#064;Data<\/span><br \/>\n<span class=\"token keyword\">public<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token class-name\">LoanAccountDTO<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> loanAccountNo<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> applicationNo<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">Long<\/span> customerId<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> accountNumber<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">BigDecimal<\/span> originalAmount<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">BigDecimal<\/span> outstandingAmount<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">BigDecimal<\/span> interestAccrued<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">BigDecimal<\/span> interestRate<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">LocalDate<\/span> startDate<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">LocalDate<\/span> maturityDate<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">LoanAccountStatus<\/span> status<span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token annotation punctuation\">&#064;Data<\/span><br \/>\n<span class=\"token keyword\">public<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token class-name\">RepaymentDTO<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">Long<\/span> id<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> loanAccountNo<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">Integer<\/span> installmentNo<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">LocalDate<\/span> dueDate<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">BigDecimal<\/span> principalAmount<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">BigDecimal<\/span> interestAmount<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">BigDecimal<\/span> totalAmount<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">BigDecimal<\/span> outstandingPrincipal<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">RepaymentStatus<\/span> status<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">LocalDate<\/span> paidDate<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">BigDecimal<\/span> paidAmount<span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token annotation punctuation\">&#064;Data<\/span><br \/>\n<span class=\"token keyword\">public<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token class-name\">RepaymentRequest<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token annotation punctuation\">&#064;NotNull<\/span><br \/>\n    <span class=\"token annotation punctuation\">&#064;DecimalMin<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;0.01&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">BigDecimal<\/span> amount<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;NotBlank<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> transactionReference<span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p>\u5de5\u5177\u7c7b<\/p>\n<p><span class=\"token annotation punctuation\">&#064;Component<\/span><br \/>\n<span class=\"token keyword\">public<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token class-name\">ApplicationNoGenerator<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">static<\/span> <span class=\"token keyword\">final<\/span> <span class=\"token class-name\">String<\/span> <span class=\"token constant\">BANK_CODE<\/span> <span class=\"token operator\">&#061;<\/span> <span class=\"token string\">&#034;888&#034;<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">final<\/span> <span class=\"token class-name\">AtomicLong<\/span> sequence <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">AtomicLong<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">1<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">String<\/span> <span class=\"token function\">generate<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">long<\/span> timestamp <span class=\"token operator\">&#061;<\/span> <span class=\"token class-name\">Instant<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">now<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">toEpochMilli<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token keyword\">long<\/span> seq <span class=\"token operator\">&#061;<\/span> sequence<span class=\"token punctuation\">.<\/span><span class=\"token function\">getAndIncrement<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> <span class=\"token class-name\">String<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">format<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;%s-LN-%d-%06d&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token constant\">BANK_CODE<\/span><span class=\"token punctuation\">,<\/span> timestamp<span class=\"token punctuation\">,<\/span> seq<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token annotation punctuation\">&#064;Component<\/span><br \/>\n<span class=\"token keyword\">public<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token class-name\">LoanAccountNoGenerator<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">static<\/span> <span class=\"token keyword\">final<\/span> <span class=\"token class-name\">String<\/span> <span class=\"token constant\">BANK_CODE<\/span> <span class=\"token operator\">&#061;<\/span> <span class=\"token string\">&#034;888&#034;<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">final<\/span> <span class=\"token class-name\">AtomicLong<\/span> sequence <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">AtomicLong<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">1<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">String<\/span> <span class=\"token function\">generate<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token class-name\">String<\/span> dateStr <span class=\"token operator\">&#061;<\/span> <span class=\"token class-name\">LocalDate<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">now<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">format<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">DateTimeFormatter<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">BASIC_ISO_DATE<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token keyword\">long<\/span> seq <span class=\"token operator\">&#061;<\/span> sequence<span class=\"token punctuation\">.<\/span><span class=\"token function\">getAndIncrement<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> <span class=\"token class-name\">String<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">format<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;%s-LA-%s-%06d&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token constant\">BANK_CODE<\/span><span class=\"token punctuation\">,<\/span> dateStr<span class=\"token punctuation\">,<\/span> seq<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p>Controller\u5c42<\/p>\n<p><span class=\"token annotation punctuation\">&#064;RestController<\/span><br \/>\n<span class=\"token annotation punctuation\">&#064;RequestMapping<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;\/api\/loan-applications&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n<span class=\"token annotation punctuation\">&#064;RequiredArgsConstructor<\/span><br \/>\n<span class=\"token keyword\">public<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token class-name\">LoanApplicationController<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">final<\/span> <span class=\"token class-name\">LoanApplicationService<\/span> applicationService<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;PostMapping<\/span><br \/>\n    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">LoanApplicationDTO<\/span> <span class=\"token function\">createApplication<\/span><span class=\"token punctuation\">(<\/span><span class=\"token annotation punctuation\">&#064;Valid<\/span> <span class=\"token annotation punctuation\">&#064;RequestBody<\/span> <span class=\"token class-name\">LoanApplicationRequest<\/span> request<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> applicationService<span class=\"token punctuation\">.<\/span><span class=\"token function\">createApplication<\/span><span class=\"token punctuation\">(<\/span>request<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;PutMapping<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;\/{applicationNo}\/approval&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token annotation punctuation\">&#064;PreAuthorize<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;hasAnyRole(&#039;LOAN_OFFICER&#039;, &#039;MANAGER&#039;, &#039;ADMIN&#039;)&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">LoanApplicationDTO<\/span> <span class=\"token function\">approveApplication<\/span><span class=\"token punctuation\">(<\/span><br \/>\n            <span class=\"token annotation punctuation\">&#064;PathVariable<\/span> <span class=\"token class-name\">String<\/span> applicationNo<span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token annotation punctuation\">&#064;Valid<\/span> <span class=\"token annotation punctuation\">&#064;RequestBody<\/span> <span class=\"token class-name\">LoanApprovalRequest<\/span> request<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> applicationService<span class=\"token punctuation\">.<\/span><span class=\"token function\">approveApplication<\/span><span class=\"token punctuation\">(<\/span>applicationNo<span class=\"token punctuation\">,<\/span> request<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;GetMapping<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;\/customer\/{customerId}&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">List<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">LoanApplicationDTO<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> <span class=\"token function\">getCustomerApplications<\/span><span class=\"token punctuation\">(<\/span><span class=\"token annotation punctuation\">&#064;PathVariable<\/span> <span class=\"token class-name\">Long<\/span> customerId<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> applicationService<span class=\"token punctuation\">.<\/span><span class=\"token function\">getCustomerApplications<\/span><span class=\"token punctuation\">(<\/span>customerId<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;GetMapping<\/span><br \/>\n    <span class=\"token annotation punctuation\">&#064;PreAuthorize<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;hasAnyRole(&#039;LOAN_OFFICER&#039;, &#039;MANAGER&#039;, &#039;ADMIN&#039;)&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">List<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">LoanApplicationDTO<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> <span class=\"token function\">getApplicationsByStatus<\/span><span class=\"token punctuation\">(<\/span><span class=\"token annotation punctuation\">&#064;RequestParam<\/span> <span class=\"token class-name\">String<\/span> status<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> applicationService<span class=\"token punctuation\">.<\/span><span class=\"token function\">getApplicationsByStatus<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">LoanStatus<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">valueOf<\/span><span class=\"token punctuation\">(<\/span>status<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token annotation punctuation\">&#064;RestController<\/span><br \/>\n<span class=\"token annotation punctuation\">&#064;RequestMapping<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;\/api\/loan-accounts&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n<span class=\"token annotation punctuation\">&#064;RequiredArgsConstructor<\/span><br \/>\n<span class=\"token keyword\">public<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token class-name\">LoanAccountController<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">final<\/span> <span class=\"token class-name\">LoanAccountService<\/span> loanAccountService<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;GetMapping<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;\/{loanAccountNo}&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">LoanAccountDTO<\/span> <span class=\"token function\">getLoanAccount<\/span><span class=\"token punctuation\">(<\/span><span class=\"token annotation punctuation\">&#064;PathVariable<\/span> <span class=\"token class-name\">String<\/span> loanAccountNo<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> loanAccountService<span class=\"token punctuation\">.<\/span><span class=\"token function\">getLoanAccount<\/span><span class=\"token punctuation\">(<\/span>loanAccountNo<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;GetMapping<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;\/customer\/{customerId}&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">List<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">LoanAccountDTO<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> <span class=\"token function\">getCustomerLoanAccounts<\/span><span class=\"token punctuation\">(<\/span><span class=\"token annotation punctuation\">&#064;PathVariable<\/span> <span class=\"token class-name\">Long<\/span> customerId<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> loanAccountService<span class=\"token punctuation\">.<\/span><span class=\"token function\">getCustomerLoanAccounts<\/span><span class=\"token punctuation\">(<\/span>customerId<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;GetMapping<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;\/{loanAccountNo}\/repayments&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">List<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">RepaymentDTO<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> <span class=\"token function\">getRepaymentSchedule<\/span><span class=\"token punctuation\">(<\/span><span class=\"token annotation punctuation\">&#064;PathVariable<\/span> <span class=\"token class-name\">String<\/span> loanAccountNo<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> loanAccountService<span class=\"token punctuation\">.<\/span><span class=\"token function\">getRepaymentSchedule<\/span><span class=\"token punctuation\">(<\/span>loanAccountNo<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;PostMapping<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;\/{loanAccountNo}\/repayments&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">RepaymentDTO<\/span> <span class=\"token function\">makeRepayment<\/span><span class=\"token punctuation\">(<\/span><br \/>\n            <span class=\"token annotation punctuation\">&#064;PathVariable<\/span> <span class=\"token class-name\">String<\/span> loanAccountNo<span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token annotation punctuation\">&#064;Valid<\/span> <span class=\"token annotation punctuation\">&#064;RequestBody<\/span> <span class=\"token class-name\">RepaymentRequest<\/span> request<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> loanAccountService<span class=\"token punctuation\">.<\/span><span class=\"token function\">makeRepayment<\/span><span class=\"token punctuation\">(<\/span>loanAccountNo<span class=\"token punctuation\">,<\/span> request<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p>Service\u5c42<\/p>\n<p><span class=\"token annotation punctuation\">&#064;Service<\/span><br \/>\n<span class=\"token annotation punctuation\">&#064;RequiredArgsConstructor<\/span><br \/>\n<span class=\"token annotation punctuation\">&#064;Slf4j<\/span><br \/>\n<span class=\"token keyword\">public<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token class-name\">LoanApplicationService<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">final<\/span> <span class=\"token class-name\">LoanApplicationRepository<\/span> applicationRepository<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">final<\/span> <span class=\"token class-name\">LoanProductRepository<\/span> productRepository<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">final<\/span> <span class=\"token class-name\">ApplicationNoGenerator<\/span> applicationNoGenerator<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">final<\/span> <span class=\"token class-name\">EncryptionUtil<\/span> encryptionUtil<span class=\"token punctuation\">;<\/span><\/p>\n<p><span class=\"token annotation punctuation\">&#064;Transactional<\/span><br \/>\n    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">LoanApplicationDTO<\/span> <span class=\"token function\">createApplication<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">LoanApplicationRequest<\/span> request<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token comment\">\/\/ \u89e3\u5bc6\u8d26\u53f7<\/span><br \/>\n        <span class=\"token class-name\">String<\/span> decryptedAccountNumber <span class=\"token operator\">&#061;<\/span> encryptionUtil<span class=\"token punctuation\">.<\/span><span class=\"token function\">decrypt<\/span><span class=\"token punctuation\">(<\/span>request<span class=\"token punctuation\">.<\/span><span class=\"token function\">getAccountNumber<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u9a8c\u8bc1\u8d37\u6b3e\u4ea7\u54c1<\/span><br \/>\n        <span class=\"token class-name\">LoanProduct<\/span> product <span class=\"token operator\">&#061;<\/span> productRepository<span class=\"token punctuation\">.<\/span><span class=\"token function\">findByLoanType<\/span><span class=\"token punctuation\">(<\/span>request<span class=\"token punctuation\">.<\/span><span class=\"token function\">getLoanType<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">orElseThrow<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">-&gt;<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">AccountException<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">ErrorCode<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">LOAN_PRODUCT_NOT_FOUND<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u9a8c\u8bc1\u8d37\u6b3e\u91d1\u989d\u548c\u671f\u9650<\/span><br \/>\n        <span class=\"token function\">validateLoanAmountAndTerm<\/span><span class=\"token punctuation\">(<\/span>request<span class=\"token punctuation\">.<\/span><span class=\"token function\">getAmount<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span> request<span class=\"token punctuation\">.<\/span><span class=\"token function\">getTerm<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span> product<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u8ba1\u7b97\u5229\u7387 (\u7b80\u5316\u5904\u7406&#xff0c;\u5b9e\u9645\u4e1a\u52a1\u4e2d\u53ef\u80fd\u6709\u66f4\u590d\u6742\u7684\u5229\u7387\u8ba1\u7b97\u903b\u8f91)<\/span><br \/>\n        <span class=\"token class-name\">BigDecimal<\/span> interestRate <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">calculateInterestRate<\/span><span class=\"token punctuation\">(<\/span>request<span class=\"token punctuation\">.<\/span><span class=\"token function\">getLoanType<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span> request<span class=\"token punctuation\">.<\/span><span class=\"token function\">getAmount<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span> request<span class=\"token punctuation\">.<\/span><span class=\"token function\">getTerm<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u521b\u5efa\u8d37\u6b3e\u7533\u8bf7<\/span><br \/>\n        <span class=\"token class-name\">LoanApplication<\/span> application <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">LoanApplication<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        application<span class=\"token punctuation\">.<\/span><span class=\"token function\">setApplicationNo<\/span><span class=\"token punctuation\">(<\/span>applicationNoGenerator<span class=\"token punctuation\">.<\/span><span class=\"token function\">generate<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        application<span class=\"token punctuation\">.<\/span><span class=\"token function\">setCustomerId<\/span><span class=\"token punctuation\">(<\/span>request<span class=\"token punctuation\">.<\/span><span class=\"token function\">getCustomerId<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        application<span class=\"token punctuation\">.<\/span><span class=\"token function\">setAccountNumber<\/span><span class=\"token punctuation\">(<\/span>decryptedAccountNumber<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        application<span class=\"token punctuation\">.<\/span><span class=\"token function\">setLoanType<\/span><span class=\"token punctuation\">(<\/span>request<span class=\"token punctuation\">.<\/span><span class=\"token function\">getLoanType<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        application<span class=\"token punctuation\">.<\/span><span class=\"token function\">setAmount<\/span><span class=\"token punctuation\">(<\/span>request<span class=\"token punctuation\">.<\/span><span class=\"token function\">getAmount<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        application<span class=\"token punctuation\">.<\/span><span class=\"token function\">setTerm<\/span><span class=\"token punctuation\">(<\/span>request<span class=\"token punctuation\">.<\/span><span class=\"token function\">getTerm<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        application<span class=\"token punctuation\">.<\/span><span class=\"token function\">setInterestRate<\/span><span class=\"token punctuation\">(<\/span>interestRate<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        application<span class=\"token punctuation\">.<\/span><span class=\"token function\">setPurpose<\/span><span class=\"token punctuation\">(<\/span>request<span class=\"token punctuation\">.<\/span><span class=\"token function\">getPurpose<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        application<span class=\"token punctuation\">.<\/span><span class=\"token function\">setStatus<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">LoanStatus<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">PENDING<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token class-name\">LoanApplication<\/span> saved <span class=\"token operator\">&#061;<\/span> applicationRepository<span class=\"token punctuation\">.<\/span><span class=\"token function\">save<\/span><span class=\"token punctuation\">(<\/span>application<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        log<span class=\"token punctuation\">.<\/span><span class=\"token function\">info<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;Loan application created: {}&#034;<\/span><span class=\"token punctuation\">,<\/span> saved<span class=\"token punctuation\">.<\/span><span class=\"token function\">getApplicationNo<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">return<\/span> <span class=\"token function\">convertToDTO<\/span><span class=\"token punctuation\">(<\/span>saved<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Transactional<\/span><br \/>\n    <span class=\"token annotation punctuation\">&#064;PreAuthorize<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;hasAnyRole(&#039;LOAN_OFFICER&#039;, &#039;MANAGER&#039;, &#039;ADMIN&#039;)&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">LoanApplicationDTO<\/span> <span class=\"token function\">approveApplication<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">String<\/span> applicationNo<span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">LoanApprovalRequest<\/span> request<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token class-name\">LoanApplication<\/span> application <span class=\"token operator\">&#061;<\/span> applicationRepository<span class=\"token punctuation\">.<\/span><span class=\"token function\">findByApplicationNo<\/span><span class=\"token punctuation\">(<\/span>applicationNo<span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">orElseThrow<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">-&gt;<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">AccountException<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">ErrorCode<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">APPLICATION_NOT_FOUND<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>application<span class=\"token punctuation\">.<\/span><span class=\"token function\">getStatus<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">!&#061;<\/span> <span class=\"token class-name\">LoanStatus<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">PENDING<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">throw<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">AccountException<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">ErrorCode<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">APPLICATION_NOT_PENDING<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><\/p>\n<p>        <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>request<span class=\"token punctuation\">.<\/span><span class=\"token function\">getApproved<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            application<span class=\"token punctuation\">.<\/span><span class=\"token function\">setStatus<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">LoanStatus<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">APPROVED<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            application<span class=\"token punctuation\">.<\/span><span class=\"token function\">setApprovedBy<\/span><span class=\"token punctuation\">(<\/span><span class=\"token function\">getCurrentUserId<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            application<span class=\"token punctuation\">.<\/span><span class=\"token function\">setApprovedAt<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">LocalDateTime<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">now<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            application<span class=\"token punctuation\">.<\/span><span class=\"token function\">setMaturityDate<\/span><span class=\"token punctuation\">(<\/span><span class=\"token function\">calculateMaturityDate<\/span><span class=\"token punctuation\">(<\/span>application<span class=\"token punctuation\">.<\/span><span class=\"token function\">getCreatedAt<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">toLocalDate<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span> application<span class=\"token punctuation\">.<\/span><span class=\"token function\">getTerm<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>            <span class=\"token comment\">\/\/ \u8bbe\u7f6e\u9884\u8ba1\u53d1\u653e\u65e5\u671f(3\u4e2a\u5de5\u4f5c\u65e5\u540e)<\/span><br \/>\n            application<span class=\"token punctuation\">.<\/span><span class=\"token function\">setDisbursementDate<\/span><span class=\"token punctuation\">(<\/span><span class=\"token function\">calculateDisbursementDate<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">LocalDate<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">now<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">else<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            application<span class=\"token punctuation\">.<\/span><span class=\"token function\">setStatus<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">LoanStatus<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">REJECTED<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            application<span class=\"token punctuation\">.<\/span><span class=\"token function\">setRejectionReason<\/span><span class=\"token punctuation\">(<\/span>request<span class=\"token punctuation\">.<\/span><span class=\"token function\">getComments<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><\/p>\n<p>        <span class=\"token class-name\">LoanApplication<\/span> saved <span class=\"token operator\">&#061;<\/span> applicationRepository<span class=\"token punctuation\">.<\/span><span class=\"token function\">save<\/span><span class=\"token punctuation\">(<\/span>application<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        log<span class=\"token punctuation\">.<\/span><span class=\"token function\">info<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;Loan application {}: {}&#034;<\/span><span class=\"token punctuation\">,<\/span> request<span class=\"token punctuation\">.<\/span><span class=\"token function\">getApproved<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">?<\/span> <span class=\"token string\">&#034;approved&#034;<\/span> <span class=\"token operator\">:<\/span> <span class=\"token string\">&#034;rejected&#034;<\/span><span class=\"token punctuation\">,<\/span> applicationNo<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">return<\/span> <span class=\"token function\">convertToDTO<\/span><span class=\"token punctuation\">(<\/span>saved<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Transactional<\/span><span class=\"token punctuation\">(<\/span>readOnly <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">true<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">List<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">LoanApplicationDTO<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> <span class=\"token function\">getCustomerApplications<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">Long<\/span> customerId<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> applicationRepository<span class=\"token punctuation\">.<\/span><span class=\"token function\">findByCustomerId<\/span><span class=\"token punctuation\">(<\/span>customerId<span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">stream<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">map<\/span><span class=\"token punctuation\">(<\/span><span class=\"token keyword\">this<\/span><span class=\"token operator\">::<\/span><span class=\"token function\">convertToDTO<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">peek<\/span><span class=\"token punctuation\">(<\/span>dto <span class=\"token operator\">-&gt;<\/span> dto<span class=\"token punctuation\">.<\/span><span class=\"token function\">setAccountNumber<\/span><span class=\"token punctuation\">(<\/span>encryptionUtil<span class=\"token punctuation\">.<\/span><span class=\"token function\">encrypt<\/span><span class=\"token punctuation\">(<\/span>dto<span class=\"token punctuation\">.<\/span><span class=\"token function\">getAccountNumber<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">collect<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">Collectors<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">toList<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Transactional<\/span><span class=\"token punctuation\">(<\/span>readOnly <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">true<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token annotation punctuation\">&#064;PreAuthorize<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;hasAnyRole(&#039;LOAN_OFFICER&#039;, &#039;MANAGER&#039;, &#039;ADMIN&#039;)&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">List<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">LoanApplicationDTO<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> <span class=\"token function\">getApplicationsByStatus<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">LoanStatus<\/span> status<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> applicationRepository<span class=\"token punctuation\">.<\/span><span class=\"token function\">findByStatus<\/span><span class=\"token punctuation\">(<\/span>status<span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">stream<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">map<\/span><span class=\"token punctuation\">(<\/span><span class=\"token keyword\">this<\/span><span class=\"token operator\">::<\/span><span class=\"token function\">convertToDTO<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">peek<\/span><span class=\"token punctuation\">(<\/span>dto <span class=\"token operator\">-&gt;<\/span> dto<span class=\"token punctuation\">.<\/span><span class=\"token function\">setAccountNumber<\/span><span class=\"token punctuation\">(<\/span>encryptionUtil<span class=\"token punctuation\">.<\/span><span class=\"token function\">encrypt<\/span><span class=\"token punctuation\">(<\/span>dto<span class=\"token punctuation\">.<\/span><span class=\"token function\">getAccountNumber<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">collect<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">Collectors<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">toList<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Scheduled<\/span><span class=\"token punctuation\">(<\/span>cron <span class=\"token operator\">&#061;<\/span> <span class=\"token string\">&#034;0 0 9 * * ?&#034;<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token comment\">\/\/ \u6bcf\u5929\u4e0a\u53489\u70b9\u6267\u884c<\/span><br \/>\n    <span class=\"token keyword\">public<\/span> <span class=\"token keyword\">void<\/span> <span class=\"token function\">processApprovedLoans<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token class-name\">LocalDate<\/span> today <span class=\"token operator\">&#061;<\/span> <span class=\"token class-name\">LocalDate<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">now<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token class-name\">List<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">LoanApplication<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> applications <span class=\"token operator\">&#061;<\/span> applicationRepository<br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">findPendingDisbursement<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">LoanStatus<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">APPROVED<\/span><span class=\"token punctuation\">,<\/span> today<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        applications<span class=\"token punctuation\">.<\/span><span class=\"token function\">forEach<\/span><span class=\"token punctuation\">(<\/span>application <span class=\"token operator\">-&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">try<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                <span class=\"token function\">disburseLoan<\/span><span class=\"token punctuation\">(<\/span>application<span class=\"token punctuation\">.<\/span><span class=\"token function\">getApplicationNo<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">catch<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token class-name\">Exception<\/span> e<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                log<span class=\"token punctuation\">.<\/span><span class=\"token function\">error<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;Failed to disburse loan: &#034;<\/span> <span class=\"token operator\">&#043;<\/span> application<span class=\"token punctuation\">.<\/span><span class=\"token function\">getApplicationNo<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span> e<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Transactional<\/span><br \/>\n    <span class=\"token keyword\">public<\/span> <span class=\"token keyword\">void<\/span> <span class=\"token function\">disburseLoan<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">String<\/span> applicationNo<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token class-name\">LoanApplication<\/span> application <span class=\"token operator\">&#061;<\/span> applicationRepository<span class=\"token punctuation\">.<\/span><span class=\"token function\">findByApplicationNo<\/span><span class=\"token punctuation\">(<\/span>applicationNo<span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">orElseThrow<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">-&gt;<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">AccountException<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">ErrorCode<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">APPLICATION_NOT_FOUND<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>application<span class=\"token punctuation\">.<\/span><span class=\"token function\">getStatus<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">!&#061;<\/span> <span class=\"token class-name\">LoanStatus<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">APPROVED<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">throw<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">AccountException<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">ErrorCode<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">APPLICATION_NOT_APPROVED<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><\/p>\n<p>        <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>application<span class=\"token punctuation\">.<\/span><span class=\"token function\">getDisbursementDate<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">isAfter<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">LocalDate<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">now<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">throw<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">AccountException<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">ErrorCode<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">DISBURSEMENT_DATE_NOT_REACHED<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u521b\u5efa\u8d37\u6b3e\u8d26\u6237<\/span><br \/>\n        <span class=\"token class-name\">LoanAccountDTO<\/span> loanAccount <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">createLoanAccount<\/span><span class=\"token punctuation\">(<\/span>application<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u6807\u8bb0\u8d37\u6b3e\u7533\u8bf7\u4e3a\u5df2\u53d1\u653e<\/span><br \/>\n        application<span class=\"token punctuation\">.<\/span><span class=\"token function\">setStatus<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">LoanStatus<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">DISBURSED<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        applicationRepository<span class=\"token punctuation\">.<\/span><span class=\"token function\">save<\/span><span class=\"token punctuation\">(<\/span>application<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        log<span class=\"token punctuation\">.<\/span><span class=\"token function\">info<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;Loan disbursed: {}&#034;<\/span><span class=\"token punctuation\">,<\/span> applicationNo<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">LoanAccountDTO<\/span> <span class=\"token function\">createLoanAccount<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">LoanApplication<\/span> application<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token comment\">\/\/ \u5b9e\u9645\u5b9e\u73b0\u4f1a\u8c03\u7528LoanAccountService\u521b\u5efa\u8d37\u6b3e\u8d26\u6237<\/span><br \/>\n        <span class=\"token comment\">\/\/ \u8fd9\u91cc\u7b80\u5316\u5904\u7406<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">LoanAccountDTO<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">void<\/span> <span class=\"token function\">validateLoanAmountAndTerm<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">BigDecimal<\/span> amount<span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">Integer<\/span> term<span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">LoanProduct<\/span> product<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>amount<span class=\"token punctuation\">.<\/span><span class=\"token function\">compareTo<\/span><span class=\"token punctuation\">(<\/span>product<span class=\"token punctuation\">.<\/span><span class=\"token function\">getMinAmount<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&lt;<\/span> <span class=\"token number\">0<\/span> <span class=\"token operator\">||<\/span> amount<span class=\"token punctuation\">.<\/span><span class=\"token function\">compareTo<\/span><span class=\"token punctuation\">(<\/span>product<span class=\"token punctuation\">.<\/span><span class=\"token function\">getMaxAmount<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&gt;<\/span> <span class=\"token number\">0<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">throw<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">AccountException<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">ErrorCode<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">INVALID_LOAN_AMOUNT<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><\/p>\n<p>        <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>term <span class=\"token operator\">&lt;<\/span> product<span class=\"token punctuation\">.<\/span><span class=\"token function\">getMinTerm<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">||<\/span> term <span class=\"token operator\">&gt;<\/span> product<span class=\"token punctuation\">.<\/span><span class=\"token function\">getMaxTerm<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">throw<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">AccountException<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">ErrorCode<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">INVALID_LOAN_TERM<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">BigDecimal<\/span> <span class=\"token function\">calculateInterestRate<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">LoanType<\/span> loanType<span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">BigDecimal<\/span> amount<span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">Integer<\/span> term<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token comment\">\/\/ \u7b80\u5316\u5904\u7406&#xff0c;\u5b9e\u9645\u4e1a\u52a1\u4e2d\u53ef\u80fd\u6709\u66f4\u590d\u6742\u7684\u5229\u7387\u8ba1\u7b97\u903b\u8f91<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> <span class=\"token class-name\">BigDecimal<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">valueOf<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">0.08<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span> <span class=\"token comment\">\/\/ 8%<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">LocalDate<\/span> <span class=\"token function\">calculateMaturityDate<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">LocalDate<\/span> startDate<span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">Integer<\/span> termMonths<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> startDate<span class=\"token punctuation\">.<\/span><span class=\"token function\">plusMonths<\/span><span class=\"token punctuation\">(<\/span>termMonths<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">LocalDate<\/span> <span class=\"token function\">calculateDisbursementDate<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">LocalDate<\/span> today<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token comment\">\/\/ \u7b80\u5316\u5904\u7406&#xff0c;\u5b9e\u9645\u4e1a\u52a1\u4e2d\u53ef\u80fd\u9700\u8981\u8003\u8651\u5de5\u4f5c\u65e5<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> today<span class=\"token punctuation\">.<\/span><span class=\"token function\">plusDays<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">3<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">Long<\/span> <span class=\"token function\">getCurrentUserId<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token comment\">\/\/ \u4ece\u5b89\u5168\u4e0a\u4e0b\u6587\u4e2d\u83b7\u53d6\u5f53\u524d\u7528\u6237ID<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> <span class=\"token number\">1L<\/span><span class=\"token punctuation\">;<\/span> <span class=\"token comment\">\/\/ \u7b80\u5316\u5904\u7406<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">LoanApplicationDTO<\/span> <span class=\"token function\">convertToDTO<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">LoanApplication<\/span> application<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token class-name\">LoanApplicationDTO<\/span> dto <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">LoanApplicationDTO<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        dto<span class=\"token punctuation\">.<\/span><span class=\"token function\">setApplicationNo<\/span><span class=\"token punctuation\">(<\/span>application<span class=\"token punctuation\">.<\/span><span class=\"token function\">getApplicationNo<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        dto<span class=\"token punctuation\">.<\/span><span class=\"token function\">setCustomerId<\/span><span class=\"token punctuation\">(<\/span>application<span class=\"token punctuation\">.<\/span><span class=\"token function\">getCustomerId<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        dto<span class=\"token punctuation\">.<\/span><span class=\"token function\">setAccountNumber<\/span><span class=\"token punctuation\">(<\/span>application<span class=\"token punctuation\">.<\/span><span class=\"token function\">getAccountNumber<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        dto<span class=\"token punctuation\">.<\/span><span class=\"token function\">setLoanType<\/span><span class=\"token punctuation\">(<\/span>application<span class=\"token punctuation\">.<\/span><span class=\"token function\">getLoanType<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        dto<span class=\"token punctuation\">.<\/span><span class=\"token function\">setAmount<\/span><span class=\"token punctuation\">(<\/span>application<span class=\"token punctuation\">.<\/span><span class=\"token function\">getAmount<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        dto<span class=\"token punctuation\">.<\/span><span class=\"token function\">setTerm<\/span><span class=\"token punctuation\">(<\/span>application<span class=\"token punctuation\">.<\/span><span class=\"token function\">getTerm<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        dto<span class=\"token punctuation\">.<\/span><span class=\"token function\">setInterestRate<\/span><span class=\"token punctuation\">(<\/span>application<span class=\"token punctuation\">.<\/span><span class=\"token function\">getInterestRate<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        dto<span class=\"token punctuation\">.<\/span><span class=\"token function\">setPurpose<\/span><span class=\"token punctuation\">(<\/span>application<span class=\"token punctuation\">.<\/span><span class=\"token function\">getPurpose<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        dto<span class=\"token punctuation\">.<\/span><span class=\"token function\">setStatus<\/span><span class=\"token punctuation\">(<\/span>application<span class=\"token punctuation\">.<\/span><span class=\"token function\">getStatus<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        dto<span class=\"token punctuation\">.<\/span><span class=\"token function\">setApprovedBy<\/span><span class=\"token punctuation\">(<\/span>application<span class=\"token punctuation\">.<\/span><span class=\"token function\">getApprovedBy<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        dto<span class=\"token punctuation\">.<\/span><span class=\"token function\">setApprovedAt<\/span><span class=\"token punctuation\">(<\/span>application<span class=\"token punctuation\">.<\/span><span class=\"token function\">getApprovedAt<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        dto<span class=\"token punctuation\">.<\/span><span class=\"token function\">setRejectionReason<\/span><span class=\"token punctuation\">(<\/span>application<span class=\"token punctuation\">.<\/span><span class=\"token function\">getRejectionReason<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        dto<span class=\"token punctuation\">.<\/span><span class=\"token function\">setDisbursementDate<\/span><span class=\"token punctuation\">(<\/span>application<span class=\"token punctuation\">.<\/span><span class=\"token function\">getDisbursementDate<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        dto<span class=\"token punctuation\">.<\/span><span class=\"token function\">setMaturityDate<\/span><span class=\"token punctuation\">(<\/span>application<span class=\"token punctuation\">.<\/span><span class=\"token function\">getMaturityDate<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        dto<span class=\"token punctuation\">.<\/span><span class=\"token function\">setCreatedAt<\/span><span class=\"token punctuation\">(<\/span>application<span class=\"token punctuation\">.<\/span><span class=\"token function\">getCreatedAt<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> dto<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token comment\">\/**<br \/>\n\u8d37\u6b3e\u8d26\u6237\u670d\u52a1<br \/>\n*\/<\/span><br \/>\n<span class=\"token annotation punctuation\">&#064;Service<\/span><br \/>\n<span class=\"token annotation punctuation\">&#064;RequiredArgsConstructor<\/span><br \/>\n<span class=\"token annotation punctuation\">&#064;Slf4j<\/span><br \/>\n<span class=\"token keyword\">public<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token class-name\">LoanAccountService<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">final<\/span> <span class=\"token class-name\">LoanAccountRepository<\/span> loanAccountRepository<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">final<\/span> <span class=\"token class-name\">LoanApplicationRepository<\/span> applicationRepository<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">final<\/span> <span class=\"token class-name\">RepaymentScheduleRepository<\/span> repaymentRepository<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">final<\/span> <span class=\"token class-name\">TransactionService<\/span> transactionService<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">final<\/span> <span class=\"token class-name\">LoanAccountNoGenerator<\/span> accountNoGenerator<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Transactional<\/span><br \/>\n    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">LoanAccountDTO<\/span> <span class=\"token function\">createLoanAccount<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">LoanApplication<\/span> application<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token comment\">\/\/ \u751f\u6210\u8fd8\u6b3e\u8ba1\u5212<\/span><br \/>\n        <span class=\"token class-name\">List<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">RepaymentSchedule<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> repaymentSchedules <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">generateRepaymentSchedule<\/span><span class=\"token punctuation\">(<\/span>application<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u521b\u5efa\u8d37\u6b3e\u8d26\u6237<\/span><br \/>\n        <span class=\"token class-name\">LoanAccount<\/span> loanAccount <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">LoanAccount<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        loanAccount<span class=\"token punctuation\">.<\/span><span class=\"token function\">setLoanAccountNo<\/span><span class=\"token punctuation\">(<\/span>accountNoGenerator<span class=\"token punctuation\">.<\/span><span class=\"token function\">generate<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        loanAccount<span class=\"token punctuation\">.<\/span><span class=\"token function\">setApplicationNo<\/span><span class=\"token punctuation\">(<\/span>application<span class=\"token punctuation\">.<\/span><span class=\"token function\">getApplicationNo<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        loanAccount<span class=\"token punctuation\">.<\/span><span class=\"token function\">setCustomerId<\/span><span class=\"token punctuation\">(<\/span>application<span class=\"token punctuation\">.<\/span><span class=\"token function\">getCustomerId<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        loanAccount<span class=\"token punctuation\">.<\/span><span class=\"token function\">setAccountNumber<\/span><span class=\"token punctuation\">(<\/span>application<span class=\"token punctuation\">.<\/span><span class=\"token function\">getAccountNumber<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        loanAccount<span class=\"token punctuation\">.<\/span><span class=\"token function\">setOriginalAmount<\/span><span class=\"token punctuation\">(<\/span>application<span class=\"token punctuation\">.<\/span><span class=\"token function\">getAmount<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        loanAccount<span class=\"token punctuation\">.<\/span><span class=\"token function\">setOutstandingAmount<\/span><span class=\"token punctuation\">(<\/span>application<span class=\"token punctuation\">.<\/span><span class=\"token function\">getAmount<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        loanAccount<span class=\"token punctuation\">.<\/span><span class=\"token function\">setInterestAccrued<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">BigDecimal<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">ZERO<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        loanAccount<span class=\"token punctuation\">.<\/span><span class=\"token function\">setInterestRate<\/span><span class=\"token punctuation\">(<\/span>application<span class=\"token punctuation\">.<\/span><span class=\"token function\">getInterestRate<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        loanAccount<span class=\"token punctuation\">.<\/span><span class=\"token function\">setStartDate<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">LocalDate<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">now<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        loanAccount<span class=\"token punctuation\">.<\/span><span class=\"token function\">setMaturityDate<\/span><span class=\"token punctuation\">(<\/span>application<span class=\"token punctuation\">.<\/span><span class=\"token function\">getMaturityDate<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        loanAccount<span class=\"token punctuation\">.<\/span><span class=\"token function\">setStatus<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">LoanAccountStatus<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">ACTIVE<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token class-name\">LoanAccount<\/span> savedAccount <span class=\"token operator\">&#061;<\/span> loanAccountRepository<span class=\"token punctuation\">.<\/span><span class=\"token function\">save<\/span><span class=\"token punctuation\">(<\/span>loanAccount<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u4fdd\u5b58\u8fd8\u6b3e\u8ba1\u5212<\/span><br \/>\n        repaymentSchedules<span class=\"token punctuation\">.<\/span><span class=\"token function\">forEach<\/span><span class=\"token punctuation\">(<\/span>schedule <span class=\"token operator\">-&gt;<\/span> schedule<span class=\"token punctuation\">.<\/span><span class=\"token function\">setLoanAccountNo<\/span><span class=\"token punctuation\">(<\/span>savedAccount<span class=\"token punctuation\">.<\/span><span class=\"token function\">getLoanAccountNo<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        repaymentRepository<span class=\"token punctuation\">.<\/span><span class=\"token function\">saveAll<\/span><span class=\"token punctuation\">(<\/span>repaymentSchedules<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u53d1\u653e\u8d37\u6b3e\u8d44\u91d1<\/span><br \/>\n        transactionService<span class=\"token punctuation\">.<\/span><span class=\"token function\">deposit<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                application<span class=\"token punctuation\">.<\/span><span class=\"token function\">getAccountNumber<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                application<span class=\"token punctuation\">.<\/span><span class=\"token function\">getAmount<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                <span class=\"token string\">&#034;Loan disbursement for &#034;<\/span> <span class=\"token operator\">&#043;<\/span> savedAccount<span class=\"token punctuation\">.<\/span><span class=\"token function\">getLoanAccountNo<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        log<span class=\"token punctuation\">.<\/span><span class=\"token function\">info<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;Loan account created: {}&#034;<\/span><span class=\"token punctuation\">,<\/span> savedAccount<span class=\"token punctuation\">.<\/span><span class=\"token function\">getLoanAccountNo<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">return<\/span> <span class=\"token function\">convertToDTO<\/span><span class=\"token punctuation\">(<\/span>savedAccount<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Transactional<\/span><br \/>\n    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">RepaymentDTO<\/span> <span class=\"token function\">makeRepayment<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">String<\/span> loanAccountNo<span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">RepaymentRequest<\/span> request<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token class-name\">LoanAccount<\/span> loanAccount <span class=\"token operator\">&#061;<\/span> loanAccountRepository<span class=\"token punctuation\">.<\/span><span class=\"token function\">findByLoanAccountNoForUpdate<\/span><span class=\"token punctuation\">(<\/span>loanAccountNo<span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">orElseThrow<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">-&gt;<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">AccountException<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">ErrorCode<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">LOAN_ACCOUNT_NOT_FOUND<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>loanAccount<span class=\"token punctuation\">.<\/span><span class=\"token function\">getStatus<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">!&#061;<\/span> <span class=\"token class-name\">LoanAccountStatus<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">ACTIVE<\/span> <span class=\"token operator\">&amp;&amp;<\/span><br \/>\n            loanAccount<span class=\"token punctuation\">.<\/span><span class=\"token function\">getStatus<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">!&#061;<\/span> <span class=\"token class-name\">LoanAccountStatus<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">DELINQUENT<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">throw<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">AccountException<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">ErrorCode<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">LOAN_ACCOUNT_NOT_ACTIVE<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u67e5\u627e\u5230\u671f\u7684\u8fd8\u6b3e\u8ba1\u5212<\/span><br \/>\n        <span class=\"token class-name\">List<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">RepaymentSchedule<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> dueInstallments <span class=\"token operator\">&#061;<\/span> repaymentRepository<br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">findDueInstallments<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                        loanAccountNo<span class=\"token punctuation\">,<\/span><br \/>\n                        <span class=\"token class-name\">LocalDate<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">now<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                        <span class=\"token class-name\">List<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">of<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">RepaymentStatus<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">PENDING<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">RepaymentStatus<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">OVERDUE<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>dueInstallments<span class=\"token punctuation\">.<\/span><span class=\"token function\">isEmpty<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">throw<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">AccountException<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">ErrorCode<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">NO_DUE_INSTALLMENTS<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u5904\u7406\u8fd8\u6b3e<\/span><br \/>\n        <span class=\"token class-name\">BigDecimal<\/span> remainingAmount <span class=\"token operator\">&#061;<\/span> request<span class=\"token punctuation\">.<\/span><span class=\"token function\">getAmount<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token keyword\">for<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token class-name\">RepaymentSchedule<\/span> installment <span class=\"token operator\">:<\/span> dueInstallments<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>remainingAmount<span class=\"token punctuation\">.<\/span><span class=\"token function\">compareTo<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">BigDecimal<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">ZERO<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&lt;&#061;<\/span> <span class=\"token number\">0<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                <span class=\"token keyword\">break<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><\/p>\n<p>            <span class=\"token class-name\">BigDecimal<\/span> amountToPay <span class=\"token operator\">&#061;<\/span> installment<span class=\"token punctuation\">.<\/span><span class=\"token function\">getTotalAmount<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">subtract<\/span><span class=\"token punctuation\">(<\/span>installment<span class=\"token punctuation\">.<\/span><span class=\"token function\">getPaidAmount<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">!&#061;<\/span> <span class=\"token keyword\">null<\/span> <span class=\"token operator\">?<\/span><br \/>\n                    installment<span class=\"token punctuation\">.<\/span><span class=\"token function\">getPaidAmount<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">:<\/span> <span class=\"token class-name\">BigDecimal<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">ZERO<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            <span class=\"token class-name\">BigDecimal<\/span> paymentAmount <span class=\"token operator\">&#061;<\/span> remainingAmount<span class=\"token punctuation\">.<\/span><span class=\"token function\">compareTo<\/span><span class=\"token punctuation\">(<\/span>amountToPay<span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&gt;&#061;<\/span> <span class=\"token number\">0<\/span> <span class=\"token operator\">?<\/span><br \/>\n                    amountToPay <span class=\"token operator\">:<\/span> remainingAmount<span class=\"token punctuation\">;<\/span><\/p>\n<p>            <span class=\"token comment\">\/\/ \u8bb0\u5f55\u8fd8\u6b3e<\/span><br \/>\n            installment<span class=\"token punctuation\">.<\/span><span class=\"token function\">setPaidAmount<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">(<\/span>installment<span class=\"token punctuation\">.<\/span><span class=\"token function\">getPaidAmount<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">!&#061;<\/span> <span class=\"token keyword\">null<\/span> <span class=\"token operator\">?<\/span><br \/>\n                    installment<span class=\"token punctuation\">.<\/span><span class=\"token function\">getPaidAmount<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">:<\/span> <span class=\"token class-name\">BigDecimal<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">ZERO<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">add<\/span><span class=\"token punctuation\">(<\/span>paymentAmount<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>            <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>installment<span class=\"token punctuation\">.<\/span><span class=\"token function\">getPaidAmount<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">compareTo<\/span><span class=\"token punctuation\">(<\/span>installment<span class=\"token punctuation\">.<\/span><span class=\"token function\">getTotalAmount<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&gt;&#061;<\/span> <span class=\"token number\">0<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                installment<span class=\"token punctuation\">.<\/span><span class=\"token function\">setStatus<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">RepaymentStatus<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">PAID<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n                installment<span class=\"token punctuation\">.<\/span><span class=\"token function\">setPaidDate<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">LocalDate<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">now<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">else<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                installment<span class=\"token punctuation\">.<\/span><span class=\"token function\">setStatus<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">RepaymentStatus<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">PARTIALLY_PAID<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><\/p>\n<p>            repaymentRepository<span class=\"token punctuation\">.<\/span><span class=\"token function\">save<\/span><span class=\"token punctuation\">(<\/span>installment<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            remainingAmount <span class=\"token operator\">&#061;<\/span> remainingAmount<span class=\"token punctuation\">.<\/span><span class=\"token function\">subtract<\/span><span class=\"token punctuation\">(<\/span>paymentAmount<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>            <span class=\"token comment\">\/\/ \u66f4\u65b0\u8d37\u6b3e\u8d26\u6237\u4f59\u989d<\/span><br \/>\n            <span class=\"token class-name\">BigDecimal<\/span> principalPaid <span class=\"token operator\">&#061;<\/span> paymentAmount<span class=\"token punctuation\">.<\/span><span class=\"token function\">multiply<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                    installment<span class=\"token punctuation\">.<\/span><span class=\"token function\">getPrincipalAmount<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">divide<\/span><span class=\"token punctuation\">(<\/span>installment<span class=\"token punctuation\">.<\/span><span class=\"token function\">getTotalAmount<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token number\">4<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">BigDecimal<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">ROUND_HALF_UP<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>            loanAccount<span class=\"token punctuation\">.<\/span><span class=\"token function\">setOutstandingAmount<\/span><span class=\"token punctuation\">(<\/span>loanAccount<span class=\"token punctuation\">.<\/span><span class=\"token function\">getOutstandingAmount<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">subtract<\/span><span class=\"token punctuation\">(<\/span>principalPaid<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            loanAccount<span class=\"token punctuation\">.<\/span><span class=\"token function\">setInterestAccrued<\/span><span class=\"token punctuation\">(<\/span>loanAccount<span class=\"token punctuation\">.<\/span><span class=\"token function\">getInterestAccrued<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">subtract<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                    paymentAmount<span class=\"token punctuation\">.<\/span><span class=\"token function\">subtract<\/span><span class=\"token punctuation\">(<\/span>principalPaid<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u4fdd\u5b58\u8d37\u6b3e\u8d26\u6237\u66f4\u65b0<\/span><br \/>\n        loanAccountRepository<span class=\"token punctuation\">.<\/span><span class=\"token function\">save<\/span><span class=\"token punctuation\">(<\/span>loanAccount<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u8bb0\u5f55\u4ea4\u6613<\/span><br \/>\n        transactionService<span class=\"token punctuation\">.<\/span><span class=\"token function\">withdraw<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                loanAccount<span class=\"token punctuation\">.<\/span><span class=\"token function\">getAccountNumber<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                request<span class=\"token punctuation\">.<\/span><span class=\"token function\">getAmount<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                <span class=\"token string\">&#034;Loan repayment for &#034;<\/span> <span class=\"token operator\">&#043;<\/span> loanAccountNo <span class=\"token operator\">&#043;<\/span> <span class=\"token string\">&#034;, Ref: &#034;<\/span> <span class=\"token operator\">&#043;<\/span> request<span class=\"token punctuation\">.<\/span><span class=\"token function\">getTransactionReference<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        log<span class=\"token punctuation\">.<\/span><span class=\"token function\">info<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;Repayment received for loan account: {}, amount: {}&#034;<\/span><span class=\"token punctuation\">,<\/span> loanAccountNo<span class=\"token punctuation\">,<\/span> request<span class=\"token punctuation\">.<\/span><span class=\"token function\">getAmount<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">return<\/span> <span class=\"token function\">convertToDTO<\/span><span class=\"token punctuation\">(<\/span>dueInstallments<span class=\"token punctuation\">.<\/span><span class=\"token function\">get<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">0<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Scheduled<\/span><span class=\"token punctuation\">(<\/span>cron <span class=\"token operator\">&#061;<\/span> <span class=\"token string\">&#034;0 0 0 * * ?&#034;<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token comment\">\/\/ \u6bcf\u5929\u5348\u591c\u6267\u884c<\/span><br \/>\n    <span class=\"token keyword\">public<\/span> <span class=\"token keyword\">void<\/span> <span class=\"token function\">checkOverdueLoans<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token class-name\">LocalDate<\/span> today <span class=\"token operator\">&#061;<\/span> <span class=\"token class-name\">LocalDate<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">now<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token class-name\">List<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">LoanAccount<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> dueLoans <span class=\"token operator\">&#061;<\/span> loanAccountRepository<span class=\"token punctuation\">.<\/span><span class=\"token function\">findDueLoans<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                <span class=\"token class-name\">List<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">of<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">LoanAccountStatus<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">ACTIVE<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">LoanAccountStatus<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">DELINQUENT<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span> today<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        dueLoans<span class=\"token punctuation\">.<\/span><span class=\"token function\">forEach<\/span><span class=\"token punctuation\">(<\/span>loan <span class=\"token operator\">-&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">try<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                <span class=\"token function\">updateOverdueStatus<\/span><span class=\"token punctuation\">(<\/span>loan<span class=\"token punctuation\">.<\/span><span class=\"token function\">getLoanAccountNo<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span> today<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">catch<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token class-name\">Exception<\/span> e<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                log<span class=\"token punctuation\">.<\/span><span class=\"token function\">error<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;Failed to update overdue status for loan: &#034;<\/span> <span class=\"token operator\">&#043;<\/span> loan<span class=\"token punctuation\">.<\/span><span class=\"token function\">getLoanAccountNo<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span> e<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Transactional<\/span><br \/>\n    <span class=\"token keyword\">public<\/span> <span class=\"token keyword\">void<\/span> <span class=\"token function\">updateOverdueStatus<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">String<\/span> loanAccountNo<span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">LocalDate<\/span> asOfDate<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token class-name\">LoanAccount<\/span> loanAccount <span class=\"token operator\">&#061;<\/span> loanAccountRepository<span class=\"token punctuation\">.<\/span><span class=\"token function\">findByLoanAccountNoForUpdate<\/span><span class=\"token punctuation\">(<\/span>loanAccountNo<span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">orElseThrow<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">-&gt;<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">AccountException<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">ErrorCode<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">LOAN_ACCOUNT_NOT_FOUND<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u67e5\u627e\u903e\u671f\u7684\u8fd8\u6b3e\u8ba1\u5212<\/span><br \/>\n        <span class=\"token class-name\">List<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">RepaymentSchedule<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> overdueInstallments <span class=\"token operator\">&#061;<\/span> repaymentRepository<br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">findDueInstallments<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                        loanAccountNo<span class=\"token punctuation\">,<\/span><br \/>\n                        asOfDate<span class=\"token punctuation\">,<\/span><br \/>\n                        <span class=\"token class-name\">List<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">of<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">RepaymentStatus<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">PENDING<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token operator\">!<\/span>overdueInstallments<span class=\"token punctuation\">.<\/span><span class=\"token function\">isEmpty<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            overdueInstallments<span class=\"token punctuation\">.<\/span><span class=\"token function\">forEach<\/span><span class=\"token punctuation\">(<\/span>installment <span class=\"token operator\">-&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                installment<span class=\"token punctuation\">.<\/span><span class=\"token function\">setStatus<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">RepaymentStatus<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">OVERDUE<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n                repaymentRepository<span class=\"token punctuation\">.<\/span><span class=\"token function\">save<\/span><span class=\"token punctuation\">(<\/span>installment<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>            loanAccount<span class=\"token punctuation\">.<\/span><span class=\"token function\">setStatus<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">LoanAccountStatus<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">DELINQUENT<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            loanAccountRepository<span class=\"token punctuation\">.<\/span><span class=\"token function\">save<\/span><span class=\"token punctuation\">(<\/span>loanAccount<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>            log<span class=\"token punctuation\">.<\/span><span class=\"token function\">info<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;Loan account marked as delinquent: {}&#034;<\/span><span class=\"token punctuation\">,<\/span> loanAccountNo<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">List<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">RepaymentSchedule<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> <span class=\"token function\">generateRepaymentSchedule<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">LoanApplication<\/span> application<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token comment\">\/\/ \u7b80\u5316\u5904\u7406&#xff0c;\u751f\u6210\u7b49\u989d\u672c\u606f\u8fd8\u6b3e\u8ba1\u5212<\/span><br \/>\n        <span class=\"token class-name\">BigDecimal<\/span> monthlyRate <span class=\"token operator\">&#061;<\/span> application<span class=\"token punctuation\">.<\/span><span class=\"token function\">getInterestRate<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">divide<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">BigDecimal<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">valueOf<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">12<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token number\">6<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">BigDecimal<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">ROUND_HALF_UP<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token class-name\">BigDecimal<\/span> monthlyPayment <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">calculateMonthlyPayment<\/span><span class=\"token punctuation\">(<\/span>application<span class=\"token punctuation\">.<\/span><span class=\"token function\">getAmount<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span> monthlyRate<span class=\"token punctuation\">,<\/span> application<span class=\"token punctuation\">.<\/span><span class=\"token function\">getTerm<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token class-name\">LocalDate<\/span> paymentDate <span class=\"token operator\">&#061;<\/span> <span class=\"token class-name\">LocalDate<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">now<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">plusMonths<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">1<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token class-name\">BigDecimal<\/span> remainingPrincipal <span class=\"token operator\">&#061;<\/span> application<span class=\"token punctuation\">.<\/span><span class=\"token function\">getAmount<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token class-name\">List<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">RepaymentSchedule<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> schedules <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">ArrayList<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">for<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token keyword\">int<\/span> i <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">1<\/span><span class=\"token punctuation\">;<\/span> i <span class=\"token operator\">&lt;&#061;<\/span> application<span class=\"token punctuation\">.<\/span><span class=\"token function\">getTerm<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span> i<span class=\"token operator\">&#043;&#043;<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token class-name\">BigDecimal<\/span> interest <span class=\"token operator\">&#061;<\/span> remainingPrincipal<span class=\"token punctuation\">.<\/span><span class=\"token function\">multiply<\/span><span class=\"token punctuation\">(<\/span>monthlyRate<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            <span class=\"token class-name\">BigDecimal<\/span> principal <span class=\"token operator\">&#061;<\/span> monthlyPayment<span class=\"token punctuation\">.<\/span><span class=\"token function\">subtract<\/span><span class=\"token punctuation\">(<\/span>interest<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>            <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>i <span class=\"token operator\">&#061;&#061;<\/span> application<span class=\"token punctuation\">.<\/span><span class=\"token function\">getTerm<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                principal <span class=\"token operator\">&#061;<\/span> remainingPrincipal<span class=\"token punctuation\">;<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><\/p>\n<p>            <span class=\"token class-name\">RepaymentSchedule<\/span> schedule <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">RepaymentSchedule<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            schedule<span class=\"token punctuation\">.<\/span><span class=\"token function\">setInstallmentNo<\/span><span class=\"token punctuation\">(<\/span>i<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            schedule<span class=\"token punctuation\">.<\/span><span class=\"token function\">setDueDate<\/span><span class=\"token punctuation\">(<\/span>paymentDate<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            schedule<span class=\"token punctuation\">.<\/span><span class=\"token function\">setPrincipalAmount<\/span><span class=\"token punctuation\">(<\/span>principal<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            schedule<span class=\"token punctuation\">.<\/span><span class=\"token function\">setInterestAmount<\/span><span class=\"token punctuation\">(<\/span>interest<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            schedule<span class=\"token punctuation\">.<\/span><span class=\"token function\">setTotalAmount<\/span><span class=\"token punctuation\">(<\/span>principal<span class=\"token punctuation\">.<\/span><span class=\"token function\">add<\/span><span class=\"token punctuation\">(<\/span>interest<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            schedule<span class=\"token punctuation\">.<\/span><span class=\"token function\">setOutstandingPrincipal<\/span><span class=\"token punctuation\">(<\/span>remainingPrincipal<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            schedule<span class=\"token punctuation\">.<\/span><span class=\"token function\">setStatus<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">RepaymentStatus<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">PENDING<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>            schedules<span class=\"token punctuation\">.<\/span><span class=\"token function\">add<\/span><span class=\"token punctuation\">(<\/span>schedule<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>            remainingPrincipal <span class=\"token operator\">&#061;<\/span> remainingPrincipal<span class=\"token punctuation\">.<\/span><span class=\"token function\">subtract<\/span><span class=\"token punctuation\">(<\/span>principal<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            paymentDate <span class=\"token operator\">&#061;<\/span> paymentDate<span class=\"token punctuation\">.<\/span><span class=\"token function\">plusMonths<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">1<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><\/p>\n<p>        <span class=\"token keyword\">return<\/span> schedules<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">BigDecimal<\/span> <span class=\"token function\">calculateMonthlyPayment<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">BigDecimal<\/span> principal<span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">BigDecimal<\/span> monthlyRate<span class=\"token punctuation\">,<\/span> <span class=\"token keyword\">int<\/span> term<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token comment\">\/\/ \u7b49\u989d\u672c\u606f\u8ba1\u7b97\u516c\u5f0f<\/span><br \/>\n        <span class=\"token class-name\">BigDecimal<\/span> temp <span class=\"token operator\">&#061;<\/span> <span class=\"token class-name\">BigDecimal<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">ONE<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">add<\/span><span class=\"token punctuation\">(<\/span>monthlyRate<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">pow<\/span><span class=\"token punctuation\">(<\/span>term<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> principal<span class=\"token punctuation\">.<\/span><span class=\"token function\">multiply<\/span><span class=\"token punctuation\">(<\/span>monthlyRate<span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">multiply<\/span><span class=\"token punctuation\">(<\/span>temp<span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">divide<\/span><span class=\"token punctuation\">(<\/span>temp<span class=\"token punctuation\">.<\/span><span class=\"token function\">subtract<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">BigDecimal<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">ONE<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token number\">2<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">BigDecimal<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">ROUND_HALF_UP<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">LoanAccountDTO<\/span> <span class=\"token function\">convertToDTO<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">LoanAccount<\/span> loanAccount<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token class-name\">LoanAccountDTO<\/span> dto <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">LoanAccountDTO<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        dto<span class=\"token punctuation\">.<\/span><span class=\"token function\">setLoanAccountNo<\/span><span class=\"token punctuation\">(<\/span>loanAccount<span class=\"token punctuation\">.<\/span><span class=\"token function\">getLoanAccountNo<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        dto<span class=\"token punctuation\">.<\/span><span class=\"token function\">setApplicationNo<\/span><span class=\"token punctuation\">(<\/span>loanAccount<span class=\"token punctuation\">.<\/span><span class=\"token function\">getApplicationNo<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        dto<span class=\"token punctuation\">.<\/span><span class=\"token function\">setCustomerId<\/span><span class=\"token punctuation\">(<\/span>loanAccount<span class=\"token punctuation\">.<\/span><span class=\"token function\">getCustomerId<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        dto<span class=\"token punctuation\">.<\/span><span class=\"token function\">setAccountNumber<\/span><span class=\"token punctuation\">(<\/span>loanAccount<span class=\"token punctuation\">.<\/span><span class=\"token function\">getAccountNumber<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        dto<span class=\"token punctuation\">.<\/span><span class=\"token function\">setOriginalAmount<\/span><span class=\"token punctuation\">(<\/span>loanAccount<span class=\"token punctuation\">.<\/span><span class=\"token function\">getOriginalAmount<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        dto<span class=\"token punctuation\">.<\/span><span class=\"token function\">setOutstandingAmount<\/span><span class=\"token punctuation\">(<\/span>loanAccount<span class=\"token punctuation\">.<\/span><span class=\"token function\">getOutstandingAmount<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        dto<span class=\"token punctuation\">.<\/span><span class=\"token function\">setInterestAccrued<\/span><span class=\"token punctuation\">(<\/span>loanAccount<span class=\"token punctuation\">.<\/span><span class=\"token function\">getInterestAccrued<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        dto<span class=\"token punctuation\">.<\/span><span class=\"token function\">setInterestRate<\/span><span class=\"token punctuation\">(<\/span>loanAccount<span class=\"token punctuation\">.<\/span><span class=\"token function\">getInterestRate<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        dto<span class=\"token punctuation\">.<\/span><span class=\"token function\">setStartDate<\/span><span class=\"token punctuation\">(<\/span>loanAccount<span class=\"token punctuation\">.<\/span><span class=\"token function\">getStartDate<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        dto<span class=\"token punctuation\">.<\/span><span class=\"token function\">setMaturityDate<\/span><span class=\"token punctuation\">(<\/span>loanAccount<span class=\"token punctuation\">.<\/span><span class=\"token function\">getMaturityDate<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        dto<span class=\"token punctuation\">.<\/span><span class=\"token function\">setStatus<\/span><span class=\"token punctuation\">(<\/span>loanAccount<span class=\"token punctuation\">.<\/span><span class=\"token function\">getStatus<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> dto<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">RepaymentDTO<\/span> <span class=\"token function\">convertToDTO<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">RepaymentSchedule<\/span> schedule<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token class-name\">RepaymentDTO<\/span> dto <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">RepaymentDTO<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        dto<span class=\"token punctuation\">.<\/span><span class=\"token function\">setId<\/span><span class=\"token punctuation\">(<\/span>schedule<span class=\"token punctuation\">.<\/span><span class=\"token function\">getId<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        dto<span class=\"token punctuation\">.<\/span><span class=\"token function\">setLoanAccountNo<\/span><span class=\"token punctuation\">(<\/span>schedule<span class=\"token punctuation\">.<\/span><span class=\"token function\">getLoanAccountNo<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        dto<span class=\"token punctuation\">.<\/span><span class=\"token function\">setInstallmentNo<\/span><span class=\"token punctuation\">(<\/span>schedule<span class=\"token punctuation\">.<\/span><span class=\"token function\">getInstallmentNo<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        dto<span class=\"token punctuation\">.<\/span><span class=\"token function\">setDueDate<\/span><span class=\"token punctuation\">(<\/span>schedule<span class=\"token punctuation\">.<\/span><span class=\"token function\">getDueDate<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        dto<span class=\"token punctuation\">.<\/span><span class=\"token function\">setPrincipalAmount<\/span><span class=\"token punctuation\">(<\/span>schedule<span class=\"token punctuation\">.<\/span><span class=\"token function\">getPrincipalAmount<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        dto<span class=\"token punctuation\">.<\/span><span class=\"token function\">setInterestAmount<\/span><span class=\"token punctuation\">(<\/span>schedule<span class=\"token punctuation\">.<\/span><span class=\"token function\">getInterestAmount<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        dto<span class=\"token punctuation\">.<\/span><span class=\"token function\">setTotalAmount<\/span><span class=\"token punctuation\">(<\/span>schedule<span class=\"token punctuation\">.<\/span><span class=\"token function\">getTotalAmount<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        dto<span class=\"token punctuation\">.<\/span><span class=\"token function\">setOutstandingPrincipal<\/span><span class=\"token punctuation\">(<\/span>schedule<span class=\"token punctuation\">.<\/span><span class=\"token function\">getOutstandingPrincipal<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        dto<span class=\"token punctuation\">.<\/span><span class=\"token function\">setStatus<\/span><span class=\"token punctuation\">(<\/span>schedule<span class=\"token punctuation\">.<\/span><span class=\"token function\">getStatus<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        dto<span class=\"token punctuation\">.<\/span><span class=\"token function\">setPaidDate<\/span><span class=\"token punctuation\">(<\/span>schedule<span class=\"token punctuation\">.<\/span><span class=\"token function\">getPaidDate<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        dto<span class=\"token punctuation\">.<\/span><span class=\"token function\">setPaidAmount<\/span><span class=\"token punctuation\">(<\/span>schedule<span class=\"token punctuation\">.<\/span><span class=\"token function\">getPaidAmount<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> dto<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p>Repository\u5c42<\/p>\n<p><span class=\"token keyword\">public<\/span> <span class=\"token keyword\">interface<\/span> <span class=\"token class-name\">LoanApplicationRepository<\/span> <span class=\"token keyword\">extends<\/span> <span class=\"token class-name\">JpaRepository<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">LoanApplication<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">Long<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token class-name\">Optional<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">LoanApplication<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> <span class=\"token function\">findByApplicationNo<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">String<\/span> applicationNo<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token class-name\">List<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">LoanApplication<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> <span class=\"token function\">findByCustomerId<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">Long<\/span> customerId<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token class-name\">List<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">LoanApplication<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> <span class=\"token function\">findByStatus<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">LoanStatus<\/span> status<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Query<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;SELECT la FROM LoanApplication la WHERE la.status &#061; :status AND la.disbursementDate &lt;&#061; :date&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token class-name\">List<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">LoanApplication<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> <span class=\"token function\">findPendingDisbursement<\/span><span class=\"token punctuation\">(<\/span><span class=\"token annotation punctuation\">&#064;Param<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;status&#034;<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token class-name\">LoanStatus<\/span> status<span class=\"token punctuation\">,<\/span><br \/>\n                                                <span class=\"token annotation punctuation\">&#064;Param<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;date&#034;<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token class-name\">LocalDate<\/span> date<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token keyword\">public<\/span> <span class=\"token keyword\">interface<\/span> <span class=\"token class-name\">LoanAccountRepository<\/span> <span class=\"token keyword\">extends<\/span> <span class=\"token class-name\">JpaRepository<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">LoanAccount<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">Long<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token class-name\">Optional<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">LoanAccount<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> <span class=\"token function\">findByLoanAccountNo<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">String<\/span> loanAccountNo<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token class-name\">List<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">LoanAccount<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> <span class=\"token function\">findByCustomerId<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">Long<\/span> customerId<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token class-name\">List<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">LoanAccount<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> <span class=\"token function\">findByStatus<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">LoanAccountStatus<\/span> status<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Lock<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">LockModeType<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">PESSIMISTIC_WRITE<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token annotation punctuation\">&#064;Query<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;SELECT la FROM LoanAccount la WHERE la.loanAccountNo &#061; :loanAccountNo&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token class-name\">Optional<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">LoanAccount<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> <span class=\"token function\">findByLoanAccountNoForUpdate<\/span><span class=\"token punctuation\">(<\/span><span class=\"token annotation punctuation\">&#064;Param<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;loanAccountNo&#034;<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token class-name\">String<\/span> loanAccountNo<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Query<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;SELECT la FROM LoanAccount la WHERE la.status IN :statuses AND la.maturityDate &lt;&#061; :date&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token class-name\">List<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">LoanAccount<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> <span class=\"token function\">findDueLoans<\/span><span class=\"token punctuation\">(<\/span><span class=\"token annotation punctuation\">&#064;Param<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;statuses&#034;<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token class-name\">List<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">LoanAccountStatus<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> statuses<span class=\"token punctuation\">,<\/span><br \/>\n                                 <span class=\"token annotation punctuation\">&#064;Param<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;date&#034;<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token class-name\">LocalDate<\/span> date<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token keyword\">public<\/span> <span class=\"token keyword\">interface<\/span> <span class=\"token class-name\">RepaymentScheduleRepository<\/span> <span class=\"token keyword\">extends<\/span> <span class=\"token class-name\">JpaRepository<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">RepaymentSchedule<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">Long<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token class-name\">List<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">RepaymentSchedule<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> <span class=\"token function\">findByLoanAccountNo<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">String<\/span> loanAccountNo<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token class-name\">List<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">RepaymentSchedule<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> <span class=\"token function\">findByLoanAccountNoAndStatus<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">String<\/span> loanAccountNo<span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">RepaymentStatus<\/span> status<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Lock<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">LockModeType<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">PESSIMISTIC_WRITE<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token annotation punctuation\">&#064;Query<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;SELECT rs FROM RepaymentSchedule rs WHERE rs.id &#061; :id&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token class-name\">Optional<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">RepaymentSchedule<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> <span class=\"token function\">findByIdForUpdate<\/span><span class=\"token punctuation\">(<\/span><span class=\"token annotation punctuation\">&#064;Param<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;id&#034;<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token class-name\">Long<\/span> id<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Query<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;SELECT rs FROM RepaymentSchedule rs WHERE rs.loanAccountNo &#061; :loanAccountNo AND rs.dueDate &lt;&#061; :date AND rs.status IN :statuses&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token class-name\">List<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">RepaymentSchedule<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> <span class=\"token function\">findDueInstallments<\/span><span class=\"token punctuation\">(<\/span><span class=\"token annotation punctuation\">&#064;Param<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;loanAccountNo&#034;<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token class-name\">String<\/span> loanAccountNo<span class=\"token punctuation\">,<\/span><br \/>\n                                              <span class=\"token annotation punctuation\">&#064;Param<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;date&#034;<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token class-name\">LocalDate<\/span> date<span class=\"token punctuation\">,<\/span><br \/>\n                                              <span class=\"token annotation punctuation\">&#064;Param<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;statuses&#034;<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token class-name\">List<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">RepaymentStatus<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> statuses<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token keyword\">public<\/span> <span class=\"token keyword\">interface<\/span> <span class=\"token class-name\">LoanProductRepository<\/span> <span class=\"token keyword\">extends<\/span> <span class=\"token class-name\">JpaRepository<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">LoanProduct<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">Long<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token class-name\">Optional<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">LoanProduct<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> <span class=\"token function\">findByProductCode<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">String<\/span> productCode<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token class-name\">List<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">LoanProduct<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> <span class=\"token function\">findByLoanType<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">LoanType<\/span> loanType<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token class-name\">List<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">LoanProduct<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> <span class=\"token function\">findByActiveTrue<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p>5. \u5ba2\u6237\u5173\u7cfb\u7ba1\u7406&#xff08;CRM&#xff09;<\/p>\n<p>\u5ba2\u6237\u4fe1\u606f\u7ba1\u7406<\/p>\n<p>\u5ba2\u6237\u5206\u7ea7<\/p>\n<p>\u5ba2\u6237\u884c\u4e3a\u5206\u6790<\/p>\n<p>\u5ba2\u6237\u670d\u52a1\u8bb0\u5f55<\/p>\n<p><span class=\"token comment\"># \u5728\u539f\u6709\u914d\u7f6e\u57fa\u7840\u4e0a\u6dfb\u52a0<\/span><br \/>\n<span class=\"token key atrule\">crm<\/span><span class=\"token punctuation\">:<\/span><br \/>\n  <span class=\"token key atrule\">customer<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    <span class=\"token key atrule\">tier-review-interval<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token number\">180<\/span> <span class=\"token comment\"># \u5ba2\u6237\u7b49\u7ea7\u8bc4\u5ba1\u95f4\u9694\u5929\u6570<\/span><br \/>\n  <span class=\"token key atrule\">encryption<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    <span class=\"token key atrule\">enabled<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token boolean important\">true<\/span><\/p>\n<p><span class=\"token annotation punctuation\">&#064;Entity<\/span><br \/>\n<span class=\"token annotation punctuation\">&#064;Table<\/span><span class=\"token punctuation\">(<\/span>name <span class=\"token operator\">&#061;<\/span> <span class=\"token string\">&#034;customer&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n<span class=\"token annotation punctuation\">&#064;Data<\/span><br \/>\n<span class=\"token keyword\">public<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token class-name\">Customer<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token annotation punctuation\">&#064;Id<\/span><br \/>\n    <span class=\"token annotation punctuation\">&#064;GeneratedValue<\/span><span class=\"token punctuation\">(<\/span>strategy <span class=\"token operator\">&#061;<\/span> <span class=\"token class-name\">GenerationType<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">IDENTITY<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">Long<\/span> id<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>nullable <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">,<\/span> unique <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">true<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> customerId<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>nullable <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> firstName<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>nullable <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> lastName<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>nullable <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">,<\/span> unique <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">true<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> idNumber<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>nullable <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">LocalDate<\/span> dateOfBirth<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>nullable <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> email<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>nullable <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> phone<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>nullable <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> address<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Enumerated<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">EnumType<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">STRING<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>nullable <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">CustomerTier<\/span> tier<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Enumerated<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">EnumType<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">STRING<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>nullable <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">CustomerStatus<\/span> status<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>nullable <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">,<\/span> precision <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">19<\/span><span class=\"token punctuation\">,<\/span> scale <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">4<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">BigDecimal<\/span> creditScore<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">LocalDate<\/span> lastReviewDate<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;CreationTimestamp<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">LocalDateTime<\/span> createdAt<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;UpdateTimestamp<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">LocalDateTime<\/span> updatedAt<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Version<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">Long<\/span> version<span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token annotation punctuation\">&#064;Entity<\/span><br \/>\n<span class=\"token annotation punctuation\">&#064;Table<\/span><span class=\"token punctuation\">(<\/span>name <span class=\"token operator\">&#061;<\/span> <span class=\"token string\">&#034;customer_interaction&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n<span class=\"token annotation punctuation\">&#064;Data<\/span><br \/>\n<span class=\"token keyword\">public<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token class-name\">CustomerInteraction<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token annotation punctuation\">&#064;Id<\/span><br \/>\n    <span class=\"token annotation punctuation\">&#064;GeneratedValue<\/span><span class=\"token punctuation\">(<\/span>strategy <span class=\"token operator\">&#061;<\/span> <span class=\"token class-name\">GenerationType<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">IDENTITY<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">Long<\/span> id<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>nullable <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">Long<\/span> customerId<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Enumerated<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">EnumType<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">STRING<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>nullable <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">InteractionType<\/span> type<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>nullable <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> description<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">Long<\/span> relatedAccountId<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> notes<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>nullable <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">Long<\/span> employeeId<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;CreationTimestamp<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">LocalDateTime<\/span> createdAt<span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token annotation punctuation\">&#064;Entity<\/span><br \/>\n<span class=\"token annotation punctuation\">&#064;Table<\/span><span class=\"token punctuation\">(<\/span>name <span class=\"token operator\">&#061;<\/span> <span class=\"token string\">&#034;customer_preference&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n<span class=\"token annotation punctuation\">&#064;Data<\/span><br \/>\n<span class=\"token keyword\">public<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token class-name\">CustomerPreference<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token annotation punctuation\">&#064;Id<\/span><br \/>\n    <span class=\"token annotation punctuation\">&#064;GeneratedValue<\/span><span class=\"token punctuation\">(<\/span>strategy <span class=\"token operator\">&#061;<\/span> <span class=\"token class-name\">GenerationType<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">IDENTITY<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">Long<\/span> id<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>nullable <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">Long<\/span> customerId<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>nullable <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> preferenceType<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>nullable <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> preferenceValue<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">Boolean<\/span> isActive <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">true<\/span><span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token annotation punctuation\">&#064;Entity<\/span><br \/>\n<span class=\"token annotation punctuation\">&#064;Table<\/span><span class=\"token punctuation\">(<\/span>name <span class=\"token operator\">&#061;<\/span> <span class=\"token string\">&#034;customer_segment&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n<span class=\"token annotation punctuation\">&#064;Data<\/span><br \/>\n<span class=\"token keyword\">public<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token class-name\">CustomerSegment<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token annotation punctuation\">&#064;Id<\/span><br \/>\n    <span class=\"token annotation punctuation\">&#064;GeneratedValue<\/span><span class=\"token punctuation\">(<\/span>strategy <span class=\"token operator\">&#061;<\/span> <span class=\"token class-name\">GenerationType<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">IDENTITY<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">Long<\/span> id<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>nullable <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">,<\/span> unique <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">true<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> segmentCode<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>nullable <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> segmentName<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> description<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>nullable <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">BigDecimal<\/span> minValueScore<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>nullable <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">BigDecimal<\/span> maxValueScore<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>nullable <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">Boolean<\/span> isActive <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">true<\/span><span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token keyword\">public<\/span> <span class=\"token keyword\">enum<\/span> <span class=\"token class-name\">CustomerTier<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token constant\">BASIC<\/span><span class=\"token punctuation\">,<\/span>      <span class=\"token comment\">\/\/ \u57fa\u7840\u5ba2\u6237<\/span><br \/>\n    <span class=\"token constant\">SILVER<\/span><span class=\"token punctuation\">,<\/span>     <span class=\"token comment\">\/\/ \u94f6\u724c\u5ba2\u6237<\/span><br \/>\n    <span class=\"token constant\">GOLD<\/span><span class=\"token punctuation\">,<\/span>       <span class=\"token comment\">\/\/ \u91d1\u724c\u5ba2\u6237<\/span><br \/>\n    <span class=\"token constant\">PLATINUM<\/span><span class=\"token punctuation\">,<\/span>   <span class=\"token comment\">\/\/ \u767d\u91d1\u5ba2\u6237<\/span><br \/>\n    <span class=\"token constant\">DIAMOND<\/span>     <span class=\"token comment\">\/\/ \u94bb\u77f3\u5ba2\u6237<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token keyword\">public<\/span> <span class=\"token keyword\">enum<\/span> <span class=\"token class-name\">CustomerStatus<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token constant\">ACTIVE<\/span><span class=\"token punctuation\">,<\/span>         <span class=\"token comment\">\/\/ \u6d3b\u8dc3<\/span><br \/>\n    <span class=\"token constant\">INACTIVE<\/span><span class=\"token punctuation\">,<\/span>       <span class=\"token comment\">\/\/ \u4e0d\u6d3b\u8dc3<\/span><br \/>\n    <span class=\"token constant\">SUSPENDED<\/span><span class=\"token punctuation\">,<\/span>      <span class=\"token comment\">\/\/ \u6682\u505c<\/span><br \/>\n    <span class=\"token constant\">BLACKLISTED<\/span><span class=\"token punctuation\">,<\/span>    <span class=\"token comment\">\/\/ \u9ed1\u540d\u5355<\/span><br \/>\n    <span class=\"token constant\">CLOSED<\/span>          <span class=\"token comment\">\/\/ \u5df2\u5173\u95ed<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token keyword\">public<\/span> <span class=\"token keyword\">enum<\/span> <span class=\"token class-name\">InteractionType<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token constant\">PHONE_CALL<\/span><span class=\"token punctuation\">,<\/span>     <span class=\"token comment\">\/\/ \u7535\u8bdd<\/span><br \/>\n    <span class=\"token constant\">EMAIL<\/span><span class=\"token punctuation\">,<\/span>          <span class=\"token comment\">\/\/ \u90ae\u4ef6<\/span><br \/>\n    <span class=\"token constant\">IN_PERSON<\/span><span class=\"token punctuation\">,<\/span>      <span class=\"token comment\">\/\/ \u9762\u8c08<\/span><br \/>\n    <span class=\"token constant\">CHAT<\/span><span class=\"token punctuation\">,<\/span>           <span class=\"token comment\">\/\/ \u5728\u7ebf\u804a\u5929<\/span><br \/>\n    <span class=\"token constant\">COMPLAINT<\/span><span class=\"token punctuation\">,<\/span>      <span class=\"token comment\">\/\/ \u6295\u8bc9<\/span><br \/>\n    <span class=\"token constant\">COMPLIMENT<\/span><span class=\"token punctuation\">,<\/span>     <span class=\"token comment\">\/\/ \u8868\u626c<\/span><br \/>\n    <span class=\"token constant\">SERVICE_REQUEST<\/span> <span class=\"token comment\">\/\/ \u670d\u52a1\u8bf7\u6c42<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token annotation punctuation\">&#064;Data<\/span><br \/>\n<span class=\"token keyword\">public<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token class-name\">CustomerDTO<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">Long<\/span> id<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> customerId<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> firstName<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> lastName<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> idNumber<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">LocalDate<\/span> dateOfBirth<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> email<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> phone<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> address<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">CustomerTier<\/span> tier<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">CustomerStatus<\/span> status<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">BigDecimal<\/span> creditScore<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">LocalDate<\/span> lastReviewDate<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">LocalDateTime<\/span> createdAt<span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token annotation punctuation\">&#064;Data<\/span><br \/>\n<span class=\"token keyword\">public<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token class-name\">CustomerCreateRequest<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token annotation punctuation\">&#064;NotBlank<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> firstName<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;NotBlank<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> lastName<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;NotBlank<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> idNumber<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;NotNull<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">LocalDate<\/span> dateOfBirth<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Email<\/span><br \/>\n    <span class=\"token annotation punctuation\">&#064;NotBlank<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> email<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;NotBlank<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> phone<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;NotBlank<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> address<span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token annotation punctuation\">&#064;Data<\/span><br \/>\n<span class=\"token keyword\">public<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token class-name\">CustomerUpdateRequest<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token annotation punctuation\">&#064;NotBlank<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> firstName<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;NotBlank<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> lastName<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Email<\/span><br \/>\n    <span class=\"token annotation punctuation\">&#064;NotBlank<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> email<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;NotBlank<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> phone<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;NotBlank<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> address<span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token annotation punctuation\">&#064;Data<\/span><br \/>\n<span class=\"token keyword\">public<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token class-name\">CustomerInteractionDTO<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">Long<\/span> id<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">Long<\/span> customerId<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">InteractionType<\/span> type<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> description<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">Long<\/span> relatedAccountId<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> notes<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">Long<\/span> employeeId<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">LocalDateTime<\/span> createdAt<span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token annotation punctuation\">&#064;Data<\/span><br \/>\n<span class=\"token keyword\">public<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token class-name\">CustomerSegmentDTO<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">Long<\/span> id<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> segmentCode<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> segmentName<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> description<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">BigDecimal<\/span> minValueScore<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">BigDecimal<\/span> maxValueScore<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">Boolean<\/span> isActive<span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token annotation punctuation\">&#064;Data<\/span><br \/>\n<span class=\"token keyword\">public<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token class-name\">CustomerAnalysisDTO<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">Long<\/span> customerId<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> customerName<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">BigDecimal<\/span> totalAssets<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">BigDecimal<\/span> totalLiabilities<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">BigDecimal<\/span> netWorth<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">BigDecimal<\/span> monthlyIncome<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">BigDecimal<\/span> monthlyExpenses<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">BigDecimal<\/span> profitabilityScore<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">LocalDate<\/span> lastActivityDate<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">Integer<\/span> productCount<span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p>\u5de5\u5177<\/p>\n<p><span class=\"token annotation punctuation\">&#064;Component<\/span><br \/>\n<span class=\"token keyword\">public<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token class-name\">CustomerIdGenerator<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">static<\/span> <span class=\"token keyword\">final<\/span> <span class=\"token class-name\">String<\/span> <span class=\"token constant\">BANK_CODE<\/span> <span class=\"token operator\">&#061;<\/span> <span class=\"token string\">&#034;888&#034;<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">final<\/span> <span class=\"token class-name\">AtomicLong<\/span> sequence <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">AtomicLong<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">1<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">String<\/span> <span class=\"token function\">generate<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token class-name\">String<\/span> dateStr <span class=\"token operator\">&#061;<\/span> <span class=\"token class-name\">LocalDate<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">now<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">format<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">DateTimeFormatter<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">BASIC_ISO_DATE<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token keyword\">long<\/span> seq <span class=\"token operator\">&#061;<\/span> sequence<span class=\"token punctuation\">.<\/span><span class=\"token function\">getAndIncrement<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> <span class=\"token class-name\">String<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">format<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;%s-CUS-%s-%06d&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token constant\">BANK_CODE<\/span><span class=\"token punctuation\">,<\/span> dateStr<span class=\"token punctuation\">,<\/span> seq<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p>Controller\u5c42<\/p>\n<p><span class=\"token annotation punctuation\">&#064;RestController<\/span><br \/>\n<span class=\"token annotation punctuation\">&#064;RequestMapping<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;\/api\/customers&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n<span class=\"token annotation punctuation\">&#064;RequiredArgsConstructor<\/span><br \/>\n<span class=\"token keyword\">public<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token class-name\">CustomerController<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">final<\/span> <span class=\"token class-name\">CustomerService<\/span> customerService<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;PostMapping<\/span><br \/>\n    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">CustomerDTO<\/span> <span class=\"token function\">createCustomer<\/span><span class=\"token punctuation\">(<\/span><span class=\"token annotation punctuation\">&#064;Valid<\/span> <span class=\"token annotation punctuation\">&#064;RequestBody<\/span> <span class=\"token class-name\">CustomerCreateRequest<\/span> request<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> customerService<span class=\"token punctuation\">.<\/span><span class=\"token function\">createCustomer<\/span><span class=\"token punctuation\">(<\/span>request<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;PutMapping<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;\/{customerId}&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">CustomerDTO<\/span> <span class=\"token function\">updateCustomer<\/span><span class=\"token punctuation\">(<\/span><br \/>\n            <span class=\"token annotation punctuation\">&#064;PathVariable<\/span> <span class=\"token class-name\">String<\/span> customerId<span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token annotation punctuation\">&#064;Valid<\/span> <span class=\"token annotation punctuation\">&#064;RequestBody<\/span> <span class=\"token class-name\">CustomerUpdateRequest<\/span> request<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> customerService<span class=\"token punctuation\">.<\/span><span class=\"token function\">updateCustomer<\/span><span class=\"token punctuation\">(<\/span>customerId<span class=\"token punctuation\">,<\/span> request<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;GetMapping<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;\/{customerId}&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">CustomerDTO<\/span> <span class=\"token function\">getCustomer<\/span><span class=\"token punctuation\">(<\/span><span class=\"token annotation punctuation\">&#064;PathVariable<\/span> <span class=\"token class-name\">String<\/span> customerId<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> customerService<span class=\"token punctuation\">.<\/span><span class=\"token function\">getCustomer<\/span><span class=\"token punctuation\">(<\/span>customerId<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;GetMapping<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;\/tier\/{tier}&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">List<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">CustomerDTO<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> <span class=\"token function\">getCustomersByTier<\/span><span class=\"token punctuation\">(<\/span><span class=\"token annotation punctuation\">&#064;PathVariable<\/span> <span class=\"token class-name\">String<\/span> tier<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> customerService<span class=\"token punctuation\">.<\/span><span class=\"token function\">getCustomersByTier<\/span><span class=\"token punctuation\">(<\/span>tier<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;PutMapping<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;\/{customerId}\/tier\/{tier}&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token annotation punctuation\">&#064;PreAuthorize<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;hasAnyRole(&#039;MANAGER&#039;, &#039;ADMIN&#039;)&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">CustomerDTO<\/span> <span class=\"token function\">updateCustomerTier<\/span><span class=\"token punctuation\">(<\/span><br \/>\n            <span class=\"token annotation punctuation\">&#064;PathVariable<\/span> <span class=\"token class-name\">String<\/span> customerId<span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token annotation punctuation\">&#064;PathVariable<\/span> <span class=\"token class-name\">String<\/span> tier<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> customerService<span class=\"token punctuation\">.<\/span><span class=\"token function\">updateCustomerTier<\/span><span class=\"token punctuation\">(<\/span>customerId<span class=\"token punctuation\">,<\/span> tier<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;PutMapping<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;\/{customerId}\/status\/{status}&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token annotation punctuation\">&#064;PreAuthorize<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;hasAnyRole(&#039;MANAGER&#039;, &#039;ADMIN&#039;)&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">CustomerDTO<\/span> <span class=\"token function\">updateCustomerStatus<\/span><span class=\"token punctuation\">(<\/span><br \/>\n            <span class=\"token annotation punctuation\">&#064;PathVariable<\/span> <span class=\"token class-name\">String<\/span> customerId<span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token annotation punctuation\">&#064;PathVariable<\/span> <span class=\"token class-name\">String<\/span> status<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> customerService<span class=\"token punctuation\">.<\/span><span class=\"token function\">updateCustomerStatus<\/span><span class=\"token punctuation\">(<\/span>customerId<span class=\"token punctuation\">,<\/span> status<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;GetMapping<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;\/{customerId}\/analysis&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">CustomerAnalysisDTO<\/span> <span class=\"token function\">getCustomerAnalysis<\/span><span class=\"token punctuation\">(<\/span><span class=\"token annotation punctuation\">&#064;PathVariable<\/span> <span class=\"token class-name\">String<\/span> customerId<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> customerService<span class=\"token punctuation\">.<\/span><span class=\"token function\">getCustomerAnalysis<\/span><span class=\"token punctuation\">(<\/span>customerId<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token annotation punctuation\">&#064;RestController<\/span><br \/>\n<span class=\"token annotation punctuation\">&#064;RequestMapping<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;\/api\/customer-interactions&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n<span class=\"token annotation punctuation\">&#064;RequiredArgsConstructor<\/span><br \/>\n<span class=\"token keyword\">public<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token class-name\">CustomerInteractionController<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">final<\/span> <span class=\"token class-name\">CustomerInteractionService<\/span> interactionService<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;PostMapping<\/span><br \/>\n    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">CustomerInteractionDTO<\/span> <span class=\"token function\">recordInteraction<\/span><span class=\"token punctuation\">(<\/span><br \/>\n            <span class=\"token annotation punctuation\">&#064;RequestParam<\/span> <span class=\"token class-name\">String<\/span> customerId<span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token annotation punctuation\">&#064;RequestParam<\/span> <span class=\"token class-name\">InteractionType<\/span> type<span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token annotation punctuation\">&#064;RequestParam<\/span> <span class=\"token class-name\">String<\/span> description<span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token annotation punctuation\">&#064;RequestParam<\/span><span class=\"token punctuation\">(<\/span>required <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token class-name\">Long<\/span> relatedAccountId<span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token annotation punctuation\">&#064;RequestParam<\/span><span class=\"token punctuation\">(<\/span>required <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token class-name\">String<\/span> notes<span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token annotation punctuation\">&#064;RequestParam<\/span> <span class=\"token class-name\">Long<\/span> employeeId<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><\/p>\n<p>        <span class=\"token keyword\">return<\/span> interactionService<span class=\"token punctuation\">.<\/span><span class=\"token function\">recordInteraction<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                customerId<span class=\"token punctuation\">,<\/span> type<span class=\"token punctuation\">,<\/span> description<span class=\"token punctuation\">,<\/span> relatedAccountId<span class=\"token punctuation\">,<\/span> notes<span class=\"token punctuation\">,<\/span> employeeId<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;GetMapping<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;\/customer\/{customerId}&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">List<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">CustomerInteractionDTO<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> <span class=\"token function\">getCustomerInteractions<\/span><span class=\"token punctuation\">(<\/span><span class=\"token annotation punctuation\">&#064;PathVariable<\/span> <span class=\"token class-name\">String<\/span> customerId<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> interactionService<span class=\"token punctuation\">.<\/span><span class=\"token function\">getCustomerInteractions<\/span><span class=\"token punctuation\">(<\/span>customerId<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;GetMapping<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;\/employee\/{employeeId}&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">List<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">CustomerInteractionDTO<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> <span class=\"token function\">getEmployeeInteractions<\/span><span class=\"token punctuation\">(<\/span><br \/>\n            <span class=\"token annotation punctuation\">&#064;PathVariable<\/span> <span class=\"token class-name\">Long<\/span> employeeId<span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token annotation punctuation\">&#064;RequestParam<\/span> <span class=\"token annotation punctuation\">&#064;DateTimeFormat<\/span><span class=\"token punctuation\">(<\/span>iso <span class=\"token operator\">&#061;<\/span> <span class=\"token class-name\">DateTimeFormat<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">ISO<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">DATE_TIME<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token class-name\">LocalDateTime<\/span> start<span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token annotation punctuation\">&#064;RequestParam<\/span> <span class=\"token annotation punctuation\">&#064;DateTimeFormat<\/span><span class=\"token punctuation\">(<\/span>iso <span class=\"token operator\">&#061;<\/span> <span class=\"token class-name\">DateTimeFormat<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">ISO<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">DATE_TIME<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token class-name\">LocalDateTime<\/span> end<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><\/p>\n<p>        <span class=\"token keyword\">return<\/span> interactionService<span class=\"token punctuation\">.<\/span><span class=\"token function\">getEmployeeInteractions<\/span><span class=\"token punctuation\">(<\/span>employeeId<span class=\"token punctuation\">,<\/span> start<span class=\"token punctuation\">,<\/span> end<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p>Service\u5c42<\/p>\n<p><span class=\"token annotation punctuation\">&#064;Service<\/span><br \/>\n<span class=\"token annotation punctuation\">&#064;RequiredArgsConstructor<\/span><br \/>\n<span class=\"token annotation punctuation\">&#064;Slf4j<\/span><br \/>\n<span class=\"token keyword\">public<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token class-name\">CustomerService<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">final<\/span> <span class=\"token class-name\">CustomerRepository<\/span> customerRepository<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">final<\/span> <span class=\"token class-name\">CustomerIdGenerator<\/span> idGenerator<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">final<\/span> <span class=\"token class-name\">EncryptionUtil<\/span> encryptionUtil<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">final<\/span> <span class=\"token class-name\">CustomerAnalysisService<\/span> analysisService<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Transactional<\/span><br \/>\n    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">CustomerDTO<\/span> <span class=\"token function\">createCustomer<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">CustomerCreateRequest<\/span> request<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token comment\">\/\/ \u68c0\u67e5\u8eab\u4efd\u8bc1\u53f7\u662f\u5426\u5df2\u5b58\u5728<\/span><br \/>\n        <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>customerRepository<span class=\"token punctuation\">.<\/span><span class=\"token function\">findByIdNumber<\/span><span class=\"token punctuation\">(<\/span>request<span class=\"token punctuation\">.<\/span><span class=\"token function\">getIdNumber<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">isPresent<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">throw<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">AccountException<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">ErrorCode<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">CUSTOMER_ALREADY_EXISTS<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u521b\u5efa\u5ba2\u6237<\/span><br \/>\n        <span class=\"token class-name\">Customer<\/span> customer <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">Customer<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        customer<span class=\"token punctuation\">.<\/span><span class=\"token function\">setCustomerId<\/span><span class=\"token punctuation\">(<\/span>idGenerator<span class=\"token punctuation\">.<\/span><span class=\"token function\">generate<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        customer<span class=\"token punctuation\">.<\/span><span class=\"token function\">setFirstName<\/span><span class=\"token punctuation\">(<\/span>request<span class=\"token punctuation\">.<\/span><span class=\"token function\">getFirstName<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        customer<span class=\"token punctuation\">.<\/span><span class=\"token function\">setLastName<\/span><span class=\"token punctuation\">(<\/span>request<span class=\"token punctuation\">.<\/span><span class=\"token function\">getLastName<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        customer<span class=\"token punctuation\">.<\/span><span class=\"token function\">setIdNumber<\/span><span class=\"token punctuation\">(<\/span>encryptionUtil<span class=\"token punctuation\">.<\/span><span class=\"token function\">encrypt<\/span><span class=\"token punctuation\">(<\/span>request<span class=\"token punctuation\">.<\/span><span class=\"token function\">getIdNumber<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        customer<span class=\"token punctuation\">.<\/span><span class=\"token function\">setDateOfBirth<\/span><span class=\"token punctuation\">(<\/span>request<span class=\"token punctuation\">.<\/span><span class=\"token function\">getDateOfBirth<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        customer<span class=\"token punctuation\">.<\/span><span class=\"token function\">setEmail<\/span><span class=\"token punctuation\">(<\/span>request<span class=\"token punctuation\">.<\/span><span class=\"token function\">getEmail<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        customer<span class=\"token punctuation\">.<\/span><span class=\"token function\">setPhone<\/span><span class=\"token punctuation\">(<\/span>encryptionUtil<span class=\"token punctuation\">.<\/span><span class=\"token function\">encrypt<\/span><span class=\"token punctuation\">(<\/span>request<span class=\"token punctuation\">.<\/span><span class=\"token function\">getPhone<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        customer<span class=\"token punctuation\">.<\/span><span class=\"token function\">setAddress<\/span><span class=\"token punctuation\">(<\/span>request<span class=\"token punctuation\">.<\/span><span class=\"token function\">getAddress<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        customer<span class=\"token punctuation\">.<\/span><span class=\"token function\">setTier<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">CustomerTier<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">BASIC<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        customer<span class=\"token punctuation\">.<\/span><span class=\"token function\">setStatus<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">CustomerStatus<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">ACTIVE<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        customer<span class=\"token punctuation\">.<\/span><span class=\"token function\">setCreditScore<\/span><span class=\"token punctuation\">(<\/span><span class=\"token function\">calculateInitialCreditScore<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token class-name\">Customer<\/span> saved <span class=\"token operator\">&#061;<\/span> customerRepository<span class=\"token punctuation\">.<\/span><span class=\"token function\">save<\/span><span class=\"token punctuation\">(<\/span>customer<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        log<span class=\"token punctuation\">.<\/span><span class=\"token function\">info<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;Customer created: {}&#034;<\/span><span class=\"token punctuation\">,<\/span> saved<span class=\"token punctuation\">.<\/span><span class=\"token function\">getCustomerId<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u521d\u59cb\u5316\u5ba2\u6237\u5206\u6790\u6570\u636e<\/span><br \/>\n        analysisService<span class=\"token punctuation\">.<\/span><span class=\"token function\">initializeCustomerAnalysis<\/span><span class=\"token punctuation\">(<\/span>saved<span class=\"token punctuation\">.<\/span><span class=\"token function\">getId<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">return<\/span> <span class=\"token function\">convertToDTO<\/span><span class=\"token punctuation\">(<\/span>saved<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Transactional<\/span><br \/>\n    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">CustomerDTO<\/span> <span class=\"token function\">updateCustomer<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">String<\/span> customerId<span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">CustomerUpdateRequest<\/span> request<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token class-name\">Customer<\/span> customer <span class=\"token operator\">&#061;<\/span> customerRepository<span class=\"token punctuation\">.<\/span><span class=\"token function\">findByCustomerId<\/span><span class=\"token punctuation\">(<\/span>customerId<span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">orElseThrow<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">-&gt;<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">AccountException<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">ErrorCode<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">CUSTOMER_NOT_FOUND<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        customer<span class=\"token punctuation\">.<\/span><span class=\"token function\">setFirstName<\/span><span class=\"token punctuation\">(<\/span>request<span class=\"token punctuation\">.<\/span><span class=\"token function\">getFirstName<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        customer<span class=\"token punctuation\">.<\/span><span class=\"token function\">setLastName<\/span><span class=\"token punctuation\">(<\/span>request<span class=\"token punctuation\">.<\/span><span class=\"token function\">getLastName<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        customer<span class=\"token punctuation\">.<\/span><span class=\"token function\">setEmail<\/span><span class=\"token punctuation\">(<\/span>request<span class=\"token punctuation\">.<\/span><span class=\"token function\">getEmail<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        customer<span class=\"token punctuation\">.<\/span><span class=\"token function\">setPhone<\/span><span class=\"token punctuation\">(<\/span>encryptionUtil<span class=\"token punctuation\">.<\/span><span class=\"token function\">encrypt<\/span><span class=\"token punctuation\">(<\/span>request<span class=\"token punctuation\">.<\/span><span class=\"token function\">getPhone<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        customer<span class=\"token punctuation\">.<\/span><span class=\"token function\">setAddress<\/span><span class=\"token punctuation\">(<\/span>request<span class=\"token punctuation\">.<\/span><span class=\"token function\">getAddress<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token class-name\">Customer<\/span> saved <span class=\"token operator\">&#061;<\/span> customerRepository<span class=\"token punctuation\">.<\/span><span class=\"token function\">save<\/span><span class=\"token punctuation\">(<\/span>customer<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        log<span class=\"token punctuation\">.<\/span><span class=\"token function\">info<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;Customer updated: {}&#034;<\/span><span class=\"token punctuation\">,<\/span> customerId<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">return<\/span> <span class=\"token function\">convertToDTO<\/span><span class=\"token punctuation\">(<\/span>saved<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Transactional<\/span><span class=\"token punctuation\">(<\/span>readOnly <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">true<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">CustomerDTO<\/span> <span class=\"token function\">getCustomer<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">String<\/span> customerId<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token class-name\">Customer<\/span> customer <span class=\"token operator\">&#061;<\/span> customerRepository<span class=\"token punctuation\">.<\/span><span class=\"token function\">findByCustomerId<\/span><span class=\"token punctuation\">(<\/span>customerId<span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">orElseThrow<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">-&gt;<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">AccountException<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">ErrorCode<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">CUSTOMER_NOT_FOUND<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token class-name\">CustomerDTO<\/span> dto <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">convertToDTO<\/span><span class=\"token punctuation\">(<\/span>customer<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        dto<span class=\"token punctuation\">.<\/span><span class=\"token function\">setPhone<\/span><span class=\"token punctuation\">(<\/span>encryptionUtil<span class=\"token punctuation\">.<\/span><span class=\"token function\">decrypt<\/span><span class=\"token punctuation\">(<\/span>dto<span class=\"token punctuation\">.<\/span><span class=\"token function\">getPhone<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> dto<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Transactional<\/span><span class=\"token punctuation\">(<\/span>readOnly <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">true<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">List<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">CustomerDTO<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> <span class=\"token function\">getCustomersByTier<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">String<\/span> tier<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> customerRepository<span class=\"token punctuation\">.<\/span><span class=\"token function\">findByTier<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">CustomerTier<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">valueOf<\/span><span class=\"token punctuation\">(<\/span>tier<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">stream<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">map<\/span><span class=\"token punctuation\">(<\/span><span class=\"token keyword\">this<\/span><span class=\"token operator\">::<\/span><span class=\"token function\">convertToDTO<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">peek<\/span><span class=\"token punctuation\">(<\/span>dto <span class=\"token operator\">-&gt;<\/span> dto<span class=\"token punctuation\">.<\/span><span class=\"token function\">setPhone<\/span><span class=\"token punctuation\">(<\/span>encryptionUtil<span class=\"token punctuation\">.<\/span><span class=\"token function\">decrypt<\/span><span class=\"token punctuation\">(<\/span>dto<span class=\"token punctuation\">.<\/span><span class=\"token function\">getPhone<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">collect<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">Collectors<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">toList<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Transactional<\/span><br \/>\n    <span class=\"token annotation punctuation\">&#064;PreAuthorize<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;hasAnyRole(&#039;MANAGER&#039;, &#039;ADMIN&#039;)&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">CustomerDTO<\/span> <span class=\"token function\">updateCustomerTier<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">String<\/span> customerId<span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">String<\/span> tier<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token class-name\">Customer<\/span> customer <span class=\"token operator\">&#061;<\/span> customerRepository<span class=\"token punctuation\">.<\/span><span class=\"token function\">findByCustomerId<\/span><span class=\"token punctuation\">(<\/span>customerId<span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">orElseThrow<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">-&gt;<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">AccountException<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">ErrorCode<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">CUSTOMER_NOT_FOUND<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        customer<span class=\"token punctuation\">.<\/span><span class=\"token function\">setTier<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">CustomerTier<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">valueOf<\/span><span class=\"token punctuation\">(<\/span>tier<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        customer<span class=\"token punctuation\">.<\/span><span class=\"token function\">setLastReviewDate<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">LocalDate<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">now<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token class-name\">Customer<\/span> saved <span class=\"token operator\">&#061;<\/span> customerRepository<span class=\"token punctuation\">.<\/span><span class=\"token function\">save<\/span><span class=\"token punctuation\">(<\/span>customer<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        log<span class=\"token punctuation\">.<\/span><span class=\"token function\">info<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;Customer tier updated to {}: {}&#034;<\/span><span class=\"token punctuation\">,<\/span> tier<span class=\"token punctuation\">,<\/span> customerId<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">return<\/span> <span class=\"token function\">convertToDTO<\/span><span class=\"token punctuation\">(<\/span>saved<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Transactional<\/span><br \/>\n    <span class=\"token annotation punctuation\">&#064;PreAuthorize<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;hasAnyRole(&#039;MANAGER&#039;, &#039;ADMIN&#039;)&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">CustomerDTO<\/span> <span class=\"token function\">updateCustomerStatus<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">String<\/span> customerId<span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">String<\/span> status<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token class-name\">Customer<\/span> customer <span class=\"token operator\">&#061;<\/span> customerRepository<span class=\"token punctuation\">.<\/span><span class=\"token function\">findByCustomerId<\/span><span class=\"token punctuation\">(<\/span>customerId<span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">orElseThrow<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">-&gt;<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">AccountException<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">ErrorCode<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">CUSTOMER_NOT_FOUND<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        customer<span class=\"token punctuation\">.<\/span><span class=\"token function\">setStatus<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">CustomerStatus<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">valueOf<\/span><span class=\"token punctuation\">(<\/span>status<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token class-name\">Customer<\/span> saved <span class=\"token operator\">&#061;<\/span> customerRepository<span class=\"token punctuation\">.<\/span><span class=\"token function\">save<\/span><span class=\"token punctuation\">(<\/span>customer<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        log<span class=\"token punctuation\">.<\/span><span class=\"token function\">info<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;Customer status updated to {}: {}&#034;<\/span><span class=\"token punctuation\">,<\/span> status<span class=\"token punctuation\">,<\/span> customerId<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">return<\/span> <span class=\"token function\">convertToDTO<\/span><span class=\"token punctuation\">(<\/span>saved<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Transactional<\/span><span class=\"token punctuation\">(<\/span>readOnly <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">true<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">CustomerAnalysisDTO<\/span> <span class=\"token function\">getCustomerAnalysis<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">String<\/span> customerId<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token class-name\">Customer<\/span> customer <span class=\"token operator\">&#061;<\/span> customerRepository<span class=\"token punctuation\">.<\/span><span class=\"token function\">findByCustomerId<\/span><span class=\"token punctuation\">(<\/span>customerId<span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">orElseThrow<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">-&gt;<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">AccountException<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">ErrorCode<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">CUSTOMER_NOT_FOUND<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">return<\/span> analysisService<span class=\"token punctuation\">.<\/span><span class=\"token function\">getCustomerAnalysis<\/span><span class=\"token punctuation\">(<\/span>customer<span class=\"token punctuation\">.<\/span><span class=\"token function\">getId<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Scheduled<\/span><span class=\"token punctuation\">(<\/span>cron <span class=\"token operator\">&#061;<\/span> <span class=\"token string\">&#034;0 0 1 * * ?&#034;<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token comment\">\/\/ \u6bcf\u5929\u51cc\u66681\u70b9\u6267\u884c<\/span><br \/>\n    <span class=\"token keyword\">public<\/span> <span class=\"token keyword\">void<\/span> <span class=\"token function\">reviewCustomerTiers<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token class-name\">LocalDate<\/span> reviewDate <span class=\"token operator\">&#061;<\/span> <span class=\"token class-name\">LocalDate<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">now<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">minusMonths<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">6<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token class-name\">List<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">Customer<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> customers <span class=\"token operator\">&#061;<\/span> customerRepository<span class=\"token punctuation\">.<\/span><span class=\"token function\">findCustomersNeedingReview<\/span><span class=\"token punctuation\">(<\/span>reviewDate<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        customers<span class=\"token punctuation\">.<\/span><span class=\"token function\">forEach<\/span><span class=\"token punctuation\">(<\/span>customer <span class=\"token operator\">-&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">try<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                <span class=\"token function\">reviewCustomerTier<\/span><span class=\"token punctuation\">(<\/span>customer<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">catch<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token class-name\">Exception<\/span> e<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                log<span class=\"token punctuation\">.<\/span><span class=\"token function\">error<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;Failed to review customer tier: &#034;<\/span> <span class=\"token operator\">&#043;<\/span> customer<span class=\"token punctuation\">.<\/span><span class=\"token function\">getCustomerId<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span> e<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">void<\/span> <span class=\"token function\">reviewCustomerTier<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">Customer<\/span> customer<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token class-name\">CustomerAnalysisDTO<\/span> analysis <span class=\"token operator\">&#061;<\/span> analysisService<span class=\"token punctuation\">.<\/span><span class=\"token function\">getCustomerAnalysis<\/span><span class=\"token punctuation\">(<\/span>customer<span class=\"token punctuation\">.<\/span><span class=\"token function\">getId<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token class-name\">CustomerTier<\/span> newTier <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">determineCustomerTier<\/span><span class=\"token punctuation\">(<\/span>analysis<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>newTier <span class=\"token operator\">!&#061;<\/span> customer<span class=\"token punctuation\">.<\/span><span class=\"token function\">getTier<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            customer<span class=\"token punctuation\">.<\/span><span class=\"token function\">setTier<\/span><span class=\"token punctuation\">(<\/span>newTier<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            customer<span class=\"token punctuation\">.<\/span><span class=\"token function\">setLastReviewDate<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">LocalDate<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">now<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            customerRepository<span class=\"token punctuation\">.<\/span><span class=\"token function\">save<\/span><span class=\"token punctuation\">(<\/span>customer<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            log<span class=\"token punctuation\">.<\/span><span class=\"token function\">info<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;Customer tier updated to {}: {}&#034;<\/span><span class=\"token punctuation\">,<\/span> newTier<span class=\"token punctuation\">,<\/span> customer<span class=\"token punctuation\">.<\/span><span class=\"token function\">getCustomerId<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">CustomerTier<\/span> <span class=\"token function\">determineCustomerTier<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">CustomerAnalysisDTO<\/span> analysis<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token class-name\">BigDecimal<\/span> score <span class=\"token operator\">&#061;<\/span> analysis<span class=\"token punctuation\">.<\/span><span class=\"token function\">getProfitabilityScore<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>score<span class=\"token punctuation\">.<\/span><span class=\"token function\">compareTo<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">BigDecimal<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">valueOf<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">90<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&gt;&#061;<\/span> <span class=\"token number\">0<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">return<\/span> <span class=\"token class-name\">CustomerTier<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">DIAMOND<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">else<\/span> <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>score<span class=\"token punctuation\">.<\/span><span class=\"token function\">compareTo<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">BigDecimal<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">valueOf<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">75<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&gt;&#061;<\/span> <span class=\"token number\">0<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">return<\/span> <span class=\"token class-name\">CustomerTier<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">PLATINUM<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">else<\/span> <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>score<span class=\"token punctuation\">.<\/span><span class=\"token function\">compareTo<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">BigDecimal<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">valueOf<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">60<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&gt;&#061;<\/span> <span class=\"token number\">0<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">return<\/span> <span class=\"token class-name\">CustomerTier<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">GOLD<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">else<\/span> <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>score<span class=\"token punctuation\">.<\/span><span class=\"token function\">compareTo<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">BigDecimal<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">valueOf<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">40<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&gt;&#061;<\/span> <span class=\"token number\">0<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">return<\/span> <span class=\"token class-name\">CustomerTier<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">SILVER<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">else<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">return<\/span> <span class=\"token class-name\">CustomerTier<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">BASIC<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">BigDecimal<\/span> <span class=\"token function\">calculateInitialCreditScore<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token comment\">\/\/ \u7b80\u5316\u5904\u7406&#xff0c;\u5b9e\u9645\u4e1a\u52a1\u4e2d\u53ef\u80fd\u6709\u66f4\u590d\u6742\u7684\u4fe1\u7528\u8bc4\u5206\u8ba1\u7b97\u903b\u8f91<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> <span class=\"token class-name\">BigDecimal<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">valueOf<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">65<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span> <span class=\"token comment\">\/\/ \u521d\u59cb\u4fe1\u7528\u520665<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">CustomerDTO<\/span> <span class=\"token function\">convertToDTO<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">Customer<\/span> customer<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token class-name\">CustomerDTO<\/span> dto <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">CustomerDTO<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        dto<span class=\"token punctuation\">.<\/span><span class=\"token function\">setId<\/span><span class=\"token punctuation\">(<\/span>customer<span class=\"token punctuation\">.<\/span><span class=\"token function\">getId<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        dto<span class=\"token punctuation\">.<\/span><span class=\"token function\">setCustomerId<\/span><span class=\"token punctuation\">(<\/span>customer<span class=\"token punctuation\">.<\/span><span class=\"token function\">getCustomerId<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        dto<span class=\"token punctuation\">.<\/span><span class=\"token function\">setFirstName<\/span><span class=\"token punctuation\">(<\/span>customer<span class=\"token punctuation\">.<\/span><span class=\"token function\">getFirstName<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        dto<span class=\"token punctuation\">.<\/span><span class=\"token function\">setLastName<\/span><span class=\"token punctuation\">(<\/span>customer<span class=\"token punctuation\">.<\/span><span class=\"token function\">getLastName<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        dto<span class=\"token punctuation\">.<\/span><span class=\"token function\">setIdNumber<\/span><span class=\"token punctuation\">(<\/span>customer<span class=\"token punctuation\">.<\/span><span class=\"token function\">getIdNumber<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        dto<span class=\"token punctuation\">.<\/span><span class=\"token function\">setDateOfBirth<\/span><span class=\"token punctuation\">(<\/span>customer<span class=\"token punctuation\">.<\/span><span class=\"token function\">getDateOfBirth<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        dto<span class=\"token punctuation\">.<\/span><span class=\"token function\">setEmail<\/span><span class=\"token punctuation\">(<\/span>customer<span class=\"token punctuation\">.<\/span><span class=\"token function\">getEmail<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        dto<span class=\"token punctuation\">.<\/span><span class=\"token function\">setPhone<\/span><span class=\"token punctuation\">(<\/span>customer<span class=\"token punctuation\">.<\/span><span class=\"token function\">getPhone<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        dto<span class=\"token punctuation\">.<\/span><span class=\"token function\">setAddress<\/span><span class=\"token punctuation\">(<\/span>customer<span class=\"token punctuation\">.<\/span><span class=\"token function\">getAddress<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        dto<span class=\"token punctuation\">.<\/span><span class=\"token function\">setTier<\/span><span class=\"token punctuation\">(<\/span>customer<span class=\"token punctuation\">.<\/span><span class=\"token function\">getTier<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        dto<span class=\"token punctuation\">.<\/span><span class=\"token function\">setStatus<\/span><span class=\"token punctuation\">(<\/span>customer<span class=\"token punctuation\">.<\/span><span class=\"token function\">getStatus<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        dto<span class=\"token punctuation\">.<\/span><span class=\"token function\">setCreditScore<\/span><span class=\"token punctuation\">(<\/span>customer<span class=\"token punctuation\">.<\/span><span class=\"token function\">getCreditScore<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        dto<span class=\"token punctuation\">.<\/span><span class=\"token function\">setLastReviewDate<\/span><span class=\"token punctuation\">(<\/span>customer<span class=\"token punctuation\">.<\/span><span class=\"token function\">getLastReviewDate<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        dto<span class=\"token punctuation\">.<\/span><span class=\"token function\">setCreatedAt<\/span><span class=\"token punctuation\">(<\/span>customer<span class=\"token punctuation\">.<\/span><span class=\"token function\">getCreatedAt<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> dto<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token annotation punctuation\">&#064;Service<\/span><br \/>\n<span class=\"token annotation punctuation\">&#064;RequiredArgsConstructor<\/span><br \/>\n<span class=\"token annotation punctuation\">&#064;Slf4j<\/span><br \/>\n<span class=\"token keyword\">public<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token class-name\">CustomerAnalysisService<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">final<\/span> <span class=\"token class-name\">CustomerRepository<\/span> customerRepository<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">final<\/span> <span class=\"token class-name\">AccountClientService<\/span> accountClientService<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">final<\/span> <span class=\"token class-name\">LoanClientService<\/span> loanClientService<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">final<\/span> <span class=\"token class-name\">TransactionClientService<\/span> transactionClientService<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Transactional<\/span><br \/>\n    <span class=\"token keyword\">public<\/span> <span class=\"token keyword\">void<\/span> <span class=\"token function\">initializeCustomerAnalysis<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">Long<\/span> customerId<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token comment\">\/\/ \u5728\u5b9e\u9645\u9879\u76ee\u4e2d&#xff0c;\u8fd9\u91cc\u4f1a\u521d\u59cb\u5316\u5ba2\u6237\u7684\u5206\u6790\u6570\u636e<\/span><br \/>\n        log<span class=\"token punctuation\">.<\/span><span class=\"token function\">info<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;Initialized analysis data for customer: {}&#034;<\/span><span class=\"token punctuation\">,<\/span> customerId<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Transactional<\/span><span class=\"token punctuation\">(<\/span>readOnly <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">true<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">CustomerAnalysisDTO<\/span> <span class=\"token function\">getCustomerAnalysis<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">Long<\/span> customerId<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token class-name\">Customer<\/span> customer <span class=\"token operator\">&#061;<\/span> customerRepository<span class=\"token punctuation\">.<\/span><span class=\"token function\">findById<\/span><span class=\"token punctuation\">(<\/span>customerId<span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">orElseThrow<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">-&gt;<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">AccountException<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">ErrorCode<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">CUSTOMER_NOT_FOUND<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token class-name\">CustomerAnalysisDTO<\/span> analysis <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">CustomerAnalysisDTO<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        analysis<span class=\"token punctuation\">.<\/span><span class=\"token function\">setCustomerId<\/span><span class=\"token punctuation\">(<\/span>customer<span class=\"token punctuation\">.<\/span><span class=\"token function\">getId<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        analysis<span class=\"token punctuation\">.<\/span><span class=\"token function\">setCustomerName<\/span><span class=\"token punctuation\">(<\/span>customer<span class=\"token punctuation\">.<\/span><span class=\"token function\">getFirstName<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#043;<\/span> <span class=\"token string\">&#034; &#034;<\/span> <span class=\"token operator\">&#043;<\/span> customer<span class=\"token punctuation\">.<\/span><span class=\"token function\">getLastName<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u83b7\u53d6\u5ba2\u6237\u8d44\u4ea7\u6570\u636e<\/span><br \/>\n        <span class=\"token class-name\">BigDecimal<\/span> totalAssets <span class=\"token operator\">&#061;<\/span> accountClientService<span class=\"token punctuation\">.<\/span><span class=\"token function\">getCustomerTotalAssets<\/span><span class=\"token punctuation\">(<\/span>customer<span class=\"token punctuation\">.<\/span><span class=\"token function\">getCustomerId<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        analysis<span class=\"token punctuation\">.<\/span><span class=\"token function\">setTotalAssets<\/span><span class=\"token punctuation\">(<\/span>totalAssets<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u83b7\u53d6\u5ba2\u6237\u8d1f\u503a\u6570\u636e<\/span><br \/>\n        <span class=\"token class-name\">BigDecimal<\/span> totalLiabilities <span class=\"token operator\">&#061;<\/span> loanClientService<span class=\"token punctuation\">.<\/span><span class=\"token function\">getCustomerTotalLiabilities<\/span><span class=\"token punctuation\">(<\/span>customer<span class=\"token punctuation\">.<\/span><span class=\"token function\">getCustomerId<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        analysis<span class=\"token punctuation\">.<\/span><span class=\"token function\">setTotalLiabilities<\/span><span class=\"token punctuation\">(<\/span>totalLiabilities<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u8ba1\u7b97\u51c0\u8d44\u4ea7<\/span><br \/>\n        analysis<span class=\"token punctuation\">.<\/span><span class=\"token function\">setNetWorth<\/span><span class=\"token punctuation\">(<\/span>totalAssets<span class=\"token punctuation\">.<\/span><span class=\"token function\">subtract<\/span><span class=\"token punctuation\">(<\/span>totalLiabilities<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u83b7\u53d6\u6708\u5ea6\u6536\u652f\u6570\u636e<\/span><br \/>\n        analysis<span class=\"token punctuation\">.<\/span><span class=\"token function\">setMonthlyIncome<\/span><span class=\"token punctuation\">(<\/span>transactionClientService<span class=\"token punctuation\">.<\/span><span class=\"token function\">getMonthlyIncome<\/span><span class=\"token punctuation\">(<\/span>customer<span class=\"token punctuation\">.<\/span><span class=\"token function\">getCustomerId<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        analysis<span class=\"token punctuation\">.<\/span><span class=\"token function\">setMonthlyExpenses<\/span><span class=\"token punctuation\">(<\/span>transactionClientService<span class=\"token punctuation\">.<\/span><span class=\"token function\">getMonthlyExpenses<\/span><span class=\"token punctuation\">(<\/span>customer<span class=\"token punctuation\">.<\/span><span class=\"token function\">getCustomerId<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u8ba1\u7b97\u76c8\u5229\u6027\u8bc4\u5206<\/span><br \/>\n        analysis<span class=\"token punctuation\">.<\/span><span class=\"token function\">setProfitabilityScore<\/span><span class=\"token punctuation\">(<\/span><span class=\"token function\">calculateProfitabilityScore<\/span><span class=\"token punctuation\">(<\/span>analysis<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u83b7\u53d6\u6700\u540e\u6d3b\u52a8\u65e5\u671f<\/span><br \/>\n        analysis<span class=\"token punctuation\">.<\/span><span class=\"token function\">setLastActivityDate<\/span><span class=\"token punctuation\">(<\/span>transactionClientService<span class=\"token punctuation\">.<\/span><span class=\"token function\">getLastActivityDate<\/span><span class=\"token punctuation\">(<\/span>customer<span class=\"token punctuation\">.<\/span><span class=\"token function\">getCustomerId<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u83b7\u53d6\u4ea7\u54c1\u6570\u91cf<\/span><br \/>\n        analysis<span class=\"token punctuation\">.<\/span><span class=\"token function\">setProductCount<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                accountClientService<span class=\"token punctuation\">.<\/span><span class=\"token function\">getAccountCount<\/span><span class=\"token punctuation\">(<\/span>customer<span class=\"token punctuation\">.<\/span><span class=\"token function\">getCustomerId<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#043;<\/span><br \/>\n                loanClientService<span class=\"token punctuation\">.<\/span><span class=\"token function\">getLoanCount<\/span><span class=\"token punctuation\">(<\/span>customer<span class=\"token punctuation\">.<\/span><span class=\"token function\">getCustomerId<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">return<\/span> analysis<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">BigDecimal<\/span> <span class=\"token function\">calculateProfitabilityScore<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">CustomerAnalysisDTO<\/span> analysis<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token comment\">\/\/ \u7b80\u5316\u5904\u7406&#xff0c;\u5b9e\u9645\u4e1a\u52a1\u4e2d\u53ef\u80fd\u6709\u66f4\u590d\u6742\u7684\u8bc4\u5206\u903b\u8f91<\/span><br \/>\n        <span class=\"token class-name\">BigDecimal<\/span> score <span class=\"token operator\">&#061;<\/span> <span class=\"token class-name\">BigDecimal<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">ZERO<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u51c0\u8d44\u4ea7\u8d21\u732e<\/span><br \/>\n        <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>analysis<span class=\"token punctuation\">.<\/span><span class=\"token function\">getNetWorth<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">compareTo<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">BigDecimal<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">valueOf<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">1000000<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&gt;&#061;<\/span> <span class=\"token number\">0<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            score <span class=\"token operator\">&#061;<\/span> score<span class=\"token punctuation\">.<\/span><span class=\"token function\">add<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">BigDecimal<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">valueOf<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">40<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">else<\/span> <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>analysis<span class=\"token punctuation\">.<\/span><span class=\"token function\">getNetWorth<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">compareTo<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">BigDecimal<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">valueOf<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">500000<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&gt;&#061;<\/span> <span class=\"token number\">0<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            score <span class=\"token operator\">&#061;<\/span> score<span class=\"token punctuation\">.<\/span><span class=\"token function\">add<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">BigDecimal<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">valueOf<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">30<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">else<\/span> <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>analysis<span class=\"token punctuation\">.<\/span><span class=\"token function\">getNetWorth<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">compareTo<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">BigDecimal<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">valueOf<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">100000<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&gt;&#061;<\/span> <span class=\"token number\">0<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            score <span class=\"token operator\">&#061;<\/span> score<span class=\"token punctuation\">.<\/span><span class=\"token function\">add<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">BigDecimal<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">valueOf<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">20<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">else<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            score <span class=\"token operator\">&#061;<\/span> score<span class=\"token punctuation\">.<\/span><span class=\"token function\">add<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">BigDecimal<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">valueOf<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">10<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u6708\u6536\u5165\u8d21\u732e<\/span><br \/>\n        <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>analysis<span class=\"token punctuation\">.<\/span><span class=\"token function\">getMonthlyIncome<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">compareTo<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">BigDecimal<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">valueOf<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">50000<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&gt;&#061;<\/span> <span class=\"token number\">0<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            score <span class=\"token operator\">&#061;<\/span> score<span class=\"token punctuation\">.<\/span><span class=\"token function\">add<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">BigDecimal<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">valueOf<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">30<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">else<\/span> <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>analysis<span class=\"token punctuation\">.<\/span><span class=\"token function\">getMonthlyIncome<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">compareTo<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">BigDecimal<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">valueOf<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">20000<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&gt;&#061;<\/span> <span class=\"token number\">0<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            score <span class=\"token operator\">&#061;<\/span> score<span class=\"token punctuation\">.<\/span><span class=\"token function\">add<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">BigDecimal<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">valueOf<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">20<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">else<\/span> <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>analysis<span class=\"token punctuation\">.<\/span><span class=\"token function\">getMonthlyIncome<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">compareTo<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">BigDecimal<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">valueOf<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">5000<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&gt;&#061;<\/span> <span class=\"token number\">0<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            score <span class=\"token operator\">&#061;<\/span> score<span class=\"token punctuation\">.<\/span><span class=\"token function\">add<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">BigDecimal<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">valueOf<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">15<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">else<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            score <span class=\"token operator\">&#061;<\/span> score<span class=\"token punctuation\">.<\/span><span class=\"token function\">add<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">BigDecimal<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">valueOf<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">5<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u4ea7\u54c1\u6570\u91cf\u8d21\u732e<\/span><br \/>\n        score <span class=\"token operator\">&#061;<\/span> score<span class=\"token punctuation\">.<\/span><span class=\"token function\">add<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">BigDecimal<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">valueOf<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">Math<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">min<\/span><span class=\"token punctuation\">(<\/span>analysis<span class=\"token punctuation\">.<\/span><span class=\"token function\">getProductCount<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token number\">10<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">*<\/span> <span class=\"token number\">2<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u6d3b\u52a8\u9891\u7387\u8d21\u732e<\/span><br \/>\n        <span class=\"token keyword\">long<\/span> daysSinceLastActivity <span class=\"token operator\">&#061;<\/span> <span class=\"token class-name\">LocalDate<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">now<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">toEpochDay<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#8211;<\/span><br \/>\n                analysis<span class=\"token punctuation\">.<\/span><span class=\"token function\">getLastActivityDate<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">toEpochDay<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>daysSinceLastActivity <span class=\"token operator\">&lt;&#061;<\/span> <span class=\"token number\">7<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            score <span class=\"token operator\">&#061;<\/span> score<span class=\"token punctuation\">.<\/span><span class=\"token function\">add<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">BigDecimal<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">valueOf<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">20<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">else<\/span> <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>daysSinceLastActivity <span class=\"token operator\">&lt;&#061;<\/span> <span class=\"token number\">30<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            score <span class=\"token operator\">&#061;<\/span> score<span class=\"token punctuation\">.<\/span><span class=\"token function\">add<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">BigDecimal<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">valueOf<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">10<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><\/p>\n<p>        <span class=\"token keyword\">return<\/span> score<span class=\"token punctuation\">.<\/span><span class=\"token function\">setScale<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">0<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">RoundingMode<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">HALF_UP<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token annotation punctuation\">&#064;Service<\/span><br \/>\n<span class=\"token annotation punctuation\">&#064;RequiredArgsConstructor<\/span><br \/>\n<span class=\"token annotation punctuation\">&#064;Slf4j<\/span><br \/>\n<span class=\"token keyword\">public<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token class-name\">CustomerInteractionService<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">final<\/span> <span class=\"token class-name\">CustomerInteractionRepository<\/span> interactionRepository<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">final<\/span> <span class=\"token class-name\">CustomerRepository<\/span> customerRepository<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Transactional<\/span><br \/>\n    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">CustomerInteractionDTO<\/span> <span class=\"token function\">recordInteraction<\/span><span class=\"token punctuation\">(<\/span><br \/>\n            <span class=\"token class-name\">String<\/span> customerId<span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token class-name\">InteractionType<\/span> type<span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token class-name\">String<\/span> description<span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token class-name\">Long<\/span> relatedAccountId<span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token class-name\">String<\/span> notes<span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token class-name\">Long<\/span> employeeId<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><\/p>\n<p>        <span class=\"token class-name\">Customer<\/span> customer <span class=\"token operator\">&#061;<\/span> customerRepository<span class=\"token punctuation\">.<\/span><span class=\"token function\">findByCustomerId<\/span><span class=\"token punctuation\">(<\/span>customerId<span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">orElseThrow<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">-&gt;<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">AccountException<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">ErrorCode<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">CUSTOMER_NOT_FOUND<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token class-name\">CustomerInteraction<\/span> interaction <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">CustomerInteraction<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        interaction<span class=\"token punctuation\">.<\/span><span class=\"token function\">setCustomerId<\/span><span class=\"token punctuation\">(<\/span>customer<span class=\"token punctuation\">.<\/span><span class=\"token function\">getId<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        interaction<span class=\"token punctuation\">.<\/span><span class=\"token function\">setType<\/span><span class=\"token punctuation\">(<\/span>type<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        interaction<span class=\"token punctuation\">.<\/span><span class=\"token function\">setDescription<\/span><span class=\"token punctuation\">(<\/span>description<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        interaction<span class=\"token punctuation\">.<\/span><span class=\"token function\">setRelatedAccountId<\/span><span class=\"token punctuation\">(<\/span>relatedAccountId<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        interaction<span class=\"token punctuation\">.<\/span><span class=\"token function\">setNotes<\/span><span class=\"token punctuation\">(<\/span>notes<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        interaction<span class=\"token punctuation\">.<\/span><span class=\"token function\">setEmployeeId<\/span><span class=\"token punctuation\">(<\/span>employeeId<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token class-name\">CustomerInteraction<\/span> saved <span class=\"token operator\">&#061;<\/span> interactionRepository<span class=\"token punctuation\">.<\/span><span class=\"token function\">save<\/span><span class=\"token punctuation\">(<\/span>interaction<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        log<span class=\"token punctuation\">.<\/span><span class=\"token function\">info<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;Interaction recorded for customer: {}&#034;<\/span><span class=\"token punctuation\">,<\/span> customerId<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">return<\/span> <span class=\"token function\">convertToDTO<\/span><span class=\"token punctuation\">(<\/span>saved<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Transactional<\/span><span class=\"token punctuation\">(<\/span>readOnly <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">true<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">List<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">CustomerInteractionDTO<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> <span class=\"token function\">getCustomerInteractions<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">String<\/span> customerId<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token class-name\">Customer<\/span> customer <span class=\"token operator\">&#061;<\/span> customerRepository<span class=\"token punctuation\">.<\/span><span class=\"token function\">findByCustomerId<\/span><span class=\"token punctuation\">(<\/span>customerId<span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">orElseThrow<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">-&gt;<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">AccountException<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">ErrorCode<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">CUSTOMER_NOT_FOUND<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">return<\/span> interactionRepository<span class=\"token punctuation\">.<\/span><span class=\"token function\">findByCustomerId<\/span><span class=\"token punctuation\">(<\/span>customer<span class=\"token punctuation\">.<\/span><span class=\"token function\">getId<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">stream<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">map<\/span><span class=\"token punctuation\">(<\/span><span class=\"token keyword\">this<\/span><span class=\"token operator\">::<\/span><span class=\"token function\">convertToDTO<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">collect<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">Collectors<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">toList<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Transactional<\/span><span class=\"token punctuation\">(<\/span>readOnly <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">true<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">List<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">CustomerInteractionDTO<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> <span class=\"token function\">getEmployeeInteractions<\/span><span class=\"token punctuation\">(<\/span><br \/>\n            <span class=\"token class-name\">Long<\/span> employeeId<span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token class-name\">LocalDateTime<\/span> start<span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token class-name\">LocalDateTime<\/span> end<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><\/p>\n<p>        <span class=\"token keyword\">return<\/span> interactionRepository<span class=\"token punctuation\">.<\/span><span class=\"token function\">findByEmployeeIdAndCreatedAtBetween<\/span><span class=\"token punctuation\">(<\/span>employeeId<span class=\"token punctuation\">,<\/span> start<span class=\"token punctuation\">,<\/span> end<span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">stream<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">map<\/span><span class=\"token punctuation\">(<\/span><span class=\"token keyword\">this<\/span><span class=\"token operator\">::<\/span><span class=\"token function\">convertToDTO<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">collect<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">Collectors<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">toList<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">CustomerInteractionDTO<\/span> <span class=\"token function\">convertToDTO<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">CustomerInteraction<\/span> interaction<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token class-name\">CustomerInteractionDTO<\/span> dto <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">CustomerInteractionDTO<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        dto<span class=\"token punctuation\">.<\/span><span class=\"token function\">setId<\/span><span class=\"token punctuation\">(<\/span>interaction<span class=\"token punctuation\">.<\/span><span class=\"token function\">getId<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        dto<span class=\"token punctuation\">.<\/span><span class=\"token function\">setCustomerId<\/span><span class=\"token punctuation\">(<\/span>interaction<span class=\"token punctuation\">.<\/span><span class=\"token function\">getCustomerId<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        dto<span class=\"token punctuation\">.<\/span><span class=\"token function\">setType<\/span><span class=\"token punctuation\">(<\/span>interaction<span class=\"token punctuation\">.<\/span><span class=\"token function\">getType<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        dto<span class=\"token punctuation\">.<\/span><span class=\"token function\">setDescription<\/span><span class=\"token punctuation\">(<\/span>interaction<span class=\"token punctuation\">.<\/span><span class=\"token function\">getDescription<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        dto<span class=\"token punctuation\">.<\/span><span class=\"token function\">setRelatedAccountId<\/span><span class=\"token punctuation\">(<\/span>interaction<span class=\"token punctuation\">.<\/span><span class=\"token function\">getRelatedAccountId<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        dto<span class=\"token punctuation\">.<\/span><span class=\"token function\">setNotes<\/span><span class=\"token punctuation\">(<\/span>interaction<span class=\"token punctuation\">.<\/span><span class=\"token function\">getNotes<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        dto<span class=\"token punctuation\">.<\/span><span class=\"token function\">setEmployeeId<\/span><span class=\"token punctuation\">(<\/span>interaction<span class=\"token punctuation\">.<\/span><span class=\"token function\">getEmployeeId<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        dto<span class=\"token punctuation\">.<\/span><span class=\"token function\">setCreatedAt<\/span><span class=\"token punctuation\">(<\/span>interaction<span class=\"token punctuation\">.<\/span><span class=\"token function\">getCreatedAt<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> dto<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p>Repository\u5c42<\/p>\n<p><span class=\"token keyword\">public<\/span> <span class=\"token keyword\">interface<\/span> <span class=\"token class-name\">CustomerRepository<\/span> <span class=\"token keyword\">extends<\/span> <span class=\"token class-name\">JpaRepository<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">Customer<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">Long<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token class-name\">Optional<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">Customer<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> <span class=\"token function\">findByCustomerId<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">String<\/span> customerId<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token class-name\">Optional<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">Customer<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> <span class=\"token function\">findByIdNumber<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">String<\/span> idNumber<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token class-name\">List<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">Customer<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> <span class=\"token function\">findByTier<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">CustomerTier<\/span> tier<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token class-name\">List<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">Customer<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> <span class=\"token function\">findByStatus<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">CustomerStatus<\/span> status<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token class-name\">List<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">Customer<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> <span class=\"token function\">findByCreditScoreBetween<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">BigDecimal<\/span> minScore<span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">BigDecimal<\/span> maxScore<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Query<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;SELECT c FROM Customer c WHERE c.lastReviewDate IS NULL OR c.lastReviewDate &lt; :date&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token class-name\">List<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">Customer<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> <span class=\"token function\">findCustomersNeedingReview<\/span><span class=\"token punctuation\">(<\/span><span class=\"token annotation punctuation\">&#064;Param<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;date&#034;<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token class-name\">LocalDate<\/span> date<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token keyword\">public<\/span> <span class=\"token keyword\">interface<\/span> <span class=\"token class-name\">CustomerInteractionRepository<\/span> <span class=\"token keyword\">extends<\/span> <span class=\"token class-name\">JpaRepository<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">CustomerInteraction<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">Long<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token class-name\">List<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">CustomerInteraction<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> <span class=\"token function\">findByCustomerId<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">Long<\/span> customerId<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token class-name\">List<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">CustomerInteraction<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> <span class=\"token function\">findByCustomerIdAndType<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">Long<\/span> customerId<span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">InteractionType<\/span> type<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token class-name\">List<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">CustomerInteraction<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> <span class=\"token function\">findByEmployeeIdAndCreatedAtBetween<\/span><span class=\"token punctuation\">(<\/span><br \/>\n            <span class=\"token class-name\">Long<\/span> employeeId<span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">LocalDateTime<\/span> start<span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">LocalDateTime<\/span> end<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token keyword\">public<\/span> <span class=\"token keyword\">interface<\/span> <span class=\"token class-name\">CustomerPreferenceRepository<\/span> <span class=\"token keyword\">extends<\/span> <span class=\"token class-name\">JpaRepository<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">CustomerPreference<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">Long<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token class-name\">List<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">CustomerPreference<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> <span class=\"token function\">findByCustomerId<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">Long<\/span> customerId<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token class-name\">Optional<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">CustomerPreference<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> <span class=\"token function\">findByCustomerIdAndPreferenceType<\/span><span class=\"token punctuation\">(<\/span><br \/>\n            <span class=\"token class-name\">Long<\/span> customerId<span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">String<\/span> preferenceType<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token class-name\">List<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">CustomerPreference<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> <span class=\"token function\">findByPreferenceTypeAndPreferenceValue<\/span><span class=\"token punctuation\">(<\/span><br \/>\n            <span class=\"token class-name\">String<\/span> preferenceType<span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">String<\/span> preferenceValue<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token keyword\">public<\/span> <span class=\"token keyword\">interface<\/span> <span class=\"token class-name\">CustomerSegmentRepository<\/span> <span class=\"token keyword\">extends<\/span> <span class=\"token class-name\">JpaRepository<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">CustomerSegment<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">Long<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token class-name\">Optional<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">CustomerSegment<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> <span class=\"token function\">findBySegmentCode<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">String<\/span> segmentCode<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token class-name\">List<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">CustomerSegment<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> <span class=\"token function\">findByIsActiveTrue<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p>6. \u98ce\u9669\u7ba1\u7406<\/p>\n<p>\u53cd\u6b3a\u8bc8\u68c0\u6d4b<\/p>\n<p>\u4ea4\u6613\u76d1\u63a7<\/p>\n<p>\u5408\u89c4\u68c0\u67e5<\/p>\n<p>\u98ce\u9669\u9884\u8b66<\/p>\n<p><span class=\"token comment\"># \u5728\u539f\u6709\u914d\u7f6e\u57fa\u7840\u4e0a\u6dfb\u52a0<\/span><br \/>\n<span class=\"token key atrule\">risk<\/span><span class=\"token punctuation\">:<\/span><br \/>\n  <span class=\"token key atrule\">engine<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    <span class=\"token key atrule\">rules-refresh-interval<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token number\">300000<\/span> <span class=\"token comment\"># \u89c4\u5219\u5237\u65b0\u95f4\u9694(5\u5206\u949f)<\/span><br \/>\n  <span class=\"token key atrule\">blacklist<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    <span class=\"token key atrule\">cache-enabled<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token boolean important\">true<\/span><br \/>\n    <span class=\"token key atrule\">cache-ttl<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token number\">3600000<\/span> <span class=\"token comment\"># 1\u5c0f\u65f6<\/span><\/p>\n<p><span class=\"token annotation punctuation\">&#064;Entity<\/span><br \/>\n<span class=\"token annotation punctuation\">&#064;Table<\/span><span class=\"token punctuation\">(<\/span>name <span class=\"token operator\">&#061;<\/span> <span class=\"token string\">&#034;risk_rule&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n<span class=\"token annotation punctuation\">&#064;Data<\/span><br \/>\n<span class=\"token keyword\">public<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token class-name\">RiskRule<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token annotation punctuation\">&#064;Id<\/span><br \/>\n    <span class=\"token annotation punctuation\">&#064;GeneratedValue<\/span><span class=\"token punctuation\">(<\/span>strategy <span class=\"token operator\">&#061;<\/span> <span class=\"token class-name\">GenerationType<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">IDENTITY<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">Long<\/span> id<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>nullable <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">,<\/span> unique <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">true<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> ruleCode<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>nullable <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> ruleName<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Enumerated<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">EnumType<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">STRING<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>nullable <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">RiskRuleCategory<\/span> category<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>nullable <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">,<\/span> columnDefinition <span class=\"token operator\">&#061;<\/span> <span class=\"token string\">&#034;TEXT&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> ruleExpression<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>nullable <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">Integer<\/span> priority<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>nullable <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">Boolean<\/span> isActive <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">true<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Enumerated<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">EnumType<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">STRING<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>nullable <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">RiskRuleStatus<\/span> status <span class=\"token operator\">&#061;<\/span> <span class=\"token class-name\">RiskRuleStatus<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">DRAFT<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> action<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;CreationTimestamp<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">LocalDateTime<\/span> createdAt<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;UpdateTimestamp<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">LocalDateTime<\/span> updatedAt<span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token annotation punctuation\">&#064;Entity<\/span><br \/>\n<span class=\"token annotation punctuation\">&#064;Table<\/span><span class=\"token punctuation\">(<\/span>name <span class=\"token operator\">&#061;<\/span> <span class=\"token string\">&#034;risk_event&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n<span class=\"token annotation punctuation\">&#064;Data<\/span><br \/>\n<span class=\"token keyword\">public<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token class-name\">RiskEvent<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token annotation punctuation\">&#064;Id<\/span><br \/>\n    <span class=\"token annotation punctuation\">&#064;GeneratedValue<\/span><span class=\"token punctuation\">(<\/span>strategy <span class=\"token operator\">&#061;<\/span> <span class=\"token class-name\">GenerationType<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">IDENTITY<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">Long<\/span> id<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>nullable <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">,<\/span> unique <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">true<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> eventId<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Enumerated<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">EnumType<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">STRING<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>nullable <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">RiskEventType<\/span> eventType<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>nullable <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> ruleCode<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">Long<\/span> customerId<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> accountNumber<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> transactionId<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>precision <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">19<\/span><span class=\"token punctuation\">,<\/span> scale <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">4<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">BigDecimal<\/span> amount<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>nullable <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> description<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Enumerated<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">EnumType<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">STRING<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>nullable <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">RiskEventStatus<\/span> status <span class=\"token operator\">&#061;<\/span> <span class=\"token class-name\">RiskEventStatus<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">PENDING<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">Long<\/span> handledBy<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">LocalDateTime<\/span> handledAt<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> handlingNotes<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;CreationTimestamp<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">LocalDateTime<\/span> createdAt<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;UpdateTimestamp<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">LocalDateTime<\/span> updatedAt<span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token annotation punctuation\">&#064;Entity<\/span><br \/>\n<span class=\"token annotation punctuation\">&#064;Table<\/span><span class=\"token punctuation\">(<\/span>name <span class=\"token operator\">&#061;<\/span> <span class=\"token string\">&#034;risk_parameter&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n<span class=\"token annotation punctuation\">&#064;Data<\/span><br \/>\n<span class=\"token keyword\">public<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token class-name\">RiskParameter<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token annotation punctuation\">&#064;Id<\/span><br \/>\n    <span class=\"token annotation punctuation\">&#064;GeneratedValue<\/span><span class=\"token punctuation\">(<\/span>strategy <span class=\"token operator\">&#061;<\/span> <span class=\"token class-name\">GenerationType<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">IDENTITY<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">Long<\/span> id<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>nullable <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">,<\/span> unique <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">true<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> paramKey<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>nullable <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> paramName<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>nullable <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> paramValue<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> description<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;CreationTimestamp<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">LocalDateTime<\/span> createdAt<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;UpdateTimestamp<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">LocalDateTime<\/span> updatedAt<span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token annotation punctuation\">&#064;Entity<\/span><br \/>\n<span class=\"token annotation punctuation\">&#064;Table<\/span><span class=\"token punctuation\">(<\/span>name <span class=\"token operator\">&#061;<\/span> <span class=\"token string\">&#034;risk_blacklist&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n<span class=\"token annotation punctuation\">&#064;Data<\/span><br \/>\n<span class=\"token keyword\">public<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token class-name\">RiskBlacklist<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token annotation punctuation\">&#064;Id<\/span><br \/>\n    <span class=\"token annotation punctuation\">&#064;GeneratedValue<\/span><span class=\"token punctuation\">(<\/span>strategy <span class=\"token operator\">&#061;<\/span> <span class=\"token class-name\">GenerationType<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">IDENTITY<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">Long<\/span> id<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>nullable <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> entityType<span class=\"token punctuation\">;<\/span> <span class=\"token comment\">\/\/ CUSTOMER, ACCOUNT, IP, DEVICE, etc.<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>nullable <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> entityValue<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>nullable <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> reason<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Column<\/span><span class=\"token punctuation\">(<\/span>nullable <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> source<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;CreationTimestamp<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">LocalDateTime<\/span> createdAt<span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token keyword\">public<\/span> <span class=\"token keyword\">enum<\/span> <span class=\"token class-name\">RiskRuleCategory<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token constant\">FRAUD_DETECTION<\/span><span class=\"token punctuation\">,<\/span>      <span class=\"token comment\">\/\/ \u6b3a\u8bc8\u68c0\u6d4b<\/span><br \/>\n    <span class=\"token constant\">AML_COMPLIANCE<\/span><span class=\"token punctuation\">,<\/span>       <span class=\"token comment\">\/\/ \u53cd\u6d17\u94b1\u5408\u89c4<\/span><br \/>\n    <span class=\"token constant\">TRANSACTION_MONITORING<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token comment\">\/\/ \u4ea4\u6613\u76d1\u63a7<\/span><br \/>\n    <span class=\"token constant\">CREDIT_RISK<\/span><span class=\"token punctuation\">,<\/span>          <span class=\"token comment\">\/\/ \u4fe1\u7528\u98ce\u9669<\/span><br \/>\n    <span class=\"token constant\">OPERATIONAL_RISK<\/span>      <span class=\"token comment\">\/\/ \u64cd\u4f5c\u98ce\u9669<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token keyword\">public<\/span> <span class=\"token keyword\">enum<\/span> <span class=\"token class-name\">RiskRuleStatus<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token constant\">DRAFT<\/span><span class=\"token punctuation\">,<\/span>        <span class=\"token comment\">\/\/ \u8349\u7a3f<\/span><br \/>\n    <span class=\"token constant\">TESTING<\/span><span class=\"token punctuation\">,<\/span>      <span class=\"token comment\">\/\/ \u6d4b\u8bd5\u4e2d<\/span><br \/>\n    <span class=\"token constant\">PRODUCTION<\/span><span class=\"token punctuation\">,<\/span>   <span class=\"token comment\">\/\/ \u751f\u4ea7\u4e2d<\/span><br \/>\n    <span class=\"token constant\">DISABLED<\/span>      <span class=\"token comment\">\/\/ \u5df2\u7981\u7528<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token keyword\">public<\/span> <span class=\"token keyword\">enum<\/span> <span class=\"token class-name\">RiskEventType<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token constant\">SUSPICIOUS_TRANSACTION<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token comment\">\/\/ \u53ef\u7591\u4ea4\u6613<\/span><br \/>\n    <span class=\"token constant\">HIGH_RISK_CUSTOMER<\/span><span class=\"token punctuation\">,<\/span>     <span class=\"token comment\">\/\/ \u9ad8\u98ce\u9669\u5ba2\u6237<\/span><br \/>\n    <span class=\"token constant\">AML_ALERT<\/span><span class=\"token punctuation\">,<\/span>              <span class=\"token comment\">\/\/ \u53cd\u6d17\u94b1\u8b66\u62a5<\/span><br \/>\n    <span class=\"token constant\">FRAUD_ATTEMPT<\/span><span class=\"token punctuation\">,<\/span>          <span class=\"token comment\">\/\/ \u6b3a\u8bc8\u5c1d\u8bd5<\/span><br \/>\n    <span class=\"token constant\">POLICY_VIOLATION<\/span>        <span class=\"token comment\">\/\/ \u653f\u7b56\u8fdd\u89c4<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token keyword\">public<\/span> <span class=\"token keyword\">enum<\/span> <span class=\"token class-name\">RiskEventStatus<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token constant\">PENDING<\/span><span class=\"token punctuation\">,<\/span>      <span class=\"token comment\">\/\/ \u5f85\u5904\u7406<\/span><br \/>\n    <span class=\"token constant\">REVIEWING<\/span><span class=\"token punctuation\">,<\/span>    <span class=\"token comment\">\/\/ \u5ba1\u6838\u4e2d<\/span><br \/>\n    <span class=\"token constant\">APPROVED<\/span><span class=\"token punctuation\">,<\/span>     <span class=\"token comment\">\/\/ \u5df2\u6279\u51c6<\/span><br \/>\n    <span class=\"token constant\">REJECTED<\/span><span class=\"token punctuation\">,<\/span>     <span class=\"token comment\">\/\/ \u5df2\u62d2\u7edd<\/span><br \/>\n    <span class=\"token constant\">MITIGATED<\/span>     <span class=\"token comment\">\/\/ \u5df2\u7f13\u89e3<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token annotation punctuation\">&#064;Data<\/span><br \/>\n<span class=\"token keyword\">public<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token class-name\">RiskRuleDTO<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">Long<\/span> id<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> ruleCode<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> ruleName<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">RiskRuleCategory<\/span> category<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> ruleExpression<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">Integer<\/span> priority<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">Boolean<\/span> isActive<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">RiskRuleStatus<\/span> status<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> action<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">LocalDateTime<\/span> createdAt<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">LocalDateTime<\/span> updatedAt<span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token annotation punctuation\">&#064;Data<\/span><br \/>\n<span class=\"token keyword\">public<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token class-name\">RiskRuleRequest<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token annotation punctuation\">&#064;NotBlank<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> ruleName<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;NotNull<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">RiskRuleCategory<\/span> category<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;NotBlank<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> ruleExpression<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;NotNull<\/span><br \/>\n    <span class=\"token annotation punctuation\">&#064;Min<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">1<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token annotation punctuation\">&#064;Max<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">100<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">Integer<\/span> priority<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> action<span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token annotation punctuation\">&#064;Data<\/span><br \/>\n<span class=\"token keyword\">public<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token class-name\">RiskEventDTO<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">Long<\/span> id<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> eventId<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">RiskEventType<\/span> eventType<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> ruleCode<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">Long<\/span> customerId<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> accountNumber<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> transactionId<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">BigDecimal<\/span> amount<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> description<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">RiskEventStatus<\/span> status<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">Long<\/span> handledBy<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">LocalDateTime<\/span> handledAt<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> handlingNotes<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">LocalDateTime<\/span> createdAt<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">LocalDateTime<\/span> updatedAt<span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token annotation punctuation\">&#064;Data<\/span><br \/>\n<span class=\"token keyword\">public<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token class-name\">RiskParameterDTO<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">Long<\/span> id<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> paramKey<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> paramName<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> paramValue<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> description<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">LocalDateTime<\/span> createdAt<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">LocalDateTime<\/span> updatedAt<span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token annotation punctuation\">&#064;Data<\/span><br \/>\n<span class=\"token keyword\">public<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token class-name\">RiskBlacklistDTO<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">Long<\/span> id<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> entityType<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> entityValue<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> reason<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> source<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">LocalDateTime<\/span> createdAt<span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token annotation punctuation\">&#064;Data<\/span><br \/>\n<span class=\"token keyword\">public<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token class-name\">RiskAssessmentResult<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> transactionId<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">BigDecimal<\/span> riskScore<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> riskLevel<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">Map<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">String<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">String<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> triggeredRules<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> recommendation<span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p>\u89c4\u5219\u5f15\u64ce\u5de5\u5177<\/p>\n<p><span class=\"token annotation punctuation\">&#064;Component<\/span><br \/>\n<span class=\"token keyword\">public<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token class-name\">RiskEngineHelper<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">public<\/span> <span class=\"token keyword\">boolean<\/span> <span class=\"token function\">evaluateRule<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">String<\/span> ruleExpression<span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">Map<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">String<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">Object<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> data<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">try<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token class-name\">Serializable<\/span> compiled <span class=\"token operator\">&#061;<\/span> <span class=\"token constant\">MVEL<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">compileExpression<\/span><span class=\"token punctuation\">(<\/span>ruleExpression<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            <span class=\"token keyword\">return<\/span> <span class=\"token constant\">MVEL<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">executeExpression<\/span><span class=\"token punctuation\">(<\/span>compiled<span class=\"token punctuation\">,<\/span> data<span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">Boolean<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">class<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">catch<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token class-name\">Exception<\/span> e<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">throw<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">RuntimeException<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;Failed to evaluate rule: &#034;<\/span> <span class=\"token operator\">&#043;<\/span> e<span class=\"token punctuation\">.<\/span><span class=\"token function\">getMessage<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span> e<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p>Controller\u5c42<\/p>\n<p><span class=\"token annotation punctuation\">&#064;RestController<\/span><br \/>\n<span class=\"token annotation punctuation\">&#064;RequestMapping<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;\/api\/risk\/rules&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n<span class=\"token annotation punctuation\">&#064;RequiredArgsConstructor<\/span><br \/>\n<span class=\"token keyword\">public<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token class-name\">RiskRuleController<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">final<\/span> <span class=\"token class-name\">RiskRuleService<\/span> ruleService<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;PostMapping<\/span><br \/>\n    <span class=\"token annotation punctuation\">&#064;PreAuthorize<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;hasAnyRole(&#039;RISK_MANAGER&#039;, &#039;ADMIN&#039;)&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">RiskRuleDTO<\/span> <span class=\"token function\">createRule<\/span><span class=\"token punctuation\">(<\/span><span class=\"token annotation punctuation\">&#064;Valid<\/span> <span class=\"token annotation punctuation\">&#064;RequestBody<\/span> <span class=\"token class-name\">RiskRuleRequest<\/span> request<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> ruleService<span class=\"token punctuation\">.<\/span><span class=\"token function\">createRule<\/span><span class=\"token punctuation\">(<\/span>request<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;PutMapping<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;\/{ruleCode}\/status\/{status}&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token annotation punctuation\">&#064;PreAuthorize<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;hasAnyRole(&#039;RISK_MANAGER&#039;, &#039;ADMIN&#039;)&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">RiskRuleDTO<\/span> <span class=\"token function\">updateRuleStatus<\/span><span class=\"token punctuation\">(<\/span><br \/>\n            <span class=\"token annotation punctuation\">&#064;PathVariable<\/span> <span class=\"token class-name\">String<\/span> ruleCode<span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token annotation punctuation\">&#064;PathVariable<\/span> <span class=\"token class-name\">RiskRuleStatus<\/span> status<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> ruleService<span class=\"token punctuation\">.<\/span><span class=\"token function\">updateRuleStatus<\/span><span class=\"token punctuation\">(<\/span>ruleCode<span class=\"token punctuation\">,<\/span> status<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;PutMapping<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;\/{ruleCode}\/active\/{isActive}&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token annotation punctuation\">&#064;PreAuthorize<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;hasAnyRole(&#039;RISK_MANAGER&#039;, &#039;ADMIN&#039;)&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">RiskRuleDTO<\/span> <span class=\"token function\">toggleRuleActivation<\/span><span class=\"token punctuation\">(<\/span><br \/>\n            <span class=\"token annotation punctuation\">&#064;PathVariable<\/span> <span class=\"token class-name\">String<\/span> ruleCode<span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token annotation punctuation\">&#064;PathVariable<\/span> <span class=\"token class-name\">Boolean<\/span> isActive<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> ruleService<span class=\"token punctuation\">.<\/span><span class=\"token function\">toggleRuleActivation<\/span><span class=\"token punctuation\">(<\/span>ruleCode<span class=\"token punctuation\">,<\/span> isActive<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;GetMapping<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;\/category\/{category}&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">List<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">RiskRuleDTO<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> <span class=\"token function\">getRulesByCategory<\/span><span class=\"token punctuation\">(<\/span><span class=\"token annotation punctuation\">&#064;PathVariable<\/span> <span class=\"token class-name\">String<\/span> category<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> ruleService<span class=\"token punctuation\">.<\/span><span class=\"token function\">getActiveRulesByCategory<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">RiskRuleCategory<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">valueOf<\/span><span class=\"token punctuation\">(<\/span>category<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;GetMapping<\/span><br \/>\n    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">List<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">RiskRuleDTO<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> <span class=\"token function\">getAllActiveRules<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> ruleService<span class=\"token punctuation\">.<\/span><span class=\"token function\">getAllActiveRules<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token annotation punctuation\">&#064;RestController<\/span><br \/>\n<span class=\"token annotation punctuation\">&#064;RequestMapping<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;\/api\/risk\/assessments&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n<span class=\"token annotation punctuation\">&#064;RequiredArgsConstructor<\/span><br \/>\n<span class=\"token keyword\">public<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token class-name\">RiskAssessmentController<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">final<\/span> <span class=\"token class-name\">RiskEngineService<\/span> riskEngineService<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;PostMapping<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;\/transactions&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">RiskAssessmentResult<\/span> <span class=\"token function\">assessTransactionRisk<\/span><span class=\"token punctuation\">(<\/span><br \/>\n            <span class=\"token annotation punctuation\">&#064;RequestParam<\/span> <span class=\"token class-name\">String<\/span> transactionId<span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token annotation punctuation\">&#064;RequestParam<\/span> <span class=\"token class-name\">String<\/span> accountNumber<span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token annotation punctuation\">&#064;RequestParam<\/span> <span class=\"token class-name\">Long<\/span> customerId<span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token annotation punctuation\">&#064;RequestParam<\/span> <span class=\"token class-name\">BigDecimal<\/span> amount<span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token annotation punctuation\">&#064;RequestBody<\/span> <span class=\"token class-name\">Map<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">String<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">Object<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> transactionData<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><\/p>\n<p>        <span class=\"token keyword\">return<\/span> riskEngineService<span class=\"token punctuation\">.<\/span><span class=\"token function\">assessTransactionRisk<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                transactionId<span class=\"token punctuation\">,<\/span> accountNumber<span class=\"token punctuation\">,<\/span> customerId<span class=\"token punctuation\">,<\/span> amount<span class=\"token punctuation\">,<\/span> transactionData<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;PostMapping<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;\/customers\/{customerId}&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">RiskAssessmentResult<\/span> <span class=\"token function\">assessCustomerRisk<\/span><span class=\"token punctuation\">(<\/span><br \/>\n            <span class=\"token annotation punctuation\">&#064;PathVariable<\/span> <span class=\"token class-name\">Long<\/span> customerId<span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token annotation punctuation\">&#064;RequestBody<\/span> <span class=\"token class-name\">Map<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">String<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">Object<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> customerData<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><\/p>\n<p>        <span class=\"token keyword\">return<\/span> riskEngineService<span class=\"token punctuation\">.<\/span><span class=\"token function\">assessCustomerRisk<\/span><span class=\"token punctuation\">(<\/span>customerId<span class=\"token punctuation\">,<\/span> customerData<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token annotation punctuation\">&#064;RestController<\/span><br \/>\n<span class=\"token annotation punctuation\">&#064;RequestMapping<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;\/api\/risk\/events&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n<span class=\"token annotation punctuation\">&#064;RequiredArgsConstructor<\/span><br \/>\n<span class=\"token keyword\">public<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token class-name\">RiskEventController<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">final<\/span> <span class=\"token class-name\">RiskEventService<\/span> eventService<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;GetMapping<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;\/pending&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token annotation punctuation\">&#064;PreAuthorize<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;hasAnyRole(&#039;RISK_OFFICER&#039;, &#039;RISK_MANAGER&#039;, &#039;ADMIN&#039;)&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">List<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">RiskEventDTO<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> <span class=\"token function\">getPendingEvents<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> eventService<span class=\"token punctuation\">.<\/span><span class=\"token function\">getPendingEvents<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;GetMapping<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;\/customers\/{customerId}&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token annotation punctuation\">&#064;PreAuthorize<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;hasAnyRole(&#039;RISK_OFFICER&#039;, &#039;RISK_MANAGER&#039;, &#039;ADMIN&#039;)&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">List<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">RiskEventDTO<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> <span class=\"token function\">getCustomerEvents<\/span><span class=\"token punctuation\">(<\/span><br \/>\n            <span class=\"token annotation punctuation\">&#064;PathVariable<\/span> <span class=\"token class-name\">Long<\/span> customerId<span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token annotation punctuation\">&#064;RequestParam<\/span><span class=\"token punctuation\">(<\/span>defaultValue <span class=\"token operator\">&#061;<\/span> <span class=\"token string\">&#034;30&#034;<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token keyword\">int<\/span> days<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> eventService<span class=\"token punctuation\">.<\/span><span class=\"token function\">getEventsByCustomer<\/span><span class=\"token punctuation\">(<\/span>customerId<span class=\"token punctuation\">,<\/span> days<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;PutMapping<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;\/{eventId}\/status\/{status}&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token annotation punctuation\">&#064;PreAuthorize<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;hasAnyRole(&#039;RISK_OFFICER&#039;, &#039;RISK_MANAGER&#039;, &#039;ADMIN&#039;)&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">RiskEventDTO<\/span> <span class=\"token function\">updateEventStatus<\/span><span class=\"token punctuation\">(<\/span><br \/>\n            <span class=\"token annotation punctuation\">&#064;PathVariable<\/span> <span class=\"token class-name\">String<\/span> eventId<span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token annotation punctuation\">&#064;PathVariable<\/span> <span class=\"token class-name\">RiskEventStatus<\/span> status<span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token annotation punctuation\">&#064;RequestParam<\/span> <span class=\"token class-name\">String<\/span> notes<span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token annotation punctuation\">&#064;RequestParam<\/span> <span class=\"token class-name\">Long<\/span> userId<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> eventService<span class=\"token punctuation\">.<\/span><span class=\"token function\">updateEventStatus<\/span><span class=\"token punctuation\">(<\/span>eventId<span class=\"token punctuation\">,<\/span> status<span class=\"token punctuation\">,<\/span> notes<span class=\"token punctuation\">,<\/span> userId<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token annotation punctuation\">&#064;RestController<\/span><br \/>\n<span class=\"token annotation punctuation\">&#064;RequestMapping<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;\/api\/risk\/blacklist&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n<span class=\"token annotation punctuation\">&#064;RequiredArgsConstructor<\/span><br \/>\n<span class=\"token keyword\">public<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token class-name\">RiskBlacklistController<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">final<\/span> <span class=\"token class-name\">RiskBlacklistService<\/span> blacklistService<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;PostMapping<\/span><br \/>\n    <span class=\"token annotation punctuation\">&#064;PreAuthorize<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;hasAnyRole(&#039;RISK_OFFICER&#039;, &#039;RISK_MANAGER&#039;, &#039;ADMIN&#039;)&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">RiskBlacklistDTO<\/span> <span class=\"token function\">addToBlacklist<\/span><span class=\"token punctuation\">(<\/span><br \/>\n            <span class=\"token annotation punctuation\">&#064;RequestParam<\/span> <span class=\"token class-name\">String<\/span> entityType<span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token annotation punctuation\">&#064;RequestParam<\/span> <span class=\"token class-name\">String<\/span> entityValue<span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token annotation punctuation\">&#064;RequestParam<\/span> <span class=\"token class-name\">String<\/span> reason<span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token annotation punctuation\">&#064;RequestParam<\/span> <span class=\"token class-name\">String<\/span> source<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> blacklistService<span class=\"token punctuation\">.<\/span><span class=\"token function\">addToBlacklist<\/span><span class=\"token punctuation\">(<\/span>entityType<span class=\"token punctuation\">,<\/span> entityValue<span class=\"token punctuation\">,<\/span> reason<span class=\"token punctuation\">,<\/span> source<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;DeleteMapping<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;\/{id}&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token annotation punctuation\">&#064;PreAuthorize<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;hasAnyRole(&#039;RISK_OFFICER&#039;, &#039;RISK_MANAGER&#039;, &#039;ADMIN&#039;)&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">public<\/span> <span class=\"token keyword\">void<\/span> <span class=\"token function\">removeFromBlacklist<\/span><span class=\"token punctuation\">(<\/span><span class=\"token annotation punctuation\">&#064;PathVariable<\/span> <span class=\"token class-name\">Long<\/span> id<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        blacklistService<span class=\"token punctuation\">.<\/span><span class=\"token function\">removeFromBlacklist<\/span><span class=\"token punctuation\">(<\/span>id<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;GetMapping<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;\/check&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">public<\/span> <span class=\"token keyword\">boolean<\/span> <span class=\"token function\">isBlacklisted<\/span><span class=\"token punctuation\">(<\/span><br \/>\n            <span class=\"token annotation punctuation\">&#064;RequestParam<\/span> <span class=\"token class-name\">String<\/span> entityType<span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token annotation punctuation\">&#064;RequestParam<\/span> <span class=\"token class-name\">String<\/span> entityValue<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> blacklistService<span class=\"token punctuation\">.<\/span><span class=\"token function\">isBlacklisted<\/span><span class=\"token punctuation\">(<\/span>entityType<span class=\"token punctuation\">,<\/span> entityValue<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;GetMapping<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;\/type\/{entityType}&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token annotation punctuation\">&#064;PreAuthorize<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;hasAnyRole(&#039;RISK_OFFICER&#039;, &#039;RISK_MANAGER&#039;, &#039;ADMIN&#039;)&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">List<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">RiskBlacklistDTO<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> <span class=\"token function\">getBlacklistByType<\/span><span class=\"token punctuation\">(<\/span><span class=\"token annotation punctuation\">&#064;PathVariable<\/span> <span class=\"token class-name\">String<\/span> entityType<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> blacklistService<span class=\"token punctuation\">.<\/span><span class=\"token function\">getBlacklistByType<\/span><span class=\"token punctuation\">(<\/span>entityType<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p>Service\u5c42<\/p>\n<p><span class=\"token annotation punctuation\">&#064;Service<\/span><br \/>\n<span class=\"token annotation punctuation\">&#064;RequiredArgsConstructor<\/span><br \/>\n<span class=\"token annotation punctuation\">&#064;Slf4j<\/span><br \/>\n<span class=\"token keyword\">public<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token class-name\">RiskRuleService<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">final<\/span> <span class=\"token class-name\">RiskRuleRepository<\/span> ruleRepository<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">final<\/span> <span class=\"token class-name\">RuleCodeGenerator<\/span> codeGenerator<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Transactional<\/span><br \/>\n    <span class=\"token annotation punctuation\">&#064;PreAuthorize<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;hasAnyRole(&#039;RISK_MANAGER&#039;, &#039;ADMIN&#039;)&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">RiskRuleDTO<\/span> <span class=\"token function\">createRule<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">RiskRuleRequest<\/span> request<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token class-name\">RiskRule<\/span> rule <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">RiskRule<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        rule<span class=\"token punctuation\">.<\/span><span class=\"token function\">setRuleCode<\/span><span class=\"token punctuation\">(<\/span>codeGenerator<span class=\"token punctuation\">.<\/span><span class=\"token function\">generate<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        rule<span class=\"token punctuation\">.<\/span><span class=\"token function\">setRuleName<\/span><span class=\"token punctuation\">(<\/span>request<span class=\"token punctuation\">.<\/span><span class=\"token function\">getRuleName<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        rule<span class=\"token punctuation\">.<\/span><span class=\"token function\">setCategory<\/span><span class=\"token punctuation\">(<\/span>request<span class=\"token punctuation\">.<\/span><span class=\"token function\">getCategory<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        rule<span class=\"token punctuation\">.<\/span><span class=\"token function\">setRuleExpression<\/span><span class=\"token punctuation\">(<\/span>request<span class=\"token punctuation\">.<\/span><span class=\"token function\">getRuleExpression<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        rule<span class=\"token punctuation\">.<\/span><span class=\"token function\">setPriority<\/span><span class=\"token punctuation\">(<\/span>request<span class=\"token punctuation\">.<\/span><span class=\"token function\">getPriority<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        rule<span class=\"token punctuation\">.<\/span><span class=\"token function\">setAction<\/span><span class=\"token punctuation\">(<\/span>request<span class=\"token punctuation\">.<\/span><span class=\"token function\">getAction<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token class-name\">RiskRule<\/span> saved <span class=\"token operator\">&#061;<\/span> ruleRepository<span class=\"token punctuation\">.<\/span><span class=\"token function\">save<\/span><span class=\"token punctuation\">(<\/span>rule<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        log<span class=\"token punctuation\">.<\/span><span class=\"token function\">info<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;Risk rule created: {}&#034;<\/span><span class=\"token punctuation\">,<\/span> saved<span class=\"token punctuation\">.<\/span><span class=\"token function\">getRuleCode<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">return<\/span> <span class=\"token function\">convertToDTO<\/span><span class=\"token punctuation\">(<\/span>saved<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Transactional<\/span><br \/>\n    <span class=\"token annotation punctuation\">&#064;PreAuthorize<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;hasAnyRole(&#039;RISK_MANAGER&#039;, &#039;ADMIN&#039;)&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">RiskRuleDTO<\/span> <span class=\"token function\">updateRuleStatus<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">String<\/span> ruleCode<span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">RiskRuleStatus<\/span> status<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token class-name\">RiskRule<\/span> rule <span class=\"token operator\">&#061;<\/span> ruleRepository<span class=\"token punctuation\">.<\/span><span class=\"token function\">findByRuleCode<\/span><span class=\"token punctuation\">(<\/span>ruleCode<span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">orElseThrow<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">-&gt;<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">AccountException<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">ErrorCode<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">RISK_RULE_NOT_FOUND<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        rule<span class=\"token punctuation\">.<\/span><span class=\"token function\">setStatus<\/span><span class=\"token punctuation\">(<\/span>status<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token class-name\">RiskRule<\/span> saved <span class=\"token operator\">&#061;<\/span> ruleRepository<span class=\"token punctuation\">.<\/span><span class=\"token function\">save<\/span><span class=\"token punctuation\">(<\/span>rule<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        log<span class=\"token punctuation\">.<\/span><span class=\"token function\">info<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;Risk rule status updated to {}: {}&#034;<\/span><span class=\"token punctuation\">,<\/span> status<span class=\"token punctuation\">,<\/span> ruleCode<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">return<\/span> <span class=\"token function\">convertToDTO<\/span><span class=\"token punctuation\">(<\/span>saved<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Transactional<\/span><br \/>\n    <span class=\"token annotation punctuation\">&#064;PreAuthorize<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;hasAnyRole(&#039;RISK_MANAGER&#039;, &#039;ADMIN&#039;)&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">RiskRuleDTO<\/span> <span class=\"token function\">toggleRuleActivation<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">String<\/span> ruleCode<span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">Boolean<\/span> isActive<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token class-name\">RiskRule<\/span> rule <span class=\"token operator\">&#061;<\/span> ruleRepository<span class=\"token punctuation\">.<\/span><span class=\"token function\">findByRuleCode<\/span><span class=\"token punctuation\">(<\/span>ruleCode<span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">orElseThrow<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">-&gt;<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">AccountException<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">ErrorCode<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">RISK_RULE_NOT_FOUND<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        rule<span class=\"token punctuation\">.<\/span><span class=\"token function\">setIsActive<\/span><span class=\"token punctuation\">(<\/span>isActive<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token class-name\">RiskRule<\/span> saved <span class=\"token operator\">&#061;<\/span> ruleRepository<span class=\"token punctuation\">.<\/span><span class=\"token function\">save<\/span><span class=\"token punctuation\">(<\/span>rule<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        log<span class=\"token punctuation\">.<\/span><span class=\"token function\">info<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;Risk rule activation set to {}: {}&#034;<\/span><span class=\"token punctuation\">,<\/span> isActive<span class=\"token punctuation\">,<\/span> ruleCode<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">return<\/span> <span class=\"token function\">convertToDTO<\/span><span class=\"token punctuation\">(<\/span>saved<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Transactional<\/span><span class=\"token punctuation\">(<\/span>readOnly <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">true<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">List<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">RiskRuleDTO<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> <span class=\"token function\">getActiveRulesByCategory<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">RiskRuleCategory<\/span> category<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> ruleRepository<span class=\"token punctuation\">.<\/span><span class=\"token function\">findByCategoryAndIsActiveTrue<\/span><span class=\"token punctuation\">(<\/span>category<span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">stream<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">map<\/span><span class=\"token punctuation\">(<\/span><span class=\"token keyword\">this<\/span><span class=\"token operator\">::<\/span><span class=\"token function\">convertToDTO<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">collect<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">Collectors<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">toList<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Transactional<\/span><span class=\"token punctuation\">(<\/span>readOnly <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">true<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">List<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">RiskRuleDTO<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> <span class=\"token function\">getAllActiveRules<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> ruleRepository<span class=\"token punctuation\">.<\/span><span class=\"token function\">findAllActiveRules<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">stream<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">map<\/span><span class=\"token punctuation\">(<\/span><span class=\"token keyword\">this<\/span><span class=\"token operator\">::<\/span><span class=\"token function\">convertToDTO<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">collect<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">Collectors<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">toList<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">RiskRuleDTO<\/span> <span class=\"token function\">convertToDTO<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">RiskRule<\/span> rule<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token class-name\">RiskRuleDTO<\/span> dto <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">RiskRuleDTO<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        dto<span class=\"token punctuation\">.<\/span><span class=\"token function\">setId<\/span><span class=\"token punctuation\">(<\/span>rule<span class=\"token punctuation\">.<\/span><span class=\"token function\">getId<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        dto<span class=\"token punctuation\">.<\/span><span class=\"token function\">setRuleCode<\/span><span class=\"token punctuation\">(<\/span>rule<span class=\"token punctuation\">.<\/span><span class=\"token function\">getRuleCode<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        dto<span class=\"token punctuation\">.<\/span><span class=\"token function\">setRuleName<\/span><span class=\"token punctuation\">(<\/span>rule<span class=\"token punctuation\">.<\/span><span class=\"token function\">getRuleName<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        dto<span class=\"token punctuation\">.<\/span><span class=\"token function\">setCategory<\/span><span class=\"token punctuation\">(<\/span>rule<span class=\"token punctuation\">.<\/span><span class=\"token function\">getCategory<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        dto<span class=\"token punctuation\">.<\/span><span class=\"token function\">setRuleExpression<\/span><span class=\"token punctuation\">(<\/span>rule<span class=\"token punctuation\">.<\/span><span class=\"token function\">getRuleExpression<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        dto<span class=\"token punctuation\">.<\/span><span class=\"token function\">setPriority<\/span><span class=\"token punctuation\">(<\/span>rule<span class=\"token punctuation\">.<\/span><span class=\"token function\">getPriority<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        dto<span class=\"token punctuation\">.<\/span><span class=\"token function\">setIsActive<\/span><span class=\"token punctuation\">(<\/span>rule<span class=\"token punctuation\">.<\/span><span class=\"token function\">getIsActive<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        dto<span class=\"token punctuation\">.<\/span><span class=\"token function\">setStatus<\/span><span class=\"token punctuation\">(<\/span>rule<span class=\"token punctuation\">.<\/span><span class=\"token function\">getStatus<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        dto<span class=\"token punctuation\">.<\/span><span class=\"token function\">setAction<\/span><span class=\"token punctuation\">(<\/span>rule<span class=\"token punctuation\">.<\/span><span class=\"token function\">getAction<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        dto<span class=\"token punctuation\">.<\/span><span class=\"token function\">setCreatedAt<\/span><span class=\"token punctuation\">(<\/span>rule<span class=\"token punctuation\">.<\/span><span class=\"token function\">getCreatedAt<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        dto<span class=\"token punctuation\">.<\/span><span class=\"token function\">setUpdatedAt<\/span><span class=\"token punctuation\">(<\/span>rule<span class=\"token punctuation\">.<\/span><span class=\"token function\">getUpdatedAt<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> dto<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token comment\">\/**<br \/>\n\u98ce\u9669\u7ba1\u7406\u5f15\u64ce<br \/>\n*\/<\/span><br \/>\n<span class=\"token annotation punctuation\">&#064;Service<\/span><br \/>\n<span class=\"token annotation punctuation\">&#064;RequiredArgsConstructor<\/span><br \/>\n<span class=\"token annotation punctuation\">&#064;Slf4j<\/span><br \/>\n<span class=\"token keyword\">public<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token class-name\">RiskEngineService<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">final<\/span> <span class=\"token class-name\">RiskRuleRepository<\/span> ruleRepository<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">final<\/span> <span class=\"token class-name\">RiskEventService<\/span> eventService<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">final<\/span> <span class=\"token class-name\">RiskEngineHelper<\/span> engineHelper<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Transactional<\/span><br \/>\n    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">RiskAssessmentResult<\/span> <span class=\"token function\">assessTransactionRisk<\/span><span class=\"token punctuation\">(<\/span><br \/>\n            <span class=\"token class-name\">String<\/span> transactionId<span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token class-name\">String<\/span> accountNumber<span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token class-name\">Long<\/span> customerId<span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token class-name\">BigDecimal<\/span> amount<span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token class-name\">Map<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">String<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">Object<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> transactionData<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><\/p>\n<p>        <span class=\"token class-name\">List<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">RiskRule<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> activeRules <span class=\"token operator\">&#061;<\/span> ruleRepository<span class=\"token punctuation\">.<\/span><span class=\"token function\">findAllActiveRules<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token class-name\">BigDecimal<\/span> riskScore <span class=\"token operator\">&#061;<\/span> <span class=\"token class-name\">BigDecimal<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">ZERO<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token class-name\">Map<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">String<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">String<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> triggeredRules <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">HashMap<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">for<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token class-name\">RiskRule<\/span> rule <span class=\"token operator\">:<\/span> activeRules<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">try<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                <span class=\"token keyword\">boolean<\/span> isTriggered <span class=\"token operator\">&#061;<\/span> engineHelper<span class=\"token punctuation\">.<\/span><span class=\"token function\">evaluateRule<\/span><span class=\"token punctuation\">(<\/span>rule<span class=\"token punctuation\">.<\/span><span class=\"token function\">getRuleExpression<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span> transactionData<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n                <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>isTriggered<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                    riskScore <span class=\"token operator\">&#061;<\/span> riskScore<span class=\"token punctuation\">.<\/span><span class=\"token function\">add<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">BigDecimal<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">valueOf<\/span><span class=\"token punctuation\">(<\/span>rule<span class=\"token punctuation\">.<\/span><span class=\"token function\">getPriority<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n                    triggeredRules<span class=\"token punctuation\">.<\/span><span class=\"token function\">put<\/span><span class=\"token punctuation\">(<\/span>rule<span class=\"token punctuation\">.<\/span><span class=\"token function\">getRuleCode<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span> rule<span class=\"token punctuation\">.<\/span><span class=\"token function\">getRuleName<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>                    <span class=\"token comment\">\/\/ \u8bb0\u5f55\u98ce\u9669\u4e8b\u4ef6<\/span><br \/>\n                    <span class=\"token class-name\">RiskEventDTO<\/span> event <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">RiskEventDTO<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n                    event<span class=\"token punctuation\">.<\/span><span class=\"token function\">setEventType<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">RiskEventType<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">SUSPICIOUS_TRANSACTION<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n                    event<span class=\"token punctuation\">.<\/span><span class=\"token function\">setRuleCode<\/span><span class=\"token punctuation\">(<\/span>rule<span class=\"token punctuation\">.<\/span><span class=\"token function\">getRuleCode<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n                    event<span class=\"token punctuation\">.<\/span><span class=\"token function\">setCustomerId<\/span><span class=\"token punctuation\">(<\/span>customerId<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n                    event<span class=\"token punctuation\">.<\/span><span class=\"token function\">setAccountNumber<\/span><span class=\"token punctuation\">(<\/span>accountNumber<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n                    event<span class=\"token punctuation\">.<\/span><span class=\"token function\">setTransactionId<\/span><span class=\"token punctuation\">(<\/span>transactionId<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n                    event<span class=\"token punctuation\">.<\/span><span class=\"token function\">setAmount<\/span><span class=\"token punctuation\">(<\/span>amount<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n                    event<span class=\"token punctuation\">.<\/span><span class=\"token function\">setDescription<\/span><span class=\"token punctuation\">(<\/span>rule<span class=\"token punctuation\">.<\/span><span class=\"token function\">getRuleName<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#043;<\/span> <span class=\"token string\">&#034; triggered&#034;<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n                    event<span class=\"token punctuation\">.<\/span><span class=\"token function\">setStatus<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">RiskEventStatus<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">PENDING<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>                    eventService<span class=\"token punctuation\">.<\/span><span class=\"token function\">createEvent<\/span><span class=\"token punctuation\">(<\/span>event<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n                <span class=\"token punctuation\">}<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">catch<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token class-name\">Exception<\/span> e<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                log<span class=\"token punctuation\">.<\/span><span class=\"token function\">error<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;Error evaluating risk rule {}: {}&#034;<\/span><span class=\"token punctuation\">,<\/span> rule<span class=\"token punctuation\">.<\/span><span class=\"token function\">getRuleCode<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span> e<span class=\"token punctuation\">.<\/span><span class=\"token function\">getMessage<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><\/p>\n<p>        <span class=\"token class-name\">RiskAssessmentResult<\/span> result <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">RiskAssessmentResult<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        result<span class=\"token punctuation\">.<\/span><span class=\"token function\">setTransactionId<\/span><span class=\"token punctuation\">(<\/span>transactionId<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        result<span class=\"token punctuation\">.<\/span><span class=\"token function\">setRiskScore<\/span><span class=\"token punctuation\">(<\/span>riskScore<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        result<span class=\"token punctuation\">.<\/span><span class=\"token function\">setRiskLevel<\/span><span class=\"token punctuation\">(<\/span><span class=\"token function\">determineRiskLevel<\/span><span class=\"token punctuation\">(<\/span>riskScore<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        result<span class=\"token punctuation\">.<\/span><span class=\"token function\">setTriggeredRules<\/span><span class=\"token punctuation\">(<\/span>triggeredRules<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        result<span class=\"token punctuation\">.<\/span><span class=\"token function\">setRecommendation<\/span><span class=\"token punctuation\">(<\/span><span class=\"token function\">generateRecommendation<\/span><span class=\"token punctuation\">(<\/span>riskScore<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        log<span class=\"token punctuation\">.<\/span><span class=\"token function\">info<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;Risk assessment completed for transaction {}: score {}&#034;<\/span><span class=\"token punctuation\">,<\/span> transactionId<span class=\"token punctuation\">,<\/span> riskScore<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">return<\/span> result<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Transactional<\/span><br \/>\n    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">RiskAssessmentResult<\/span> <span class=\"token function\">assessCustomerRisk<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">Long<\/span> customerId<span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">Map<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">String<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">Object<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> customerData<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token class-name\">List<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">RiskRule<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> activeRules <span class=\"token operator\">&#061;<\/span> ruleRepository<span class=\"token punctuation\">.<\/span><span class=\"token function\">findAllActiveRules<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token class-name\">BigDecimal<\/span> riskScore <span class=\"token operator\">&#061;<\/span> <span class=\"token class-name\">BigDecimal<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">ZERO<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token class-name\">Map<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">String<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">String<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> triggeredRules <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">HashMap<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">for<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token class-name\">RiskRule<\/span> rule <span class=\"token operator\">:<\/span> activeRules<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">try<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                <span class=\"token keyword\">boolean<\/span> isTriggered <span class=\"token operator\">&#061;<\/span> engineHelper<span class=\"token punctuation\">.<\/span><span class=\"token function\">evaluateRule<\/span><span class=\"token punctuation\">(<\/span>rule<span class=\"token punctuation\">.<\/span><span class=\"token function\">getRuleExpression<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span> customerData<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n                <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>isTriggered<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                    riskScore <span class=\"token operator\">&#061;<\/span> riskScore<span class=\"token punctuation\">.<\/span><span class=\"token function\">add<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">BigDecimal<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">valueOf<\/span><span class=\"token punctuation\">(<\/span>rule<span class=\"token punctuation\">.<\/span><span class=\"token function\">getPriority<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n                    triggeredRules<span class=\"token punctuation\">.<\/span><span class=\"token function\">put<\/span><span class=\"token punctuation\">(<\/span>rule<span class=\"token punctuation\">.<\/span><span class=\"token function\">getRuleCode<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span> rule<span class=\"token punctuation\">.<\/span><span class=\"token function\">getRuleName<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>                    <span class=\"token comment\">\/\/ \u8bb0\u5f55\u98ce\u9669\u4e8b\u4ef6<\/span><br \/>\n                    <span class=\"token class-name\">RiskEventDTO<\/span> event <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">RiskEventDTO<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n                    event<span class=\"token punctuation\">.<\/span><span class=\"token function\">setEventType<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">RiskEventType<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">HIGH_RISK_CUSTOMER<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n                    event<span class=\"token punctuation\">.<\/span><span class=\"token function\">setRuleCode<\/span><span class=\"token punctuation\">(<\/span>rule<span class=\"token punctuation\">.<\/span><span class=\"token function\">getRuleCode<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n                    event<span class=\"token punctuation\">.<\/span><span class=\"token function\">setCustomerId<\/span><span class=\"token punctuation\">(<\/span>customerId<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n                    event<span class=\"token punctuation\">.<\/span><span class=\"token function\">setDescription<\/span><span class=\"token punctuation\">(<\/span>rule<span class=\"token punctuation\">.<\/span><span class=\"token function\">getRuleName<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#043;<\/span> <span class=\"token string\">&#034; triggered&#034;<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n                    event<span class=\"token punctuation\">.<\/span><span class=\"token function\">setStatus<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">RiskEventStatus<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">PENDING<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>                    eventService<span class=\"token punctuation\">.<\/span><span class=\"token function\">createEvent<\/span><span class=\"token punctuation\">(<\/span>event<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n                <span class=\"token punctuation\">}<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">catch<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token class-name\">Exception<\/span> e<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                log<span class=\"token punctuation\">.<\/span><span class=\"token function\">error<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;Error evaluating risk rule {}: {}&#034;<\/span><span class=\"token punctuation\">,<\/span> rule<span class=\"token punctuation\">.<\/span><span class=\"token function\">getRuleCode<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span> e<span class=\"token punctuation\">.<\/span><span class=\"token function\">getMessage<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><\/p>\n<p>        <span class=\"token class-name\">RiskAssessmentResult<\/span> result <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">RiskAssessmentResult<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        result<span class=\"token punctuation\">.<\/span><span class=\"token function\">setRiskScore<\/span><span class=\"token punctuation\">(<\/span>riskScore<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        result<span class=\"token punctuation\">.<\/span><span class=\"token function\">setRiskLevel<\/span><span class=\"token punctuation\">(<\/span><span class=\"token function\">determineRiskLevel<\/span><span class=\"token punctuation\">(<\/span>riskScore<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        result<span class=\"token punctuation\">.<\/span><span class=\"token function\">setTriggeredRules<\/span><span class=\"token punctuation\">(<\/span>triggeredRules<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        result<span class=\"token punctuation\">.<\/span><span class=\"token function\">setRecommendation<\/span><span class=\"token punctuation\">(<\/span><span class=\"token function\">generateRecommendation<\/span><span class=\"token punctuation\">(<\/span>riskScore<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        log<span class=\"token punctuation\">.<\/span><span class=\"token function\">info<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;Risk assessment completed for customer {}: score {}&#034;<\/span><span class=\"token punctuation\">,<\/span> customerId<span class=\"token punctuation\">,<\/span> riskScore<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">return<\/span> result<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> <span class=\"token function\">determineRiskLevel<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">BigDecimal<\/span> score<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>score<span class=\"token punctuation\">.<\/span><span class=\"token function\">compareTo<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">BigDecimal<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">valueOf<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">80<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&gt;&#061;<\/span> <span class=\"token number\">0<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">return<\/span> <span class=\"token string\">&#034;CRITICAL&#034;<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">else<\/span> <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>score<span class=\"token punctuation\">.<\/span><span class=\"token function\">compareTo<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">BigDecimal<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">valueOf<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">50<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&gt;&#061;<\/span> <span class=\"token number\">0<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">return<\/span> <span class=\"token string\">&#034;HIGH&#034;<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">else<\/span> <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>score<span class=\"token punctuation\">.<\/span><span class=\"token function\">compareTo<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">BigDecimal<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">valueOf<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">30<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&gt;&#061;<\/span> <span class=\"token number\">0<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">return<\/span> <span class=\"token string\">&#034;MEDIUM&#034;<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">else<\/span> <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>score<span class=\"token punctuation\">.<\/span><span class=\"token function\">compareTo<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">BigDecimal<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">valueOf<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">10<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&gt;&#061;<\/span> <span class=\"token number\">0<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">return<\/span> <span class=\"token string\">&#034;LOW&#034;<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">else<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">return<\/span> <span class=\"token string\">&#034;NORMAL&#034;<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">String<\/span> <span class=\"token function\">generateRecommendation<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">BigDecimal<\/span> score<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>score<span class=\"token punctuation\">.<\/span><span class=\"token function\">compareTo<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">BigDecimal<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">valueOf<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">80<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&gt;&#061;<\/span> <span class=\"token number\">0<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">return<\/span> <span class=\"token string\">&#034;BLOCK and ALERT&#034;<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">else<\/span> <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>score<span class=\"token punctuation\">.<\/span><span class=\"token function\">compareTo<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">BigDecimal<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">valueOf<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">50<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&gt;&#061;<\/span> <span class=\"token number\">0<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">return<\/span> <span class=\"token string\">&#034;REVIEW and VERIFY&#034;<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">else<\/span> <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>score<span class=\"token punctuation\">.<\/span><span class=\"token function\">compareTo<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">BigDecimal<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">valueOf<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">30<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&gt;&#061;<\/span> <span class=\"token number\">0<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">return<\/span> <span class=\"token string\">&#034;MONITOR CLOSELY&#034;<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">else<\/span> <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>score<span class=\"token punctuation\">.<\/span><span class=\"token function\">compareTo<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">BigDecimal<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">valueOf<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">10<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&gt;&#061;<\/span> <span class=\"token number\">0<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">return<\/span> <span class=\"token string\">&#034;STANDARD MONITORING&#034;<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">else<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">return<\/span> <span class=\"token string\">&#034;NO ACTION REQUIRED&#034;<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token comment\">\/**<br \/>\n\u98ce\u9669\u4e8b\u4ef6\u670d\u52a1<br \/>\n*\/<\/span><br \/>\n<span class=\"token annotation punctuation\">&#064;Service<\/span><br \/>\n<span class=\"token annotation punctuation\">&#064;RequiredArgsConstructor<\/span><br \/>\n<span class=\"token annotation punctuation\">&#064;Slf4j<\/span><br \/>\n<span class=\"token keyword\">public<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token class-name\">RiskEventService<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">final<\/span> <span class=\"token class-name\">RiskEventRepository<\/span> eventRepository<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">final<\/span> <span class=\"token class-name\">EventIdGenerator<\/span> idGenerator<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Transactional<\/span><br \/>\n    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">RiskEventDTO<\/span> <span class=\"token function\">createEvent<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">RiskEventDTO<\/span> eventDTO<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token class-name\">RiskEvent<\/span> event <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">RiskEvent<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        event<span class=\"token punctuation\">.<\/span><span class=\"token function\">setEventId<\/span><span class=\"token punctuation\">(<\/span>idGenerator<span class=\"token punctuation\">.<\/span><span class=\"token function\">generate<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        event<span class=\"token punctuation\">.<\/span><span class=\"token function\">setEventType<\/span><span class=\"token punctuation\">(<\/span>eventDTO<span class=\"token punctuation\">.<\/span><span class=\"token function\">getEventType<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        event<span class=\"token punctuation\">.<\/span><span class=\"token function\">setRuleCode<\/span><span class=\"token punctuation\">(<\/span>eventDTO<span class=\"token punctuation\">.<\/span><span class=\"token function\">getRuleCode<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        event<span class=\"token punctuation\">.<\/span><span class=\"token function\">setCustomerId<\/span><span class=\"token punctuation\">(<\/span>eventDTO<span class=\"token punctuation\">.<\/span><span class=\"token function\">getCustomerId<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        event<span class=\"token punctuation\">.<\/span><span class=\"token function\">setAccountNumber<\/span><span class=\"token punctuation\">(<\/span>eventDTO<span class=\"token punctuation\">.<\/span><span class=\"token function\">getAccountNumber<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        event<span class=\"token punctuation\">.<\/span><span class=\"token function\">setTransactionId<\/span><span class=\"token punctuation\">(<\/span>eventDTO<span class=\"token punctuation\">.<\/span><span class=\"token function\">getTransactionId<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        event<span class=\"token punctuation\">.<\/span><span class=\"token function\">setAmount<\/span><span class=\"token punctuation\">(<\/span>eventDTO<span class=\"token punctuation\">.<\/span><span class=\"token function\">getAmount<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        event<span class=\"token punctuation\">.<\/span><span class=\"token function\">setDescription<\/span><span class=\"token punctuation\">(<\/span>eventDTO<span class=\"token punctuation\">.<\/span><span class=\"token function\">getDescription<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        event<span class=\"token punctuation\">.<\/span><span class=\"token function\">setStatus<\/span><span class=\"token punctuation\">(<\/span>eventDTO<span class=\"token punctuation\">.<\/span><span class=\"token function\">getStatus<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token class-name\">RiskEvent<\/span> saved <span class=\"token operator\">&#061;<\/span> eventRepository<span class=\"token punctuation\">.<\/span><span class=\"token function\">save<\/span><span class=\"token punctuation\">(<\/span>event<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        log<span class=\"token punctuation\">.<\/span><span class=\"token function\">info<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;Risk event created: {}&#034;<\/span><span class=\"token punctuation\">,<\/span> saved<span class=\"token punctuation\">.<\/span><span class=\"token function\">getEventId<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">return<\/span> <span class=\"token function\">convertToDTO<\/span><span class=\"token punctuation\">(<\/span>saved<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Transactional<\/span><br \/>\n    <span class=\"token annotation punctuation\">&#064;PreAuthorize<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;hasAnyRole(&#039;RISK_OFFICER&#039;, &#039;RISK_MANAGER&#039;, &#039;ADMIN&#039;)&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">RiskEventDTO<\/span> <span class=\"token function\">updateEventStatus<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">String<\/span> eventId<span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">RiskEventStatus<\/span> status<span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">String<\/span> notes<span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">Long<\/span> userId<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token class-name\">RiskEvent<\/span> event <span class=\"token operator\">&#061;<\/span> eventRepository<span class=\"token punctuation\">.<\/span><span class=\"token function\">findByEventId<\/span><span class=\"token punctuation\">(<\/span>eventId<span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">orElseThrow<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">-&gt;<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">AccountException<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">ErrorCode<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">RISK_EVENT_NOT_FOUND<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        event<span class=\"token punctuation\">.<\/span><span class=\"token function\">setStatus<\/span><span class=\"token punctuation\">(<\/span>status<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        event<span class=\"token punctuation\">.<\/span><span class=\"token function\">setHandledBy<\/span><span class=\"token punctuation\">(<\/span>userId<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        event<span class=\"token punctuation\">.<\/span><span class=\"token function\">setHandledAt<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">LocalDateTime<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">now<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        event<span class=\"token punctuation\">.<\/span><span class=\"token function\">setHandlingNotes<\/span><span class=\"token punctuation\">(<\/span>notes<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token class-name\">RiskEvent<\/span> saved <span class=\"token operator\">&#061;<\/span> eventRepository<span class=\"token punctuation\">.<\/span><span class=\"token function\">save<\/span><span class=\"token punctuation\">(<\/span>event<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        log<span class=\"token punctuation\">.<\/span><span class=\"token function\">info<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;Risk event status updated to {}: {}&#034;<\/span><span class=\"token punctuation\">,<\/span> status<span class=\"token punctuation\">,<\/span> eventId<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">return<\/span> <span class=\"token function\">convertToDTO<\/span><span class=\"token punctuation\">(<\/span>saved<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Transactional<\/span><span class=\"token punctuation\">(<\/span>readOnly <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">true<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">List<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">RiskEventDTO<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> <span class=\"token function\">getPendingEvents<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> eventRepository<span class=\"token punctuation\">.<\/span><span class=\"token function\">findPendingEvents<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">stream<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">map<\/span><span class=\"token punctuation\">(<\/span><span class=\"token keyword\">this<\/span><span class=\"token operator\">::<\/span><span class=\"token function\">convertToDTO<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">collect<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">Collectors<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">toList<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Transactional<\/span><span class=\"token punctuation\">(<\/span>readOnly <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">true<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">List<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">RiskEventDTO<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> <span class=\"token function\">getEventsByCustomer<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">Long<\/span> customerId<span class=\"token punctuation\">,<\/span> <span class=\"token keyword\">int<\/span> days<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token class-name\">LocalDateTime<\/span> date <span class=\"token operator\">&#061;<\/span> <span class=\"token class-name\">LocalDateTime<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">now<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">minusDays<\/span><span class=\"token punctuation\">(<\/span>days<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> eventRepository<span class=\"token punctuation\">.<\/span><span class=\"token function\">findByCustomerIdAndCreatedAtAfter<\/span><span class=\"token punctuation\">(<\/span>customerId<span class=\"token punctuation\">,<\/span> date<span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">stream<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">map<\/span><span class=\"token punctuation\">(<\/span><span class=\"token keyword\">this<\/span><span class=\"token operator\">::<\/span><span class=\"token function\">convertToDTO<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">collect<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">Collectors<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">toList<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">RiskEventDTO<\/span> <span class=\"token function\">convertToDTO<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">RiskEvent<\/span> event<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token class-name\">RiskEventDTO<\/span> dto <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">RiskEventDTO<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        dto<span class=\"token punctuation\">.<\/span><span class=\"token function\">setId<\/span><span class=\"token punctuation\">(<\/span>event<span class=\"token punctuation\">.<\/span><span class=\"token function\">getId<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        dto<span class=\"token punctuation\">.<\/span><span class=\"token function\">setEventId<\/span><span class=\"token punctuation\">(<\/span>event<span class=\"token punctuation\">.<\/span><span class=\"token function\">getEventId<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        dto<span class=\"token punctuation\">.<\/span><span class=\"token function\">setEventType<\/span><span class=\"token punctuation\">(<\/span>event<span class=\"token punctuation\">.<\/span><span class=\"token function\">getEventType<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        dto<span class=\"token punctuation\">.<\/span><span class=\"token function\">setRuleCode<\/span><span class=\"token punctuation\">(<\/span>event<span class=\"token punctuation\">.<\/span><span class=\"token function\">getRuleCode<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        dto<span class=\"token punctuation\">.<\/span><span class=\"token function\">setCustomerId<\/span><span class=\"token punctuation\">(<\/span>event<span class=\"token punctuation\">.<\/span><span class=\"token function\">getCustomerId<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        dto<span class=\"token punctuation\">.<\/span><span class=\"token function\">setAccountNumber<\/span><span class=\"token punctuation\">(<\/span>event<span class=\"token punctuation\">.<\/span><span class=\"token function\">getAccountNumber<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        dto<span class=\"token punctuation\">.<\/span><span class=\"token function\">setTransactionId<\/span><span class=\"token punctuation\">(<\/span>event<span class=\"token punctuation\">.<\/span><span class=\"token function\">getTransactionId<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        dto<span class=\"token punctuation\">.<\/span><span class=\"token function\">setAmount<\/span><span class=\"token punctuation\">(<\/span>event<span class=\"token punctuation\">.<\/span><span class=\"token function\">getAmount<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        dto<span class=\"token punctuation\">.<\/span><span class=\"token function\">setDescription<\/span><span class=\"token punctuation\">(<\/span>event<span class=\"token punctuation\">.<\/span><span class=\"token function\">getDescription<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        dto<span class=\"token punctuation\">.<\/span><span class=\"token function\">setStatus<\/span><span class=\"token punctuation\">(<\/span>event<span class=\"token punctuation\">.<\/span><span class=\"token function\">getStatus<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        dto<span class=\"token punctuation\">.<\/span><span class=\"token function\">setHandledBy<\/span><span class=\"token punctuation\">(<\/span>event<span class=\"token punctuation\">.<\/span><span class=\"token function\">getHandledBy<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        dto<span class=\"token punctuation\">.<\/span><span class=\"token function\">setHandledAt<\/span><span class=\"token punctuation\">(<\/span>event<span class=\"token punctuation\">.<\/span><span class=\"token function\">getHandledAt<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        dto<span class=\"token punctuation\">.<\/span><span class=\"token function\">setHandlingNotes<\/span><span class=\"token punctuation\">(<\/span>event<span class=\"token punctuation\">.<\/span><span class=\"token function\">getHandlingNotes<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        dto<span class=\"token punctuation\">.<\/span><span class=\"token function\">setCreatedAt<\/span><span class=\"token punctuation\">(<\/span>event<span class=\"token punctuation\">.<\/span><span class=\"token function\">getCreatedAt<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        dto<span class=\"token punctuation\">.<\/span><span class=\"token function\">setUpdatedAt<\/span><span class=\"token punctuation\">(<\/span>event<span class=\"token punctuation\">.<\/span><span class=\"token function\">getUpdatedAt<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> dto<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token comment\">\/**<br \/>\n\u9ed1\u540d\u5355\u670d\u52a1<br \/>\n*\/<\/span><br \/>\n<span class=\"token annotation punctuation\">&#064;Service<\/span><br \/>\n<span class=\"token annotation punctuation\">&#064;RequiredArgsConstructor<\/span><br \/>\n<span class=\"token annotation punctuation\">&#064;Slf4j<\/span><br \/>\n<span class=\"token keyword\">public<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token class-name\">RiskBlacklistService<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">final<\/span> <span class=\"token class-name\">RiskBlacklistRepository<\/span> blacklistRepository<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Transactional<\/span><br \/>\n    <span class=\"token annotation punctuation\">&#064;PreAuthorize<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;hasAnyRole(&#039;RISK_OFFICER&#039;, &#039;RISK_MANAGER&#039;, &#039;ADMIN&#039;)&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">RiskBlacklistDTO<\/span> <span class=\"token function\">addToBlacklist<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">String<\/span> entityType<span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">String<\/span> entityValue<span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">String<\/span> reason<span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">String<\/span> source<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>blacklistRepository<span class=\"token punctuation\">.<\/span><span class=\"token function\">findByEntityTypeAndEntityValue<\/span><span class=\"token punctuation\">(<\/span>entityType<span class=\"token punctuation\">,<\/span> entityValue<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">isPresent<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">throw<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">AccountException<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">ErrorCode<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">ENTITY_ALREADY_BLACKLISTED<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><\/p>\n<p>        <span class=\"token class-name\">RiskBlacklist<\/span> entry <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">RiskBlacklist<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        entry<span class=\"token punctuation\">.<\/span><span class=\"token function\">setEntityType<\/span><span class=\"token punctuation\">(<\/span>entityType<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        entry<span class=\"token punctuation\">.<\/span><span class=\"token function\">setEntityValue<\/span><span class=\"token punctuation\">(<\/span>entityValue<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        entry<span class=\"token punctuation\">.<\/span><span class=\"token function\">setReason<\/span><span class=\"token punctuation\">(<\/span>reason<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        entry<span class=\"token punctuation\">.<\/span><span class=\"token function\">setSource<\/span><span class=\"token punctuation\">(<\/span>source<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token class-name\">RiskBlacklist<\/span> saved <span class=\"token operator\">&#061;<\/span> blacklistRepository<span class=\"token punctuation\">.<\/span><span class=\"token function\">save<\/span><span class=\"token punctuation\">(<\/span>entry<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        log<span class=\"token punctuation\">.<\/span><span class=\"token function\">info<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;Added to blacklist: {} &#8211; {}&#034;<\/span><span class=\"token punctuation\">,<\/span> entityType<span class=\"token punctuation\">,<\/span> entityValue<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">return<\/span> <span class=\"token function\">convertToDTO<\/span><span class=\"token punctuation\">(<\/span>saved<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Transactional<\/span><br \/>\n    <span class=\"token annotation punctuation\">&#064;PreAuthorize<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;hasAnyRole(&#039;RISK_OFFICER&#039;, &#039;RISK_MANAGER&#039;, &#039;ADMIN&#039;)&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">public<\/span> <span class=\"token keyword\">void<\/span> <span class=\"token function\">removeFromBlacklist<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">Long<\/span> id<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token class-name\">RiskBlacklist<\/span> entry <span class=\"token operator\">&#061;<\/span> blacklistRepository<span class=\"token punctuation\">.<\/span><span class=\"token function\">findById<\/span><span class=\"token punctuation\">(<\/span>id<span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">orElseThrow<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">-&gt;<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">AccountException<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">ErrorCode<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">BLACKLIST_ENTRY_NOT_FOUND<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        blacklistRepository<span class=\"token punctuation\">.<\/span><span class=\"token function\">delete<\/span><span class=\"token punctuation\">(<\/span>entry<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        log<span class=\"token punctuation\">.<\/span><span class=\"token function\">info<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;Removed from blacklist: {} &#8211; {}&#034;<\/span><span class=\"token punctuation\">,<\/span> entry<span class=\"token punctuation\">.<\/span><span class=\"token function\">getEntityType<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span> entry<span class=\"token punctuation\">.<\/span><span class=\"token function\">getEntityValue<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Transactional<\/span><span class=\"token punctuation\">(<\/span>readOnly <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">true<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">public<\/span> <span class=\"token keyword\">boolean<\/span> <span class=\"token function\">isBlacklisted<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">String<\/span> entityType<span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">String<\/span> entityValue<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> blacklistRepository<span class=\"token punctuation\">.<\/span><span class=\"token function\">findByEntityTypeAndEntityValue<\/span><span class=\"token punctuation\">(<\/span>entityType<span class=\"token punctuation\">,<\/span> entityValue<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">isPresent<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Transactional<\/span><span class=\"token punctuation\">(<\/span>readOnly <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">true<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">List<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">RiskBlacklistDTO<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> <span class=\"token function\">getBlacklistByType<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">String<\/span> entityType<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> blacklistRepository<span class=\"token punctuation\">.<\/span><span class=\"token function\">findByEntityType<\/span><span class=\"token punctuation\">(<\/span>entityType<span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">stream<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">map<\/span><span class=\"token punctuation\">(<\/span><span class=\"token keyword\">this<\/span><span class=\"token operator\">::<\/span><span class=\"token function\">convertToDTO<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">collect<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">Collectors<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">toList<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">RiskBlacklistDTO<\/span> <span class=\"token function\">convertToDTO<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">RiskBlacklist<\/span> entry<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token class-name\">RiskBlacklistDTO<\/span> dto <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">RiskBlacklistDTO<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        dto<span class=\"token punctuation\">.<\/span><span class=\"token function\">setId<\/span><span class=\"token punctuation\">(<\/span>entry<span class=\"token punctuation\">.<\/span><span class=\"token function\">getId<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        dto<span class=\"token punctuation\">.<\/span><span class=\"token function\">setEntityType<\/span><span class=\"token punctuation\">(<\/span>entry<span class=\"token punctuation\">.<\/span><span class=\"token function\">getEntityType<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        dto<span class=\"token punctuation\">.<\/span><span class=\"token function\">setEntityValue<\/span><span class=\"token punctuation\">(<\/span>entry<span class=\"token punctuation\">.<\/span><span class=\"token function\">getEntityValue<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        dto<span class=\"token punctuation\">.<\/span><span class=\"token function\">setReason<\/span><span class=\"token punctuation\">(<\/span>entry<span class=\"token punctuation\">.<\/span><span class=\"token function\">getReason<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        dto<span class=\"token punctuation\">.<\/span><span class=\"token function\">setSource<\/span><span class=\"token punctuation\">(<\/span>entry<span class=\"token punctuation\">.<\/span><span class=\"token function\">getSource<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        dto<span class=\"token punctuation\">.<\/span><span class=\"token function\">setCreatedAt<\/span><span class=\"token punctuation\">(<\/span>entry<span class=\"token punctuation\">.<\/span><span class=\"token function\">getCreatedAt<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> dto<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p>Repository\u5c42<\/p>\n<p><span class=\"token keyword\">public<\/span> <span class=\"token keyword\">interface<\/span> <span class=\"token class-name\">RiskRuleRepository<\/span> <span class=\"token keyword\">extends<\/span> <span class=\"token class-name\">JpaRepository<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">RiskRule<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">Long<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token class-name\">Optional<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">RiskRule<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> <span class=\"token function\">findByRuleCode<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">String<\/span> ruleCode<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token class-name\">List<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">RiskRule<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> <span class=\"token function\">findByCategoryAndIsActiveTrue<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">RiskRuleCategory<\/span> category<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token class-name\">List<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">RiskRule<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> <span class=\"token function\">findByStatus<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">RiskRuleStatus<\/span> status<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Query<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;SELECT r FROM RiskRule r WHERE r.isActive &#061; true AND r.status &#061; &#039;PRODUCTION&#039; ORDER BY r.priority DESC&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token class-name\">List<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">RiskRule<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> <span class=\"token function\">findAllActiveRules<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token keyword\">public<\/span> <span class=\"token keyword\">interface<\/span> <span class=\"token class-name\">RiskEventRepository<\/span> <span class=\"token keyword\">extends<\/span> <span class=\"token class-name\">JpaRepository<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">RiskEvent<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">Long<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token class-name\">Optional<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">RiskEvent<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> <span class=\"token function\">findByEventId<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">String<\/span> eventId<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token class-name\">List<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">RiskEvent<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> <span class=\"token function\">findByEventTypeAndStatus<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">RiskEventType<\/span> eventType<span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">RiskEventStatus<\/span> status<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token class-name\">List<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">RiskEvent<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> <span class=\"token function\">findByCustomerIdAndCreatedAtAfter<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">Long<\/span> customerId<span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">LocalDateTime<\/span> date<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Query<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;SELECT e FROM RiskEvent e WHERE e.status &#061; &#039;PENDING&#039; ORDER BY e.createdAt DESC&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token class-name\">List<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">RiskEvent<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> <span class=\"token function\">findPendingEvents<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Query<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;SELECT e FROM RiskEvent e WHERE e.createdAt BETWEEN :start AND :end&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token class-name\">List<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">RiskEvent<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> <span class=\"token function\">findEventsBetweenDates<\/span><span class=\"token punctuation\">(<\/span><span class=\"token annotation punctuation\">&#064;Param<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;start&#034;<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token class-name\">LocalDateTime<\/span> start<span class=\"token punctuation\">,<\/span> <span class=\"token annotation punctuation\">&#064;Param<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;end&#034;<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token class-name\">LocalDateTime<\/span> end<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token keyword\">public<\/span> <span class=\"token keyword\">interface<\/span> <span class=\"token class-name\">RiskParameterRepository<\/span> <span class=\"token keyword\">extends<\/span> <span class=\"token class-name\">JpaRepository<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">RiskParameter<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">Long<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token class-name\">Optional<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">RiskParameter<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> <span class=\"token function\">findByParamKey<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">String<\/span> paramKey<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token keyword\">public<\/span> <span class=\"token keyword\">interface<\/span> <span class=\"token class-name\">RiskBlacklistRepository<\/span> <span class=\"token keyword\">extends<\/span> <span class=\"token class-name\">JpaRepository<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">RiskBlacklist<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">Long<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token class-name\">Optional<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">RiskBlacklist<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> <span class=\"token function\">findByEntityTypeAndEntityValue<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">String<\/span> entityType<span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">String<\/span> entityValue<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token class-name\">List<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">RiskBlacklist<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> <span class=\"token function\">findByEntityType<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">String<\/span> entityType<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u6587\u7ae0\u6d4f\u89c8\u9605\u8bfb243\u6b21\uff0c\u70b9\u8d5e3\u6b21\uff0c\u6536\u85cf2\u6b21\u3002\u91d1\u878d\u9886\u57df\u94f6\u884c\u7cfb\u7edf\u4e1a\u52a1<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[99,190,3179,6200],"topic":[],"class_list":["post-58795","post","type-post","status-publish","format-standard","hentry","category-server","tag-java","tag-190","tag-3179","tag-6200"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v20.3 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>\u4f01\u4e1a\u7ea7Java\u9879\u76ee\u91d1\u878d\u5e94\u7528\u9886\u57df\u2014\u2014\u94f6\u884c\u7cfb\u7edf - \u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.wsisp.com\/helps\/58795.html\" \/>\n<meta property=\"og:locale\" content=\"zh_CN\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"\u4f01\u4e1a\u7ea7Java\u9879\u76ee\u91d1\u878d\u5e94\u7528\u9886\u57df\u2014\u2014\u94f6\u884c\u7cfb\u7edf - \u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3\" \/>\n<meta property=\"og:description\" content=\"\u6587\u7ae0\u6d4f\u89c8\u9605\u8bfb243\u6b21\uff0c\u70b9\u8d5e3\u6b21\uff0c\u6536\u85cf2\u6b21\u3002\u91d1\u878d\u9886\u57df\u94f6\u884c\u7cfb\u7edf\u4e1a\u52a1\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.wsisp.com\/helps\/58795.html\" \/>\n<meta property=\"og:site_name\" content=\"\u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3\" \/>\n<meta property=\"article:published_time\" content=\"2025-08-16T07:40:34+00:00\" \/>\n<meta name=\"author\" content=\"admin\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"\u4f5c\u8005\" \/>\n\t<meta name=\"twitter:data1\" content=\"admin\" \/>\n\t<meta name=\"twitter:label2\" content=\"\u9884\u8ba1\u9605\u8bfb\u65f6\u95f4\" \/>\n\t<meta name=\"twitter:data2\" content=\"63 \u5206\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.wsisp.com\/helps\/58795.html\",\"url\":\"https:\/\/www.wsisp.com\/helps\/58795.html\",\"name\":\"\u4f01\u4e1a\u7ea7Java\u9879\u76ee\u91d1\u878d\u5e94\u7528\u9886\u57df\u2014\u2014\u94f6\u884c\u7cfb\u7edf - \u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3\",\"isPartOf\":{\"@id\":\"https:\/\/www.wsisp.com\/helps\/#website\"},\"datePublished\":\"2025-08-16T07:40:34+00:00\",\"dateModified\":\"2025-08-16T07:40:34+00:00\",\"author\":{\"@id\":\"https:\/\/www.wsisp.com\/helps\/#\/schema\/person\/358e386c577a3ab51c4493330a20ad41\"},\"breadcrumb\":{\"@id\":\"https:\/\/www.wsisp.com\/helps\/58795.html#breadcrumb\"},\"inLanguage\":\"zh-Hans\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.wsisp.com\/helps\/58795.html\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.wsisp.com\/helps\/58795.html#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"\u9996\u9875\",\"item\":\"https:\/\/www.wsisp.com\/helps\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"\u4f01\u4e1a\u7ea7Java\u9879\u76ee\u91d1\u878d\u5e94\u7528\u9886\u57df\u2014\u2014\u94f6\u884c\u7cfb\u7edf\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.wsisp.com\/helps\/#website\",\"url\":\"https:\/\/www.wsisp.com\/helps\/\",\"name\":\"\u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3\",\"description\":\"\u9999\u6e2f\u670d\u52a1\u5668_\u9999\u6e2f\u4e91\u670d\u52a1\u5668\u8d44\u8baf_\u670d\u52a1\u5668\u5e2e\u52a9\u6587\u6863_\u670d\u52a1\u5668\u6559\u7a0b\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.wsisp.com\/helps\/?s={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"zh-Hans\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.wsisp.com\/helps\/#\/schema\/person\/358e386c577a3ab51c4493330a20ad41\",\"name\":\"admin\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"zh-Hans\",\"@id\":\"https:\/\/www.wsisp.com\/helps\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/gravatar.wp-china-yes.net\/avatar\/?s=96&d=mystery\",\"contentUrl\":\"https:\/\/gravatar.wp-china-yes.net\/avatar\/?s=96&d=mystery\",\"caption\":\"admin\"},\"sameAs\":[\"http:\/\/wp.wsisp.com\"],\"url\":\"https:\/\/www.wsisp.com\/helps\/author\/admin\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"\u4f01\u4e1a\u7ea7Java\u9879\u76ee\u91d1\u878d\u5e94\u7528\u9886\u57df\u2014\u2014\u94f6\u884c\u7cfb\u7edf - \u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.wsisp.com\/helps\/58795.html","og_locale":"zh_CN","og_type":"article","og_title":"\u4f01\u4e1a\u7ea7Java\u9879\u76ee\u91d1\u878d\u5e94\u7528\u9886\u57df\u2014\u2014\u94f6\u884c\u7cfb\u7edf - \u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3","og_description":"\u6587\u7ae0\u6d4f\u89c8\u9605\u8bfb243\u6b21\uff0c\u70b9\u8d5e3\u6b21\uff0c\u6536\u85cf2\u6b21\u3002\u91d1\u878d\u9886\u57df\u94f6\u884c\u7cfb\u7edf\u4e1a\u52a1","og_url":"https:\/\/www.wsisp.com\/helps\/58795.html","og_site_name":"\u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3","article_published_time":"2025-08-16T07:40:34+00:00","author":"admin","twitter_card":"summary_large_image","twitter_misc":{"\u4f5c\u8005":"admin","\u9884\u8ba1\u9605\u8bfb\u65f6\u95f4":"63 \u5206"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/www.wsisp.com\/helps\/58795.html","url":"https:\/\/www.wsisp.com\/helps\/58795.html","name":"\u4f01\u4e1a\u7ea7Java\u9879\u76ee\u91d1\u878d\u5e94\u7528\u9886\u57df\u2014\u2014\u94f6\u884c\u7cfb\u7edf - \u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3","isPartOf":{"@id":"https:\/\/www.wsisp.com\/helps\/#website"},"datePublished":"2025-08-16T07:40:34+00:00","dateModified":"2025-08-16T07:40:34+00:00","author":{"@id":"https:\/\/www.wsisp.com\/helps\/#\/schema\/person\/358e386c577a3ab51c4493330a20ad41"},"breadcrumb":{"@id":"https:\/\/www.wsisp.com\/helps\/58795.html#breadcrumb"},"inLanguage":"zh-Hans","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.wsisp.com\/helps\/58795.html"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.wsisp.com\/helps\/58795.html#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"\u9996\u9875","item":"https:\/\/www.wsisp.com\/helps"},{"@type":"ListItem","position":2,"name":"\u4f01\u4e1a\u7ea7Java\u9879\u76ee\u91d1\u878d\u5e94\u7528\u9886\u57df\u2014\u2014\u94f6\u884c\u7cfb\u7edf"}]},{"@type":"WebSite","@id":"https:\/\/www.wsisp.com\/helps\/#website","url":"https:\/\/www.wsisp.com\/helps\/","name":"\u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3","description":"\u9999\u6e2f\u670d\u52a1\u5668_\u9999\u6e2f\u4e91\u670d\u52a1\u5668\u8d44\u8baf_\u670d\u52a1\u5668\u5e2e\u52a9\u6587\u6863_\u670d\u52a1\u5668\u6559\u7a0b","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.wsisp.com\/helps\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"zh-Hans"},{"@type":"Person","@id":"https:\/\/www.wsisp.com\/helps\/#\/schema\/person\/358e386c577a3ab51c4493330a20ad41","name":"admin","image":{"@type":"ImageObject","inLanguage":"zh-Hans","@id":"https:\/\/www.wsisp.com\/helps\/#\/schema\/person\/image\/","url":"https:\/\/gravatar.wp-china-yes.net\/avatar\/?s=96&d=mystery","contentUrl":"https:\/\/gravatar.wp-china-yes.net\/avatar\/?s=96&d=mystery","caption":"admin"},"sameAs":["http:\/\/wp.wsisp.com"],"url":"https:\/\/www.wsisp.com\/helps\/author\/admin"}]}},"_links":{"self":[{"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/posts\/58795","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/comments?post=58795"}],"version-history":[{"count":0,"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/posts\/58795\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/media?parent=58795"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/categories?post=58795"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/tags?post=58795"},{"taxonomy":"topic","embeddable":true,"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/topic?post=58795"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}