Commit 64c9ace3 authored by lilei's avatar lilei

首席定制定时任务

parent 2ed18d3c
...@@ -101,4 +101,6 @@ public class CommonConfig { ...@@ -101,4 +101,6 @@ public class CommonConfig {
private String surveyStockPriceTask; private String surveyStockPriceTask;
@Value("${nacos.config.highStockPriceTask}") @Value("${nacos.config.highStockPriceTask}")
private String highStockPriceTask; private String highStockPriceTask;
@Value("${nacos.config.chiefStockPriceTask}")
private String chiefStockPriceTask;
} }
...@@ -108,6 +108,7 @@ public class MybatisConfiguration { ...@@ -108,6 +108,7 @@ public class MybatisConfiguration {
mapperLocations.add("classpath*:mybatis/mapper/product/*.xml"); mapperLocations.add("classpath*:mybatis/mapper/product/*.xml");
mapperLocations.add("classpath*:mybatis/mapper/report/*.xml"); mapperLocations.add("classpath*:mybatis/mapper/report/*.xml");
mapperLocations.add("classpath*:mybatis/mapper/high/*.xml"); mapperLocations.add("classpath*:mybatis/mapper/high/*.xml");
mapperLocations.add("classpath*:mybatis/mapper/chief/*.xml");
List<Resource> resources = new ArrayList(); List<Resource> resources = new ArrayList();
if (!CollectionUtils.isEmpty(mapperLocations)) { if (!CollectionUtils.isEmpty(mapperLocations)) {
for (String mapperLocation : mapperLocations) { for (String mapperLocation : mapperLocations) {
......
package com.zfxftech.telmarket.common.pojo.request.chief;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotNull;
import java.util.List;
/**
* @Description
* @Author jianghua
* @Date 2021/9/27 13:51
*/
@Data
@ApiModel(value = "批量卖出指令", description = "从客户端,交易指令封装的表单数据封装在此entity中")
public class ChiefBatchSellingOrderBO {
@NotNull
@ApiModelProperty(value = "股票代码集合", name = "code", required = true)
private List<String> code;
@NotNull
@ApiModelProperty(value = "示范盘id", name = "marketId", required = true)
private Long marketId;
}
package com.zfxftech.telmarket.common.pojo.request.chief;
import com.zfxftech.telmarket.common.pojo.request.PageBO;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* @Description TODO
* @Author Dell
* @Date 2021/12/25 18:58
*/
@Data
@ApiModel(value = "查询收集统计页面数据", description = "从客户端,查询收集统计数据传入的数据封装在此entity中")
public class ChiefPagePositionTradeInfoRecordGroupByBatchBO extends PageBO {
@ApiModelProperty(value = "股票代码", name = "code", required = false)
private String code;
@ApiModelProperty(value = "交易状态", name = "tradeStatus", required = false)
private Long tradeStatus;
@ApiModelProperty(value = "是否一对多过滤", name = "filterOneMore", required = false)
private Boolean filterOneMore;
@ApiModelProperty(value = "产品类型", name = "productType", required = false)
private String productType;
@ApiModelProperty(value = "产品id", name = "productId", required = false)
private Long productId;
@ApiModelProperty(value = "收益率下限", name = "profitLowerLimit", required = false)
private String profitLowerLimit;
@ApiModelProperty(value = "收益率上限", name = "profitUpperLimit", required = false)
private String profitUpperLimit;
@ApiModelProperty(value = "买入时间开始", name = "profitLowerLimit", required = false)
private Long buyingTimeLowerLimit;
@ApiModelProperty(value = "买入时间结束", name = "profitLowerLimit", required = false)
private Long buyingTimeUpperLimit;
@ApiModelProperty(value = "卖出时间开始", name = "profitLowerLimit", required = false)
private Long sellingTimeLowerLimit;
@ApiModelProperty(value = "卖出时间结束", name = "profitLowerLimit", required = false)
private Long sellingTimeUpperLimit;
@ApiModelProperty(value = "排序 格式:排序字段:ASC", name = "orderBy", required = false)
private String orderBy;
@ApiModelProperty(value = "公司id", name = "companyId", required = false)
private Integer companyId;
@ApiModelProperty(value = "委托方向", name = "trustSourceId", required = false)
private Integer trustSourceId;
@ApiModelProperty(value = "行业", name = "industry", required = false)
private String industry;
}
package com.zfxftech.telmarket.common.pojo.request.chief;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
/**
* @Description TODO
* @Author Dell
* @Date 2021/11/15 15:07
*/
@ApiModel(value = "模拟盘详情查询表单", description = "从客户端,模拟盘详情查询传入的数据封装在此entity中")
@Data
public class ChiefQueryCustomerMarketDetailsBO {
@NotNull
@ApiModelProperty(value = "模拟盘id", name = "marketId", required = true)
private Long marketId;
@NotBlank
@ApiModelProperty(value = "模拟盘类型 实盘:real 示范:simulated", name = "type", required = true)
private String type;
}
package com.zfxftech.telmarket.common.pojo.request.chief;
import com.zfxftech.telmarket.common.pojo.request.PageBO;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
@ApiModel(value = "查询产品列表", description = "从客户端,查询产品列表传入的数据封装在此entity中")
public class ChiefQueryProductBO extends PageBO {
@ApiModelProperty(value = "产品类型", name = "productType", required = false)
private String productType;
@ApiModelProperty(value = "产品id", name = "productId", required = false)
private String productId;
@ApiModelProperty(value = "风险等级", name = "riskLevel", required = false)
private String riskLevel;
@ApiModelProperty(value = "分析师", name = "analyst", required = false)
private Long analyst;
@ApiModelProperty(value = "产品经理", name = "productManager", required = false)
private Long productManager;
@ApiModelProperty(value = "所属公司", name = "companyId", required = false)
private Integer companyId;
// @ApiModelProperty(value = "初始本金", name = "initialPrincipal", required = false)
// private String initialPrincipal;
@ApiModelProperty(value = "开始时间", name = "startCreateTime", example = "1626739300000", required = false)
private Long startCreateTime;
@ApiModelProperty(value = "结束时间", name = "endExpiredTime", example = "1626739300000", required = false)
private Long endCreateTime;
@ApiModelProperty(value = "公众号", name = "weChatId", example = "19", required = false)
private Long weChatId;
@ApiModelProperty(value = "排序(格式:排序字段:排序规则) 支持的字段:created_time、initial_funding、modify_time, 序:desc降序 asc升序", name = "sort", example = "created_time:desc", required = false)
private String orderBy;
private String uid;
}
package com.zfxftech.telmarket.common.pojo.request.chief;
import com.zfxftech.telmarket.common.pojo.request.PageBO;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotBlank;
@Data
@ApiModel(value = "查询股票录入记录", description = "从客户端,查询股票录入记录的数据封装在此entity中")
public class ChiefQueryStockInputLogBO extends PageBO {
@ApiModelProperty(value = "客户id", name = "description", required = false)
private String customerId;
@ApiModelProperty(value = "产品类型", name = "productType", example = "6050350b758289001f6bb543", required = false)
private String productType;
@ApiModelProperty(value = "产品id", name = "productId", example = "6051c185338354001cc327cf", required = false)
private String productId;
@ApiModelProperty(value = "股票代码", name = "code", example = "000001", required = false)
private String code;
@ApiModelProperty(value = "交易方向", name = "startExpiredTime", example = "1626739100000", required = false)
private Integer operation;
@ApiModelProperty(value = "交易时间上限", name = "tradingTimeUpperLimit", example = "1626739100000", required = false)
private Long tradingTimeUpperLimit;
@ApiModelProperty(value = "交易时间下限", name = "tradingTimeLowerLimit", example = "1626739300000", required = false)
private Long tradingTimeLowerLimit;
@ApiModelProperty(value = "示范盘Id", name = "description", required = false)
private String marketId;
@NotBlank
@ApiModelProperty(value = "实盘|示范", name = "marketType", required = true)
private String marketType;
private Integer companyId;
}
package com.zfxftech.telmarket.common.pojo.request.chief;
import com.zfxftech.telmarket.common.pojo.request.PageBO;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotNull;
/**
* @Description TODO
* @Author Dell
* @Date 2021/11/23 15:45
*/
@ApiModel(value = "个股盈亏列表表单", description = "个股盈亏列表表单")
@Data
public class ChiefQueryStockProfitLogBO extends PageBO {
@NotNull
@ApiModelProperty(value = "模拟盘id", name = "marketId", required = true)
private Long marketId;
}
package com.zfxftech.telmarket.common.pojo.request.chief;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotNull;
/**
* @Description TODO
* @Author jianghua
* @Date 2021/8/31 17:34
*/
@Data
@ApiModel(value = "保存产品", description = "从客户端,保存产品传入的数据封装在此entity中")
public class ChiefSaveProductBO {
@ApiModelProperty(value = "产品id", name = "id", required = false)
private Long id;
@NotNull(message = "客戶名称不能为空")
@ApiModelProperty(value = "产品名称", name = "productName", required = true)
private String productName;
@NotNull(message = "产品类型不能为空")
@ApiModelProperty(value = "产品类型", name = "productType", required = true)
private String productType;
@NotNull(message = "所属分公司不能为空")
@ApiModelProperty(value = "所属分公司,格式:1,2,3", name = "companyId", required = true)
private Long companyId;
// @NotNull(message = "交易风格不能为空")
@ApiModelProperty(value = "交易风格", name = "tradeStyle", required = false)
private Long tradeStyle;
@ApiModelProperty(value = "风险等级,暂时只有跟投有产品", name = "riskLevel", required = false)
private String riskLevel;
// @ApiModelProperty(value = "初始本金", name = "initialPrincipal", required = false)
// private String initialPrincipal;
@ApiModelProperty(value = "卖出股票消息通知 0 未勾选 1勾选", name = "sellMessage", required = false)
private String sellMessage;
@ApiModelProperty(value = "买入消息股票通知 0 未勾选 1勾选", name = "buyMessage", required = false)
private String buyMessage;
// @ApiModelProperty(value = "每日统计发送通知 0 未勾选 1勾选", name = "dayStatisticsSend", required = false)
// private String dayStatisticsSend;
@ApiModelProperty(value = "产品经理", name = "productManagerList", required = false)
private String productManagerList;
@NotNull(message = "公众号不能为空")
@ApiModelProperty(value = "公众号Id", name = "weChatId", required = true)
private Long weChatId;
@ApiModelProperty(value = "分析师", name = "analyst", required = true)
private Long analyst;
@ApiModelProperty(value = "备注", name = "remark", required = false)
private String remark;
}
package com.zfxftech.telmarket.common.pojo.request.chief;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.util.List;
/**
* @Description 系统常量字典表
* @Author jianghua
* @Date 2021/9/27 13:51
*/
@Data
@ApiModel(value = "卖出指令", description = "从客户端,交易指令封装的表单数据封装在此entity中")
public class ChiefSellingOrderBO {
@NotBlank
@ApiModelProperty(value = "股票代码", name = "code", required = true)
private String code;
@NotNull
@ApiModelProperty(value = "是否是现价卖出,是:true,否:false", name = "type", required = true)
private boolean isPresent;
@ApiModelProperty(value = "价格,若是现价当前值为空", name = "type", required = false)
private String price;
@NotBlank
@ApiModelProperty(value = "卖出仓位", name = "position", example = "0.333", required = true)
private String position;
@NotNull
@ApiModelProperty(value = "用户和产品关联id", name = "relationId", required = true)
private List<Long> relationId;
@NotBlank
@ApiModelProperty(value = "卖出理由", name = "reason", required = true)
private String reason;
private boolean followAccountLink;
private String followAccountName;
}
package com.zfxftech.telmarket.common.pojo.request.chief;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotNull;
import java.util.List;
/**
* @Description
* @Author jianghua
* @Date 2021/9/27 13:51
*/
@Data
@ApiModel(value = "原价清零", description = "从客户端,交易指令封装的表单数据封装在此entity中")
public class ChiefSendClearOrderBO {
@NotNull
@ApiModelProperty(value = "股票代码集合", name = "code", required = true)
private List<String> code;
@NotNull
@ApiModelProperty(value = "示范盘id", name = "marketId", required = true)
private Long marketId;
}
package com.zfxftech.telmarket.common.pojo.request.chief;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.util.List;
/**
* @Description 系统常量字典表
* @Author jianghua
* @Date 2021/9/27 13:51
*/
@Data
@ApiModel(value = "", description = "从客户端,交易指令封装的表单数据封装在此entity中")
public class ChiefTradeOrderBO {
@NotBlank
@ApiModelProperty(value = "股票代码", name = "code", required = true)
private String code;
@ApiModelProperty(value = "风险等级", name = "riskLevel", required = false)
private String riskLevel;
@NotNull
@ApiModelProperty(value = "是否是现价买入,是:true,否:false", name = "isPresent", required = true)
private boolean isPresent;
@ApiModelProperty(value = "价格,若是现价当前值为空", name = "type", required = false)
private String price;
@NotBlank
@ApiModelProperty(value = "买入仓位", name = "position", example = "0.333", required = true)
private String position;
@NotNull
@ApiModelProperty(value = "用户和产品关联id", name = "relationId", required = true)
private List<Long> relationId;
@NotBlank
@ApiModelProperty(value = "买入理由", name = "reason", required = true)
private String reason;
@ApiModelProperty(value = "止盈位", name = "interferenceStopPosition", required = false)
private String interferenceStopPosition;
@ApiModelProperty(value = "止损位", name = "stopLossPosition", required = false)
private String stopLossPosition;
@ApiModelProperty(value = "买入股票数量,录入上海数据使用,以后删除", name = "buyStockToSyncDataCount", required = false)
private Long buyStockToSyncDataCount;
private boolean followAccountLink;
private String followAccountName;
}
package com.zfxftech.telmarket.common.pojo.vo.chief;
import lombok.Data;
import org.apache.commons.lang3.tuple.Pair;
import java.util.List;
/**
* @Description TODO
* @Author Dell
* @Date 2021/11/17 15:10
*/
@Data
public class ChiefMarketDetailsVO {
/**
* 姓名
*/
private String name;
/**
* 昵称
*/
private String nickName;
/**
* 投资风格
*/
private String investmentStyle;
/**
* 公司
*/
private String company;
/**
* 账户限制
*/
private String accountLimit;
/**
* 产品名称
*/
private String productName;
/**
* 产品类型
*/
private String productType;
/**
* 产品开始时间
*/
private Long productStartTime;
/**
* 产品结束时间
*/
private Long productEndTime;
/**
* 总价格
*/
private String totalPrice;
/**
* 总股票价值
*/
private String totalStocksPrice;
/**
* 可用资金
*/
private String availableFunding;
/**
* 当前仓位
*/
private String position;
/**
* 交易股票数
*/
private Integer stockCount;
/**
* 盈利股票数
*/
private Integer profitStockCount;
/**
* 持仓信息
*/
List<ChiefStockVO> stocksInfo;
/**
* 行业占比
*/
List<Pair<String, String>> industryProportion;
/**
* 产品类型(中文)
*/
private String productTypeDesc;
/**
* 总盈亏比例
*/
private String totalProfitRate;
/**
* 总盈亏
*/
private String totalProfit;
/**
* 产品经理
*/
private String pmUserName;
/**
* 销售关系名称
*/
private String teamRelationNames;
/**
* 客户id
*/
private Long customerId;
/**
* 是否问题客户 1=问题客户
*/
private String isProblem;
}
package com.zfxftech.telmarket.common.pojo.vo.chief;
import lombok.Data;
import lombok.ToString;
@Data
@ToString
public class ChiefProductStrategyVO {
private Integer id;
private String productName;
}
package com.zfxftech.telmarket.common.pojo.vo.chief;
import lombok.Data;
/**
* @Description TODO
* @Author Dell
* @Date 2021/11/23 15:46
*/
@Data
public class ChiefStockProfitLogVO {
private Long buyingTime;
private Long sellingTime;
private String code;
private String name;
private String stockDesc;
private String profitPrice;
private String profitRatio;
private Integer holdingDays;
/**
* 买入途径
*/
private String buyingRoute;
/**
* 卖出途径
*/
private String sellingRoute;
}
package com.zfxftech.telmarket.common.pojo.vo.chief;
import lombok.Data;
/**
* @Description TODO
* @Author Dell
* @Date 2021/11/17 15:27
*/
@Data
public class ChiefStockVO {
/**
* 代码
*/
private String code;
/**
* 名称
*/
private String name;
/**
* 来源
*/
private String channel;
/**
* 产品类型
*/
private String businessType;
/**
* 购入时间
*/
private Long buyTime;
/**
* 持仓数量
*/
private Long count;
/**
* 可用数量
*/
private Long availableCount;
/**
* 成本价格
*/
private String cost;
/**
* 最新价格
*/
private String currentPrice;
/**
* 当前市值
*/
private String marketValue;
/**
* 盈亏比例
*/
private String profitRate;
/**
* 浮动盈亏
*/
private String dynamicProfit;
}
package com.zfxftech.telmarket.common.pojo.vo.chief;
import io.swagger.annotations.ApiModel;
import lombok.Data;
/**
* @Description TODO
* @Author Dell
* @Date 2021/11/15 14:29
*/
@ApiModel(value = "交易指令交易失败返回实体类", description = "交易指令交易失败返回实体类")
@Data
public class ChiefTradeOrderVO {
/**
* 客户姓名
*/
private String customerName;
/**
* 错误码
*/
private Integer errorCode;
private Long customerId;
}
package com.zfxftech.telmarket.service.business.chief;
import com.baomidou.mybatisplus.extension.service.IService;
import com.zfxftech.telmarket.common.pojo.dao.chief.ChiefAccountProductRelation;
import com.zfxftech.telmarket.common.pojo.dto.chief.ChiefProductCustomerFansDto;
import java.util.List;
public interface ChiefAccountProductRelationService extends IService<ChiefAccountProductRelation> {
List<ChiefAccountProductRelation> queryAll();
//通过用户id批量查询用户的产品信息
List<ChiefAccountProductRelation> queryAccountProductRelationByMemberIds(List<Long> memberIds);
//通过用户id 产品id 批量查询用户的产品信息
List<ChiefAccountProductRelation> getMarkId(Long memberIds, List<Long> productList);
//批量查询用户的产品
List<ChiefAccountProductRelation> queryAccountProductRelationByMemberId(Long memberId);
//根据粉丝id查询用户的产品
List<ChiefAccountProductRelation> queryAccountProductRelationByFansId(Long fansId);
void updateAccountProductRelation(ChiefAccountProductRelation accountProductRelation, Long memberId, Long productId);
void updateAccountProductRelation(ChiefAccountProductRelation accountProductRelation);
void batchUpdateAccountProductRelation(List<ChiefAccountProductRelation> accountProductRelations);
void addAccountProductRelation(ChiefAccountProductRelation accountProductRelation);
//查询用户的指定产品
ChiefAccountProductRelation queryAccountProductRelationByMemberIdAndProductId(Long memberId, Long productId);
/**
* @param marketId
* @param type (实盘:real 示范:simulated)
* @return
*/
ChiefAccountProductRelation queryAccountProductRelationByMarketInfo(Long marketId, String type);
//通过id批量查询产品和用户的关联关系
List<ChiefAccountProductRelation> queryAccountProductRelationByIds(List<Long> relationIds);
//通过虚拟帐号批量查询产品和用户的关联关系
List<ChiefAccountProductRelation> queryAccountProductRelationBySimulatedIds(List<Long> simulatedIdsIds);
void checkProductIsExpire();
//根据产品id获取对应的客户userId 1表是只要客户的userId 2 表示只要分析师的userId 3.表示全都要
List<Long> getUserId(Long productId ,Integer type);
//根据产品id获取客户id
List<Long> getCustomerIds(Long productId);
List<ChiefProductCustomerFansDto> getProductUserList(Long productId);
List<ChiefAccountProductRelation> getRelationByProductIds(List<Long> ids);
void updateList(List<ChiefAccountProductRelation> list);
}
package com.zfxftech.telmarket.service.business.chief;
import com.zfxftech.telmarket.common.pojo.dao.Quote;
import com.zfxftech.telmarket.common.pojo.dao.StocksCode;
import com.zfxftech.telmarket.common.pojo.dao.chief.ChiefStockPosition;
import org.apache.commons.lang3.tuple.Pair;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
public interface ChiefFinanceCalculateService {
/**
* 计算股价均值
*
* @param totalPrice
* @param count
* @return
*/
BigDecimal calculateAverageStockPrice(BigDecimal totalPrice, Long count);
/**
* 计算股价均值
*
* @param count1 新买入股数
* @param price1 新买入股票成交价
* @param count2 原先总股数
* @param price2 原先股票平均成交价
* @return
*/
BigDecimal calculateAverageStockPrice(Long count1, BigDecimal price1, Long count2, BigDecimal price2);
/**
* 计算总资产(股票+可用资金)
*
* @param availableFund 可用资金
* @param stockPositions 股票持仓
* @param stockCodeAndPriceMapping 股票代码-股票映射关系
* @return
*/
BigDecimal calculateTotalAssets(BigDecimal availableFund, List<ChiefStockPosition> stockPositions, Map<String, Quote> stockCodeAndPriceMapping);
/**
* 计算股票总市值(当前价格)
*
* @param stockPositions
* @param stockCodeAndPriceMapping
* @return
*/
BigDecimal calculateTotalAssets(List<ChiefStockPosition> stockPositions, Map<String, Quote> stockCodeAndPriceMapping);
/**
* 计算股票总市值(成本价格)
*
* @param stockPositions
* @return
*/
BigDecimal calculateTotalAssets(List<ChiefStockPosition> stockPositions);
/**
* 计算可买入股票价格
*
* @param totalFund 资金
* @param price 价格
* @return
*/
Long calculateBuyStockCount(BigDecimal totalFund, BigDecimal price);
/**
* 计算总价
*
* @param count 股数
* @param price 股票价格
* @return
*/
BigDecimal calculateTotalPrice(Long count, BigDecimal price);
/**
* 计算股票站总股票市值的占比
*
* @param totalValue 股票总值
* @param count 股数
* @param price 价格
* @return
*/
BigDecimal calculateIndustryShare(BigDecimal totalValue, Long count, BigDecimal price);
/**
* 计算收益率(盈亏比例)
*
* @param value1 减数
* @param value2 被减数
* @return
*/
BigDecimal calculateProfitRate(BigDecimal value1, BigDecimal value2);
/**
* 计算收益率(盈亏比例)
*
* @param value1 减数
* @param value2 被减数
* @return
*/
BigDecimal calculateProfitRate2(BigDecimal value1, BigDecimal value2);
/**
* 计算单个股票的涨跌幅
* 最新价格
* 收盘价格
* 涨跌幅=(现价-上一个交易日收盘价)/上一个交易日收盘价*100%
* @return
*/
BigDecimal riseDownRange(BigDecimal now, BigDecimal close);
/**
* 计算单个股票的盈亏比例
* 最新价格
* 成本价格
* 盈亏比例=(现价-成本价)/成本价×100%
* @return
*/
BigDecimal profitLossRatio(BigDecimal now, BigDecimal cost);
/**
* 计算收益
*
* @param value1 分子
* @param value2 分母
* @return
*/
BigDecimal calculateProfit(BigDecimal value1, BigDecimal value2);
/**
* @param price 价格
* @param range 范围
* @return
*/
Pair<String, String> calculatePriceRange(String price, String range);
/**
* @param stocksCode 根据股票计算涨跌幅
* @return
*/
Pair<BigDecimal, BigDecimal> calculatePriceLimit(StocksCode stocksCode);
}
package com.zfxftech.telmarket.service.business.chief;
import com.zfxftech.telmarket.common.pojo.dao.chief.ChiefFrozenRecord;
import java.util.List;
/**
* @Description TODO
* @Author Dell
* @Date 2021/12/21 14:30
*/
public interface ChiefFrozenRecordService {
/**
* marketId和股票代码获取股票
*
* @param marketId
* @param code
* @return
*/
ChiefFrozenRecord getStockByMarketIdAndCode(Long marketId, String code);
/**
* 通过股票和marketId集合批量查询冻结股票
*
* @param marketIds
* @param code
* @return
*/
List<ChiefFrozenRecord> getStockByMarketIdsAndCode(List<Long> marketIds, String code);
/**
* 通过股票和marketId集合批量查询冻结股票
*
* @param marketIds
* @param codes
* @return
*/
List<ChiefFrozenRecord> getStockByMarketIdsAndCode(List<Long> marketIds, List<String> codes);
/**
* 通过marketId查询当前账户下的所有冻结股票
*
* @param marketId
* @return
*/
List<ChiefFrozenRecord> getStockByMarketId(Long marketId);
/**
* 获取冻结资金
*
* @param marketId
* @return
*/
ChiefFrozenRecord getFrozenFundByMarketId(Long marketId);
/**
* 插入冻结股票
*
* @param marketId 盘
* @param code 股票代码
* @param count 股票数量
*/
void insertFrozenStock(Long marketId, String code, String count);
/**
* 插入冻结资金
*
* @param marketId 盘id
* @param fund 资金
*/
void insertFrozenFund(Long marketId, String fund);
/**
* 清除冻结记录
*/
void clearFrozenRecords();
/**
* 清除冻结记录为同步数据使用
*/
void clearFrozenRecordsForSynData();
}
package com.zfxftech.telmarket.service.business.chief;
import com.baomidou.mybatisplus.extension.service.IService;
import com.zfxftech.telmarket.common.pojo.dao.chief.ChiefMarketProfitLog;
/**
* @Description TODO
* @Author Dell
* @Date 2021/11/19 9:44
*/
public interface ChiefMarketProfitLogService extends IService<ChiefMarketProfitLog> {
}
package com.zfxftech.telmarket.service.business.chief;
import com.zfxftech.telmarket.common.bean.CommonPage;
import com.zfxftech.telmarket.common.enums.StockInputLogTrustSource;
import com.zfxftech.telmarket.common.pojo.dao.chief.ChiefPositionTradeInfoRecord;
import com.zfxftech.telmarket.common.pojo.dao.chief.ChiefPositionTradeInfoRecord4Page;
import com.zfxftech.telmarket.common.pojo.dao.chief.ChiefStockPosition;
import com.zfxftech.telmarket.common.pojo.request.chief.ChiefPagePositionTradeInfoRecordGroupByBatchBO;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
public interface ChiefPositionTradeInfoRecordService {
/**
* 分页查询交易记录,批次分组
*
* @param pagePositionTradeInfoRecordGroupByBatchBO
* @return
*/
@Deprecated
List pagePositionTradeInfoRecordGroupByBatch(ChiefPagePositionTradeInfoRecordGroupByBatchBO pagePositionTradeInfoRecordGroupByBatchBO);
/**
* 历史收益统计
*
* @param pagePositionTradeInfoRecordGroupByBatchBO
* @return
*/
Map<String, Object> positionTradeInfoRecordCount(ChiefPagePositionTradeInfoRecordGroupByBatchBO pagePositionTradeInfoRecordGroupByBatchBO);
/**
* 历史收益统计-详细数据
*
* @param pagePositionTradeInfoRecordGroupByBatchBO
* @return
*/
CommonPage<ChiefPositionTradeInfoRecord4Page> positionTradeInfoRecordCountDetail(ChiefPagePositionTradeInfoRecordGroupByBatchBO pagePositionTradeInfoRecordGroupByBatchBO);
/**
持仓id获取交易记录
*
* @param positionIds
* @return
*/
List<ChiefPositionTradeInfoRecord> listByPositionIds(List<Long> positionIds);
/**
* 批量修改交易记录
*
* @param list
*/
void updateBatchPositionTradeInfoRecord(List<ChiefPositionTradeInfoRecord> list);
/**
* 批量插入交易记录
*
* @param list
*/
void addBatch(List<ChiefPositionTradeInfoRecord> list);
/**
* @param positionIds 持仓id
* @param action 动作,买入、减仓、加仓、清仓
* @param positionMapping
* @param batch 批次
* @param sellingPrice 清仓时候的卖出价格,买入、减仓、加仓均不传
* @param status 只有在示有实无的时候才传
* @param trustSource 委托方向
* @param trustSourceName 委托方向描述
*/
void updateData(List<Long> positionIds, Integer action, Map<Long, ChiefStockPosition> positionMapping, Long batch, BigDecimal sellingPrice, Integer status, Integer entrustWay, StockInputLogTrustSource trustSource, String trustSourceName);
List<ChiefPositionTradeInfoRecord> getPositionTradeInfoRecordByPositionId(String code,Long positionId);
int updatePositionTradeInfoRecord(ChiefPositionTradeInfoRecord positionTradeInfoRecord);
}
package com.zfxftech.telmarket.service.business.chief;
import com.baomidou.mybatisplus.extension.service.IService;
import com.zfxftech.telmarket.common.bean.MapIntgerVo;
import com.zfxftech.telmarket.common.pojo.dao.chief.ChiefProduct;
import com.zfxftech.telmarket.common.pojo.dao.permission.UsAdmin;
import com.zfxftech.telmarket.common.pojo.request.PageProportionBO;
import com.zfxftech.telmarket.common.pojo.request.chief.ChiefQueryProductBO;
import com.zfxftech.telmarket.common.pojo.request.chief.ChiefSaveProductBO;
import com.zfxftech.telmarket.common.pojo.vo.chief.ChiefProductStrategyVO;
import java.util.List;
/**
* 产品服务类接口
*
* @author jianghua
* @version 1.0
* @date 2021-08-24 15:55
*/
public interface ChiefProductService extends IService<ChiefProduct> {
void saveProduct(ChiefSaveProductBO saveProductBO, UsAdmin usAdmin);
List<ChiefProduct> queryProductByIds(List<Long> id);
ChiefProduct queryProductById(Long id);
List<ChiefProduct> queryAll();
List<ChiefProduct> queryListForAuthority();
List<ChiefProduct> pageProduct(ChiefQueryProductBO queryProductBO);
List<ChiefProduct> getListForDataSource();
void operationSubstituteAnalyst(Long productId, Long analyst, String operation);
List<ChiefProduct> queryProductByType(String type);
/**
* 获取私人定制产品名称未删除
*
* @return
*/
List<ChiefProductStrategyVO> getAllFollowAccount();
List<MapIntgerVo> getProductName(PageProportionBO pageProportionBO);
List<UsAdmin> getProductUserByRoleIds(Long productId, List<Long> roleIds);
}
package com.zfxftech.telmarket.service.business.chief;
import com.zfxftech.telmarket.common.pojo.dao.chief.ChiefStockInputLog;
import com.zfxftech.telmarket.common.pojo.request.chief.ChiefQueryStockInputLogBO;
import java.util.List;
/**
* @Description TODO
* @Author Dell
* @Date 2021/11/3 9:34
*/
public interface ChiefStockInputLogService {
List<ChiefStockInputLog> pageStockInputLogs(ChiefQueryStockInputLogBO queryStockInputLogBO);
/**
* 新增股票
*
* @param stockInputLog
*/
void addStockInputLog(ChiefStockInputLog stockInputLog);
void addStockInputLog2(ChiefStockInputLog stockInputLog);
void addStockInputLogs(List<ChiefStockInputLog> stockInputLogs);
void updateStockInputLog(ChiefStockInputLog stockInputLog);
List<ChiefStockInputLog> queryStockInputLogs(long customerId, long productId, String code);
/**
* 通过持仓id获取交易日志
*
* @param stockPositionId
* @param operation
* @return
*/
List<ChiefStockInputLog> queryStockInputLogs(long stockPositionId, Integer operation);
/**
* 获取最近一次交易的记录
*
* @param stockPositionId
* @param operation
* @return
*/
ChiefStockInputLog queryOldestStockInputLog(long stockPositionId, Integer operation);
/**
* 获取当日的操作记录
*
* @param marketIds
* @return
*/
List<ChiefStockInputLog> queryByMarketIdsAndToday(List<Long> marketIds);
/**
* 获取前一日的操作记录
*
* @param marketType 根据类型查询前一天的操作记录
* @return
*/
List<ChiefStockInputLog> queryPreToday(String marketType, String operation);
List<ChiefStockInputLog> all();
void updateAA(ChiefStockInputLog stockInputLog);
}
package com.zfxftech.telmarket.service.business.chief;
import cn.hutool.core.date.DateTime;
import com.baomidou.mybatisplus.extension.service.IService;
import com.zfxftech.telmarket.common.enums.StockInputLogTrustSource;
import com.zfxftech.telmarket.common.pojo.dao.MemberBase;
import com.zfxftech.telmarket.common.pojo.dao.Quote;
import com.zfxftech.telmarket.common.pojo.dao.chief.ChiefAccountProductRelation;
import com.zfxftech.telmarket.common.pojo.dao.chief.ChiefMemberStockPage;
import com.zfxftech.telmarket.common.pojo.dao.chief.ChiefStockPosition;
import com.zfxftech.telmarket.common.pojo.dao.chief.ChiefTradingStrategyParam;
import com.zfxftech.telmarket.common.pojo.dao.permission.UsAdmin;
import com.zfxftech.telmarket.common.pojo.dto.remind.FullStockPositionTask;
import com.zfxftech.telmarket.common.pojo.dto.remind.StockPositionTask;
import com.zfxftech.telmarket.common.pojo.request.QueryCustomerPositionBO;
import com.zfxftech.telmarket.common.pojo.request.chief.*;
import com.zfxftech.telmarket.common.pojo.request.statistics.CurrDayRiseDownDataBO;
import com.zfxftech.telmarket.common.pojo.request.statistics.CurrDayRiseDownGroupDataVO;
import com.zfxftech.telmarket.common.pojo.request.statistics.RealTimeCodeQueryDataBO;
import com.zfxftech.telmarket.common.pojo.request.statistics.RealTimeCodeQueryGroupDataVO;
import com.zfxftech.telmarket.common.pojo.vo.chief.ChiefMarketDetailsVO;
import com.zfxftech.telmarket.common.pojo.vo.chief.ChiefStockVO;
import com.zfxftech.telmarket.common.pojo.vo.chief.ChiefTradeOrderVO;
import org.apache.commons.lang3.tuple.Pair;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
/**
* @Description TODO
* @Author Dell
* @Date 2021/11/3 9:34
*/
public interface ChiefStockPositionService extends IService<ChiefStockPosition> {
/**
* 获取所有的股票持仓
*
* @return
*/
List<ChiefStockPosition> getAll();
/**
* 实盘新增股票
*
* @param stockPosition
* @return
*/
ChiefStockPosition saveStockPosition(ChiefStockPosition stockPosition);
int updateStockPosition(ChiefStockPosition stockPosition);
int bactchUpdateStockPosition(List<ChiefStockPosition> stockPositions);
void del(Long id);
/**
* 示范盘添加股票
*
* @param stockPosition
* @return
*/
Pair<ChiefStockPosition, Boolean> saveStockPosition4Demonstration(ChiefStockPosition stockPosition, String interferenceStopPosition, String stopLossPosition);
ChiefStockPosition queryStockPosition(Long marketId, String code);
List<ChiefStockPosition> queryStockPosition(List<Long> marketIds, String codes);
List<ChiefStockPosition> queryStockPositionByCode(String code);
List<ChiefStockPosition> queryStockPosition(Long marketId, List<String> codes);
List<ChiefStockPosition> queryStockPositionsContainIsDeleted(Long marketId);
//根据marketId 批量查出股票持仓
List<ChiefStockPosition> queryStockPositions(List<Long> allMarketIds);
List<ChiefTradeOrderVO> sendTradeOrder(ChiefTradeOrderBO tradeOrderBO, UsAdmin usAdmin);
List<ChiefTradeOrderVO> sendSellingOrder(ChiefSellingOrderBO sellingOrderBO, UsAdmin usAdmin);
/**
* 止盈止损
*
* @param sellingOrderBO
* @param usAdmin
* @return
*/
List<ChiefTradeOrderVO> sendSellingOrderTask(ChiefSellingOrderBO sellingOrderBO, UsAdmin usAdmin, StockInputLogTrustSource stockInputLogTrustSource);
//定时任务自动卖出,当天示范账户买入一只股票后,到第二天24点前客户未录入实盘账户
void autoSellingOrder();
List<ChiefMemberStockPage> pageCustomerPositionList(QueryCustomerPositionBO customerPositionBO);
/**
* 查询模拟盘详情
*
* @param customerMarketDetailsBO
* @return
*/
ChiefMarketDetailsVO queryMarketDetails(ChiefQueryCustomerMarketDetailsBO customerMarketDetailsBO);
List<ChiefStockPosition> queryStockPositions(Long marketId);
ChiefStockPosition queryStockPosition(Long id);
/**
* 重算持仓
*
* @param stockPosition
*/
void recalculateStockPosition(ChiefStockPosition stockPosition);
/**
* 动态清零
*
* @param sendClearOrderBO
* @param usAdmin
* @return
*/
List<String> sendClearOrder(ChiefSendClearOrderBO sendClearOrderBO, UsAdmin usAdmin);
/**
* 批量卖出
*
* @param sellingOrderBO
* @param usAdmin
* @return
*/
List<String> sendSellingOrderOfBatch(ChiefBatchSellingOrderBO sellingOrderBO, UsAdmin usAdmin);
public ChiefTradingStrategyParam createTradingStrategyParam(String pushTime, String reason, ChiefAccountProductRelation accountProductRelation, String interferenceStopPosition, String stopLossPosition);
/**
* 清仓卖出
*
* @param
* @param usAdmin
* @return
*/
boolean selling(ChiefAccountProductRelation accountProductRelation, ChiefStockPosition stockPosition, String position, BigDecimal currentPrice, ChiefTradingStrategyParam tradingStrategyParam, UsAdmin usAdmin, Boolean isPresent, StockInputLogTrustSource trustSource);
ChiefMarketDetailsVO createMarketDetailsVO(MemberBase memberBase, List<ChiefStockPosition> stockPositions, BigDecimal funding, ChiefAccountProductRelation accountProductRelation, Long marketId);
ChiefMarketDetailsVO createMarketDetailsVOTask(List<ChiefStockPosition> stockPositions, BigDecimal funding, ChiefAccountProductRelation accountProductRelation);
ChiefStockVO createStockVO(ChiefStockPosition stockPosition, Map<String, Quote> codeAndQuoteMapping);
/**
* 根据产品id获取股票信息
*
* @param id
* @return
*/
List<ChiefStockPosition> getCode(Long id);
List<StockPositionTask> getStockPositionTask(Long productId);
/**
* 获取持仓 获取一只股票
*
* @param productId 产品id
* @param userId 用户id
* @param code 股票 code
* @return
*/
ChiefStockPosition getPosition(Long productId, Long userId, String code);
/**
* 获取持仓 获取多只股票 获取
*
* @param productId 产品id
* @param userId 用户id
* @return
*/
List<ChiefStockPosition> getPositionList(Long productId, Long userId, String stockCode, BigDecimal stopProfit, BigDecimal stopLoss);
List<FullStockPositionTask> getFullStockPositionTask();
/**
* 同步今日涨跌幅到昨日涨跌幅
*/
void syncYdayRiseDownRange(DateTime dateTime);
CurrDayRiseDownGroupDataVO getCurrDayRiseDownData(CurrDayRiseDownDataBO currDayRiseDownDataBO);
RealTimeCodeQueryGroupDataVO getRealTimeCodeQueryData(RealTimeCodeQueryDataBO realTimeCodeQueryDataBO);
}
package com.zfxftech.telmarket.service.business.chief;
import com.zfxftech.telmarket.common.bean.CommonPage;
import com.zfxftech.telmarket.common.pojo.dao.chief.ChiefStockProfitLog;
import com.zfxftech.telmarket.common.pojo.request.chief.ChiefQueryStockProfitLogBO;
import com.zfxftech.telmarket.common.pojo.vo.chief.ChiefStockProfitLogVO;
import java.util.List;
public interface ChiefStockProfitLogService {
/**
* 插入记录
*
* @param stockProfitLog
*/
void add(ChiefStockProfitLog stockProfitLog);
CommonPage<ChiefStockProfitLogVO> queryStockProfitLogs4page(ChiefQueryStockProfitLogBO queryStockProfitLogBO);
List<ChiefStockProfitLog> queryStockProfitLogs(Long marketId);
List<ChiefStockProfitLog> queryStockProfitLogsSort(ChiefQueryStockProfitLogBO queryStockProfitLogsSort);
List<ChiefStockProfitLog> queryStockProfitLogs(List<Long> positionIds);
}
package com.zfxftech.telmarket.service.impl.business.chief;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zfxf.tools.utils.AssertUtil;
import com.zfxftech.telmarket.common.constant.AdminConstant;
import com.zfxftech.telmarket.common.excepitonHandler.ApiException;
import com.zfxftech.telmarket.common.pojo.dao.chief.ChiefAccountProductRelation;
import com.zfxftech.telmarket.common.pojo.dao.chief.ChiefProduct;
import com.zfxftech.telmarket.common.pojo.dto.chief.ChiefProductCustomerFansDto;
import com.zfxftech.telmarket.common.util.DateUtil;
import com.zfxftech.telmarket.common.util.SnowflakeIdWorker;
import com.zfxftech.telmarket.mapper.business.chief.ChiefAccountProductRelationMapper;
import com.zfxftech.telmarket.service.business.chief.ChiefAccountProductRelationService;
import com.zfxftech.telmarket.service.business.chief.ChiefProductService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
import static com.zfxftech.telmarket.common.constant.AdminConstant.MarketTypeEnum.REAL;
import static com.zfxftech.telmarket.common.constant.AdminConstant.MarketTypeEnum.SIMULATED;
import static com.zfxftech.telmarket.common.constant.AdminConstant.ProductStatusEnum.OVERDUE;
import static com.zfxftech.telmarket.common.constant.AdminConstant.ProductStatusEnum.WILLOVERDUE;
/**
* 交易周期服务类
*
* @author jianghua
* @version 1.0
* 用户产品关系
* @date 2021-08-24 15:55
*/
@Service
public class ChiefAccountProductRelationServiceImpl extends ServiceImpl<ChiefAccountProductRelationMapper, ChiefAccountProductRelation> implements ChiefAccountProductRelationService {
@Resource
ChiefProductService productService;
@Transactional(propagation = Propagation.SUPPORTS)
@Override
public List<ChiefAccountProductRelation> queryAll() {
return list();
}
@Override
public List<ChiefAccountProductRelation> getMarkId(Long memberIds, List<Long> productList) {
LambdaQueryWrapper<ChiefAccountProductRelation> queryWrapper = new LambdaQueryWrapper();
queryWrapper.in(ChiefAccountProductRelation::getProductId, productList);
queryWrapper.eq(ChiefAccountProductRelation::getCustomerId, memberIds);
queryWrapper.eq(ChiefAccountProductRelation::getIsDeleted, 0);
queryWrapper.in(ChiefAccountProductRelation::getStatus, 1, 2);
queryWrapper.orderByDesc(ChiefAccountProductRelation::getCreatedTime);
return list(queryWrapper);
}
@Override
public List<ChiefAccountProductRelation> queryAccountProductRelationByMemberIds(List<Long> memberIds) {
QueryWrapper<ChiefAccountProductRelation> queryWrapper = new QueryWrapper();
queryWrapper.in("customer_id", memberIds);
return list(queryWrapper);
}
@Transactional(propagation = Propagation.SUPPORTS)
@Override
public List<ChiefAccountProductRelation> queryAccountProductRelationByMemberId(Long memberId) {
QueryWrapper<ChiefAccountProductRelation> queryWrapper = new QueryWrapper();
queryWrapper.eq("customer_id", memberId);
return list(queryWrapper);
}
@Override
public List<ChiefAccountProductRelation> queryAccountProductRelationByFansId(Long fansId) {
QueryWrapper<ChiefAccountProductRelation> queryWrapper = new QueryWrapper();
queryWrapper.eq("tp_fans_id", fansId);
return list(queryWrapper);
}
@Transactional(propagation = Propagation.REQUIRED)
@Override
public void updateAccountProductRelation(ChiefAccountProductRelation accountProductRelation, Long memberId, Long productId) {
UpdateWrapper<ChiefAccountProductRelation> updateWrapper = new UpdateWrapper();
updateWrapper.eq("customer_id", memberId);
updateWrapper.eq("product_id", productId);
update(accountProductRelation, updateWrapper);
}
@Transactional(propagation = Propagation.REQUIRED)
@Override
public void updateAccountProductRelation(ChiefAccountProductRelation accountProductRelation) {
updateById(accountProductRelation);
}
@Override
public void batchUpdateAccountProductRelation(List<ChiefAccountProductRelation> accountProductRelations) {
updateBatchById(accountProductRelations);
}
@Transactional(propagation = Propagation.REQUIRED)
@Override
public void addAccountProductRelation(ChiefAccountProductRelation accountProductRelation) {
QueryWrapper<ChiefAccountProductRelation> queryWrapper = new QueryWrapper();
queryWrapper.eq("customer_id", accountProductRelation.getCustomerId());
queryWrapper.eq("product_id", accountProductRelation.getProductId());
ChiefAccountProductRelation exist = getOne(queryWrapper);
if (exist != null) {
throw new ApiException("该产品已绑定");
}
accountProductRelation.setId(SnowflakeIdWorker.nextId());
save(accountProductRelation);
}
//查询用户的指定产品
@Transactional(propagation = Propagation.SUPPORTS)
@Override
public ChiefAccountProductRelation queryAccountProductRelationByMemberIdAndProductId(Long memberId, Long productId) {
QueryWrapper<ChiefAccountProductRelation> queryWrapper = new QueryWrapper();
queryWrapper.eq("customer_id", memberId);
queryWrapper.eq("product_id", productId);
return getOne(queryWrapper);
}
@Transactional(propagation = Propagation.SUPPORTS)
@Override
public ChiefAccountProductRelation queryAccountProductRelationByMarketInfo(Long marketId, String type) {
QueryWrapper<ChiefAccountProductRelation> queryWrapper = new QueryWrapper();
if (REAL.getCode().equals(type)) {
queryWrapper.eq("real_market_id", marketId);
}
if (SIMULATED.getCode().equals(type)) {
queryWrapper.eq("simulated_market_id", marketId);
}
return getOne(queryWrapper);
}
@Transactional(propagation = Propagation.SUPPORTS)
@Override
public List<ChiefAccountProductRelation> queryAccountProductRelationByIds(List<Long> relationIds) {
return new ArrayList<>(listByIds(relationIds));
}
@Override
public List<ChiefAccountProductRelation> queryAccountProductRelationBySimulatedIds(List<Long> simulatedIdsIds) {
QueryWrapper<ChiefAccountProductRelation> queryWrapper = new QueryWrapper();
queryWrapper.in("simulated_market_id", simulatedIdsIds);
return list(queryWrapper);
}
@Transactional(propagation = Propagation.REQUIRED)
@Override
public void checkProductIsExpire() {
//获取结束时间小于当前时间的产品 把过期时间小于当前时间的刷成过期
UpdateWrapper<ChiefAccountProductRelation> updateWrapper = new UpdateWrapper();
updateWrapper.lt("expired_at", new Date());
ChiefAccountProductRelation accountProductRelation = new ChiefAccountProductRelation();
accountProductRelation.setStatus(OVERDUE.getCode());
update(accountProductRelation, updateWrapper);
//把过期时间在当前时间和下一个月时间之间的刷成即将过期
QueryWrapper<ChiefAccountProductRelation> willExpiredUpdateWrapper = new QueryWrapper();
willExpiredUpdateWrapper.between("expired_at", new Date(), DateUtil.getLastMonthDay(new Date()));
ChiefAccountProductRelation willExpiredAccountProductRelation = new ChiefAccountProductRelation();
willExpiredAccountProductRelation.setStatus(WILLOVERDUE.getCode());
update(willExpiredAccountProductRelation, willExpiredUpdateWrapper);
}
/**
* 根据产品id获取对应的客户userId 1表是只要客户的userId 2 表示只要分析师的userId 3.表示全都要
*
* @param productId
* @param type
* @return
*/
@Override
public List<Long> getUserId(Long productId, Integer type) {
if (type == 1) {
LambdaQueryWrapper<ChiefAccountProductRelation> queryWrapper = Wrappers.lambdaQuery();
queryWrapper.eq(ChiefAccountProductRelation::getProductId, productId);
queryWrapper.eq(ChiefAccountProductRelation::getIsDeleted, 0);
List<ChiefAccountProductRelation> relationList = list(queryWrapper);
if (ObjectUtils.isEmpty(relationList)) {
return null;
}
return relationList.stream().map(ChiefAccountProductRelation::getCustomerId).collect(Collectors.toList());
} else if (type == 2) {
ChiefProduct product = productService.queryProductById(productId);
if (ObjectUtils.isEmpty(product) || ObjectUtils.isEmpty(product.getAnalyst())) {
return null;
}
List<Long> list = new ArrayList<>();
list.add(product.getAnalyst());
return list;
} else {
List<Long> list = new ArrayList<>();
LambdaQueryWrapper<ChiefAccountProductRelation> queryWrapper = Wrappers.lambdaQuery();
queryWrapper.eq(ChiefAccountProductRelation::getProductId, productId);
queryWrapper.eq(ChiefAccountProductRelation::getIsDeleted, 0);
List<ChiefAccountProductRelation> relationList = list(queryWrapper);
if (ObjectUtils.isEmpty(relationList)) {
return null;
}
list.addAll(relationList.stream().map(ChiefAccountProductRelation::getCustomerId).collect(Collectors.toList()));
ChiefProduct product = productService.queryProductById(productId);
if (ObjectUtils.isEmpty(product) || ObjectUtils.isEmpty(product.getAnalyst())) {
return null;
}
list.add(product.getAnalyst());
return list;
}
}
@Override
public List<Long> getCustomerIds(Long productId) {
LambdaQueryWrapper<ChiefAccountProductRelation> queryWrapper = Wrappers.lambdaQuery();
queryWrapper.eq(ChiefAccountProductRelation::getProductId, productId);
queryWrapper.eq(ChiefAccountProductRelation::getIsDeleted, 0);
queryWrapper.select(ChiefAccountProductRelation::getCustomerId);
List<ChiefAccountProductRelation> datas = super.list(
queryWrapper
);
if (datas != null && datas.size() > 0) {
return datas.stream().map(ChiefAccountProductRelation::getCustomerId).collect(Collectors.toList());
}
return null;
}
@Override
public List<ChiefProductCustomerFansDto> getProductUserList(Long productId) {
if (AssertUtil.isNotEmpty(productId)) {
return super.baseMapper.queryProductUserList(productId);
}
return null;
}
@Override
public List<ChiefAccountProductRelation> getRelationByProductIds(List<Long> ids) {
List<Integer> status = Arrays.stream(AdminConstant.ProductStatusEnum.values())
.filter(f -> !f.getCode().equals(AdminConstant.ProductStatusEnum.OVERDUE.getCode()))
.map(f -> f.getCode())
.collect(Collectors.toList());
LambdaQueryWrapper<ChiefAccountProductRelation> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(ChiefAccountProductRelation::getIsProblem, "0");
queryWrapper.and(w -> w.in(ChiefAccountProductRelation::getStatus, status));
queryWrapper.and(w -> w.in(ChiefAccountProductRelation::getProductId, ids));
List<ChiefAccountProductRelation> result = super.list(queryWrapper);
return result;
}
@Override
public void updateList(List<ChiefAccountProductRelation> list) {
updateBatchById(list);
}
}
package com.zfxftech.telmarket.service.impl.business.chief;
import com.zfxftech.telmarket.common.pojo.dao.Quote;
import com.zfxftech.telmarket.common.pojo.dao.StocksCode;
import com.zfxftech.telmarket.common.pojo.dao.chief.ChiefStockPosition;
import com.zfxftech.telmarket.common.util.BigDecimalUtil;
import com.zfxftech.telmarket.service.business.chief.ChiefFinanceCalculateService;
import org.apache.commons.lang3.tuple.ImmutablePair;
import org.apache.commons.lang3.tuple.Pair;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import static com.zfxftech.telmarket.common.constant.AdminConstant.CompareTypeEnum.LESS;
import static com.zfxftech.telmarket.common.constant.AdminConstant.NumberEnum.*;
/**
* @Description TODO
* @Author Dell
* @Date 2021/11/10 17:* 金融计算类
*/
@Service
public class ChiefFinanceCalculateServiceImpl implements ChiefFinanceCalculateService {
@Override
public BigDecimal calculateAverageStockPrice(BigDecimal totalPrice, Long count) {
return BigDecimalUtil.div(totalPrice, new BigDecimal(count), 4);
}
@Override
public BigDecimal calculateAverageStockPrice(Long count1, BigDecimal price1, Long count2, BigDecimal price2) {
BigDecimal mul1 = BigDecimalUtil.mul(new BigDecimal(count1), price1);
BigDecimal mul2 = BigDecimalUtil.mul(new BigDecimal(count2), price2);
BigDecimal totalCost = BigDecimalUtil.add(mul1, mul2);
BigDecimal totalCount = BigDecimalUtil.add(new BigDecimal(count1), new BigDecimal(count2));
if (BigDecimalUtil.compare(totalCount, new BigDecimal("0"), 0)) {
return price1;
}
return BigDecimalUtil.div(totalCost, totalCount, 4);
}
@Override
public BigDecimal calculateTotalAssets(BigDecimal availableFund, List<ChiefStockPosition> stockPositions, Map<String, Quote> stockCodeAndQuoteMapping) {
if (CollectionUtils.isEmpty(stockPositions)) {
return availableFund;
}
BigDecimal totalStock = calculateTotalAssets(stockPositions, stockCodeAndQuoteMapping);
BigDecimal totalAssets = BigDecimalUtil.add(availableFund, totalStock);
return totalAssets;
}
@Override
public BigDecimal calculateTotalAssets(List<ChiefStockPosition> stockPositions, Map<String, Quote> stockCodeAndPriceMapping) {
BigDecimal totalAssets = new BigDecimal(ZERO.getCode());
for (ChiefStockPosition temStockPosition : stockPositions) {
Long count = temStockPosition.getCount();
String code = temStockPosition.getCode();
Quote quote = stockCodeAndPriceMapping.get(code);
String price = BigDecimalUtil.compare(quote.getNow(), new BigDecimal("0"), 0) ? quote.getClose().toString() : quote.getNow().toString();
totalAssets = BigDecimalUtil.add(BigDecimalUtil.mul(String.valueOf(count), price), totalAssets);
}
return totalAssets;
}
@Override
public BigDecimal calculateTotalAssets(List<ChiefStockPosition> stockPositions) {
BigDecimal totalAssets = new BigDecimal(ZERO.getCode());
for (ChiefStockPosition stockPosition : stockPositions) {
Long count = stockPosition.getCount();
BigDecimal cost = stockPosition.getCost();
totalAssets = BigDecimalUtil.add(BigDecimalUtil.mul(new BigDecimal(count), cost), totalAssets);
}
return totalAssets;
}
@Override
public Long calculateBuyStockCount(BigDecimal totalFund, BigDecimal price) {
BigDecimal total = BigDecimalUtil.div(totalFund, price, ZERO.getCode());
if (BigDecimalUtil.compare(total, new BigDecimal(HUNDRED.getCode().toString()), LESS.getCode())) {
return 0L;
}
total = BigDecimalUtil.roundToHundreds(total);
//除以100
return total.longValue();
}
@Override
public BigDecimal calculateTotalPrice(Long count, BigDecimal price) {
return BigDecimalUtil.mul(new BigDecimal(count), price);
}
@Override
public BigDecimal calculateIndustryShare(BigDecimal totalValue, Long count, BigDecimal price) {
//计算股票市值
BigDecimal value = BigDecimalUtil.mul(new BigDecimal(count), price);
return BigDecimalUtil.div(value, totalValue);
}
@Override
public BigDecimal calculateProfitRate(BigDecimal value1, BigDecimal value2) {
if (Objects.equals(value1, value2)) {
return new BigDecimal(ZERO.getCode());
}
BigDecimal value = BigDecimalUtil.div(value1, value2);
return BigDecimalUtil.sub(value.toString(), ONE.getCode().toString());
}
@Override
public BigDecimal calculateProfitRate2(BigDecimal value1, BigDecimal value2) {
if (Objects.equals(value1, value2)) {
return new BigDecimal(ZERO.getCode());
}
BigDecimal profitRate = BigDecimalUtil.div(
BigDecimalUtil.sub(
value1,
value2
),
value2);
return profitRate;
}
@Override
public BigDecimal riseDownRange(BigDecimal now, BigDecimal close) {
return BigDecimalUtil.div(BigDecimalUtil.sub(now, close), close);
}
@Override
public BigDecimal profitLossRatio(BigDecimal now, BigDecimal cost) {
return BigDecimalUtil.div(BigDecimalUtil.sub(now, cost), cost);
}
@Override
public BigDecimal calculateProfit(BigDecimal value1, BigDecimal value2) {
return BigDecimalUtil.sub(value1, value2);
}
@Override
public Pair<String, String> calculatePriceRange(String price, String range) {
BigDecimal upperLimit = BigDecimalUtil.mul(price, BigDecimalUtil.add("1", range).toString());
BigDecimal lowerLimit = BigDecimalUtil.mul(price, BigDecimalUtil.sub("1", range).toString());
ImmutablePair<String, String> rangePair = new ImmutablePair(BigDecimalUtil.keepDecimal(lowerLimit).toPlainString(), BigDecimalUtil.keepDecimal(upperLimit).toPlainString());
return rangePair;
}
@Override
public Pair<BigDecimal, BigDecimal> calculatePriceLimit(StocksCode stocksCode) {
//300 688 浮动20%
String code = stocksCode.getSymbol();
BigDecimal up;
BigDecimal low;
if (stocksCode.getName().contains("ST") || stocksCode.getName().contains("st")) {
low = BigDecimalUtil.mul(stocksCode.getRecentClosingPrice(), new BigDecimal("0.95"));
up = BigDecimalUtil.mul(stocksCode.getRecentClosingPrice(), new BigDecimal("1.05"));
} else if (code.startsWith("300") || code.startsWith("688")) {
low = BigDecimalUtil.mul(stocksCode.getRecentClosingPrice(), new BigDecimal("0.8"));
up = BigDecimalUtil.mul(stocksCode.getRecentClosingPrice(), new BigDecimal("1.2"));
} else {
//其他 浮动10%
low = BigDecimalUtil.mul(stocksCode.getRecentClosingPrice(), new BigDecimal("0.9"));
up = BigDecimalUtil.mul(stocksCode.getRecentClosingPrice(), new BigDecimal("1.1"));
}
Pair<BigDecimal, BigDecimal> pair = new ImmutablePair(BigDecimalUtil.keepDecimal(low), BigDecimalUtil.keepDecimal(up));
return pair;
}
}
package com.zfxftech.telmarket.service.impl.business.chief;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zfxftech.telmarket.common.pojo.dao.chief.ChiefFrozenRecord;
import com.zfxftech.telmarket.common.util.BigDecimalUtil;
import com.zfxftech.telmarket.common.util.DateUtil;
import com.zfxftech.telmarket.mapper.business.chief.ChiefFrozenRecordMapper;
import com.zfxftech.telmarket.service.business.chief.ChiefFrozenRecordService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
import java.util.List;
import java.util.stream.Collectors;
import static com.zfxftech.telmarket.common.constant.AdminConstant.FrozenEnum.FUND;
import static com.zfxftech.telmarket.common.constant.AdminConstant.FrozenEnum.STOCK;
/**
* @Description TODO
* @Author Dell
* @Date 2021/12/21 14:35
* 冻结记录相关
*/
@Service
public class ChiefFrozenRecordServiceImpl extends ServiceImpl<ChiefFrozenRecordMapper, ChiefFrozenRecord> implements ChiefFrozenRecordService {
@Value("${frozenRecord.clearHour}")
private Integer clearHour;
@Transactional(propagation = Propagation.SUPPORTS)
@Override
public ChiefFrozenRecord getStockByMarketIdAndCode(Long marketId, String code) {
QueryWrapper<ChiefFrozenRecord> queryWrapper = new QueryWrapper();
queryWrapper.eq("market_id", marketId);
queryWrapper.eq("code", code);
queryWrapper.eq("frozen_target", STOCK.getDesc());
return getOne(queryWrapper);
}
@Transactional(propagation = Propagation.SUPPORTS)
@Override
public List<ChiefFrozenRecord> getStockByMarketIdsAndCode(List<Long> marketIds, String code) {
QueryWrapper<ChiefFrozenRecord> queryWrapper = new QueryWrapper();
queryWrapper.in("market_id", marketIds);
queryWrapper.eq("code", code);
queryWrapper.eq("frozen_target", STOCK.getDesc());
return list(queryWrapper);
}
@Override
public List<ChiefFrozenRecord> getStockByMarketIdsAndCode(List<Long> marketIds, List<String> codes) {
QueryWrapper<ChiefFrozenRecord> queryWrapper = new QueryWrapper();
queryWrapper.in("market_id", marketIds);
queryWrapper.in("code", codes);
queryWrapper.eq("frozen_target", STOCK.getDesc());
return list(queryWrapper);
}
@Transactional(propagation = Propagation.SUPPORTS)
@Override
public List<ChiefFrozenRecord> getStockByMarketId(Long marketId) {
QueryWrapper<ChiefFrozenRecord> queryWrapper = new QueryWrapper();
queryWrapper.in("market_id", marketId);
queryWrapper.eq("frozen_target", STOCK.getDesc());
return list(queryWrapper);
}
@Transactional(propagation = Propagation.SUPPORTS)
@Override
public ChiefFrozenRecord getFrozenFundByMarketId(Long marketId) {
QueryWrapper<ChiefFrozenRecord> queryWrapper = new QueryWrapper();
queryWrapper.eq("market_id", marketId);
queryWrapper.eq("frozen_target", FUND.getDesc());
return getOne(queryWrapper);
}
@Transactional(propagation = Propagation.REQUIRED)
@Override
public void insertFrozenStock(Long marketId, String code, String count) {
//查询当前用户今天是否已经冻结过股票
ChiefFrozenRecord byMarketIdAndCode = getStockByMarketIdAndCode(marketId, code);
if (byMarketIdAndCode != null) {
BigDecimal count1 = byMarketIdAndCode.getCount();
byMarketIdAndCode.setCount(BigDecimalUtil.add(count1, new BigDecimal(count)));
//zw318 当天多次买入都冻结
updateById(byMarketIdAndCode);
} else {
ChiefFrozenRecord frozenStock = createFrozenStock(code, count, marketId);
save(frozenStock);
}
}
@Transactional(propagation = Propagation.REQUIRED)
@Override
public void insertFrozenFund(Long marketId, String fund) {
//查询当前用户今天是否已经冻结过资金
ChiefFrozenRecord byMarketIdAndCode = getFrozenFundByMarketId(marketId);
if (byMarketIdAndCode != null) {
BigDecimal count1 = byMarketIdAndCode.getCount();
byMarketIdAndCode.setCount(BigDecimalUtil.add(count1, new BigDecimal(fund)));
} else {
ChiefFrozenRecord frozenFund = createFrozenFund(fund, marketId);
save(frozenFund);
}
}
@Override
public void clearFrozenRecords() {
//获取当前时间要大于5点后执行
Integer hour = DateUtil.getCurrentHour();
//大于指定时间才能进行冻结股票记录的清理
if (hour < clearHour) {
return;
}
List<ChiefFrozenRecord> list = list();
List<Long> ids = list.stream().map(ChiefFrozenRecord::getId).collect(Collectors.toList());
removeByIds(ids);
}
@Override
public void clearFrozenRecordsForSynData() {
List<ChiefFrozenRecord> list = list();
List<Long> ids = list.stream().map(ChiefFrozenRecord::getId).collect(Collectors.toList());
removeByIds(ids);
}
/**
* 创建冻结股票对象
*
* @param code
* @param count
* @param marketId
* @return
*/
private ChiefFrozenRecord createFrozenStock(String code, String count, Long marketId) {
ChiefFrozenRecord frozenRecord = new ChiefFrozenRecord();
frozenRecord.setCode(code);
frozenRecord.setCount(new BigDecimal(count));
frozenRecord.setFrozenTarget(STOCK.getDesc());
frozenRecord.setMarketId(marketId);
return frozenRecord;
}
/**
* 创建冻结资金对象
*
* @param count
* @param marketId
* @return
*/
private ChiefFrozenRecord createFrozenFund(String count, Long marketId) {
ChiefFrozenRecord frozenRecord = new ChiefFrozenRecord();
frozenRecord.setCount(new BigDecimal(count));
frozenRecord.setFrozenTarget(FUND.getDesc());
frozenRecord.setMarketId(marketId);
return frozenRecord;
}
}
package com.zfxftech.telmarket.service.impl.business.chief;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zfxftech.telmarket.common.pojo.dao.chief.ChiefMarketProfitLog;
import com.zfxftech.telmarket.mapper.business.chief.ChiefMarketProfitLogMapper;
import com.zfxftech.telmarket.service.business.chief.ChiefMarketProfitLogService;
import lombok.extern.log4j.Log4j2;
import org.springframework.stereotype.Service;
/**
* @Description TODO
* @Author Dell
* @Date 2021/11/19 9:47
*/
@Service
@Log4j2
public class ChiefMarketProfitLogServiceImpl extends ServiceImpl<ChiefMarketProfitLogMapper, ChiefMarketProfitLog> implements ChiefMarketProfitLogService {
}
package com.zfxftech.telmarket.service.impl.business.chief;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.zfxf.tools.utils.AssertUtil;
import com.zfxftech.telmarket.common.bean.CommonPage;
import com.zfxftech.telmarket.common.constant.AdminConstant;
import com.zfxftech.telmarket.common.enums.StockInputLogTrustSource;
import com.zfxftech.telmarket.common.excepitonHandler.ApiException;
import com.zfxftech.telmarket.common.pojo.dao.CustomerProductEntity;
import com.zfxftech.telmarket.common.pojo.dao.MemberBase;
import com.zfxftech.telmarket.common.pojo.dao.Quote;
import com.zfxftech.telmarket.common.pojo.dao.chief.*;
import com.zfxftech.telmarket.common.pojo.dto.account.DataAuthorityDto;
import com.zfxftech.telmarket.common.pojo.request.PageBO;
import com.zfxftech.telmarket.common.pojo.request.chief.ChiefPagePositionTradeInfoRecordGroupByBatchBO;
import com.zfxftech.telmarket.common.util.DateUtil;
import com.zfxftech.telmarket.common.util.SortUtil;
import com.zfxftech.telmarket.mapper.business.chief.ChiefPositionTradeInfoRecordMapper;
import com.zfxftech.telmarket.service.UsAdminService;
import com.zfxftech.telmarket.service.business.StockCodeService;
import com.zfxftech.telmarket.service.business.UsMemberBaseService;
import com.zfxftech.telmarket.service.business.chief.*;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;
import static com.zfxftech.telmarket.common.constant.AdminConstant.NumberEnum.ZERO;
import static com.zfxftech.telmarket.common.constant.AdminConstant.OperationEnum.*;
import static com.zfxftech.telmarket.common.constant.AdminConstant.StockHoldingEnum.*;
import static com.zfxftech.telmarket.common.util.DateUtil.DATE_FMT;
import static com.zfxftech.telmarket.common.util.DateUtil.DATE_TIME_FMT;
/**
* @Description TODO
* @Author Dell
* @Date 2021/12/24 11:04
* 交易记录
*/
@Log4j2
@Service
public class ChiefPositionTradeInfoRecordServiceImpl extends ServiceImpl<ChiefPositionTradeInfoRecordMapper, ChiefPositionTradeInfoRecord> implements ChiefPositionTradeInfoRecordService {
@Autowired
private ChiefPositionTradeInfoRecordMapper positionTradeInfoRecordMapper;
@Autowired
private ChiefProductService productService;
@Autowired
private ChiefStockProfitLogService stockProfitLogService;
@Autowired
private StockCodeService stockCodeService;
@Autowired
private UsMemberBaseService usMemberBaseService;
@Autowired
private ChiefFinanceCalculateService financeCalculateService;
@Autowired
private ChiefAccountProductRelationService accountProductRelationService;
@Resource
private UsAdminService usAdminService;
@Override
public Map<String, Object> positionTradeInfoRecordCount(ChiefPagePositionTradeInfoRecordGroupByBatchBO pagePositionTradeInfoRecordGroupByBatchBO) {
//查询全量数据
Map<String, Object> param = createPageParam(pagePositionTradeInfoRecordGroupByBatchBO, false);
List<ChiefPositionTradeInfoRecord> positionTradeInfoRecordCountData = positionTradeInfoRecordMapper.pagePositionTradeInfoRecordGroupByBatch(param);
Integer total = positionTradeInfoRecordCountData.size();
log.info("获取数据量:", total);
//获取
if (total <= ZERO.getCode()) {
//饼图数据
//柱状图数据 barChart;
Map<String, Object> chartData = new HashMap<String, Object>() {
{
put("barChart", new HashMap<>());
put("pieChart", new HashMap<>());
}
};
return chartData;
}
//全量数据添加总盈亏(图片计算要用)
for (ChiefPositionTradeInfoRecord positionTradeInfoRecord4Page : positionTradeInfoRecordCountData) {
//盈亏比例
Integer status = positionTradeInfoRecord4Page.getStatus();
if (status == IN_POSITION.getCode()) {
Quote stocksCode = stockCodeService.getStockQuote(positionTradeInfoRecord4Page.getCode());
Date buyingTime = positionTradeInfoRecord4Page.getBuyingTime();
Long dayDiff = DateUtil.calculateTimeDifference(buyingTime, new Date());
BigDecimal now = stocksCode.getNow();
positionTradeInfoRecord4Page.setProfitRatio(financeCalculateService.calculateProfitRate(now, positionTradeInfoRecord4Page.getCost()));
positionTradeInfoRecord4Page.setHoldingDays(Integer.valueOf(String.valueOf(dayDiff)));
}
}
//生成饼图
Map<Integer, Integer> pieChartData = calculatePieChartData(positionTradeInfoRecordCountData);
//生成柱状图
Map<Integer, Integer> barChartData = calculateBarChartData(positionTradeInfoRecordCountData);
Map<String, Object> chartData = new HashMap<>();
chartData.put("barChart", barChartData);
chartData.put("pieChart", pieChartData);
return chartData;
}
@Override
public CommonPage<ChiefPositionTradeInfoRecord4Page> positionTradeInfoRecordCountDetail(ChiefPagePositionTradeInfoRecordGroupByBatchBO pagePositionTradeInfoRecordGroupByBatchBO) {
//查询全量数据
Map<String, Object> param = createPageParam(pagePositionTradeInfoRecordGroupByBatchBO, false);
//下面分页数据
Page page = PageHelper.startPage(pagePositionTradeInfoRecordGroupByBatchBO.getPageNo(), pagePositionTradeInfoRecordGroupByBatchBO.getPageSize());
List<ChiefPositionTradeInfoRecord> positionTradeInfoRecord4Pages = positionTradeInfoRecordMapper.pagePositionTradeInfoRecordGroupByBatch(param);
if (AssertUtil.isEmpty(positionTradeInfoRecord4Pages)) {
CommonPage<ChiefPositionTradeInfoRecord4Page> listData = getPositionTradeInfoRecordPage(positionTradeInfoRecord4Pages, pagePositionTradeInfoRecordGroupByBatchBO, 0L, pagePositionTradeInfoRecordGroupByBatchBO.getPageSize().longValue());
return listData;
}
//获取所有用户的客户信息
Set<Long> customerIdSet = new HashSet<>();
for (ChiefPositionTradeInfoRecord positionTradeInfoRecord4Page : positionTradeInfoRecord4Pages) {
if (positionTradeInfoRecord4Page.getCustomerIds() != null) {
List<String> customerIds = Arrays.asList(positionTradeInfoRecord4Page.getCustomerIds().split(","));
for (int i = 0; i < customerIds.size(); i++) {
customerIdSet.add(Long.valueOf(customerIds.get(i)));
}
}
}
//查询产品id和产品类型的中文
Map<String, String> productTypeAndDescMapping = new HashMap<>();
for (AdminConstant.MemberProductTypeEnum tem : EnumSet.allOf(AdminConstant.MemberProductTypeEnum.class)) {
productTypeAndDescMapping.put(tem.getCode(), tem.getDesc());
}
//买入、减仓、清仓、加仓动作标记
Map<Integer, String> operationAndDescMapping = new HashMap<>();
for (AdminConstant.OperationEnum tem : EnumSet.allOf(AdminConstant.OperationEnum.class)) {
operationAndDescMapping.put(tem.getCode(), tem.getDesc());
}
//买入、减仓、清仓、加仓动作标记
Map<Integer, String> enwayAndDescMapping = new HashMap<>();
for (AdminConstant.EntrustWayEnum tem : EnumSet.allOf(AdminConstant.EntrustWayEnum.class)) {
enwayAndDescMapping.put(tem.getCode(), tem.getDesc());
}
//持仓中、清仓
Map<Integer, String> stockHoldingAndDescMapping = new HashMap<>();
for (AdminConstant.StockHoldingEnum tem : EnumSet.allOf(AdminConstant.StockHoldingEnum.class)) {
stockHoldingAndDescMapping.put(tem.getCode(), tem.getDesc());
}
List<MemberBase> memberBases = usMemberBaseService.queryUsMemberBaseByIds(new ArrayList<>(customerIdSet));
Map<Long, MemberBase> customerIdAndMemberBaseMapping = memberBases.stream().collect(Collectors.toMap(MemberBase::getId, MemberBase -> MemberBase));
//获取所有产品信息
List<ChiefProduct> products = productService.queryListForAuthority();
Map<Long, ChiefProduct> productIdAndProductMapping = products.stream().collect(Collectors.toMap(ChiefProduct::getId, ChiefProduct -> ChiefProduct));
customerAndProductMapper(positionTradeInfoRecord4Pages,
productIdAndProductMapping,
customerIdAndMemberBaseMapping);
//补充剩余字段
for (ChiefPositionTradeInfoRecord positionTradeInfoRecord4Page : positionTradeInfoRecord4Pages) {
// //查询股票代码
Quote stocksCode = stockCodeService.getStockQuote(positionTradeInfoRecord4Page.getCode());
positionTradeInfoRecord4Page.setCodeName(stocksCode.getName());
List<String> productIds = Arrays.asList(positionTradeInfoRecord4Page.getProductIds().split(","));
List<String> productNames = new ArrayList<>();
if (AssertUtil.isNotEmpty(productIds)) {
List<String> newProductIds = productIds.stream().distinct().collect(Collectors.toList());
for (int i = 0; i < newProductIds.size(); i++) {
String prodId = newProductIds.get(i);
if (ObjectUtils.isEmpty(productIdAndProductMapping.get(Long.valueOf(prodId))) || StringUtils.isEmpty(productIdAndProductMapping.get(Long.valueOf(prodId)).getProductName())) {
continue;
}
productNames.add(productIdAndProductMapping.get(Long.valueOf(prodId)).getProductName());
}
}
positionTradeInfoRecord4Page.setProductName(productNames);
positionTradeInfoRecord4Page.setProductTypeDesc(productTypeAndDescMapping.get(positionTradeInfoRecord4Page.getProductType()));
positionTradeInfoRecord4Page.setStatusDesc(stockHoldingAndDescMapping.get(positionTradeInfoRecord4Page.getStatus()));
positionTradeInfoRecord4Page.setOperationDesc(operationAndDescMapping.get(positionTradeInfoRecord4Page.getOperation()));
positionTradeInfoRecord4Page.setWayDesc(enwayAndDescMapping.get(positionTradeInfoRecord4Page.getEntrustWay()));
//盈亏比例
Integer status = positionTradeInfoRecord4Page.getStatus();
if (status == IN_POSITION.getCode()) {
Date buyingTime = positionTradeInfoRecord4Page.getBuyingTime();
Long dayDiff = DateUtil.calculateTimeDifference(buyingTime, new Date());
BigDecimal now = stocksCode.getNow();
positionTradeInfoRecord4Page.setProfitRatio(financeCalculateService.calculateProfitRate(now, positionTradeInfoRecord4Page.getCost()));
positionTradeInfoRecord4Page.setHoldingDays(Integer.parseInt(String.valueOf(dayDiff)));
}
List<Map> customerNames = new ArrayList<>();
List<String> customerIds = Arrays.asList(positionTradeInfoRecord4Page.getCustomerIds().split(","));
if (AssertUtil.isNotEmpty(customerIds)) {
List<String> newCustomerIds = customerIds.stream().distinct().collect(Collectors.toList());
for (int i = 0; i < newCustomerIds.size(); i++) {
MemberBase memberBase = customerIdAndMemberBaseMapping.get(Long.valueOf(newCustomerIds.get(i)));
// AccountProductRelation accountProductRelation = accountProductRelationService.queryAccountProductRelationByMemberIdAndProductId(Long.valueOf(customerIds.get(i)), Long.valueOf(productIds.get(i)));
// if (memberBase == null) {
// continue;
// }
Map nameMap = new HashMap();
nameMap.put("customName", memberBase.getName());
// if (accountProductRelation != null) {
// nameMap.put("realMarketId", accountProductRelation.getRealMarketId());
// nameMap.put("simulatedMarketId", accountProductRelation.getSimulatedMarketId());
// }
customerNames.add(nameMap);
}
}
positionTradeInfoRecord4Page.setCustomerNameArray(customerNames);
}
CommonPage<ChiefPositionTradeInfoRecord4Page> listData = getPositionTradeInfoRecordPage(positionTradeInfoRecord4Pages, pagePositionTradeInfoRecordGroupByBatchBO, page.getTotal(), pagePositionTradeInfoRecordGroupByBatchBO.getPageSize().longValue());
return listData;
}
private void customerAndProductMapper(List<ChiefPositionTradeInfoRecord> source,
Map<Long, ChiefProduct> allProducts,
Map<Long, MemberBase> allCustomers) {
//查询出多个产品的id用于查询关系表数据
// List<PositionTradeInfoRecord> handlerData = source.stream()
// .filter(p -> p.getProductIds().contains(",") || p.getCustomerIds().contains(","))
// .collect(Collectors.toList());
List<ChiefPositionTradeInfoRecord> handlerData = source;
if (AssertUtil.isNotEmpty(handlerData)) {
List<Long> pids = new ArrayList<>();
List<Long> cids = new ArrayList<>();
handlerData.forEach(d -> {
pids.addAll(Arrays.stream(d.getProductIds().split(","))
.map(p -> Long.parseLong(p))
.collect(Collectors.toList()));
cids.addAll(Arrays.stream(d.getCustomerIds().split(","))
.map(c -> Long.parseLong(c))
.collect(Collectors.toList()));
});
LambdaQueryWrapper<ChiefAccountProductRelation> wrapper = new LambdaQueryWrapper<>();
wrapper.in(ChiefAccountProductRelation::getProductId, pids);
wrapper.in(ChiefAccountProductRelation::getCustomerId, cids);
List<ChiefAccountProductRelation> relation = accountProductRelationService.list(
wrapper
);
handlerData.forEach(d -> {
String[] customerIds = d.getCustomerIds().split(",");
List<String> productIds = Arrays.asList(d.getProductIds().split(","));
List<CustomerProductEntity> customerProducts = new ArrayList<>();
Arrays.stream(customerIds).forEach(customerId -> {
Long customerIdVal = Long.parseLong(customerId);
CustomerProductEntity productEntity = new CustomerProductEntity();
productEntity.setCustomerId(customerIdVal);
MemberBase memberBase = allCustomers.get(customerIdVal);
if (memberBase != null) {
productEntity.setCustomerName(memberBase.getName());
}
List<CustomerProductEntity.CustomerProductList> products = null;
products = relation.stream()
.filter(p -> p.getCustomerId().equals(customerIdVal) &&
productIds.contains(p.getProductId().toString()))
.map(p -> {
CustomerProductEntity.CustomerProductList customerProduct = new CustomerProductEntity().new CustomerProductList();
customerProduct.setId(p.getProductId());
ChiefProduct product = allProducts.get(p.getProductId());
if (product != null) {
customerProduct.setName(p.getProductName());
customerProduct.setSimulatedMarketId(p.getSimulatedMarketId());
customerProduct.setRealMarketId(p.getRealMarketId());
}
return customerProduct;
})
.collect(Collectors.toList());
productEntity.setProducts(products);
customerProducts.add(productEntity);
});
d.setCustomerProducts(customerProducts);
});
}
}
@Deprecated
@Override
public List pagePositionTradeInfoRecordGroupByBatch(ChiefPagePositionTradeInfoRecordGroupByBatchBO pagePositionTradeInfoRecordGroupByBatchBO) {
List result = new ArrayList<>();
//查询全量数据
Map<String, Object> param = createPageParam(pagePositionTradeInfoRecordGroupByBatchBO, false);
List<ChiefPositionTradeInfoRecord> allPositionTradeInfoRecords = positionTradeInfoRecordMapper.pagePositionTradeInfoRecordGroupByBatch(param);
Integer total = allPositionTradeInfoRecords.size();
log.info("获取数据量:", total);
//获取
if (total <= ZERO.getCode()) {
//饼图数据
//柱状图数据 barChart;
Map<String, Object> chartData = new HashMap<String, Object>() {
{
put("barChart", new HashMap<>());
put("pieChart", new HashMap<>());
}
};
CommonPage<ChiefPositionTradeInfoRecord4Page> listData = getPositionTradeInfoRecordPage(Arrays.asList(), pagePositionTradeInfoRecordGroupByBatchBO, ZERO.getCode().longValue(), ZERO.getCode().longValue());
result.add(0, listData);
result.add(1, chartData);
return result;
}
//下面分页数据
Page page = PageHelper.startPage(pagePositionTradeInfoRecordGroupByBatchBO.getPageNo(), pagePositionTradeInfoRecordGroupByBatchBO.getPageSize());
List<ChiefPositionTradeInfoRecord> positionTradeInfoRecord4Pages = positionTradeInfoRecordMapper.pagePositionTradeInfoRecordGroupByBatch(param);
//查询产品id和产品类型的中文
Map<String, String> productTypeAndDescMapping = new HashMap<>();
for (AdminConstant.MemberProductTypeEnum tem : EnumSet.allOf(AdminConstant.MemberProductTypeEnum.class)) {
productTypeAndDescMapping.put(tem.getCode(), tem.getDesc());
}
//买入、减仓、清仓、加仓动作标记
Map<Integer, String> operationAndDescMapping = new HashMap<>();
for (AdminConstant.OperationEnum tem : EnumSet.allOf(AdminConstant.OperationEnum.class)) {
operationAndDescMapping.put(tem.getCode(), tem.getDesc());
}
//买入、减仓、清仓、加仓动作标记
Map<Integer, String> enwayAndDescMapping = new HashMap<>();
for (AdminConstant.EntrustWayEnum tem : EnumSet.allOf(AdminConstant.EntrustWayEnum.class)) {
enwayAndDescMapping.put(tem.getCode(), tem.getDesc());
}
//持仓中、清仓
Map<Integer, String> stockHoldingAndDescMapping = new HashMap<>();
for (AdminConstant.StockHoldingEnum tem : EnumSet.allOf(AdminConstant.StockHoldingEnum.class)) {
stockHoldingAndDescMapping.put(tem.getCode(), tem.getDesc());
}
//获取所有用户的客户信息
Set<Long> customerIdSet = new HashSet<>();
for (ChiefPositionTradeInfoRecord positionTradeInfoRecord4Page : positionTradeInfoRecord4Pages) {
if (positionTradeInfoRecord4Page.getCustomerIds() != null) {
List<String> customerIds = Arrays.asList(positionTradeInfoRecord4Page.getCustomerIds().split(","));
for (int i = 0; i < customerIds.size(); i++) {
customerIdSet.add(Long.valueOf(customerIds.get(i)));
}
}
}
List<MemberBase> memberBases = usMemberBaseService.queryUsMemberBaseByIds(new ArrayList<>(customerIdSet));
Map<Long, MemberBase> customerIdAndMemberBaseMapping = memberBases.stream().collect(Collectors.toMap(MemberBase::getId, MemberBase -> MemberBase));
//获取所有产品信息
List<ChiefProduct> products = productService.queryListForAuthority();
Map<Long, ChiefProduct> productIdAndProductMapping = products.stream().collect(Collectors.toMap(ChiefProduct::getId, ChiefProduct -> ChiefProduct));
//补充剩余字段
for (ChiefPositionTradeInfoRecord positionTradeInfoRecord4Page : positionTradeInfoRecord4Pages) {
// //查询股票代码
Quote stocksCode = stockCodeService.getStockQuote(positionTradeInfoRecord4Page.getCode());
positionTradeInfoRecord4Page.setCodeName(stocksCode.getName());
List<String> productIds = Arrays.asList(positionTradeInfoRecord4Page.getProductIds().split(","));
List<String> productNames = new ArrayList<>();
if (AssertUtil.isNotEmpty(productIds)) {
List<String> newProductIds = productIds.stream().distinct().collect(Collectors.toList());
for (int i = 0; i < newProductIds.size(); i++) {
String prodId = newProductIds.get(i);
if (ObjectUtils.isEmpty(productIdAndProductMapping.get(Long.valueOf(prodId))) || StringUtils.isEmpty(productIdAndProductMapping.get(Long.valueOf(prodId)).getProductName())) {
continue;
}
productNames.add(productIdAndProductMapping.get(Long.valueOf(prodId)).getProductName());
}
}
positionTradeInfoRecord4Page.setProductName(productNames);
positionTradeInfoRecord4Page.setProductTypeDesc(productTypeAndDescMapping.get(positionTradeInfoRecord4Page.getProductType()));
positionTradeInfoRecord4Page.setStatusDesc(stockHoldingAndDescMapping.get(positionTradeInfoRecord4Page.getStatus()));
positionTradeInfoRecord4Page.setOperationDesc(operationAndDescMapping.get(positionTradeInfoRecord4Page.getOperation()));
positionTradeInfoRecord4Page.setWayDesc(enwayAndDescMapping.get(positionTradeInfoRecord4Page.getEntrustWay()));
//盈亏比例
Integer status = positionTradeInfoRecord4Page.getStatus();
if (status == IN_POSITION.getCode()) {
Date buyingTime = positionTradeInfoRecord4Page.getBuyingTime();
Long dayDiff = DateUtil.calculateTimeDifference(buyingTime, new Date());
BigDecimal now = stocksCode.getNow();
positionTradeInfoRecord4Page.setProfitRatio(financeCalculateService.calculateProfitRate(now, positionTradeInfoRecord4Page.getCost()));
positionTradeInfoRecord4Page.setHoldingDays(Integer.parseInt(String.valueOf(dayDiff)));
}
List<Map> customerNames = new ArrayList<>();
List<String> customerIds = Arrays.asList(positionTradeInfoRecord4Page.getCustomerIds().split(","));
if (AssertUtil.isNotEmpty(customerIds)) {
List<String> newCustomerIds = customerIds.stream().distinct().collect(Collectors.toList());
for (int i = 0; i < newCustomerIds.size(); i++) {
MemberBase memberBase = customerIdAndMemberBaseMapping.get(Long.valueOf(newCustomerIds.get(i)));
// AccountProductRelation accountProductRelation = accountProductRelationService.queryAccountProductRelationByMemberIdAndProductId(Long.valueOf(customerIds.get(i)), Long.valueOf(productIds.get(i)));
if (memberBase == null) {
continue;
}
Map nameMap = new HashMap();
nameMap.put("customName", memberBase.getName());
// if (accountProductRelation != null) {
// nameMap.put("realMarketId", accountProductRelation.getRealMarketId());
// nameMap.put("simulatedMarketId", accountProductRelation.getSimulatedMarketId());
// }
customerNames.add(nameMap);
}
}
positionTradeInfoRecord4Page.setCustomerNameArray(customerNames);
}
//全量数据添加总盈亏(图片计算要用)
for (ChiefPositionTradeInfoRecord positionTradeInfoRecord4Page : allPositionTradeInfoRecords) {
//盈亏比例
Integer status = positionTradeInfoRecord4Page.getStatus();
if (status == IN_POSITION.getCode()) {
Quote stocksCode = stockCodeService.getStockQuote(positionTradeInfoRecord4Page.getCode());
Date buyingTime = positionTradeInfoRecord4Page.getBuyingTime();
Long dayDiff = DateUtil.calculateTimeDifference(buyingTime, new Date());
BigDecimal now = stocksCode.getNow();
positionTradeInfoRecord4Page.setProfitRatio(financeCalculateService.calculateProfitRate(now, positionTradeInfoRecord4Page.getCost()));
positionTradeInfoRecord4Page.setHoldingDays(Integer.valueOf(String.valueOf(dayDiff)));
}
}
//生成饼图
Map<Integer, Integer> pieChartData = calculatePieChartData(allPositionTradeInfoRecords);
//生成柱状图
Map<Integer, Integer> barChartData = calculateBarChartData(allPositionTradeInfoRecords);
Map<String, Object> chartData = new HashMap<>();
chartData.put("barChart", barChartData);
chartData.put("pieChart", pieChartData);
CommonPage<ChiefPositionTradeInfoRecord4Page> listData = getPositionTradeInfoRecordPage(positionTradeInfoRecord4Pages, pagePositionTradeInfoRecordGroupByBatchBO, total.longValue(), pagePositionTradeInfoRecordGroupByBatchBO.getPageSize().longValue());
result.add(0, listData);
result.add(1, chartData);
return result;
}
private CommonPage<ChiefPositionTradeInfoRecord4Page> getPositionTradeInfoRecordPage(List<ChiefPositionTradeInfoRecord> positionTradeInfoRecord4Pages, PageBO pageBO, Long total, Long pageSize) {
CommonPage page = new CommonPage();
page.setList(positionTradeInfoRecord4Pages);
page.setPageNum(pageBO.getPageNo());
page.setPageSize(pageBO.getPageSize());
if (CollectionUtils.isEmpty(positionTradeInfoRecord4Pages)) {
page.setTotal(ZERO.getCode().longValue());
page.setTotalPage(ZERO.getCode());
} else {
Long totalPage = Long.valueOf(total % pageSize == 0L ? total / pageSize : total / pageSize + 1);
page.setTotal(total);
page.setTotalPage(totalPage.intValue());
}
return page;
}
/**
* 计算饼图数据
*
* @param positionTradeInfoRecord4Pages
* @return
*/
private Map<Integer, Integer> calculatePieChartData(List<ChiefPositionTradeInfoRecord> positionTradeInfoRecord4Pages) {
//0号元素对应的是涨 1号元素是跌 2号元素是平
Map<Integer, Integer> pieChart = new HashMap<Integer, Integer>() {
{
put(0, ZERO.getCode());
put(1, ZERO.getCode());
put(2, ZERO.getCode());
}
};
//
for (ChiefPositionTradeInfoRecord tem : positionTradeInfoRecord4Pages) {
Double profit = tem.getProfitRatio().doubleValue();
Integer index = null;
if (profit > 0)
index = 0;
if (profit < 0)
index = 1;
if (profit == 0)
index = 2;
Integer count = pieChart.get(index);
count++;
pieChart.put(index, count);
}
return pieChart;
}
/**
* 计算棒状图数据
*
* @param positionTradeInfoRecord4Pages
* @return
*/
private Map<Integer, Integer> calculateBarChartData(List<ChiefPositionTradeInfoRecord> positionTradeInfoRecord4Pages) {
Map<Integer, Integer> barChart = new HashMap<Integer, Integer>() {
{
put(0, ZERO.getCode());
put(1, ZERO.getCode());
put(2, ZERO.getCode());
put(3, ZERO.getCode());
put(4, ZERO.getCode());
put(5, ZERO.getCode());
put(6, ZERO.getCode());
put(7, ZERO.getCode());
put(8, ZERO.getCode());
}
};
for (ChiefPositionTradeInfoRecord tem : positionTradeInfoRecord4Pages) {
Double profit = tem.getProfitRatio().doubleValue();
Integer index = null;
if (profit <= -0.07)
index = 0;
if (profit > -0.07 && profit <= -0.05)
index = 1;
if (profit > -0.05 && profit <= -0.02)
index = 2;
if (profit > -0.02 && profit < 0)
index = 3;
if (profit == 0)
index = 4;
if (profit < 2 && profit > 0)
index = 5;
if (profit < 5 && profit >= 2)
index = 6;
if (profit < 7 && profit >= 5)
index = 7;
if (profit >= 7)
index = 8;
Integer count = barChart.get(index);
count++;
barChart.put(index, count);
}
return barChart;
}
@Override
public List<ChiefPositionTradeInfoRecord> listByPositionIds(List<Long> positionIds) {
QueryWrapper<ChiefPositionTradeInfoRecord> queryWrapper = new QueryWrapper();
queryWrapper.in("position_id", positionIds);
return list(queryWrapper);
}
@Override
public void updateBatchPositionTradeInfoRecord(List<ChiefPositionTradeInfoRecord> list) {
saveBatch(list);
}
@Override
public void addBatch(List<ChiefPositionTradeInfoRecord> list) {
for (int i = 0; i <= 3; i++) {
try {
saveBatch(list);
break;
} catch (Exception e) {
try {
Thread.sleep(500L);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
}
}
@Override
public void updateData(List<Long> positionIds, Integer action, Map<Long, ChiefStockPosition> positionMapping, Long batch, BigDecimal sellingPrice, Integer status, Integer entrustWay, StockInputLogTrustSource trustSource, String trustSourceName) {
if (BUY.getCode() == action) {
List<ChiefProduct> products = productService.queryAll();
Map<Long, ChiefProduct> productMap = products.stream().collect(Collectors.toMap(ChiefProduct::getId, ChiefProduct -> ChiefProduct));
//买入
List<ChiefPositionTradeInfoRecord> positionTradeInfoRecords = new ArrayList<>();
for (Long positionId : positionIds) {
ChiefStockPosition stockPosition = positionMapping.get(positionId);
ChiefPositionTradeInfoRecord positionTradeInfoRecord = createPositionTradeInfoRecord(stockPosition, batch, productMap.get(stockPosition.getProductId()), entrustWay, trustSource, trustSourceName);
positionTradeInfoRecords.add(positionTradeInfoRecord);
}
addBatch(positionTradeInfoRecords);
} else if (SELL.getCode() == action) {
List<ChiefProduct> products = productService.queryAll();
Map<Long, ChiefProduct> productMap = products.stream().collect(Collectors.toMap(ChiefProduct::getId, ChiefProduct -> ChiefProduct));
//批量查询个股盈亏记录
List<ChiefStockProfitLog> stockProfitLogs = stockProfitLogService.queryStockProfitLogs(positionIds);
Map<Long, ChiefStockProfitLog> positionIdAndStockProfitLogMapping = stockProfitLogs.stream().collect(Collectors.toMap(ChiefStockProfitLog::getPositionId, ChiefStockProfitLog -> ChiefStockProfitLog));
//批量查询
List<ChiefPositionTradeInfoRecord> positionTradeInfoRecords = listByPositionIds(positionIds);
for (ChiefPositionTradeInfoRecord positionTradeInfoRecord : positionTradeInfoRecords) {
Long positionId = positionTradeInfoRecord.getPositionId();
ChiefStockPosition stockPosition = positionMapping.get(positionId);
ChiefStockProfitLog stockProfitLog = positionIdAndStockProfitLogMapping.get(positionId);
createPositionTradeInfoRecord(stockProfitLog, productMap.get(positionTradeInfoRecord.getProductId()), positionTradeInfoRecord, batch, stockPosition, sellingPrice, status, entrustWay, trustSource, trustSourceName);
}
//清仓
updateBatchPositionTradeInfoRecord(positionTradeInfoRecords);
} else if (INCREASE.getCode() == action) {
//查询所有的记录
List<ChiefPositionTradeInfoRecord> positionTradeInfoRecords = listByPositionIds(positionIds);
for (ChiefPositionTradeInfoRecord positionTradeInfoRecord : positionTradeInfoRecords) {
ChiefStockPosition stockPosition = positionMapping.get(positionTradeInfoRecord.getPositionId());
//成本,买入批次、卖出批次、操作类型、交易状态
positionTradeInfoRecord.setCost(stockPosition.getCost());
positionTradeInfoRecord.setBuyingBatch(batch);
positionTradeInfoRecord.setOperation(action);
positionTradeInfoRecord.setEntrustWay(entrustWay);
positionTradeInfoRecord.setTrustSourceName(trustSourceName);
positionTradeInfoRecord.setTrustSource(trustSource.getCode());
}
updateBatchPositionTradeInfoRecord(positionTradeInfoRecords);
} else if (DECREASE.getCode() == action) {
//查询所有的记录
List<ChiefPositionTradeInfoRecord> positionTradeInfoRecords = listByPositionIds(positionIds);
for (ChiefPositionTradeInfoRecord positionTradeInfoRecord : positionTradeInfoRecords) {
ChiefStockPosition stockPosition = positionMapping.get(positionTradeInfoRecord.getPositionId());
//成本,买入批次、卖出批次、操作类型、交易状态
positionTradeInfoRecord.setCost(stockPosition.getCost());
positionTradeInfoRecord.setBuyingBatch(batch);
positionTradeInfoRecord.setOperation(action);
positionTradeInfoRecord.setEntrustWay(entrustWay);
positionTradeInfoRecord.setTrustSourceName(trustSourceName);
positionTradeInfoRecord.setTrustSource(trustSource.getCode());
// if (status == REAL_OR_NOT.getCode()){
// positionTradeInfoRecord.setStatus(REAL_OR_NOT.getCode());
// }
}
updateBatchPositionTradeInfoRecord(positionTradeInfoRecords);
} else {
throw new ApiException("操作错误");
}
//清仓非常好确定,没有百分之百卖出,肯定卖不干净,所以就看卖出事件的时候。百分比是多少就可以断定是否是清仓
}
//买入 加仓 减仓 清仓,这些动作是根据当时 是否有股票持仓和卖出股票的动作判断的,所以每个人应该都不一样
//买入 无持仓 买入股票
//加仓 有持仓 买入股票
//减仓 不全量卖出 全量卖出(有冻结) 卖出股票
//清仓 全量卖出 卖出股票
//盈亏比例,用当前市场价格计算,用昨日计算的结果直接拼接,用昨日收盘价实时计算,后两种方案其实是一个效果
//持仓天数实时计算
//要更新的字段 成本,买入批次、卖出批次、操作类型、交易状态
//第一次的买入批次,后续加仓批次会跟着变,通过position_id进行查询获取要操作的记录
//能查出来就是买入过的(接下来就是加仓动作),查不出来就是买入动作,新建position的时候进行买入动作 加仓的时候进行加仓日志动作
/**
* 通过股票持仓生成股票买入记录
*
* @param stockPosition
* @param batch
* @return
*/
private ChiefPositionTradeInfoRecord createPositionTradeInfoRecord(ChiefStockPosition stockPosition, Long batch, ChiefProduct product, Integer entrustWay, StockInputLogTrustSource trustSource, String trustSourceName) {
ChiefPositionTradeInfoRecord positionTradeInfoRecord = new ChiefPositionTradeInfoRecord();
positionTradeInfoRecord.setOperation(BUY.getCode());
positionTradeInfoRecord.setBuyingBatch(batch);
positionTradeInfoRecord.setCost(stockPosition.getCost());
positionTradeInfoRecord.setBuyingTime(stockPosition.getCreatedTime());
positionTradeInfoRecord.setCode(stockPosition.getCode());
positionTradeInfoRecord.setCustomerId(stockPosition.getCustomerId());
positionTradeInfoRecord.setPositionId(stockPosition.getId());
Long productId = stockPosition.getProductId();
positionTradeInfoRecord.setProductId(productId);
positionTradeInfoRecord.setProductType(product.getProductType());
positionTradeInfoRecord.setStatus(IN_POSITION.getCode());
positionTradeInfoRecord.setCompanyId(product.getCompanyId().intValue());
positionTradeInfoRecord.setEntrustWay(entrustWay);
positionTradeInfoRecord.setTrustSource(trustSource.getCode());
positionTradeInfoRecord.setTrustSourceName(trustSourceName);
String industry = stockCodeService.queryStockIndustryByCode(stockPosition.getCode());
positionTradeInfoRecord.setIndustry(industry);
return positionTradeInfoRecord;
}
/**
* 清仓股票数据补充
*
* @param stockProfitLog
* @param positionTradeInfoRecord
* @param batch
* @param stockPosition
* @return
*/
private ChiefPositionTradeInfoRecord createPositionTradeInfoRecord(ChiefStockProfitLog stockProfitLog, ChiefProduct product, ChiefPositionTradeInfoRecord positionTradeInfoRecord, Long batch, ChiefStockPosition stockPosition, BigDecimal sellingPrice, Integer status, Integer entrustWay, StockInputLogTrustSource trustSource, String trustSourceName) {
positionTradeInfoRecord.setOperation(SELL.getCode());
positionTradeInfoRecord.setBuyingBatch(batch);
positionTradeInfoRecord.setCost(stockProfitLog.getCost());
positionTradeInfoRecord.setBuyingTime(stockProfitLog.getBuyingTime());
positionTradeInfoRecord.setSellingTime(stockProfitLog.getSellingTime());
positionTradeInfoRecord.setCode(stockProfitLog.getCode());
positionTradeInfoRecord.setCustomerId(stockPosition.getCustomerId());
positionTradeInfoRecord.setPositionId(stockProfitLog.getId());
Long productId = stockProfitLog.getProductId();
positionTradeInfoRecord.setHoldingDays(stockProfitLog.getHoldingDays());
positionTradeInfoRecord.setProductId(productId);
positionTradeInfoRecord.setProductType(product.getProductType());
if (status != null && status == REAL_OR_NOT.getCode()) {
positionTradeInfoRecord.setStatus(REAL_OR_NOT.getCode());
}
positionTradeInfoRecord.setStatus(CLEAR_POSITION.getCode());
positionTradeInfoRecord.setProfitRatio(stockProfitLog.getProfitRatio());
positionTradeInfoRecord.setSellingPrice(sellingPrice);
positionTradeInfoRecord.setEntrustWay(entrustWay);
positionTradeInfoRecord.setTrustSourceName(trustSourceName);
positionTradeInfoRecord.setTrustSource(trustSource.getCode());
String industry = stockCodeService.queryStockIndustryByCode(stockProfitLog.getCode());
positionTradeInfoRecord.setIndustry(industry);
return positionTradeInfoRecord;
}
private Map<String, Object> createPageParam(ChiefPagePositionTradeInfoRecordGroupByBatchBO pagePositionTradeInfoRecordGroupByBatchBO,
boolean isPagingQuery) {
Map<String, Object> param = new HashMap<>();
String orderBy = pagePositionTradeInfoRecordGroupByBatchBO.getOrderBy();
String productType = pagePositionTradeInfoRecordGroupByBatchBO.getProductType();
Long productId = pagePositionTradeInfoRecordGroupByBatchBO.getProductId();
Long tradeStatus = pagePositionTradeInfoRecordGroupByBatchBO.getTradeStatus();
String code = pagePositionTradeInfoRecordGroupByBatchBO.getCode();
String profitLowerLimit = pagePositionTradeInfoRecordGroupByBatchBO.getProfitLowerLimit();
String profitUpperLimit = pagePositionTradeInfoRecordGroupByBatchBO.getProfitUpperLimit();
Long buyingTimeLowerLimit = pagePositionTradeInfoRecordGroupByBatchBO.getBuyingTimeLowerLimit();
Long buyingTimeUpperLimit = pagePositionTradeInfoRecordGroupByBatchBO.getBuyingTimeUpperLimit();
Long sellingTimeLowerLimit = pagePositionTradeInfoRecordGroupByBatchBO.getSellingTimeLowerLimit();
Long sellingTimeUpperLimit = pagePositionTradeInfoRecordGroupByBatchBO.getSellingTimeUpperLimit();
Integer trustSourceId = pagePositionTradeInfoRecordGroupByBatchBO.getTrustSourceId();
Boolean filterOneMore = pagePositionTradeInfoRecordGroupByBatchBO.getFilterOneMore();
String industry = pagePositionTradeInfoRecordGroupByBatchBO.getIndustry();
DataAuthorityDto authorityDto = usAdminService.getCurrUserDataAuthorityDTO();
//UsAdmin user= UserUtil.getUser();
AdminConstant.DataAuthority authority = authorityDto.getDataAuthority();
Long analystId = null;
if (authority.equals(AdminConstant.DataAuthority.COMPANY)) {
pagePositionTradeInfoRecordGroupByBatchBO.setCompanyId(authorityDto.getUser().getCompanyId());
}
if (authority.equals(AdminConstant.DataAuthority.CURR_USER)) {
analystId = authorityDto.getUser().getId();
}
Integer companyId = pagePositionTradeInfoRecordGroupByBatchBO.getCompanyId();
if (analystId != null) {
param.put("analyst", analystId);
}
if (trustSourceId != null) {
param.put("trustSource", trustSourceId);
}
if (StringUtils.isNotBlank(productType)) {
param.put("productType", productType);
}
if (AssertUtil.isNotBlank(industry)) {
param.put("industry", industry);
}
if (productId != null) {
param.put("productId", productId);
}
if (tradeStatus != null) {
param.put("status", tradeStatus);
}
if (StringUtils.isNotBlank(code)) {
param.put("code", code);
}
if (companyId != null) {
param.put("companyId", companyId);
}
if (buyingTimeLowerLimit != null) {
Date date = DateUtil.dateStrToDate(DateUtil.timeStampToStr(buyingTimeLowerLimit, DATE_FMT) + " 00:00:00", DATE_TIME_FMT);
param.put("buyingTimeLowerLimit", date);
}
if (buyingTimeUpperLimit != null) {
Date date = DateUtil.dateStrToDate(DateUtil.timeStampToStr(buyingTimeUpperLimit, DATE_FMT) + " 23:59:59", DATE_TIME_FMT);
param.put("buyingTimeUpperLimit", date);
}
if (sellingTimeLowerLimit != null) {
Date date = DateUtil.dateStrToDate(DateUtil.timeStampToStr(sellingTimeLowerLimit, DATE_FMT) + " 00:00:00", DATE_TIME_FMT);
param.put("sellingTimeLowerLimit", date);
}
if (sellingTimeUpperLimit != null) {
Date date = DateUtil.dateStrToDate(DateUtil.timeStampToStr(sellingTimeUpperLimit, DATE_FMT) + " 23:59:59", DATE_TIME_FMT);
param.put("sellingTimeUpperLimit", date);
}
if (profitLowerLimit != null) {
param.put("profitLowerLimit", profitLowerLimit);
}
if (profitUpperLimit != null) {
param.put("profitUpperLimit", profitUpperLimit);
}
if (filterOneMore != null && filterOneMore) {
param.put("filterOneMore", filterOneMore);
}
//排序
if (StringUtils.isBlank(orderBy)) {
orderBy = "buyingTime:DESC";
}
orderBy = SortUtil.humpToSnake(orderBy.split(":"));
param.put("orderBy", orderBy);
return param;
}
@Transactional(propagation = Propagation.SUPPORTS)
@Override
public List<ChiefPositionTradeInfoRecord> getPositionTradeInfoRecordByPositionId(String code, Long positionId) {
QueryWrapper<ChiefPositionTradeInfoRecord> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("position_id", positionId);
queryWrapper.eq("code", code);
queryWrapper.eq("status", 1);
return list(queryWrapper);
}
@Override
public int updatePositionTradeInfoRecord(ChiefPositionTradeInfoRecord positionTradeInfoRecord) {
updateById(positionTradeInfoRecord);
return 1;
}
}
package com.zfxftech.telmarket.service.impl.business.chief;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.zfxf.tools.utils.AssertUtil;
import com.zfxftech.telmarket.common.bean.MapIntgerVo;
import com.zfxftech.telmarket.common.constant.AdminConstant;
import com.zfxftech.telmarket.common.excepitonHandler.ApiException;
import com.zfxftech.telmarket.common.pojo.dao.DataDictionary;
import com.zfxftech.telmarket.common.pojo.dao.InitialPrincipal;
import com.zfxftech.telmarket.common.pojo.dao.RiskLevel;
import com.zfxftech.telmarket.common.pojo.dao.WeChatOfficialAccount;
import com.zfxftech.telmarket.common.pojo.dao.chief.ChiefProduct;
import com.zfxftech.telmarket.common.pojo.dao.permission.UsAdmin;
import com.zfxftech.telmarket.common.pojo.dto.account.DataAuthorityDto;
import com.zfxftech.telmarket.common.pojo.request.PageProportionBO;
import com.zfxftech.telmarket.common.pojo.request.chief.ChiefQueryProductBO;
import com.zfxftech.telmarket.common.pojo.request.chief.ChiefSaveProductBO;
import com.zfxftech.telmarket.common.pojo.vo.chief.ChiefProductStrategyVO;
import com.zfxftech.telmarket.common.util.OptionalUtil;
import com.zfxftech.telmarket.common.util.RedisUtil;
import com.zfxftech.telmarket.common.util.SortUtil;
import com.zfxftech.telmarket.mapper.business.chief.ChiefProductMapper;
import com.zfxftech.telmarket.service.UsAdminService;
import com.zfxftech.telmarket.service.business.DataDictionaryService;
import com.zfxftech.telmarket.service.business.InitialPrincipalService;
import com.zfxftech.telmarket.service.business.RiskLevelService;
import com.zfxftech.telmarket.service.business.WeChatOfficialAccountService;
import com.zfxftech.telmarket.service.business.chief.ChiefProductService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;
import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
import java.util.stream.Collectors;
import static com.zfxftech.telmarket.common.constant.AdminConstant.AnalystOperationEnum.ADD;
import static com.zfxftech.telmarket.common.constant.AdminConstant.AnalystOperationEnum.DELETE;
import static com.zfxftech.telmarket.common.constant.AdminConstant.ObjectEnum.COMPANY;
/**
* 产品服务类
*
* @author jianghua
* @version 1.0
* @date 2021-08-24 15:55
*/
@Service
public class ChiefProductServiceImpl extends ServiceImpl<ChiefProductMapper, ChiefProduct> implements ChiefProductService {
@Autowired
private InitialPrincipalService initialPrincipalService;
@Autowired
private RiskLevelService riskLevelService;
@Autowired
private DataDictionaryService dataDictionaryService;
// @Autowired
// private WeChatRouteService weChatRouteService;
@Autowired
private WeChatOfficialAccountService weChatOfficialAccountService;
@Resource
private UsAdminService usAdminService;
@Autowired
private RedisUtil redisUtil;
/**
* 保存产品
*
* @param saveProductBO
* @param usAdmin
*/
@Transactional(propagation = Propagation.REQUIRED)
@Override
public void saveProduct(ChiefSaveProductBO saveProductBO, UsAdmin usAdmin) {
//查询当前用户是否是分析师
Long id = saveProductBO.getId();
QueryWrapper<ChiefProduct> queryWrapper = new QueryWrapper();
queryWrapper.eq("product_name", saveProductBO.getProductName());
ChiefProduct existed = getOne(queryWrapper);
//通过公众号id查询对应的appId
ChiefProduct product = createProduct(saveProductBO, usAdmin);
if (id != null) {
//修改
if (existed != null) {
Long existedId = existed.getId();
if (!Objects.equals(id, existedId)) {
throw new ApiException("要修改的产品已经存在");
}
}
product.setId(saveProductBO.getId());
UpdateWrapper<ChiefProduct> productUpdateWrapper = new UpdateWrapper<>();
productUpdateWrapper.eq("id", saveProductBO.getId());
if (saveProductBO.getTradeStyle() == null) {
productUpdateWrapper.set("trade_style", null);
}
if (StringUtils.isBlank(saveProductBO.getRiskLevel())) {
productUpdateWrapper.set("risk_level", null);
}
// if (StringUtils.isBlank(saveProductBO.getInitialPrincipal())) {
// productUpdateWrapper.set("initial_principal", null);
// }
update(product, productUpdateWrapper);
if(!ObjectUtils.isEmpty(product.getId())){
redisUtil.remove("chief:productId:"+product.getId());
}
} else {
//插入
if (existed != null) {
throw new ApiException("要添加的产品已经存在");
}
saveOrUpdate(product);
if(!ObjectUtils.isEmpty(product.getId())){
redisUtil.remove("chief:productId:"+product.getId());
}
}
}
/**
* 保存产品表单转化为产品对象
*
* @param productBO
* @param admin
* @return
*/
public ChiefProduct createProduct(ChiefSaveProductBO productBO, UsAdmin admin) {
ChiefProduct product = new ChiefProduct();
product.setCompanyId(productBO.getCompanyId());
product.setSubstituteAnalystList(Arrays.asList(productBO.getAnalyst()));
product.setTradeStyle(productBO.getTradeStyle());
//product.setInitialPrincipal(productBO.getInitialPrincipal());
product.setRiskLevel(productBO.getRiskLevel());
product.setCompanyId(productBO.getCompanyId());
product.setProductType(productBO.getProductType());
product.setProductName(productBO.getProductName());
product.setModifyBy(admin.getUsername());
product.setRemark(productBO.getRemark());
product.setAnalyst(productBO.getAnalyst());
//product.setDayStatisticsSend(productBO.getDayStatisticsSend());
product.setSellMessage(productBO.getSellMessage());
product.setBuyMessage(productBO.getBuyMessage());
WeChatOfficialAccount weChatOfficialAccount = weChatOfficialAccountService.queryById(productBO.getWeChatId());
OptionalUtil.checkNull(weChatOfficialAccount, "当前公众号不存在");
product.setWeChatId(weChatOfficialAccount.getId());
if (productBO.getId() == null) {
product.setCreatedBy(admin.getUsername());
} else {
product.setModifyTime(new Date());
}
if(!ObjectUtils.isEmpty(product.getId())){
redisUtil.remove("chief:productId:"+product.getId());
}
return product;
}
@Transactional(propagation = Propagation.SUPPORTS)
@Override
public List<ChiefProduct> queryProductByIds(List<Long> ids) {
QueryWrapper<ChiefProduct> queryWrapper = new QueryWrapper();
queryWrapper.in("id", ids);
return list(queryWrapper);
}
/**
* 查询产品详情
*
* @param id
*/
@Transactional(propagation = Propagation.SUPPORTS)
@Override
public ChiefProduct queryProductById(Long id) {
if(!ObjectUtils.isEmpty(redisUtil.get("chief:productId:"+id))){
ChiefProduct ob= (ChiefProduct) redisUtil.get("chief:productId:"+id);
return ob;
}
//3秒
redisUtil.set("chief:productId:"+id,getById(id),3L, TimeUnit.MINUTES);
return getById(id);
}
@Transactional(propagation = Propagation.SUPPORTS)
@Override
public List<ChiefProduct> queryAll() {
return list();
}
@Override
public List<ChiefProduct> queryListForAuthority() {
LambdaQueryWrapper<ChiefProduct> queryWrapper =new LambdaQueryWrapper<>();
DataAuthorityDto authorityDto = usAdminService.getCurrUserDataAuthorityDTO();
AdminConstant.DataAuthority authority = authorityDto.getDataAuthority();
if(authority.equals(AdminConstant.DataAuthority.COMPANY)){
queryWrapper.eq(ChiefProduct::getCompanyId,authorityDto.getUser().getCompanyId());
}
if(authority.equals(AdminConstant.DataAuthority.CURR_USER)){
queryWrapper.eq(ChiefProduct::getAnalyst,authorityDto.getUser().getId());
}
return super.list(queryWrapper);
}
@Transactional(propagation = Propagation.SUPPORTS)
@Override
public List<ChiefProduct> pageProduct(ChiefQueryProductBO queryProductBO) {
DataAuthorityDto authorityDto = usAdminService.getCurrUserDataAuthorityDTO();
AdminConstant.DataAuthority authority = authorityDto.getDataAuthority();
UsAdmin userAdmin = authorityDto.getUser();
if(authority.equals(AdminConstant.DataAuthority.COMPANY)){
queryProductBO.setCompanyId(userAdmin.getCompanyId());
}
if(authority.equals(AdminConstant.DataAuthority.CURR_USER)){
queryProductBO.setAnalyst(userAdmin.getId());
}
Long productManager = queryProductBO.getProductManager();
String productType = queryProductBO.getProductType();
String productId = queryProductBO.getProductId();
String riskLevel = queryProductBO.getRiskLevel();
Long analyst = queryProductBO.getAnalyst();
Integer companyId = queryProductBO.getCompanyId();
//String initialPrincipal = queryProductBO.getInitialPrincipal();
Long officialAccountId = queryProductBO.getWeChatId();
//查询
QueryWrapper<ChiefProduct> queryWrapper = new QueryWrapper();
if (companyId != null) {
queryWrapper.eq("company_id", companyId);
}
if (analyst != null) {
queryWrapper.eq("analyst", analyst);
}
if (StringUtils.isNotBlank(productId)) {
queryWrapper.eq("id", productId);
} else {
if (StringUtils.isNotBlank(productType)) {
queryWrapper.eq("product_type", productType);
}
if (officialAccountId != null) {
queryWrapper.eq("w_id", officialAccountId);
}
if (StringUtils.isNotBlank(riskLevel)) {
queryWrapper.eq("risk_level", riskLevel);
}
if (productManager != null) {
// criteria.and("product_manager_list").in(Arrays.asList(productManager));
}
// if (initialPrincipal != null) {
// queryWrapper.eq("initial_principal", initialPrincipal);
// }
Long startCreateTime = queryProductBO.getStartCreateTime();
Long endCreateTime = queryProductBO.getEndCreateTime();
if (startCreateTime != null) {
queryWrapper.ge("created_time", new Date(startCreateTime));
}
if (endCreateTime != null) {
queryWrapper.le("created_time", new Date(endCreateTime));
}
}
//排序
String orderBy = queryProductBO.getOrderBy();
if (StringUtils.isBlank(orderBy)) {
orderBy = "modify_time desc";
} else {
orderBy = SortUtil.humpToSnake(orderBy.split(":"));
}
//查询数据
Integer pageSize = queryProductBO.getPageSize();
Integer pageNo = queryProductBO.getPageNo();
PageHelper.orderBy(orderBy);
PageHelper.startPage(pageNo, pageSize);
List<ChiefProduct> products = list(queryWrapper);
//查询风险等级
List<RiskLevel> riskLevels = riskLevelService.queryAll();
Map<String, String> riskLevelAndDescMapping = new HashMap<>();
for (RiskLevel temRiskLevel : riskLevels) {
riskLevelAndDescMapping.put(temRiskLevel.getId(), temRiskLevel.getName());
}
//查询交易风格
Map<Long, String> tradeStyleAndDescMapping = new HashMap<>();
for (AdminConstant.TradeStyleEnum tradeStyle : EnumSet.allOf(AdminConstant.TradeStyleEnum.class)) {
tradeStyleAndDescMapping.put(tradeStyle.getCode(), tradeStyle.getDesc());
}
//查询公司
List<DataDictionary> companys = dataDictionaryService.queryByBusinessType(COMPANY.getCode());
Map<Integer, String> companyAndDescMapping = new HashMap<>();
for (DataDictionary company : companys) {
companyAndDescMapping.put(Integer.valueOf(company.getBusinessCode()), company.getDescription());
}
//产品类型映射
Map<String, String> productAndDescMapping = new HashMap<>();
for (AdminConstant.MemberProductTypeEnum productTypeEnum : EnumSet.allOf(AdminConstant.MemberProductTypeEnum.class)) {
productAndDescMapping.put(productTypeEnum.getCode(), productTypeEnum.getDesc());
}
//初始本金
List<InitialPrincipal> initialPrincipals = initialPrincipalService.queryInitialPrincipalList();
Map<String, Long> initialPrincipalAndDescMapping = new HashMap<>();
for (InitialPrincipal temInitialPrincipal : initialPrincipals) {
initialPrincipalAndDescMapping.put(temInitialPrincipal.getId(), temInitialPrincipal.getAmount());
}
//通过appId查询对应的公众号名称
List<WeChatOfficialAccount> weChatOfficialAccounts = weChatOfficialAccountService.list();
Map<Long, WeChatOfficialAccount> idAndWeChatOfficialAccountsMapping = weChatOfficialAccounts.stream().collect(Collectors.toMap(WeChatOfficialAccount::getId, Function.identity(), (key1, key2) -> key2));
//查询产品类型
for (ChiefProduct product : products) {
product.setCompanyDesc(companyAndDescMapping.get(product.getCompanyId().intValue()));
product.setTradeStyleDesc(tradeStyleAndDescMapping.get(product.getTradeStyle()));
product.setRiskLevelDesc(riskLevelAndDescMapping.get(product.getRiskLevel()));
product.setProductTypeDesc(productAndDescMapping.get(product.getProductType()));
//product.setInitialPrincipalDesc(initialPrincipalAndDescMapping.get(product.getInitialPrincipal()));
product.setWeChatIdDesc(idAndWeChatOfficialAccountsMapping.get(product.getWeChatId()).getName());
}
return products;
}
@Override
public List<ChiefProduct> getListForDataSource() {
DataAuthorityDto authorityDto = usAdminService.getCurrUserDataAuthorityDTO();
AdminConstant.DataAuthority authority = authorityDto.getDataAuthority();
UsAdmin userAdmin = authorityDto.getUser();
List<Integer> companyWhere = null;
if(authority.equals(AdminConstant.DataAuthority.COMPANY)){
companyWhere = authorityDto.getGetOtherCompanyData();
if(!AssertUtil.isNotEmpty(companyWhere)){
companyWhere = new ArrayList<>();
}
if(!companyWhere.contains(userAdmin.getCompanyId())){
companyWhere.add(userAdmin.getCompanyId());
}
}
LambdaQueryWrapper<ChiefProduct> queryWrapper = Wrappers.lambdaQuery();
if(AssertUtil.isNotEmpty(companyWhere)){
queryWrapper.in(ChiefProduct::getCompanyId,companyWhere);
}
if(authority.equals(AdminConstant.DataAuthority.CURR_USER)){
queryWrapper.eq(ChiefProduct::getAnalyst,userAdmin.getId());
}
queryWrapper.orderByDesc(ChiefProduct::getModifyTime);
List<ChiefProduct> products = list(queryWrapper);
//查询公司
List<DataDictionary> companys = dataDictionaryService.queryByBusinessType(COMPANY.getCode());
Map<Integer, String> companyAndDescMapping = new HashMap<>();
for (DataDictionary company : companys) {
companyAndDescMapping.put(Integer.valueOf(company.getBusinessCode()), company.getDescription());
}
//产品类型映射
Map<String, String> productAndDescMapping = new HashMap<>();
for (AdminConstant.MemberProductTypeEnum productTypeEnum : EnumSet.allOf(AdminConstant.MemberProductTypeEnum.class)) {
productAndDescMapping.put(productTypeEnum.getCode(), productTypeEnum.getDesc());
}
//通过appId查询对应的公众号名称
List<WeChatOfficialAccount> weChatOfficialAccounts = weChatOfficialAccountService.list();
Map<Long, WeChatOfficialAccount> idAndWeChatOfficialAccountsMapping = weChatOfficialAccounts.stream().collect(Collectors.toMap(WeChatOfficialAccount::getId, Function.identity(), (key1, key2) -> key2));
//查询产品类型
for (ChiefProduct product : products) {
product.setCompanyDesc(companyAndDescMapping.get(product.getCompanyId().intValue()));
product.setProductTypeDesc(productAndDescMapping.get(product.getProductType()));
product.setWeChatIdDesc(idAndWeChatOfficialAccountsMapping.get(product.getWeChatId()).getName());
}
return products;
}
@Transactional(propagation = Propagation.REQUIRED)
@Override
public void operationSubstituteAnalyst(Long productId, Long analyst, String operation) {
ChiefProduct product = queryProductById(productId);
//添加分析师
if (ADD.getDesc().equals(operation)) {
List<Long> substituteAnalystList = product.getSubstituteAnalystList();
if (!substituteAnalystList.contains(analyst)) {
substituteAnalystList.add(analyst);
} else {
//当前分析师已添加过
throw new ApiException("当前分析师已添加过");
}
}
//删除分析师
if (DELETE.getDesc().equals(operation)) {
List<Long> substituteAnalystList = product.getSubstituteAnalystList();
Iterator<Long> iterator = substituteAnalystList.iterator();
while (iterator.hasNext()) {
Long next = iterator.next();
if (next == analyst) {
iterator.remove();
}
}
}
// repository.save(product);
}
@Transactional(propagation = Propagation.SUPPORTS)
@Override
public List<ChiefProduct> queryProductByType(String type) {
QueryWrapper<ChiefProduct> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("product_type", type);
return list(queryWrapper);
}
@Override
public List<ChiefProductStrategyVO> getAllFollowAccount() {
QueryWrapper<ChiefProduct> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("is_deleted", 0);
List<ChiefProduct> productList = list(queryWrapper);
if(!ObjectUtils.isEmpty(productList)){
List<ChiefProductStrategyVO> productStrategyVOList = new ArrayList<>();
for (ChiefProduct product : productList) {
ChiefProductStrategyVO productStrategyVO = new ChiefProductStrategyVO();
productStrategyVO.setId(product.getId().intValue());
productStrategyVO.setProductName(product.getProductName());
productStrategyVOList.add(productStrategyVO);
}
return productStrategyVOList;
}
return null;
}
@Override
public List<MapIntgerVo> getProductName(PageProportionBO pageProportionBO) {
LambdaQueryWrapper<ChiefProduct> queryWrapper =new LambdaQueryWrapper<>();
DataAuthorityDto authorityDto = usAdminService.getCurrUserDataAuthorityDTO();
AdminConstant.DataAuthority authority = authorityDto.getDataAuthority();
if(authority.equals(AdminConstant.DataAuthority.COMPANY)){
queryWrapper.eq(ChiefProduct::getCompanyId,authorityDto.getUser().getCompanyId());
}
if(authorityDto.isAnalyst() || authority.equals(AdminConstant.DataAuthority.CURR_USER)){
queryWrapper.eq(ChiefProduct::getAnalyst,authorityDto.getUser().getId());
}
if(!ObjectUtils.isEmpty(pageProportionBO)&&!StringUtils.isEmpty(pageProportionBO.getProductNmae())){
queryWrapper.like(ChiefProduct::getProductName,pageProportionBO.getProductNmae());
}
List<ChiefProduct> list = super.list(queryWrapper);
List<MapIntgerVo> mapIntgerVos = new ArrayList<>();
if(!ObjectUtils.isEmpty(list)){
for (ChiefProduct product : list) {
MapIntgerVo mapIntgerVo = new MapIntgerVo();
if(StringUtils.isEmpty(product.getProductName())){
continue;
}
mapIntgerVo.setKey(product.getProductName());
mapIntgerVo.setValue(product.getId().intValue());
mapIntgerVos.add(mapIntgerVo);
}
}
return mapIntgerVos;
}
@Override
public List<UsAdmin> getProductUserByRoleIds(Long productId, List<Long> roleIds) {
return null;
}
}
package com.zfxftech.telmarket.service.impl.business.chief;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.zfxftech.telmarket.common.constant.AdminConstant;
import com.zfxftech.telmarket.common.pojo.dao.chief.ChiefAccountProductRelation;
import com.zfxftech.telmarket.common.pojo.dao.chief.ChiefStockInputLog;
import com.zfxftech.telmarket.common.pojo.dao.chief.ChiefStockPosition;
import com.zfxftech.telmarket.common.pojo.request.chief.ChiefQueryStockInputLogBO;
import com.zfxftech.telmarket.common.util.BigDecimalUtil;
import com.zfxftech.telmarket.mapper.business.chief.ChiefStockInputLogMapper;
import com.zfxftech.telmarket.service.business.chief.ChiefAccountProductRelationService;
import com.zfxftech.telmarket.service.business.chief.ChiefStockInputLogService;
import com.zfxftech.telmarket.service.business.chief.ChiefStockPositionService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
import java.util.*;
import static com.zfxftech.telmarket.common.constant.AdminConstant.OperationEnum.BUY;
import static com.zfxftech.telmarket.common.constant.AdminConstant.OperationEnum.SELL;
/**
* @version 1.0
* @Author: hxq
* @Date: 2021/9/16 13:49
*/
@Service
@Slf4j
public class ChiefStockInputLogServiceImpl extends ServiceImpl<ChiefStockInputLogMapper, ChiefStockInputLog> implements ChiefStockInputLogService {
@Autowired
private ChiefStockPositionService stockPositionService;
@Autowired
private ChiefAccountProductRelationService accountProductRelationService;
@Transactional(propagation = Propagation.SUPPORTS)
@Override
public List<ChiefStockInputLog> pageStockInputLogs(ChiefQueryStockInputLogBO queryStockInputLogBO) {
return pageStockInputLogs(queryStockInputLogBO, true);
}
@Transactional(propagation = Propagation.REQUIRED)
@Override
public void addStockInputLog(ChiefStockInputLog stockInputLog) {
ChiefStockPosition stockPosition = convertStockInputLog2StockPosition(stockInputLog);
//插入持仓
stockPosition = stockPositionService.saveStockPosition(stockPosition);
//插入记录
stockInputLog.setStockPositionId(stockPosition.getId());
save(stockInputLog);
}
@Transactional(propagation = Propagation.REQUIRED)
@Override
public void addStockInputLog2(ChiefStockInputLog stockInputLog) {
//插入记录
save(stockInputLog);
}
@Transactional(propagation = Propagation.REQUIRED)
@Override
public void addStockInputLogs(List<ChiefStockInputLog> stockInputLogs) {
saveBatch(stockInputLogs);
}
@Transactional(propagation = Propagation.REQUIRED)
@Override
public void updateStockInputLog(ChiefStockInputLog stockInputLog) {
//计算增量 使用原来的成本和价格,和修正后的成本和价格做差值,这个差值是实盘要加入、减少的资金
ChiefStockInputLog one = getById(stockInputLog.getId());
BigDecimal before = BigDecimalUtil.mul(new BigDecimal(one.getCount()), one.getCost());
BigDecimal after = BigDecimalUtil.mul(new BigDecimal(stockInputLog.getCount()), stockInputLog.getCost());
BigDecimal increment = BigDecimalUtil.sub(after, before);
//查询用户和产品关联信息
ChiefAccountProductRelation accountProductRelation = accountProductRelationService.queryAccountProductRelationByMemberIdAndProductId(stockInputLog.getCustomerId(), stockInputLog.getProductId());
Integer operation = stockInputLog.getOperation();
if (operation == BUY.getCode()) {
//increment大于0就是输错的时候,买少花钱了,所以做减法
accountProductRelation.setRealFunding(BigDecimalUtil.sub(accountProductRelation.getRealFunding(), increment));
}
if (operation == SELL.getCode()) {
//increment大于0就是输错的时候,卖少花钱了,所及做加法
accountProductRelation.setRealFunding(BigDecimalUtil.add(accountProductRelation.getRealFunding(), BigDecimalUtil.sub(after, before)));
}
accountProductRelationService.updateAccountProductRelation(accountProductRelation);
//修改记录
updateById(stockInputLog);
ChiefStockPosition stockPosition = convertStockInputLog2StockPosition(stockInputLog);
//重算持仓
stockPositionService.recalculateStockPosition(stockPosition);
}
@Transactional(propagation = Propagation.SUPPORTS)
@Override
public List<ChiefStockInputLog> queryStockInputLogs(long customerId, long productId, String code) {
QueryWrapper<ChiefStockInputLog> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("customer_id", customerId);
queryWrapper.eq("product_id", productId);
queryWrapper.eq("code", code);
return list(queryWrapper);
}
@Transactional(propagation = Propagation.SUPPORTS)
@Override
public List<ChiefStockInputLog> queryStockInputLogs(long stockPositionId, Integer operation) {
QueryWrapper<ChiefStockInputLog> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("stock_position_id", stockPositionId);
if (operation != null) {
queryWrapper.eq("operation", operation);
}
return list(queryWrapper);
}
@Transactional(propagation = Propagation.SUPPORTS)
@Override
public ChiefStockInputLog queryOldestStockInputLog(long stockPositionId, Integer operation) {
QueryWrapper<ChiefStockInputLog> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("stock_position_id", stockPositionId);
if (operation != null) {
queryWrapper.eq("operation", operation);
}
queryWrapper.orderByAsc("trading_time").last("limit 1");
return getOne(queryWrapper);
}
@Transactional(propagation = Propagation.REQUIRED)
@Override
public List<ChiefStockInputLog> queryByMarketIdsAndToday(List<Long> marketIds) {
QueryWrapper<ChiefStockInputLog> queryWrapper = new QueryWrapper<>();
Calendar start = Calendar.getInstance();
start.setTime(new Date());
start.set(Calendar.HOUR_OF_DAY, 8);
start.set(Calendar.MINUTE, 0);
start.set(Calendar.SECOND, 0);
Calendar end = Calendar.getInstance();
end.setTime(new Date());
end.set(Calendar.HOUR_OF_DAY, 17);
end.set(Calendar.MINUTE, 0);
end.set(Calendar.SECOND, 0);
// queryWrapper.in("market_id", marketIds);
// queryWrapper.eq("operation","1");
// queryWrapper.ge("trading_time", start.getTime());
// queryWrapper.le("trading_time", end.getTime());
List<String> operations = new ArrayList<>();
operations.add(AdminConstant.OperationEnum.BUY.getCode().toString());
operations.add(AdminConstant.OperationEnum.INCREASE.getCode().toString());
queryWrapper.ge("trading_time", start.getTime());
queryWrapper.le("trading_time", end.getTime());
queryWrapper.and(w -> w.in("market_id", marketIds));
queryWrapper.and(w -> w.in("operation", operations));
return list(queryWrapper);
}
@Override
public List<ChiefStockInputLog> queryPreToday(String marketType, String operation) {
//例如:17号买的 18号0-9点之间都可以
Calendar start = Calendar.getInstance();
start.setTime(new Date());
start.set(Calendar.HOUR_OF_DAY, 0);
start.set(Calendar.MINUTE, 1);
start.set(Calendar.SECOND, 0);
start.add(Calendar.DATE, -1);
start.set(Calendar.MILLISECOND, 0);
Calendar end = Calendar.getInstance();
end.setTime(new Date());
end.set(Calendar.HOUR_OF_DAY, 23);
end.set(Calendar.MINUTE, 59);
end.set(Calendar.SECOND, 59);
end.add(Calendar.DATE, -1);
end.set(Calendar.MILLISECOND, 0);
//获取结束时间,为昨天最后时间,精确到毫秒级别
Date beginDate = start.getTime();
Date endDate = end.getTime();
QueryWrapper<ChiefStockInputLog> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("operation", operation);
queryWrapper.eq("market_type", marketType);
queryWrapper.ge("trading_time", beginDate);
queryWrapper.le("trading_time", endDate);
return list(queryWrapper);
}
@Override
public List<ChiefStockInputLog> all() {
return list();
}
@Override
public void updateAA(ChiefStockInputLog stockInputLog) {
updateById(stockInputLog);
}
/**
* 将操作日志转换成股票持仓对象
*
* @param stockInputLog
* @return
*/
private ChiefStockPosition convertStockInputLog2StockPosition(ChiefStockInputLog stockInputLog) {
long customerId = stockInputLog.getCustomerId();
long productId = stockInputLog.getProductId();
String code = stockInputLog.getCode();
Integer operation = stockInputLog.getOperation();
ChiefStockPosition stockPosition = new ChiefStockPosition();
if (operation == SELL.getCode()) {
stockPosition.setCount(-stockInputLog.getCount());
} else {
stockPosition.setCount(stockInputLog.getCount());
}
stockPosition.setCustomerId(customerId);
stockPosition.setCode(code);
stockPosition.setMarketId(stockInputLog.getMarketId());
stockPosition.setCost(stockInputLog.getCost());
stockPosition.setName(stockInputLog.getStockName());
stockPosition.setProductId(productId);
stockPosition.setId(stockInputLog.getStockPositionId());
return stockPosition;
}
private List<ChiefStockInputLog> pageStockInputLogs(ChiefQueryStockInputLogBO queryStockInputLogBO, boolean isPagingQuery) {
//分页查询
Map<String, Object> param = createParam(queryStockInputLogBO);
PageHelper.startPage(queryStockInputLogBO.getPageNo(), queryStockInputLogBO.getPageSize());
List<ChiefStockInputLog> stockInputLogs = getBaseMapper().queryStockInputLogs(param);
if (!CollectionUtils.isEmpty(stockInputLogs)) {
//操作映射
Map<Integer, String> operationCodeAndDescMapping = new HashMap<>();
for (AdminConstant.OperationEnum tem : EnumSet.allOf(AdminConstant.OperationEnum.class)) {
operationCodeAndDescMapping.put(tem.getCode(), tem.getDesc());
}
//产品类型映射
Map<String, String> productTypeCodeAndDescMapping = new HashMap<>();
for (AdminConstant.MemberProductTypeEnum tem : EnumSet.allOf(AdminConstant.MemberProductTypeEnum.class)) {
productTypeCodeAndDescMapping.put(tem.getCode(), tem.getDesc());
}
for (ChiefStockInputLog stockInputLog : stockInputLogs) {
stockInputLog.setOperationDesc(operationCodeAndDescMapping.get(stockInputLog.getOperation()));
stockInputLog.setProductTypeDesc(productTypeCodeAndDescMapping.get(stockInputLog.getProductType()));
}
}
return stockInputLogs;
}
private Map<String, Object> createParam(ChiefQueryStockInputLogBO queryStockInputLogBO) {
Map<String, Object> param = new HashMap<>();
String productId = queryStockInputLogBO.getProductId();
String productType = queryStockInputLogBO.getProductType();
String customerId = queryStockInputLogBO.getCustomerId();
Integer operation = queryStockInputLogBO.getOperation();
Long tradingTimeLowerLimit = queryStockInputLogBO.getTradingTimeLowerLimit();
Long tradingTimeUpperLimit = queryStockInputLogBO.getTradingTimeUpperLimit();
String code = queryStockInputLogBO.getCode();
String marketId = queryStockInputLogBO.getMarketId();
Integer companyId = queryStockInputLogBO.getCompanyId();
String marketType = queryStockInputLogBO.getMarketType();
if (companyId != null) {
param.put("companyId", companyId);
}
if (StringUtils.isNotBlank(marketId)) {
param.put("marketId", marketId);
}
if (StringUtils.isNotBlank(customerId)) {
param.put("customerId", customerId);
}
if (StringUtils.isNotBlank(productId)) {
param.put("productId", productId);
}
if (operation != null) {
param.put("operation", operation);
}
if (StringUtils.isNotBlank(code)) {
param.put("code", code);
}
//因为这个查询是时间戳直接查询,所以使用秒
if (tradingTimeLowerLimit != null) {
param.put("tradingTimeLowerLimit", tradingTimeLowerLimit / 1000);
}
if (tradingTimeUpperLimit != null) {
param.put("tradingTimeUpperLimit", tradingTimeUpperLimit / 1000);
}
//若只给出查询类型
// if (StringUtils.isBlank(productId) && StringUtils.isNotBlank(productType)) {
// List<Product> products = productService.queryProductByType(productType);
// List<Integer> productIds = products.stream().map(Product::getId).collect(Collectors.toList());
// queryWrapper.in("product_id", productIds);
// }
if (marketType != null) {
param.put("marketType", marketType);
}
//添加排序
String orderBy = "modify_time DESC";
param.put("orderBy", orderBy);
return param;
}
}
This source diff could not be displayed because it is too large. You can view the blob instead.
package com.zfxftech.telmarket.service.impl.business.chief;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.zfxftech.telmarket.common.bean.CommonPage;
import com.zfxftech.telmarket.common.pojo.dao.Quote;
import com.zfxftech.telmarket.common.pojo.dao.StockProfitLog;
import com.zfxftech.telmarket.common.pojo.dao.chief.ChiefStockProfitLog;
import com.zfxftech.telmarket.common.pojo.request.chief.ChiefQueryStockProfitLogBO;
import com.zfxftech.telmarket.common.pojo.vo.chief.ChiefStockProfitLogVO;
import com.zfxftech.telmarket.common.util.LambdaOrderUtil;
import com.zfxftech.telmarket.mapper.business.chief.ChiefStockProfitLogMapper;
import com.zfxftech.telmarket.service.business.StockCodeService;
import com.zfxftech.telmarket.service.business.chief.ChiefStockProfitLogService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* 个股收益分析
*
* @author jianghua
* @version 1.0
* @date 2021-08-24 15:55
*/
@Service
public class ChiefStockProfitLogServiceImpl extends ServiceImpl<ChiefStockProfitLogMapper, ChiefStockProfitLog> implements ChiefStockProfitLogService {
@Autowired
private StockCodeService stockCodeService;
@Transactional(propagation = Propagation.REQUIRED)
@Override
public void add(ChiefStockProfitLog stockProfitLog) {
save(stockProfitLog);
}
@Transactional(propagation = Propagation.SUPPORTS)
@Override
public CommonPage<ChiefStockProfitLogVO> queryStockProfitLogs4page(ChiefQueryStockProfitLogBO queryStockProfitLogBO) {
PageHelper.startPage(queryStockProfitLogBO.getPageNo(), queryStockProfitLogBO.getPageSize());
List<ChiefStockProfitLog> stockProfitLogs = queryStockProfitLogsSort(queryStockProfitLogBO);
PageInfo<ChiefStockProfitLog> pageInfo = new PageInfo<ChiefStockProfitLog>(stockProfitLogs);
CommonPage<ChiefStockProfitLogVO> commonPage = new CommonPage();
commonPage.setTotalPage(pageInfo.getPages());
commonPage.setPageNum(pageInfo.getPageNum());
commonPage.setPageSize(pageInfo.getPageSize());
commonPage.setTotal(pageInfo.getTotal());
List<String> codes = stockProfitLogs.stream().map(ChiefStockProfitLog::getCode).collect(Collectors.toList());
Map<String, Quote> codeAndPriceMapping = stockCodeService.batchQueryStockPrice(codes);
for (ChiefStockProfitLog stockProfitLog : stockProfitLogs) {
String code = stockProfitLog.getCode();
if (codeAndPriceMapping.containsKey(code)) {
Quote quote = codeAndPriceMapping.get(code);
stockProfitLog.setName(quote.getName());
}
}
commonPage.setList(createStockProfitLogVO(stockProfitLogs));
// List<String> codes = stockProfitLogs.stream().map(StockProfitLog::getCode).collect(Collectors.toList());
// //批量获取股票当前价格
// Map<String, Quote> codeAndPriceMapping = stockCodeService.batchQueryStockPrice(codes);
// for (StockProfitLog stockProfitLog : stockProfitLogs) {
// String code = stockProfitLog.getCode();
// if (codeAndPriceMapping.containsKey(code)) {
// Quote quote = codeAndPriceMapping.get(code);
// stockProfitLog.setName(quote.getName());
// }
// }
return commonPage;
}
@Transactional(propagation = Propagation.SUPPORTS)
@Override
public List<ChiefStockProfitLog> queryStockProfitLogs(Long marketId) {
LambdaQueryWrapper<ChiefStockProfitLog> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper
.and(i->i.eq(ChiefStockProfitLog::getCode,"601005").gt(ChiefStockProfitLog::getCreatedTime,"2022-04-17 23:59:59").lt(ChiefStockProfitLog::getCreatedTime,"2022-04-01 00:00:00"))
.or(i->i.ne(ChiefStockProfitLog::getCode,"601005"))
.and(i->i.eq(ChiefStockProfitLog::getMarketId,marketId));
// QueryWrapper<StockProfitLog> queryWrapper = new QueryWrapper();
// queryWrapper.eq("market_id", marketId);
return list(queryWrapper);
}
@Transactional(propagation = Propagation.SUPPORTS)
@Override
public List<ChiefStockProfitLog> queryStockProfitLogsSort(ChiefQueryStockProfitLogBO queryStockProfitLogBO) {
LambdaQueryWrapper<ChiefStockProfitLog> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper
.and(i->i.eq(ChiefStockProfitLog::getCode,"601005").gt(ChiefStockProfitLog::getCreatedTime,"2022-04-17 23:59:59").lt(ChiefStockProfitLog::getCreatedTime,"2022-04-01 00:00:00"))
.or(i->i.ne(ChiefStockProfitLog::getCode,"601005"))
.and(i->i.eq(ChiefStockProfitLog::getMarketId,queryStockProfitLogBO.getMarketId()));
//.orderBy(true,queryStockProfitLogBO.getSortBoolean(), StringUtils.isEmpty(queryStockProfitLogBO.getBuyingTimeSortName()) ? StockProfitLog::getSellingTime : StockProfitLog::getBuyingTime);
LambdaOrderUtil.setOrderBy(
queryStockProfitLogBO.getOrderBy(),
queryWrapper,
StockProfitLog.class);
// QueryWrapper<StockProfitLog> queryWrapper = new QueryWrapper();
// queryWrapper.eq("market_id", marketId);
return list(queryWrapper);
}
@Transactional(propagation = Propagation.SUPPORTS)
@Override
public List<ChiefStockProfitLog> queryStockProfitLogs(List<Long> positionIds) {
QueryWrapper<ChiefStockProfitLog> queryWrapper = new QueryWrapper();
queryWrapper.in("position_id", positionIds);
return list(queryWrapper);
}
private List<ChiefStockProfitLogVO> createStockProfitLogVO(List<ChiefStockProfitLog> stockProfitLogs) {
List<ChiefStockProfitLogVO> stockProfitLogVOS = new ArrayList<>();
for (ChiefStockProfitLog stockProfitLog : stockProfitLogs) {
ChiefStockProfitLogVO stockProfitLogVO = new ChiefStockProfitLogVO();
stockProfitLogVO.setBuyingTime(stockProfitLog.getBuyingTime().getTime());
stockProfitLogVO.setSellingTime(stockProfitLog.getSellingTime().getTime());
stockProfitLogVO.setCode(stockProfitLog.getCode());
stockProfitLogVO.setHoldingDays(stockProfitLog.getHoldingDays());
stockProfitLogVO.setProfitPrice(stockProfitLog.getProfitPrice().toPlainString());
stockProfitLogVO.setProfitRatio(stockProfitLog.getProfitRatio().toPlainString());
stockProfitLogVO.setName(stockProfitLog.getName());
stockProfitLogVO.setBuyingRoute("未使用");
stockProfitLogVO.setSellingRoute("未使用");
stockProfitLogVOS.add(stockProfitLogVO);
}
return stockProfitLogVOS;
}
}
package com.zfxftech.telmarket.task.followAccount;
import com.zfxftech.telmarket.common.config.CommonConfig;
import com.zfxftech.telmarket.common.pojo.dao.MemberBase;
import com.zfxftech.telmarket.common.pojo.dao.chief.ChiefAccountProductRelation;
import com.zfxftech.telmarket.common.pojo.dao.chief.ChiefStockPosition;
import com.zfxftech.telmarket.common.pojo.vo.chief.ChiefMarketDetailsVO;
import com.zfxftech.telmarket.common.util.DateUtil;
import com.zfxftech.telmarket.common.util.OptionalUtil;
import com.zfxftech.telmarket.service.business.UsMemberBaseService;
import com.zfxftech.telmarket.service.business.chief.ChiefAccountProductRelationService;
import com.zfxftech.telmarket.service.business.chief.ChiefStockPositionService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicReference;
import static com.zfxftech.telmarket.common.constant.AdminConstant.MarketTypeEnum.REAL;
import static com.zfxftech.telmarket.common.constant.AdminConstant.MarketTypeEnum.SIMULATED;
/**
* Create time: 2022/1/26
*/
@Slf4j
@Component
@Order(value = 1)
/**
* 首席定制计算总市值、股票市值、持仓数量
*/
public class ChiefStockPriceTask implements ApplicationRunner {
@Autowired
private ChiefAccountProductRelationService accountProductRelationService;
@Autowired
private ChiefStockPositionService stockPositionService;
@Autowired
private CommonConfig commonConfig;
@Autowired
private UsMemberBaseService memberBaseService;
@Override
public void run(ApplicationArguments args) throws Exception {
log.info("高端定制计算股票统计日志开始");
//log.info("私人定制计算股票统计日志开始配置更新开关状态:" + commonConfig.getStockPriceTask());
if (commonConfig.getChiefStockPriceTask() != null && commonConfig.getChiefStockPriceTask().equals("run")) {
//if (true) {
//分页查询异动配置列表
ExecutorService PersonalexecutorService = Executors.newSingleThreadExecutor();
ExecutorService executorServicePersonal = Executors.newFixedThreadPool(100);
CompletableFuture.runAsync(() -> {
while (true) {
if (DateUtil.isTradeDayForChangeRemind() && commonConfig.getChiefStockPriceTask().equals("run")) {
// if (true) {
AtomicReference<Integer> pageNo = new AtomicReference<>(1);
Integer pageSize = 50;
Date startTime = new Date();
List<CompletableFuture<String>> futureList = new ArrayList<>();
List<ChiefAccountProductRelation> accountProductRelations = accountProductRelationService.queryAll();
if (!ObjectUtils.isEmpty(accountProductRelations) && accountProductRelations.size() > 0) {
log.info("高端定制计算股票统计数据大小:{}", accountProductRelations.size());
Integer pageTOtl = accountProductRelations.size() % pageSize == 0 ? accountProductRelations.size() / pageSize : accountProductRelations.size() / pageSize + 1;
for (Integer i = 0; i < pageTOtl; i++) {
List<ChiefAccountProductRelation> accountProductRelationList = this.page(accountProductRelations, pageNo.get(), pageSize);
CompletableFuture cf = CompletableFuture.supplyAsync(() -> {
List<ChiefAccountProductRelation> list = new ArrayList<>();
for (ChiefAccountProductRelation accountProductRelation : accountProductRelationList) {
ChiefAccountProductRelation productRelation = this.AccountProductRelationTask(accountProductRelation);
if (!ObjectUtils.isEmpty(productRelation) && !ObjectUtils.isEmpty(productRelation.getId())) {
list.add(productRelation);
}
}
accountProductRelationService.updateBatchById(list);
return " ";
}, executorServicePersonal).handle((result, ex) -> {
if (null != ex) {
log.error("高端定制错误消息:{}", ex);
return 0;
} else {
return result;
}
});
futureList.add(cf);
pageNo.set(pageNo.get() + 1);
}
}
try {
CompletableFuture<Void> combinedFuture = CompletableFuture.allOf(futureList.toArray(new CompletableFuture[0]));
combinedFuture.get();
log.info("持仓统计--------主线程开始阻塞,消息发送完成--------");
log.info("高端定制持仓统计,本次共计算" + (ObjectUtils.isEmpty(accountProductRelations) == true ? 0 : accountProductRelations.size()) + "持仓统计。耗时" + DateUtil.calculateTimeGapSecond(startTime, new Date()) + "秒");
} catch (Exception e) {
log.error("持仓统计错误信息:{}", e);
e.printStackTrace();
}
try {
Thread.sleep(600000);
} catch (Exception e) {
e.printStackTrace();
}
} else {
try {
Thread.sleep(1200000);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}, PersonalexecutorService);
}
}
public List<ChiefAccountProductRelation> page(List<ChiefAccountProductRelation> list, Integer pageNo, Integer pageSize) {
if (CollectionUtils.isEmpty(list)) {
return list;
}
List<ChiefAccountProductRelation> resultList = new ArrayList();
// 所有dataList数据中的第几条
int currIdx = pageNo > 1 ? (pageNo - 1) * pageSize : 0;
for (int i = 0; i < pageSize && i < list.size() - currIdx; i++) {
resultList.add(list.get(currIdx + i));
}
return resultList;
}
//高端定制
public ChiefAccountProductRelation AccountProductRelationTask(ChiefAccountProductRelation accountProductRelation) {
ChiefAccountProductRelation productRelation = new ChiefAccountProductRelation();
try {
String type = SIMULATED.getCode();
OptionalUtil.checkNull(accountProductRelation, "当前用户产品关系不存在");
//查询客户信息
Long customerId = accountProductRelation.getCustomerId();
MemberBase memberBase = memberBaseService.queryUsMemberBaseById(customerId);
Long marketId = accountProductRelation.getSimulatedMarketId();
OptionalUtil.checkNull(memberBase, "查询用户数据不存在");
//查询持仓信息
BigDecimal funding = null;
//获取可用资金
if (REAL.getCode().equals(type)) {
funding = accountProductRelation.getRealFunding();
}
if (SIMULATED.getCode().equals(type)) {
funding = accountProductRelation.getSimulatedFunding();
}
//获取所有买入过的股票
List<ChiefStockPosition> stockPositions = stockPositionService.queryStockPositions(marketId);
//汇总数据
ChiefMarketDetailsVO marketDetailsVO = stockPositionService.createMarketDetailsVOTask(stockPositions, funding, accountProductRelation);
productRelation.setId(accountProductRelation.getId());
if (!ObjectUtils.isEmpty(marketDetailsVO.getTotalProfitRate())) {
productRelation.setSimulatedTotalProfit(new BigDecimal(marketDetailsVO.getTotalProfitRate()));
}
if (!ObjectUtils.isEmpty(marketDetailsVO.getTotalPrice())) {
//示范盘总资产
productRelation.setSimulatedTotalPrice(new BigDecimal(marketDetailsVO.getTotalPrice()));
}
if (!ObjectUtils.isEmpty(marketDetailsVO.getPosition())) {
//示范持仓比
productRelation.setSimulatedProportion(new BigDecimal(marketDetailsVO.getPosition()));
}
//示范盘持仓数量
productRelation.setPositionCount(ObjectUtils.isEmpty(stockPositions.size()) ? 0 : stockPositions.size());
if (!ObjectUtils.isEmpty(marketDetailsVO.getTotalProfit())) {
//示范盘盈亏金额
productRelation.setProfitAmount(new BigDecimal(marketDetailsVO.getTotalProfit()));
}
} catch (Exception e) {
log.error("高端定制更新数据错误:{}", e);
}
return productRelation;
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment