浏览代码

解决冲突

wangzaijun 1 年之前
父节点
当前提交
362d4d3ec9
共有 20 个文件被更改,包括 823 次插入18 次删除
  1. 23 0
      src/main/java/com/smppw/analysis/application/dto/info/ManualFundManagerParams.java
  2. 227 10
      src/main/java/com/smppw/analysis/application/service/info/FundInfoService.java
  3. 35 1
      src/main/java/com/smppw/analysis/client/FundApi.java
  4. 4 0
      src/main/java/com/smppw/analysis/domain/dao/FundInformationDao.java
  5. 45 0
      src/main/java/com/smppw/analysis/domain/dataobject/ManualFundFeeDo.java
  6. 37 0
      src/main/java/com/smppw/analysis/domain/dataobject/ManualFundManagerChangeDo.java
  7. 42 0
      src/main/java/com/smppw/analysis/domain/dataobject/PersonnelInformationDo.java
  8. 38 0
      src/main/java/com/smppw/analysis/domain/dataobject/PersonnelWorkExperienceDo.java
  9. 1 1
      src/main/java/com/smppw/analysis/domain/dto/info/FundBaseFeeVO.java
  10. 57 0
      src/main/java/com/smppw/analysis/domain/dto/info/FundManagerInfoVo.java
  11. 46 0
      src/main/java/com/smppw/analysis/domain/dto/info/ManualFundFeeInfoVO.java
  12. 58 0
      src/main/java/com/smppw/analysis/domain/dto/info/ManualFundManagerChangeVO.java
  13. 9 0
      src/main/java/com/smppw/analysis/domain/mapper/core/FundInformationDoMapper.java
  14. 24 0
      src/main/java/com/smppw/analysis/domain/mapper/core/MfChargeRateMapper.java
  15. 35 0
      src/main/java/com/smppw/analysis/domain/mapper/core/PersonnelInformationMapper.java
  16. 33 0
      src/main/java/com/smppw/analysis/domain/service/BaseInfoService.java
  17. 28 6
      src/main/java/com/smppw/analysis/domain/service/impl/BaseInfoServiceImpl.java
  18. 17 0
      src/main/resources/mapping/core/FundInformationDoMapper.xml
  19. 18 0
      src/main/resources/mapping/core/MfChargeRetMapper.xml
  20. 46 0
      src/main/resources/mapping/core/PersonnelInformationMapper.xml

+ 23 - 0
src/main/java/com/smppw/analysis/application/dto/info/ManualFundManagerParams.java

@@ -0,0 +1,23 @@
+package com.smppw.analysis.application.dto.info;
+
+import lombok.Data;
+
+/**
+ * @author mozuwen
+ * @date 2023/8/9 17:00
+ * @description 公募基金的基金经理变更历史请求参数
+ */
+@Data
+public class ManualFundManagerParams {
+
+    /**
+     * 基金id
+     */
+    private String refId;
+
+    /**
+     * 基准
+     */
+    private String benchmarkId;
+
+}

+ 227 - 10
src/main/java/com/smppw/analysis/application/service/info/FundInfoService.java

@@ -3,30 +3,35 @@ package com.smppw.analysis.application.service.info;
 import cn.hutool.core.bean.BeanUtil;
 import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.collection.ListUtil;
+import cn.hutool.core.date.DateUnit;
 import cn.hutool.core.date.DateUtil;
 import cn.hutool.core.map.MapUtil;
 import cn.hutool.core.text.CharSequenceUtil;
+import cn.hutool.core.util.NumberUtil;
 import cn.hutool.core.util.StrUtil;
 import com.smppw.analysis.application.dto.info.FundSimilarReq;
+import com.smppw.analysis.application.dto.info.ManualFundManagerParams;
 import com.smppw.analysis.application.dto.info.ManualFundNoticeReq;
-import com.smppw.analysis.domain.dataobject.FundArchivesInfoDO;
-import com.smppw.analysis.domain.dataobject.FundFeeDo;
-import com.smppw.analysis.domain.dataobject.FundSimilarDo;
-import com.smppw.analysis.domain.dataobject.ManualFundNoticeInfoDO;
+import com.smppw.analysis.domain.dataobject.*;
 import com.smppw.analysis.domain.dto.info.*;
+import com.smppw.analysis.domain.manager.performance.PerformanceFactory;
 import com.smppw.analysis.domain.service.BaseIndicatorServiceV2;
 import com.smppw.analysis.domain.service.BaseInfoService;
 import com.smppw.analysis.domain.service.NavService;
 import com.smppw.analysis.infrastructure.utils.StringUtil;
 import com.smppw.common.pojo.IStrategy;
 import com.smppw.common.pojo.NewSubStrategy;
+import com.smppw.common.pojo.ValueLabelVO;
 import com.smppw.common.pojo.dto.DateValue;
+import com.smppw.common.pojo.dto.calc.IndicatorCalcIndexDataDto;
 import com.smppw.common.pojo.dto.calc.IndicatorCalcPropertyDto;
+import com.smppw.common.pojo.dto.calc.IndicatorCalcSecDataDto;
 import com.smppw.common.pojo.dto.calc.IndicatorCalcTimeRangeDto;
