From d7ce3cb987153c0d78b9b34ba5a7427f7e3ea20d Mon Sep 17 00:00:00 2001 From: wangshaoping Date: Sun, 4 Feb 2024 14:03:23 +0800 Subject: [PATCH] update --- .../service/CardGongXinImporterService.java | 5 + .../service/CardJingyingImporterService.java | 5 + .../impl/CardGongXinImporterServiceImpl.java | 194 ++++++++++++++++++ .../impl/CardJingyingImporterServiceImpl.java | 189 +++++++++++++++++ .../mv/controller/sc/CapWebController.java | 104 ++++++++++ 5 files changed, 497 insertions(+) create mode 100644 io.sc.engine.mv.sample/src/main/java/io/sc/engine/mv/sample/service/CardGongXinImporterService.java create mode 100644 io.sc.engine.mv.sample/src/main/java/io/sc/engine/mv/sample/service/CardJingyingImporterService.java create mode 100644 io.sc.engine.mv.sample/src/main/java/io/sc/engine/mv/sample/service/impl/CardGongXinImporterServiceImpl.java create mode 100644 io.sc.engine.mv.sample/src/main/java/io/sc/engine/mv/sample/service/impl/CardJingyingImporterServiceImpl.java create mode 100644 io.sc.engine.mv/src/main/java/io/sc/engine/mv/controller/sc/CapWebController.java diff --git a/io.sc.engine.mv.sample/src/main/java/io/sc/engine/mv/sample/service/CardGongXinImporterService.java b/io.sc.engine.mv.sample/src/main/java/io/sc/engine/mv/sample/service/CardGongXinImporterService.java new file mode 100644 index 00000000..f53e0378 --- /dev/null +++ b/io.sc.engine.mv.sample/src/main/java/io/sc/engine/mv/sample/service/CardGongXinImporterService.java @@ -0,0 +1,5 @@ +package io.sc.engine.mv.sample.service; + +public interface CardGongXinImporterService { + public void load() throws Exception; +} diff --git a/io.sc.engine.mv.sample/src/main/java/io/sc/engine/mv/sample/service/CardJingyingImporterService.java b/io.sc.engine.mv.sample/src/main/java/io/sc/engine/mv/sample/service/CardJingyingImporterService.java new file mode 100644 index 00000000..a8db83b6 --- /dev/null +++ b/io.sc.engine.mv.sample/src/main/java/io/sc/engine/mv/sample/service/CardJingyingImporterService.java @@ -0,0 +1,5 @@ +package io.sc.engine.mv.sample.service; + +public interface CardJingyingImporterService { + public void load() throws Exception; +} diff --git a/io.sc.engine.mv.sample/src/main/java/io/sc/engine/mv/sample/service/impl/CardGongXinImporterServiceImpl.java b/io.sc.engine.mv.sample/src/main/java/io/sc/engine/mv/sample/service/impl/CardGongXinImporterServiceImpl.java new file mode 100644 index 00000000..261b5ab0 --- /dev/null +++ b/io.sc.engine.mv.sample/src/main/java/io/sc/engine/mv/sample/service/impl/CardGongXinImporterServiceImpl.java @@ -0,0 +1,194 @@ +package io.sc.engine.mv.sample.service.impl; + +import com.opencsv.CSVReader; +import com.opencsv.CSVReaderBuilder; +import io.sc.engine.mv.sample.service.CardGongXinImporterService; +import io.sc.platform.core.util.DateUtil; +import io.sc.platform.core.util.StringUtil; +import io.sc.platform.jdbc.sql.builder.InsertIntoSqlBuilder; +import io.sc.platform.jdbc.util.SqlBatcher; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.io.DefaultResourceLoader; +import org.springframework.core.io.Resource; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.stereotype.Service; +import org.springframework.util.StringUtils; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.time.Instant; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.temporal.TemporalField; +import java.util.Date; +import java.util.Iterator; +import java.util.UUID; + +@Service +public class CardGongXinImporterServiceImpl implements CardGongXinImporterService { + private static final String URL ="classpath:/io/sc/engine/mv/sample/信用卡_工薪模型.csv"; + private static final String MODEL_ID ="CARD_GONGXIN"; + private static final String MODEL_NAME ="信用卡-工薪"; + @Autowired + private JdbcTemplate jdbcTemplate; + + @Override + public void load() throws Exception { + //删除违约记录表的数据 + deleteDefaultRecord(); + //删除评分记录表的数据 + deleteScoreRecord(); + //更新模型配置表的数据 + updateModelConfigure(); + //更新咨询建模时的客户分布配置表的数据 + updateDistributionConfigure(); + //更新标尺表的数据 + updateScaleConfigure(); + //导入测试用例评分记录和违约记录 + importData(); + } + + private void deleteDefaultRecord(){ + jdbcTemplate.update("delete from MV_DEFAULT_RECORD where FD_CUSTOM_ID in (select distinct FD_CUSTOM_ID from MV_SCORE_RECORD where FD_MODEL_ID=?)",MODEL_ID); + } + + private void deleteScoreRecord(){ + jdbcTemplate.update("delete from MV_SCORE_RECORD where FD_MODEL_ID=?",MODEL_ID); + } + + private void updateModelConfigure(){ + jdbcTemplate.update("delete from MV_CFG_MODEL where FD_MODEL_ID=?",MODEL_ID); + InsertIntoSqlBuilder builder =new InsertIntoSqlBuilder(); + builder.table("MV_CFG_MODEL") + .field("FD_ID",MODEL_ID) + .field("FD_MODEL_ID",MODEL_ID) + .field("FD_MODEL_NAME",MODEL_NAME) + .field("FD_TYPE","IMPORT_FROM_SCORE_RECORD") + .field("DATA_COME_FROM_","IMPORT") + .field("CREATOR_","system") + .field("CREATE_DATE_",new Date()) + .field("LAST_MODIFIER_","system") + .field("LAST_MODIFYDATE_",new Date()) + .insert(jdbcTemplate); + + + } + + private void updateDistributionConfigure(){ + jdbcTemplate.update("delete from MV_CFG_DISTRIBUTION where FD_MODEL_ID=?",MODEL_ID); + insertDistributionConfigure( 1,10,0); + insertDistributionConfigure(11,20,0); + insertDistributionConfigure(21,30,0); + insertDistributionConfigure(31,40,30); + insertDistributionConfigure(41,50,30); + insertDistributionConfigure(51,60,2000); + insertDistributionConfigure(61,70,1000); + insertDistributionConfigure(71,80,600); + insertDistributionConfigure(81,90,600); + insertDistributionConfigure(91,100,1500); + } + + private void insertDistributionConfigure(int start,int end,int count){ + new InsertIntoSqlBuilder().table("MV_CFG_DISTRIBUTION") + .field("FD_ID",UUID.randomUUID().toString()) + .field("FD_MODEL_ID",MODEL_ID) + .field("FD_MODEL_NAME",MODEL_NAME) + .field("FD_SCORE_SEG_START",start) + .field("FD_SCORE_SEG_END",end) + .field("FD_COUNT",count) + .field("CREATOR_","system") + .field("CREATE_DATE_",new Date()) + .field("LAST_MODIFIER_","system") + .field("LAST_MODIFYDATE_",new Date()) + .insert(jdbcTemplate); + } + + private void updateScaleConfigure(){ + jdbcTemplate.update("delete from MV_CFG_SCALE where FD_MODEL_ID is null"); + insertScaleConfigure( 1,0.0); + insertScaleConfigure(2,0.0015); + insertScaleConfigure(3,0.0033); + insertScaleConfigure(4,0.0060); + insertScaleConfigure(5,0.0088); + insertScaleConfigure(6,0.0189); + insertScaleConfigure(7,0.03); + insertScaleConfigure(8,0.0486); + insertScaleConfigure(9,0.0685); + insertScaleConfigure(10,0.1054); + insertScaleConfigure(11,0.2869); + insertScaleConfigure(12,0.5128); + } + + private void insertScaleConfigure(int order,double pd){ + new InsertIntoSqlBuilder().table("MV_CFG_SCALE") + .field("FD_ID", UUID.randomUUID().toString()) + .field("FD_LEVEL",order) + .field("FD_PD",pd) + .field("FD_ORDER",order) + .field("CREATOR_","system") + .field("CREATE_DATE_",new Date()) + .field("LAST_MODIFIER_","system") + .field("LAST_MODIFYDATE_",new Date()) + .insert(jdbcTemplate); + } + + private void importData() throws Exception { + Date scroeBeginDate =DateUtil.parseDate("2014-05-01", DateUtil.yyyy_MM_dd); + Date scroeEndDate =DateUtil.parseDate("2015-05-01", DateUtil.yyyy_MM_dd); + Date defaultConfirmDate =DateUtil.parseDate("2015-01-01", DateUtil.yyyy_MM_dd); + Resource resource =new DefaultResourceLoader().getResource(URL); + if(resource==null|| !resource.exists()){ + throw new IOException("resource '" + URL + "' is not exists"); + } + BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(resource.getInputStream())); + CSVReader reader = new CSVReaderBuilder(bufferedReader).withSkipLines(1).build(); + Iterator iterator = reader.iterator(); + SqlBatcher scoreRecordBatcher =new SqlBatcher(getScoreRecordInsertSql()); + SqlBatcher defaultRecordBatcher =new SqlBatcher(getDefaultRecordInsertSql()); + long index =1; + while(iterator.hasNext()) { + String[] values = iterator.next(); + scoreRecordBatcher.addArg( + values[0], /* FD_CUSTOM_ID */ + values[0], /* FD_CUSTOM_NAME */ + MODEL_ID, /* FD_MODEL_ID */ + MODEL_NAME, /* FD_MODEL_NAME */ + Double.parseDouble(values[1]), /* FD_SCORE */ + values[2], /* FD_LEVEL */ + scroeBeginDate, /* FD_SCORE_BEGIN_DATE */ + scroeEndDate /* FD_SCORE_END_DATE */ + ); + + if("1".equalsIgnoreCase(values[3])){ + defaultRecordBatcher.addArg(values[0],defaultConfirmDate); + } + + if(index%500==0){ + scoreRecordBatcher.execute(jdbcTemplate); + defaultRecordBatcher.execute(jdbcTemplate); + } + index++; + } + scoreRecordBatcher.execute(jdbcTemplate); + defaultRecordBatcher.execute(jdbcTemplate); + } + + private String getScoreRecordInsertSql(){ + return "" + + "insert into MV_SCORE_RECORD(" + + " FD_CUSTOM_ID," + + " FD_CUSTOM_NAME," + + " FD_MODEL_ID," + + " FD_MODEL_NAME," + + " FD_SCORE," + + " FD_LEVEL," + + " FD_SCORE_BEGIN_DATE," + + " FD_SCORE_END_DATE" + + ") values (?,?,?,?,?,?,?,?)"; + } + + private String getDefaultRecordInsertSql(){ + return "insert into MV_DEFAULT_RECORD(FD_CUSTOM_ID,FD_DEFAULT_CONFIRM_DATE) values (?,?)"; + } +} diff --git a/io.sc.engine.mv.sample/src/main/java/io/sc/engine/mv/sample/service/impl/CardJingyingImporterServiceImpl.java b/io.sc.engine.mv.sample/src/main/java/io/sc/engine/mv/sample/service/impl/CardJingyingImporterServiceImpl.java new file mode 100644 index 00000000..b68ee111 --- /dev/null +++ b/io.sc.engine.mv.sample/src/main/java/io/sc/engine/mv/sample/service/impl/CardJingyingImporterServiceImpl.java @@ -0,0 +1,189 @@ +package io.sc.engine.mv.sample.service.impl; + +import com.opencsv.CSVReader; +import com.opencsv.CSVReaderBuilder; +import io.sc.engine.mv.sample.service.CardGongXinImporterService; +import io.sc.engine.mv.sample.service.CardJingyingImporterService; +import io.sc.platform.core.util.DateUtil; +import io.sc.platform.jdbc.sql.builder.InsertIntoSqlBuilder; +import io.sc.platform.jdbc.util.SqlBatcher; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.io.DefaultResourceLoader; +import org.springframework.core.io.Resource; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.stereotype.Service; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.Date; +import java.util.Iterator; +import java.util.UUID; + +@Service +public class CardJingyingImporterServiceImpl implements CardJingyingImporterService { + private static final String URL ="classpath:/io/sc/engine/mv/sample/信用卡_经营模型.csv"; + private static final String MODEL_ID ="CARD_JINGYING"; + private static final String MODEL_NAME ="信用卡-经营"; + @Autowired + private JdbcTemplate jdbcTemplate; + + @Override + public void load() throws Exception { + //删除违约记录表的数据 + deleteDefaultRecord(); + //删除评分记录表的数据 + deleteScoreRecord(); + //更新模型配置表的数据 + updateModelConfigure(); + //更新咨询建模时的客户分布配置表的数据 + updateDistributionConfigure(); + //更新标尺表的数据 + updateScaleConfigure(); + //导入测试用例评分记录和违约记录 + importData(); + } + + private void deleteDefaultRecord(){ + jdbcTemplate.update("delete from MV_DEFAULT_RECORD where FD_CUSTOM_ID in (select distinct FD_CUSTOM_ID from MV_SCORE_RECORD where FD_MODEL_ID=?)",MODEL_ID); + } + + private void deleteScoreRecord(){ + jdbcTemplate.update("delete from MV_SCORE_RECORD where FD_MODEL_ID=?",MODEL_ID); + } + + private void updateModelConfigure(){ + jdbcTemplate.update("delete from MV_CFG_MODEL where FD_MODEL_ID=?",MODEL_ID); + InsertIntoSqlBuilder builder =new InsertIntoSqlBuilder(); + builder.table("MV_CFG_MODEL") + .field("FD_ID",MODEL_ID) + .field("FD_MODEL_ID",MODEL_ID) + .field("FD_MODEL_NAME",MODEL_NAME) + .field("FD_TYPE","IMPORT_FROM_SCORE_RECORD") + .field("DATA_COME_FROM_","IMPORT") + .field("CREATOR_","system") + .field("CREATE_DATE_",new Date()) + .field("LAST_MODIFIER_","system") + .field("LAST_MODIFYDATE_",new Date()) + .insert(jdbcTemplate); + + + } + + private void updateDistributionConfigure(){ + jdbcTemplate.update("delete from MV_CFG_DISTRIBUTION where FD_MODEL_ID=?",MODEL_ID); + insertDistributionConfigure( 1,10,0); + insertDistributionConfigure(11,20,0); + insertDistributionConfigure(21,30,0); + insertDistributionConfigure(31,40,30); + insertDistributionConfigure(41,50,30); + insertDistributionConfigure(51,60,2000); + insertDistributionConfigure(61,70,1000); + insertDistributionConfigure(71,80,600); + insertDistributionConfigure(81,90,600); + insertDistributionConfigure(91,100,1500); + } + + private void insertDistributionConfigure(int start,int end,int count){ + new InsertIntoSqlBuilder().table("MV_CFG_DISTRIBUTION") + .field("FD_ID",UUID.randomUUID().toString()) + .field("FD_MODEL_ID",MODEL_ID) + .field("FD_MODEL_NAME",MODEL_NAME) + .field("FD_SCORE_SEG_START",start) + .field("FD_SCORE_SEG_END",end) + .field("FD_COUNT",count) + .field("CREATOR_","system") + .field("CREATE_DATE_",new Date()) + .field("LAST_MODIFIER_","system") + .field("LAST_MODIFYDATE_",new Date()) + .insert(jdbcTemplate); + } + + private void updateScaleConfigure(){ + jdbcTemplate.update("delete from MV_CFG_SCALE where FD_MODEL_ID is null"); + insertScaleConfigure( 1,0.0); + insertScaleConfigure(2,0.0015); + insertScaleConfigure(3,0.0033); + insertScaleConfigure(4,0.0060); + insertScaleConfigure(5,0.0088); + insertScaleConfigure(6,0.0189); + insertScaleConfigure(7,0.03); + insertScaleConfigure(8,0.0486); + insertScaleConfigure(9,0.0685); + insertScaleConfigure(10,0.1054); + insertScaleConfigure(11,0.2869); + insertScaleConfigure(12,0.5128); + } + + private void insertScaleConfigure(int order,double pd){ + new InsertIntoSqlBuilder().table("MV_CFG_SCALE") + .field("FD_ID", UUID.randomUUID().toString()) + .field("FD_LEVEL",order) + .field("FD_PD",pd) + .field("FD_ORDER",order) + .field("CREATOR_","system") + .field("CREATE_DATE_",new Date()) + .field("LAST_MODIFIER_","system") + .field("LAST_MODIFYDATE_",new Date()) + .insert(jdbcTemplate); + } + + private void importData() throws Exception { + Date scroeBeginDate =DateUtil.parseDate("2014-05-01", DateUtil.yyyy_MM_dd); + Date scroeEndDate =DateUtil.parseDate("2015-05-01", DateUtil.yyyy_MM_dd); + Date defaultConfirmDate =DateUtil.parseDate("2015-01-01", DateUtil.yyyy_MM_dd); + Resource resource =new DefaultResourceLoader().getResource(URL); + if(resource==null|| !resource.exists()){ + throw new IOException("resource '" + URL + "' is not exists"); + } + BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(resource.getInputStream())); + CSVReader reader = new CSVReaderBuilder(bufferedReader).withSkipLines(1).build(); + Iterator iterator = reader.iterator(); + SqlBatcher scoreRecordBatcher =new SqlBatcher(getScoreRecordInsertSql()); + SqlBatcher defaultRecordBatcher =new SqlBatcher(getDefaultRecordInsertSql()); + long index =1; + while(iterator.hasNext()) { + String[] values = iterator.next(); + scoreRecordBatcher.addArg( + values[0], /* FD_CUSTOM_ID */ + values[0], /* FD_CUSTOM_NAME */ + MODEL_ID, /* FD_MODEL_ID */ + MODEL_NAME, /* FD_MODEL_NAME */ + Double.parseDouble(values[1]), /* FD_SCORE */ + values[2], /* FD_LEVEL */ + scroeBeginDate, /* FD_SCORE_BEGIN_DATE */ + scroeEndDate /* FD_SCORE_END_DATE */ + ); + + if("1".equalsIgnoreCase(values[3])){ + defaultRecordBatcher.addArg(values[0],defaultConfirmDate); + } + + if(index%500==0){ + scoreRecordBatcher.execute(jdbcTemplate); + defaultRecordBatcher.execute(jdbcTemplate); + } + index++; + } + scoreRecordBatcher.execute(jdbcTemplate); + defaultRecordBatcher.execute(jdbcTemplate); + } + + private String getScoreRecordInsertSql(){ + return "" + + "insert into MV_SCORE_RECORD(" + + " FD_CUSTOM_ID," + + " FD_CUSTOM_NAME," + + " FD_MODEL_ID," + + " FD_MODEL_NAME," + + " FD_SCORE," + + " FD_LEVEL," + + " FD_SCORE_BEGIN_DATE," + + " FD_SCORE_END_DATE" + + ") values (?,?,?,?,?,?,?,?)"; + } + + private String getDefaultRecordInsertSql(){ + return "insert into MV_DEFAULT_RECORD(FD_CUSTOM_ID,FD_DEFAULT_CONFIRM_DATE) values (?,?)"; + } +} diff --git a/io.sc.engine.mv/src/main/java/io/sc/engine/mv/controller/sc/CapWebController.java b/io.sc.engine.mv/src/main/java/io/sc/engine/mv/controller/sc/CapWebController.java new file mode 100644 index 00000000..47b5db58 --- /dev/null +++ b/io.sc.engine.mv/src/main/java/io/sc/engine/mv/controller/sc/CapWebController.java @@ -0,0 +1,104 @@ +package io.sc.engine.mv.controller.sc; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; + +import io.sc.engine.mv.jpa.entity.GeneralResultHistory; +import io.sc.engine.mv.jpa.entity.ScCapHistory; +import io.sc.engine.mv.jpa.entity.id.ScCapHistoryId; +import io.sc.engine.mv.jpa.repository.GeneralResultHistoryRepository; +import io.sc.engine.mv.jpa.repository.ScCapHistoryRepository; +import io.sc.engine.mv.sc.echarts.Coordinates; +import io.sc.engine.mv.service.sc.ScCapHistoryService; +import io.sc.engine.mv.vo.ScCapHistoryVo; +import io.sc.platform.core.util.CollectionUtil; +import io.sc.platform.mvc.controller.support.RestCrudController; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.dao.DataAccessException; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.core.PreparedStatementCreator; +import org.springframework.jdbc.core.ResultSetExtractor; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.servlet.ModelAndView; + +@Controller +@RequestMapping("/mv/sc/cap") +public class CapWebController extends RestCrudController { + //模型验证结果DAO + @Autowired private GeneralResultHistoryRepository generalResultHistoryRepository; + //CAP 曲线指标DAO + @Autowired private ScCapHistoryRepository scCapHistoryRepository; + //jdbc 模板 + @Autowired private JdbcTemplate jdbcTemplate; + + /** + * 查看模型区分能力验证 CAP 指标数据UI + * @param modelId 模型标识 + * @param validateDate 验证日期 + * @return UI视图 + */ + @RequestMapping("capDataView") + public ModelAndView rocKpiDataView( + @RequestParam(name="modelId",required=false) String modelId, + @RequestParam(name="validateDate",required=false) String validateDate + ){ + ModelAndView mv =new ModelAndView("org/wsp/model/validator/view/sc/capDataView.html"); + mv.addObject("removeNavbar", true); + mv.addObject("modelId", modelId); + mv.addObject("validateDate", validateDate); + mv.addObject("distinctModelIdAndNames", CollectionUtil.arrayList2Map(scCapHistoryRepository.findDistinctModelIdAndNames())); + return mv; + } + + /** + * 获取模型区分能力 CAP 曲线的 echarts Options + * @param modelId 模型标识 + * @param validateDate 验证日期 + * @return 模型区分能力 CAP 曲线的 echarts Options 的 javascript + * @throws Exception 违例 + */ + @RequestMapping("cap.js") + public ModelAndView cap( + @RequestParam("modelId") String modelId, + @RequestParam("validateDate") String validateDate + ) throws Exception{ + ModelAndView mv =new ModelAndView("org/wsp/model/validator/view/sc/echarts/cap.js"); + GeneralResultHistory resultSummary =generalResultHistoryRepository.findByModelIdAndValidateDate(modelId, validateDate); + mv.addObject("resultSummary", resultSummary); + mv.addObject("coordinates",getCoordinates(modelId,validateDate)); + return mv; + } + + /** + * 获取 CAP 曲线图中 X,Y 坐标集 + * @param modelId 模型标识 + * @param validateDate 验证日期 + * @return ROC 曲线图中 X,Y 坐标集 + */ + private Coordinates getCoordinates(final String modelId, final String validateDate){ + return jdbcTemplate.query(new PreparedStatementCreator() { + @Override + public PreparedStatement createPreparedStatement(Connection con) throws SQLException { + String sql ="select FD_X,FD_Y from MV_SC_CAP_HIS where FD_MODEL_ID=? and FD_VALIDATE_DATE=? order by FD_X"; + PreparedStatement ps =con.prepareStatement(sql); + ps.setString(1, modelId); + ps.setString(2, validateDate); + return ps; + } + }, new ResultSetExtractor() { + @Override + public Coordinates extractData(ResultSet rs) throws SQLException, DataAccessException { + Coordinates coordinates =new Coordinates(); + while(rs.next()){ + coordinates.add(rs.getBigDecimal("FD_X"), rs.getBigDecimal("FD_Y")); + } + coordinates.setScale(6); + return coordinates; + } + }); + } +}