-import com.smppw.common.pojo.enums.Frequency;
-import com.smppw.common.pojo.enums.NavType;
-import com.smppw.common.pojo.enums.TimeRange;
-import com.smppw.common.pojo.enums.Visibility;
+import com.smppw.common.pojo.dto.indicator.CalcMultipleSecMultipleTimeRangeIndicatorReq;
+import com.smppw.common.pojo.dto.indicator.DateIntervalDto;
+import com.smppw.common.pojo.enums.*;
+import com.smppw.common.pojo.enums.strategy.Strategy;
+import com.smppw.constants.Consts;
 import com.smppw.constants.DateConst;
 import com.smppw.core.IndicatorService;
 import com.smppw.utils.BigDecimalUtils;
@@ -38,12 +43,14 @@ import org.springframework.stereotype.Service;
 
 import java.math.RoundingMode;
 import java.util.*;
+import java.util.function.Function;
 import java.util.stream.Collectors;
 
 @Service
 public class FundInfoService {
-    private static final Map<String, String> ACCRUED_FREQUENCY = MapUtil.newHashMap();
-    private static final Map<String, String> ACCRUED_METHOD = MapUtil.newHashMap();
+    private static final Map<String, String> ACCRUED_FREQUENCY = MapUtil.newHashMap(5);
+    private static final Map<String, String> ACCRUED_METHOD = MapUtil.newHashMap(3);
+    private static final Map<Integer, String> EDUCATION_NAME_MAP = MapUtil.newHashMap(8);
 
     static {
         ACCRUED_FREQUENCY.put("1", "月");
@@ -54,15 +61,26 @@ public class FundInfoService {
         ACCRUED_METHOD.put("1", "高水位");
         ACCRUED_METHOD.put("2", "高水位+赎回时补充");
         ACCRUED_METHOD.put("3", "单客户高水位");
+        EDUCATION_NAME_MAP.put(1, "小学");
+        EDUCATION_NAME_MAP.put(2, "中学");
+        EDUCATION_NAME_MAP.put(3, "大专");
+        EDUCATION_NAME_MAP.put(4, "本科");
+        EDUCATION_NAME_MAP.put(5, "硕士");
+        EDUCATION_NAME_MAP.put(6, "博士");
+        EDUCATION_NAME_MAP.put(7, "博士后");
+        EDUCATION_NAME_MAP.put(-1, "其他");
     }
 
     private final NavService navService;
+    private final PerformanceFactory factory;
     private final BaseInfoService baseInfoService;
     private final BaseIndicatorServiceV2 baseIndicatorServiceV2;
 
     public FundInfoService(NavService navService,
+                           PerformanceFactory factory,
                            BaseInfoService baseInfoService,
                            BaseIndicatorServiceV2 baseIndicatorServiceV2) {
+        this.factory = factory;
         this.navService = navService;
         this.baseInfoService = baseInfoService;
         this.baseIndicatorServiceV2 = baseIndicatorServiceV2;
@@ -244,4 +262,203 @@ public class FundInfoService {
         return fundFeeDo;
     }
 
+    public ManualFundFeeInfoVO getMfFundFee(String fundId) {
+        List<ManualFundFeeDo> dataList = this.baseInfoService.getManualFundFee(fundId);
+        ManualFundFeeInfoVO result = new ManualFundFeeInfoVO();
+        // 数据库 费率 类型与中文映射
+        Map<String, String> typeMapper = MapUtil.builder("10210", "认购金额").put("11210", "申购金额").put("11010", "申购金额")
+                .put("12200", "持有期限").put("12000", "持有期限").build();
+        // 费率类型 与 单位映射
+        Map<String, String> unitMapper = MapUtil.builder("10210", "万元").put("11210", "万元").put("11010", "万元")
+                .put("12200", "日").put("12000", "日").build();
+        // 记录映射函数,返回一个包含最大最小的范围
+        Function<ManualFundFeeDo, ValueLabelVO> function = e -> {
+            ValueLabelVO vo = new ValueLabelVO();
+            vo.setValue(e.getChargeRateDes());
+            String label = typeMapper.get(e.getChargeRateType());
+            // 最小值不为0和null时,设置为起始数据
+            if (e.getStDivStand1() != null && !Double.valueOf(0.0d).equals(e.getStDivStand1())) {
+                label = NumberUtil.roundStr(e.getStDivStand1(), 0) + unitMapper.get(e.getChargeRateType()) + " <= " + label;
+            }
+            // 最大值不为null时设置截止范围数据
+            if (e.getEnDivStand1() != null) {
+                label += " < " + NumberUtil.roundStr(e.getEnDivStand1(), 0) + unitMapper.get(e.getChargeRateType());
+            }
+            vo.setLabel(label);
+            return vo;
+        };
+        // 认购费
+        List<ValueLabelVO> subscriptionFee = this.handleFee(dataList, "10210", function);
+        result.setSubscriptionFee(subscriptionFee);
+        // 申购费,先取场外
+        List<ValueLabelVO> applyFee = this.handleFee(dataList, "11210", function);
+        if (applyFee.isEmpty()) {
+            applyFee = this.handleFee(dataList, "11010", function);
+        }
+        result.setApplyFee(applyFee);
+        // 赎回费,先取场外
+        List<ValueLabelVO> redemptionFee = this.handleFee(dataList, "12200", function);
+        if (redemptionFee.isEmpty()) {
+            redemptionFee = this.handleFee(dataList, "12000", function);
+        }
+        result.setRedemptionFee(redemptionFee);
+        // 管理费、托管费和营销费
+        result.setManagementFeeTrust(this.handleOneFee(dataList, "15000", ManualFundFeeDo::getChargeRateDes));
+        result.setManagementFeeBank(this.handleOneFee(dataList, "16000", ManualFundFeeDo::getChargeRateDes));
+        result.setSaleFee(this.handleOneFee(dataList, "19000", ManualFundFeeDo::getChargeRateDes));
+        return result;
+    }
+
+    /**
+     * 费率处理工具,返回一个列表
+     *
+     * @param dataList 费率数据
+     * @param type     过滤的关键字
+     * @param function 转换函数
+     * @param <T>      类型参数
+     * @return /
+     */
+    private <T> List<T> handleFee(List<ManualFundFeeDo> dataList, String type, Function<ManualFundFeeDo, T> function) {
+        return dataList.stream().filter(e -> type.equals(e.getChargeRateType())).map(function).collect(Collectors.toList());
+    }
+
+    /**
+     * 费率处理工具,返回一个对象
+     *
+     * @param dataList 费率数据
+     * @param type     过滤的关键字
+     * @param function 转换函数
+     * @param <T>      类型参数
+     * @return /
+     */
+    private <T> T handleOneFee(List<ManualFundFeeDo> dataList, String type, Function<ManualFundFeeDo, T> function) {
+        return this.handleFee(dataList, type, function).stream().findFirst().orElse(null);
+    }
+
+    public List<FundManagerInfoVo> getHFManagerInfo(String refId) {
+        List<FundManagerInfoVo> resultList = ListUtil.list(true);
+        List<PersonnelInformationDo> managerInfoList = this.baseInfoService.getFundManagerInfo(refId);
+        if (CollUtil.isEmpty(managerInfoList)) {
+            return resultList;
+        }
+        List<String> managerIdList = managerInfoList.stream().map(PersonnelInformationDo::getPersonnelId).collect(Collectors.toList());
+        List<PersonnelWorkExperienceDo> workExperienceList = this.baseInfoService.listPersonnelWorkExperience(managerIdList);
+        //过滤掉任职开始日期和任职结束日期为空的数据
+        if (CollUtil.isNotEmpty(workExperienceList)) {
+            workExperienceList = workExperienceList.stream()
+                    .filter(e -> !(StrUtil.isEmpty(e.getStartDate()) && StrUtil.isEmpty(e.getEndDate()))).collect(Collectors.toList());
+        }
+        if (CollUtil.isNotEmpty(workExperienceList)) {
+            Map<String, List<PersonnelWorkExperienceDo>> personnelIdWorkExperienceMap = workExperienceList.stream()
+                    .collect(Collectors.groupingBy(PersonnelWorkExperienceDo::getPersonnelId));
+            for (PersonnelInformationDo fundManagerInfo : managerInfoList) {
+                FundManagerInfoVo result = new FundManagerInfoVo();
+                result.setManagerId(fundManagerInfo.getPersonnelId());
+                result.setManagerName(fundManagerInfo.getPersonnelName());
+                result.setAvatar(fundManagerInfo.getAvatar());
+                result.setAvatar2(fundManagerInfo.getAvatar2());
+                result.setEducation(EDUCATION_NAME_MAP.get(fundManagerInfo.getEducation()));
+                result.setProfile(fundManagerInfo.getProfile());
+                List<PersonnelWorkExperienceDo> workExperienceDoList = personnelIdWorkExperienceMap.get(fundManagerInfo.getPersonnelId());
+                if (CollUtil.isNotEmpty(workExperienceDoList)) {
+                    String latestPosition = workExperienceDoList.stream().filter(e -> e.getEndDate() == null)
+                            .sorted(Comparator.comparing(PersonnelWorkExperienceDo::getStartDate).reversed())
+                            .map(PersonnelWorkExperienceDo::getPosition).findFirst().orElse(null);
+                    result.setManagerWorkExperienceList(workExperienceDoList);
+                    result.setLatestPosition(latestPosition);
+                }
+                resultList.add(result);
+            }
+        }
+        return resultList;
+    }
+
+    public List<ManualFundManagerChangeVO> managerChangeList(ManualFundManagerParams params) {
+        String refId = params.getRefId();
+        String benchmarkId = params.getBenchmarkId();
+        List<ManualFundManagerChangeDo> dataList = this.baseInfoService.listFundManagerChangeHistory(refId);
+
+        dataList = dataList.stream().filter(e -> e.getStartDate() != null).collect(Collectors.toList());
+        // 按基金经理+开始任职时间分组每个经理只取一条数据
+        Map<String, ManualFundManagerChangeDo> managerInfoMap = MapUtil.newHashMap();
+        Map<String, List<ManualFundManagerChangeDo>> collect = dataList.stream().collect(Collectors.groupingBy(e -> e.getManagerId() + e.getStartDate(), Collectors.toList()));
+        collect.forEach((k, v) -> {
+            ManualFundManagerChangeDo temp = v.stream().findFirst().orElse(null);
+            managerInfoMap.put(k, temp);
+        });
+
+        List<ManualFundManagerChangeVO> resultList = ListUtil.list(true);
+        List<Indicator> indicatorList = ListUtil.of(Indicator.IntervalReturn, Indicator.AnnualReturn, Indicator.MaxDrawdown,
+                Indicator.SortinoRatio, Indicator.CalmarRatio);
+        managerInfoMap.forEach((k, data) -> {
+            ManualFundManagerChangeVO vo = new ManualFundManagerChangeVO();
+            vo.setManagerId(data.getManagerId());
+            vo.setManagerName(data.getManagerName());
+            // 任职日期和天数计算
+            vo.setEmployDate(data.getStartDate() + "~" + (CharSequenceUtil.isBlank(data.getEndDate()) ? "至今" : data.getEndDate()));
+            Date date = new Date();
+            if (CharSequenceUtil.isNotBlank(data.getEndDate())) {
+                date = DateUtil.parseDate(data.getEndDate());
+            }
+            vo.setEmployDayNum(DateUtil.between(DateUtil.parseDate(data.getStartDate()), date, DateUnit.DAY) + "");
+            // 指标计算
+            Map<String, Map<String, String>> indicatorValue =
+                    this.getIndicatorValue(refId, benchmarkId, data.getStartDate(), data.getEndDate(), indicatorList);
+            if (indicatorValue.get(refId) != null) {
+                vo.setFundRet(indicatorValue.get(refId).get(Indicator.IntervalReturn.name()));
+                vo.setAnnualRet(indicatorValue.get(refId).get(Indicator.AnnualReturn.name()));
+                vo.setMaxDrawdown(indicatorValue.get(refId).get(Indicator.MaxDrawdown.name()));
+                vo.setCalmar(indicatorValue.get(refId).get(Indicator.CalmarRatio.name()));
+                vo.setSortino(indicatorValue.get(refId).get(Indicator.SortinoRatio.name()));
+            }
+            resultList.add(vo);
+        });
+        return resultList;
+    }
+
+
+    /**
+     * 计算公募基金和其基准区间内的指标
+     *
+     * @param refId         公募基金
+     * @param benchmarkId   基准
+     * @param startDate     开始日期
+     * @param endDate       结束日期
+     * @param indicatorList 计算指标
+     * @return /
+     */
+    private Map<String, Map<String, String>> getIndicatorValue(String refId, String benchmarkId, String startDate, String endDate, List<Indicator> indicatorList) {
+        DateIntervalDto dateIntervalDto = DateIntervalDto.builder()
+                .id(DateIntervalType.CustomInterval.name()).startDate(startDate).endDate(endDate)
+                .dateIntervalType(DateIntervalType.CustomInterval).frequency(Frequency.Default).build();
+        Map<String, List<DateIntervalDto>> dateIntervalMap = MapUtil.builder(refId, ListUtil.of(dateIntervalDto)).build();
+        Map<String, String> benchmarkIdMap = MapUtil.builder(refId, benchmarkId).build();
+        CalcMultipleSecMultipleTimeRangeIndicatorReq req = CalcMultipleSecMultipleTimeRangeIndicatorReq.builder()
+                .mainSecIdList(ListUtil.of(refId))
+                .secBenchmarkIdMap(benchmarkIdMap)
+                .indexIdList(ListUtil.of(benchmarkId))
+                .raiseType(RaiseType.Both)
+                .strategy(Strategy.All)
+                .visibility(Visibility.Both)
+                .dataFrequency(Frequency.Default)
+                .navType(NavType.CumulativeNav)
+                .secDateIntervalDtoListMap(dateIntervalMap)
+                .indicatorList(indicatorList)
+                .geoExtraindicatorList(ListUtil.empty())
+                .ifAnnualize(true)
+                .riskOfFreeId(Consts.RISK_OF_FREE)
+                .calcIndexRetIndicatorValue(true)
+                .ifConvertPerformanceConsistencyWord(true).build();
+        Map<String, List<IndicatorCalcPropertyDto>> indicatorValueMap = this.baseIndicatorServiceV2.calcMultipleSecMultipleTimeRangeIndicator(req);
+
+        // DateIntervalType.CustomInterval 类型下每个标的只会返回一个维度下的指标计算结果,所以只获取第一条记录的指标计算结果
+        Map<String, Map<String, String>> result = MapUtil.newHashMap();
+        Map<String, String> valueMap = Optional.ofNullable(indicatorValueMap).map(e -> e.get(refId)).orElse(ListUtil.empty()).stream().findFirst()
+                .map(IndicatorCalcPropertyDto::getSecData).map(IndicatorCalcSecDataDto::getIndicatorValueMap).orElse(MapUtil.empty());
+        Map<String, String> valueBenchmarkMap = Optional.ofNullable(indicatorValueMap).map(e -> e.get(refId)).orElse(ListUtil.empty()).stream().findFirst()
+                .map(IndicatorCalcPropertyDto::getIndexData).map(IndicatorCalcIndexDataDto::getIndexIndicatorValueMap).map(e -> e.get(benchmarkId)).orElse(MapUtil.empty());
+        result.put(refId, valueMap);
+        result.put(benchmarkId, valueBenchmarkMap);
+        return result;
+    }
 }

+ 35 - 1
src/main/java/com/smppw/analysis/client/FundApi.java

@@ -95,7 +95,7 @@ public class FundApi {
     }
 
     /**
-     * 基金费率信息
+     * 私募基金费率信息
      *
      * @param refId 基金id
      * @return 基金费率信息
@@ -105,4 +105,38 @@ public class FundApi {
         return ResultVo.ok(this.service.getFundFee(refId));
     }
 
+    /**
+     * 公募基金费率信息
+     *
+     * @param refId 基金id
+     * @return 基金费率信息
+     */
+    @GetMapping("mf-fee")
+    public ResultVo<ManualFundFeeInfoVO> mFFundFee(String refId) {
+        return ResultVo.ok(this.service.getMfFundFee(refId));
+    }
+
+
+    /**
+     * 私募基金详情页-基金经理
+     *
+     * @param refId 基金id
+     * @return 基金经理信息
+     */
+    @GetMapping("manager-info")
+    public ResultVo<List<FundManagerInfoVo>> managerInfo(@RequestParam("refId") String refId) {
+        return ResultVo.ok(this.service.getHFManagerInfo(refId));
+    }
+
+    /**
+     * 公募基金的基金经理变更历史
+     *
+     * @param params 基金id
+     * @return 公募基金的基金经理变更历史
+     */
+    @GetMapping("manager-change")
+    public ResultVo<List<ManualFundManagerChangeVO>> managerChange(ManualFundManagerParams params) {
+        return ResultVo.ok(this.service.managerChangeList(params));
+    }
+
 }

+ 4 - 0
src/main/java/com/smppw/analysis/domain/dao/FundInformationDao.java

@@ -86,4 +86,8 @@ public class FundInformationDao {
     public FundFeeDo getFundFee(String fundId) {
         return this.fundInformationDoMapper.getFundFee(fundId);
     }
+
+    public List<ManualFundManagerChangeDo> listFundManagerChangeHistory(String fundId) {
+        return this.fundInformationDoMapper.listFundManagerChangeHistory(fundId);
+    }
 }

+ 45 - 0
src/main/java/com/smppw/analysis/domain/dataobject/ManualFundFeeDo.java

@@ -0,0 +1,45 @@
+package com.smppw.analysis.domain.dataobject;
+
+import lombok.Data;
+
+/**
+ * @author mozuwen
+ * @date 2023/8/9 14:30
+ * @description 公募基金费率信息
+ */
+@Data
+public class ManualFundFeeDo {
+
+    /**
+     * 基金id
+     */
+    private String fundId;
+    /**
+     * 费率类别
+     * 10210 - 认购费场外前端
+     * 11010 - 日常申购费前端
+     * 11210 - 日常申购费场外前端
+     * 12000 - 日常赎回费
+     * 12200 - 日常赎回费场外
+     * 15000 - 管理费
+     * 16000 - 托管费
+     * 19000 - 营销费
+     */
+    private String chargeRateType;
+
+    /**
+     * 费率描述
+     */
+    private String chargeRateDes;
+
+    /**
+     * 费率划分标准范围Ⅰ起始数值
+     */
+    private Double stDivStand1;
+
+    /**
+     * 费率划分标准范围Ⅰ截止数值
+     */
+    private Double enDivStand1;
+
+}

+ 37 - 0
src/main/java/com/smppw/analysis/domain/dataobject/ManualFundManagerChangeDo.java

@@ -0,0 +1,37 @@
+package com.smppw.analysis.domain.dataobject;
+
+import lombok.Data;
+
+/**
+ * @author mozuwen
+ * @date 2023/8/9 14:00
+ * @description 公募基金的基金经理变更历史
+ */
+@Data
+public class ManualFundManagerChangeDo {
+
+    /**
+     * 基金id
+     */
+    private String fundId;
+
+    /**
+     * 基金经理id
+     */
+    private String managerId;
+
+    /**
+     * 经理名称
+     */
+    private String managerName;
+
+    /**
+     * 任职开始时间
+     */
+    private String startDate;
+    /**
+     * 任职结束时间
+     */
+    private String endDate;
+
+}

+ 42 - 0
src/main/java/com/smppw/analysis/domain/dataobject/PersonnelInformationDo.java

@@ -0,0 +1,42 @@
+package com.smppw.analysis.domain.dataobject;
+
+import lombok.Data;
+
+/**
+ * @author mozuwen
+ * @date 2023/8/9 15:30
+ * @description 人员信息
+ */
+@Data
+public class PersonnelInformationDo {
+
+    /**
+     * 人员id
+     */
+    private String personnelId;
+
+    /**
+     * 人员名称
+     */
+    private String personnelName;
+
+    /**
+     * 人员头像1
+     */
+    private String avatar;
+
+    /**
+     * 人员头像2
+     */
+    private String avatar2;
+
+    /**
+     * 最高学历
+     */
+    private Integer education;
+
+    /**
+     * 简介
+     */
+    private String profile;
+}

+ 38 - 0
src/main/java/com/smppw/analysis/domain/dataobject/PersonnelWorkExperienceDo.java

@@ -0,0 +1,38 @@
+package com.smppw.analysis.domain.dataobject;
+
+import lombok.Data;
+
+/**
+ * @author mozuwen
+ * @date 2023/8/9 16:00
+ * @description 人员任职经历
+ */
+@Data
+public class PersonnelWorkExperienceDo {
+
+    /**
+     * 人员id
+     */
+    private String personnelId;
+
+    /**
+     * 任职公司
+     */
+    private String companyName;
+
+    /**
+     * 任职开始时间
+     */
+    private String startDate;
+
+    /**
+     * 任职结束时间
+     */
+    private String endDate;
+
+    /**
+     * 任职期间职务
+     */
+    private String position;
+
+}

+ 1 - 1
src/main/java/com/smppw/analysis/domain/dto/info/FundBaseFeeVO.java

@@ -5,7 +5,7 @@ import lombok.Data;
 /**
  * @author mozuwen
  * @date 2023/8/9 11:25
- * @description 基金费率信息
+ * @description 私募基金费率信息
  */
 @Data
 public class FundBaseFeeVO {

+ 57 - 0
src/main/java/com/smppw/analysis/domain/dto/info/FundManagerInfoVo.java

@@ -0,0 +1,57 @@
+package com.smppw.analysis.domain.dto.info;
+
+import com.smppw.analysis.domain.dataobject.PersonnelWorkExperienceDo;
+import lombok.Data;
+
+import java.util.List;
+
+
+/**
+ * @author mozuwen
+ * @date 2023/8/9 15:00
+ * @description 私募基金详情页-基金经理
+ */
+@Data
+public class FundManagerInfoVo {
+
+    /**
+     * 基金经理id
+     */
+    private String managerId;
+
+    /**
+     * 基金经理名字
+     */
+    private String managerName;
+
+    /**
+     * 任务头像1
+     */
+    private String avatar;
+
+    /**
+     * 人物头像2
+     */
+    private String avatar2;
+
+    /**
+     * 最新职务
+     */
+    private String latestPosition;
+
+    /**
+     * 学历
+     */
+    private String education;
+
+    /**
+     * 经理简历
+     */
+    private String profile;
+
+    /**
+     * 基金经理工作履历
+     */
+    List<PersonnelWorkExperienceDo> managerWorkExperienceList;
+
+}

+ 46 - 0
src/main/java/com/smppw/analysis/domain/dto/info/ManualFundFeeInfoVO.java

@@ -0,0 +1,46 @@
+package com.smppw.analysis.domain.dto.info;
+
+import com.smppw.common.pojo.ValueLabelVO;
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * @author mozuwen
+ * @date 2023/8/9 14:30
+ * @description 公募基金费率信息
+ */
+@Data
+public class ManualFundFeeInfoVO {
+
+    /**
+     * 认购费
+     */
+    private List<ValueLabelVO> subscriptionFee;
+
+    /**
+     * 申购费
+     */
+    private List<ValueLabelVO> applyFee;
+
+    /**
+     * 赎回费
+     */
+    private List<ValueLabelVO> redemptionFee;
+
+    /**
+     * 管理费
+     */
+    private String managementFeeTrust;
+
+    /**
+     * 托管费
+     */
+    private String managementFeeBank;
+
+    /**
+     * 营销费
+     */
+    private String saleFee;
+
+}

+ 58 - 0
src/main/java/com/smppw/analysis/domain/dto/info/ManualFundManagerChangeVO.java

@@ -0,0 +1,58 @@
+package com.smppw.analysis.domain.dto.info;
+
+import lombok.Data;
+
+/**
+ * @author mozuwen
+ * @date 2023/8/9 17:00
+ * @description 公募基金的基金经理变更历史
+ */
+@Data
+public class ManualFundManagerChangeVO {
+
+    /**
+     * 任内年化收益
+     */
+    private String annualRet;
+
+    /**
+     * 任内卡玛比率
+     */
+    private String calmar;
+
+    /**
+     * 任职日期
+     */
+    private String employDate;
+
+    /**
+     * 任职天数
+     */
+    private String employDayNum;
+
+    /**
+     * 任职期间收益
+     */
+    private String fundRet;
+
+    /**
+     * 基金经理id
+     */
+    private String managerId;
+
+    /**
+     * 基金经理名字
+     */
+    private String managerName;
+
+    /**
+     * 任内最大回撤
+     */
+    private String maxDrawdown;
+
+    /**
+     * 任内索提诺比率
+     */
+    private String sortino;
+
+}

+ 9 - 0
src/main/java/com/smppw/analysis/domain/mapper/core/FundInformationDoMapper.java

@@ -3,6 +3,7 @@ package com.smppw.analysis.domain.mapper.core;
 import com.smppw.analysis.domain.dataobject.FundFeeDo;
 import com.smppw.analysis.domain.dataobject.FundInformationDo;
 import com.smppw.analysis.domain.dataobject.FundSimilarDo;
+import com.smppw.analysis.domain.dataobject.ManualFundManagerChangeDo;
 import org.apache.ibatis.annotations.Param;
 import org.springframework.stereotype.Repository;
 
@@ -60,4 +61,12 @@ public interface FundInformationDoMapper {
      */
     FundFeeDo getFundFee(String fundId);
 
+    /**
+     * 获取公募基金的基金经理变更历史
+     *
+     * @param fundId 基金id
+     * @return 公募基金的基金经理变更历史
+     */
+    List<ManualFundManagerChangeDo> listFundManagerChangeHistory(@Param("fundId") String fundId);
+
 }

+ 24 - 0
src/main/java/com/smppw/analysis/domain/mapper/core/MfChargeRateMapper.java

@@ -0,0 +1,24 @@
+package com.smppw.analysis.domain.mapper.core;
+
+import com.smppw.analysis.domain.dataobject.ManualFundFeeDo;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+
+/**
+ * @author mozuwen
+ * @date 2023/8/9 14:30
+ * @description 公募基金费率信息Mapper
+ */
+@Repository
+public interface MfChargeRateMapper {
+
+    /**
+     * 获取公募基金费率信息
+     *
+     * @param fundId 基金id
+     * @return 公募基金费率信息
+     */
+    List<ManualFundFeeDo> getManualFundFee(String fundId);
+
+}

+ 35 - 0
src/main/java/com/smppw/analysis/domain/mapper/core/PersonnelInformationMapper.java

@@ -0,0 +1,35 @@
+package com.smppw.analysis.domain.mapper.core;
+
+import com.smppw.analysis.domain.dataobject.PersonnelInformationDo;
+
+import com.smppw.analysis.domain.dataobject.PersonnelWorkExperienceDo;
+import org.apache.ibatis.annotations.Param;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+
+/**
+ * @author mozuwen
+ * @date 2023/8/9 15:30
+ * @description 人员信息Mapper
+ */
+@Repository
+public interface PersonnelInformationMapper {
+
+    /**
+     * 获取人员基本信息
+     *
+     * @param refId 基金id
+     * @return 人员基本信息
+     */
+    List<PersonnelInformationDo> getFundManagerInfo(String refId);
+
+    /**
+     * 获取人员任职经历
+     *
+     * @param personnelIdList 人员id列表
+     * @return 人员任职经历
+     */
+    List<PersonnelWorkExperienceDo> listPersonnelWorkExperience(@Param("personnelIdList") List<String> personnelIdList);
+
+}

+ 33 - 0
src/main/java/com/smppw/analysis/domain/service/BaseInfoService.java

@@ -129,4 +129,37 @@ public interface BaseInfoService {
      * @return 基金的申赎费率信息
      */
     FundFeeDo getFundFee(String fundId);
+
+
+    /**
+     * 获取公募基金费率信息
+     *
+     * @param fundId 基金id
+     * @return 公募基金费率信息
+     */
+    List<ManualFundFeeDo> getManualFundFee(String fundId);
+
+    /**
+     * 获取人员基本信息
+     *
+     * @param refId 基金id
+     * @return 人员基本信息
+     */
+    List<PersonnelInformationDo> getFundManagerInfo(String refId);
+
+    /**
+     * 获取人员任职经历
+     *
+     * @param personnelIdList 人员id礼列表
+     * @return 人员任职经历
+     */
+    List<PersonnelWorkExperienceDo> listPersonnelWorkExperience(List<String> personnelIdList);
+
+    /**
+     * 获取公募基金的基金经理变更历史
+     *
+     * @param fundId 基金id
+     * @return 公募基金的基金经理变更历史
+     */
+    List<ManualFundManagerChangeDo> listFundManagerChangeHistory(String fundId);
 }

+ 28 - 6
src/main/java/com/smppw/analysis/domain/service/impl/BaseInfoServiceImpl.java

@@ -8,16 +8,14 @@ import cn.hutool.core.util.StrUtil;
 import com.smppw.analysis.domain.dao.*;
 import com.smppw.analysis.domain.dao.rank.RankDao;
 import com.smppw.analysis.domain.dao.rank.RankFactory;
-import com.smppw.analysis.domain.dataobject.FundArchivesInfoDO;
-import com.smppw.analysis.domain.dataobject.FundSimilarDo;
-import com.smppw.analysis.domain.dataobject.ManualFundNoticeInfoDO;
-import com.smppw.analysis.domain.dataobject.MonetaryFundProfitDO;
 import com.smppw.analysis.domain.dataobject.*;
 import com.smppw.analysis.domain.dto.info.FundSimilarParams;
 import com.smppw.analysis.domain.event.SaveCacheEvent;
 import com.smppw.analysis.domain.gateway.CacheFactory;
 import com.smppw.analysis.domain.gateway.CacheGateway;
 import com.smppw.analysis.domain.mapper.core.CommonIndexMapper;
+import com.smppw.analysis.domain.mapper.core.MfChargeRateMapper;
+import com.smppw.analysis.domain.mapper.core.PersonnelInformationMapper;
 import com.smppw.analysis.domain.service.BaseInfoService;
 import com.smppw.analysis.infrastructure.config.AnalysisProperty;
 import com.smppw.analysis.infrastructure.consts.RedisConst;
@@ -68,14 +66,16 @@ public class BaseInfoServiceImpl implements BaseInfoService, ApplicationContextA
     private final FundInformationDao fundInformationDao;
     private final FundAnnounceDao fundAnnounceDao;
     private final FundArchivesDao fundArchivesDao;
+    private final MfChargeRateMapper mfChargeRateMapper;
+    private final PersonnelInformationMapper personnelInformationMapper;
     private ApplicationContext applicationContext;
-
     @Autowired
     private CommonIndexMapper commonIndexMapper;
 
     public BaseInfoServiceImpl(AnalysisProperty property, CacheFactory factory, RankFactory rankFactory,
                                IndexesProfileDao indexesProfileDao, RongzhiIndexNavDao rongzhiIndexNavDao,
-                               FundInformationDao fundInformationDao, FundAnnounceDao fundAnnounceDao, FundArchivesDao fundArchivesDao) {
+                               FundInformationDao fundInformationDao, FundAnnounceDao fundAnnounceDao,
+                               FundArchivesDao fundArchivesDao, MfChargeRateMapper mfChargeRateMapper, PersonnelInformationMapper personnelInformationMapper) {
         this.rankDao = rankFactory.getInstance(property.getDataSource());
         this.cacheGateway = factory.getCacheGateway(property.getCacheType());
         this.indexesProfileDao = indexesProfileDao;
@@ -83,6 +83,8 @@ public class BaseInfoServiceImpl implements BaseInfoService, ApplicationContextA
         this.fundInformationDao = fundInformationDao;
         this.fundAnnounceDao = fundAnnounceDao;
         this.fundArchivesDao = fundArchivesDao;
+        this.mfChargeRateMapper = mfChargeRateMapper;
+        this.personnelInformationMapper = personnelInformationMapper;
     }
 
     @Override
@@ -296,6 +298,26 @@ public class BaseInfoServiceImpl implements BaseInfoService, ApplicationContextA
         return fundInformationDao.getFundFee(fundId);
     }
 
+    @Override
+    public List<ManualFundFeeDo> getManualFundFee(String fundId) {
+        return mfChargeRateMapper.getManualFundFee(fundId);
+    }
+
+    @Override
+    public List<PersonnelInformationDo> getFundManagerInfo(String fundId) {
+        return personnelInformationMapper.getFundManagerInfo(fundId);
+    }
+
+    @Override
+    public List<PersonnelWorkExperienceDo> listPersonnelWorkExperience(List<String> personnelIdList) {
+        return personnelInformationMapper.listPersonnelWorkExperience(personnelIdList);
+    }
+
+    @Override
+    public List<ManualFundManagerChangeDo> listFundManagerChangeHistory(String fundId) {
+        return fundInformationDao.listFundManagerChangeHistory(fundId);
+    }
+
     /**
      * 把指定类型的标的的名称映射查询出来
      *

+ 17 - 0
src/main/resources/mapping/core/FundInformationDoMapper.xml

@@ -338,4 +338,21 @@
         where t1.fund_id = #{fundId}
     </select>
 
+    <select id="listFundManagerChangeHistory"
+            resultType="com.smppw.analysis.domain.dataobject.ManualFundManagerChangeDo">
+        select t1.fund_id               as fundId,
+               t2.fund_manager_id       as managerId,
+               t3.personnel_name        as managerName,
+               t2.management_start_date as startDate,
+               t2.management_end_date   as endDate
+        from rz_hfdb_core.fund_information t1
+                 join rz_hfdb_core.fund_manager_mapping t2
+                      on t1.fund_id = t2.fund_id and t2.isvalid = 1
+                 join rz_hfdb_core.personnel_information t3
+                      on t2.fund_manager_id = t3.personnel_id and t3.isvalid = 1
+        where t1.isvalid = 1
+          and t1.fund_id = #{fundId}
+        order by startDate desc
+    </select>
+
 </mapper>

+ 18 - 0
src/main/resources/mapping/core/MfChargeRetMapper.xml

@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.smppw.analysis.domain.mapper.core.MfChargeRateMapper">
+
+    <select id="getManualFundFee" resultType="com.smppw.analysis.domain.dataobject.ManualFundFeeDo">
+        select fund_id          as fundId,
+               charge_rate_type as chargeRateType,
+               charge_rate_des  as chargeRateDes,
+               st_div_stand1    as stDivStand1,
+               en_div_stand1    as enDivStand1
+        from rz_hfdb_core.mf_charge_rate
+        where fund_id = #{fundId}
+          and charge_rate_type in (10210, 11010, 11210, 12000, 12200, 15000, 16000, 19000)
+          and isvalid = 1
+          and if_executed = 1
+    </select>
+
+</mapper>

+ 46 - 0
src/main/resources/mapping/core/PersonnelInformationMapper.xml

@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.smppw.analysis.domain.mapper.core.PersonnelInformationMapper">
+
+
+    <select id="getFundManagerInfo" resultType="com.smppw.analysis.domain.dataobject.PersonnelInformationDo">
+        select t1.personnel_id   as personnelId,
+               t1.personnel_name as personnelName,
+               t1.avatar         as avatar,
+               t1.avatar2        as avatar2,
+               t1.education      as education,
+               t1.profile        as profile
+        from rz_hfdb_core.personnel_information t1
+                 inner join rz_hfdb_core.fund_manager_mapping t2
+                            on t1.personnel_id = t2.fund_manager_id and t2.isvalid = 1
+        where t2.fund_id = #{refId}
+          and t1.isvalid = 1
+    </select>
+
+    <select id="listPersonnelWorkExperience"
+            resultType="com.smppw.analysis.domain.dataobject.PersonnelWorkExperienceDo">
+        SELECT t1.personnel_id as personnelId,
+               t5.company_name as companyName,
+               t1.start_date   as startDate,
+               t1.end_date     as endDate,
+               GROUP_CONCAT(DISTINCT t4.position_name ORDER BY t1.start_date) AS position
+        FROM rz_hfdb_core.personnel_company_mapping t1
+            JOIN rz_hfdb_core.personnel_company_position_mapping t2
+        ON t2.personnel_id = t1.personnel_id AND t2.company_id = t1.company_id
+            AND t2.isvalid = 1
+            JOIN rz_hfdb_core.personnel_company_position_id_mapping t3
+            ON t3.rec_id = t2.id AND t3.isvalid = 1
+            JOIN rz_hfdb_core.d_position t4
+            ON t4.id = t3.position_id AND t4.isvalid = 1
+            JOIN rz_hfdb_core.company_information t5
+            on t1.company_id =t5.company_id and t5.isvalid =1
+        WHERE t1.isvalid = 1
+          AND t1.personnel_id in
+            <foreach collection="personnelIdList" item="personnelId" index="index" open="(" separator="," close=")">
+                #{personnelId}
+            </foreach>
+        GROUP BY t1.personnel_id, t1.company_id, t1.start_date, t1.end_date
+        ORDER BY t1.start_date DESC, t1.company_id DESC
+    </select>
+
+</mapper>