fix: qoder增加新的数据结构及相关类;新增三个接口;新增前端页面;尚存问题:数据导入失败;原接口无法使用

dev_refactor_0120_qoder
Lxy 4 months ago
parent 698887cba5
commit 26dc129099

@ -0,0 +1,380 @@
package com.ruoyi.newstocksystem.controller;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import javax.servlet.http.HttpServletResponse;
import com.ruoyi.newstocksystem.domain.TIndustryIndex;
import com.ruoyi.newstocksystem.domain.TStockBasic;
import com.ruoyi.newstocksystem.domain.TStockDailyTrade;
import com.ruoyi.newstocksystem.domain.TStockHighLowStatus;
import com.ruoyi.newstocksystem.service.IIndustryIndexService;
import com.ruoyi.newstocksystem.service.IStockBasicService;
import com.ruoyi.newstocksystem.service.IStockDailyTradeService;
import com.ruoyi.newstocksystem.service.IStockHighLowStatusService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.common.core.page.TableDataInfo;
import org.springframework.web.multipart.MultipartFile;
/**
* Controller
*
* @author lxy
* @date 2026-01-21
*/
@RestController
@RequestMapping("/newstocksystem/stockdata")
public class StockDataController extends BaseController
{
@Autowired
private IIndustryIndexService industryIndexService;
@Autowired
private IStockBasicService stockBasicService;
@Autowired
private IStockDailyTradeService stockDailyTradeService;
@Autowired
private IStockHighLowStatusService stockHighLowStatusService;
// ========================= 行业指数相关接口 =========================
/**
*
*/
@GetMapping("/industryIndex/list")
public TableDataInfo listIndustryIndex(TIndustryIndex industryIndex)
{
startPage();
List<TIndustryIndex> list = industryIndexService.selectIndustryIndexList(industryIndex);
return getDataTable(list);
}
/**
*
*/
@GetMapping("/industryIndex/distinctList")
public AjaxResult distinctIndustryIndexList()
{
List<TIndustryIndex> list = industryIndexService.selectDistinctIndustryIndexList();
return AjaxResult.success(list);
}
/**
*
*/
@PostMapping("/industryIndex/export")
public void exportIndustryIndex(HttpServletResponse response, TIndustryIndex industryIndex)
{
List<TIndustryIndex> list = industryIndexService.selectIndustryIndexList(industryIndex);
ExcelUtil<TIndustryIndex> util = new ExcelUtil<TIndustryIndex>(TIndustryIndex.class);
util.exportExcel(response, list, "行业指数数据");
}
/**
* xlsx1
*
* @param file Excel
* @param updateSupport
* @param tradeDate yyyy-MM-dd
*/
@Log(title = "行业指数数据导入", businessType = BusinessType.IMPORT)
@PostMapping("/industryIndex/importData")
public AjaxResult importIndustryIndex(MultipartFile file, boolean updateSupport, String tradeDate)
{
Date tradeDateValue = parseTradeDate(tradeDate);
if (tradeDateValue == null)
{
return AjaxResult.error("交易日期格式错误请使用yyyy-MM-dd格式");
}
ExcelUtil<TIndustryIndex> util = new ExcelUtil<TIndustryIndex>(TIndustryIndex.class);
try
{
List<TIndustryIndex> industryIndexList = util.importExcel(file.getInputStream());
int successNum = industryIndexService.importIndustryIndex(industryIndexList, tradeDateValue);
return AjaxResult.success("成功导入 " + successNum + " 条行业指数数据");
}
catch (Exception e)
{
return AjaxResult.error("导入失败:" + e.getMessage());
}
}
/**
*
*/
@GetMapping("/industryIndex/tradeDates")
public AjaxResult getIndustryIndexTradeDates()
{
List<String> tradeDates = industryIndexService.selectTradeDates();
return AjaxResult.success(tradeDates);
}
// ========================= 个股基础信息相关接口 =========================
/**
*
*/
@GetMapping("/stockBasic/list")
public TableDataInfo listStockBasic(TStockBasic stockBasic)
{
startPage();
List<TStockBasic> list = stockBasicService.selectStockBasicList(stockBasic);
return getDataTable(list);
}
/**
*
*/
@GetMapping("/stockBasic/{stockCode}")
public AjaxResult getStockBasicInfo(@PathVariable("stockCode") String stockCode)
{
return AjaxResult.success(stockBasicService.selectStockBasicByCode(stockCode));
}
/**
*
*/
@PostMapping("/stockBasic/export")
public void exportStockBasic(HttpServletResponse response, TStockBasic stockBasic)
{
List<TStockBasic> list = stockBasicService.selectStockBasicList(stockBasic);
ExcelUtil<TStockBasic> util = new ExcelUtil<TStockBasic>(TStockBasic.class);
util.exportExcel(response, list, "个股基础信息数据");
}
/**
* xlsx2
*
* @param file Excel
* @param updateSupport
*/
@Log(title = "个股基础信息导入", businessType = BusinessType.IMPORT)
@PostMapping("/stockBasic/importData")
public AjaxResult importStockBasic(MultipartFile file, boolean updateSupport)
{
ExcelUtil<TStockBasic> util = new ExcelUtil<TStockBasic>(TStockBasic.class);
try
{
List<TStockBasic> stockBasicList = util.importExcel(file.getInputStream());
int successNum = stockBasicService.importStockBasic(stockBasicList);
return AjaxResult.success("成功导入 " + successNum + " 条个股基础信息数据");
}
catch (Exception e)
{
return AjaxResult.error("导入失败:" + e.getMessage());
}
}
/**
*
*/
@Log(title = "个股基础信息", businessType = BusinessType.INSERT)
@PostMapping("/stockBasic")
public AjaxResult addStockBasic(@RequestBody TStockBasic stockBasic)
{
return toAjax(stockBasicService.insertStockBasic(stockBasic));
}
/**
*
*/
@Log(title = "个股基础信息", businessType = BusinessType.UPDATE)
@PutMapping("/stockBasic")
public AjaxResult editStockBasic(@RequestBody TStockBasic stockBasic)
{
return toAjax(stockBasicService.updateStockBasic(stockBasic));
}
/**
*
*/
@Log(title = "个股基础信息", businessType = BusinessType.DELETE)
@DeleteMapping("/stockBasic/{stockCodes}")
public AjaxResult removeStockBasic(@PathVariable String[] stockCodes)
{
return toAjax(stockBasicService.deleteStockBasicByCodes(stockCodes));
}
// ========================= 个股每日交易数据相关接口 =========================
/**
*
*/
@GetMapping("/stockDailyTrade/list")
public TableDataInfo listStockDailyTrade(TStockDailyTrade stockDailyTrade)
{
startPage();
List<TStockDailyTrade> list = stockDailyTradeService.selectStockDailyTradeList(stockDailyTrade);
return getDataTable(list);
}
/**
*
*/
@GetMapping("/stockDailyTrade/listWithBasic")
public TableDataInfo listStockDailyTradeWithBasic(TStockDailyTrade stockDailyTrade)
{
startPage();
List<TStockDailyTrade> list = stockDailyTradeService.selectStockDailyTradeListWithBasic(stockDailyTrade);
return getDataTable(list);
}
/**
*
*/
@PostMapping("/stockDailyTrade/export")
public void exportStockDailyTrade(HttpServletResponse response, TStockDailyTrade stockDailyTrade)
{
List<TStockDailyTrade> list = stockDailyTradeService.selectStockDailyTradeList(stockDailyTrade);
ExcelUtil<TStockDailyTrade> util = new ExcelUtil<TStockDailyTrade>(TStockDailyTrade.class);
util.exportExcel(response, list, "个股每日交易数据");
}
/**
* xlsx3
*
* @param file Excel
* @param updateSupport
* @param tradeDate yyyy-MM-dd
*/
@Log(title = "个股每日交易数据导入", businessType = BusinessType.IMPORT)
@PostMapping("/stockDailyTrade/importData")
public AjaxResult importStockDailyTrade(MultipartFile file, boolean updateSupport, String tradeDate)
{
Date tradeDateValue = parseTradeDate(tradeDate);
if (tradeDateValue == null)
{
return AjaxResult.error("交易日期格式错误请使用yyyy-MM-dd格式");
}
ExcelUtil<TStockDailyTrade> util = new ExcelUtil<TStockDailyTrade>(TStockDailyTrade.class);
try
{
List<TStockDailyTrade> stockDailyTradeList = util.importExcel(file.getInputStream());
int successNum = stockDailyTradeService.importStockDailyTrade(stockDailyTradeList, tradeDateValue);
return AjaxResult.success("成功导入 " + successNum + " 条个股每日交易数据");
}
catch (Exception e)
{
return AjaxResult.error("导入失败:" + e.getMessage());
}
}
/**
*
*/
@GetMapping("/stockDailyTrade/tradeDates")
public AjaxResult getStockDailyTradeDates()
{
List<String> tradeDates = stockDailyTradeService.selectTradeDates();
return AjaxResult.success(tradeDates);
}
/**
*
*/
@GetMapping("/stockDailyTrade/limitUpList")
public TableDataInfo listLimitUpStocks(TStockDailyTrade stockDailyTrade)
{
startPage();
List<TStockDailyTrade> list = stockDailyTradeService.selectLimitUpStockList(stockDailyTrade);
return getDataTable(list);
}
/**
*
*/
@GetMapping("/stockDailyTrade/strongList")
public TableDataInfo listStrongStocks(TStockDailyTrade stockDailyTrade)
{
startPage();
List<TStockDailyTrade> list = stockDailyTradeService.selectStrongStockList(stockDailyTrade);
return getDataTable(list);
}
// ========================= 个股新高新低状态相关接口 =========================
/**
*
*/
@GetMapping("/stockHighLow/list")
public TableDataInfo listStockHighLowStatus(TStockHighLowStatus stockHighLowStatus)
{
startPage();
List<TStockHighLowStatus> list = stockHighLowStatusService.selectStockHighLowStatusList(stockHighLowStatus);
return getDataTable(list);
}
/**
*
*/
@GetMapping("/stockHighLow/listWithBasic")
public TableDataInfo listStockHighLowStatusWithBasic(TStockHighLowStatus stockHighLowStatus)
{
startPage();
List<TStockHighLowStatus> list = stockHighLowStatusService.selectStockHighLowStatusListWithBasic(stockHighLowStatus);
return getDataTable(list);
}
/**
*
*/
@GetMapping("/stockHighLow/newHighList")
public TableDataInfo listNewHighStocks(TStockHighLowStatus stockHighLowStatus)
{
startPage();
List<TStockHighLowStatus> list = stockHighLowStatusService.selectNewHighStockList(stockHighLowStatus);
return getDataTable(list);
}
/**
*
*/
@GetMapping("/stockHighLow/newLowList")
public TableDataInfo listNewLowStocks(TStockHighLowStatus stockHighLowStatus)
{
startPage();
List<TStockHighLowStatus> list = stockHighLowStatusService.selectNewLowStockList(stockHighLowStatus);
return getDataTable(list);
}
// ========================= 工具方法 =========================
/**
*
*/
private Date parseTradeDate(String tradeDate)
{
if (tradeDate == null || tradeDate.isEmpty())
{
return null;
}
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
try
{
return sdf.parse(tradeDate);
}
catch (ParseException e)
{
return null;
}
}
}

@ -0,0 +1,223 @@
package com.ruoyi.newstocksystem.domain;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.ruoyi.common.annotation.Excel;
import com.ruoyi.common.core.domain.BaseEntity;
import java.math.BigDecimal;
import java.util.Date;
/**
*
* t_industry_index
*
* @author lxy
* @date 2026-01-21
*/
public class TIndustryIndex extends BaseEntity
{
private static final long serialVersionUID = 1L;
/** 行业指数代码如802089.EI */
@Excel(name = "行业指数代码")
private String industryIndexCode;
/** 行业指数名称(如"银行" */
@Excel(name = "行业指数名称")
private String industryIndexName;
/** 成份个数(行业包含个股数量) */
@Excel(name = "成份个数")
private Integer componentCount;
/** 交易日期 */
@JsonFormat(pattern = "yyyy-MM-dd")
@Excel(name = "交易日期", dateFormat = "yyyy-MM-dd")
private Date tradeDate;
/** 开盘价(指数点位) */
@Excel(name = "开盘价")
private BigDecimal openPrice;
/** 收盘价(指数点位) */
@Excel(name = "收盘价")
private BigDecimal closePrice;
/** 成交量(指数成交总量) */
@Excel(name = "成交量")
private Long volume;
/** 成交额(单位:万元) */
@Excel(name = "成交额")
private BigDecimal turnover;
/** 总市值(单位:万元) */
@Excel(name = "总市值")
private BigDecimal totalMarketCap;
/** 自由流通市值(单位:万元) */
@Excel(name = "自由流通市值")
private BigDecimal freeCirculationCap;
/** 涨跌幅百分比如1.2937=1.2937% */
@Excel(name = "涨跌幅")
private BigDecimal priceChangeRate;
/** 市盈率PE(TTM) */
@Excel(name = "市盈率PE(TTM)")
private BigDecimal peTtm;
/** 市盈率PE(TTM)中位值 */
@Excel(name = "市盈率PE(TTM)中位值")
private BigDecimal peTtmMedian;
public String getIndustryIndexCode()
{
return industryIndexCode;
}
public void setIndustryIndexCode(String industryIndexCode)
{
this.industryIndexCode = industryIndexCode;
}
public String getIndustryIndexName()
{
return industryIndexName;
}
public void setIndustryIndexName(String industryIndexName)
{
this.industryIndexName = industryIndexName;
}
public Integer getComponentCount()
{
return componentCount;
}
public void setComponentCount(Integer componentCount)
{
this.componentCount = componentCount;
}
public Date getTradeDate()
{
return tradeDate;
}
public void setTradeDate(Date tradeDate)
{
this.tradeDate = tradeDate;
}
public BigDecimal getOpenPrice()
{
return openPrice;
}
public void setOpenPrice(BigDecimal openPrice)
{
this.openPrice = openPrice;
}
public BigDecimal getClosePrice()
{
return closePrice;
}
public void setClosePrice(BigDecimal closePrice)
{
this.closePrice = closePrice;
}
public Long getVolume()
{
return volume;
}
public void setVolume(Long volume)
{
this.volume = volume;
}
public BigDecimal getTurnover()
{
return turnover;
}
public void setTurnover(BigDecimal turnover)
{
this.turnover = turnover;
}
public BigDecimal getTotalMarketCap()
{
return totalMarketCap;
}
public void setTotalMarketCap(BigDecimal totalMarketCap)
{
this.totalMarketCap = totalMarketCap;
}
public BigDecimal getFreeCirculationCap()
{
return freeCirculationCap;
}
public void setFreeCirculationCap(BigDecimal freeCirculationCap)
{
this.freeCirculationCap = freeCirculationCap;
}
public BigDecimal getPriceChangeRate()
{
return priceChangeRate;
}
public void setPriceChangeRate(BigDecimal priceChangeRate)
{
this.priceChangeRate = priceChangeRate;
}
public BigDecimal getPeTtm()
{
return peTtm;
}
public void setPeTtm(BigDecimal peTtm)
{
this.peTtm = peTtm;
}
public BigDecimal getPeTtmMedian()
{
return peTtmMedian;
}
public void setPeTtmMedian(BigDecimal peTtmMedian)
{
this.peTtmMedian = peTtmMedian;
}
@Override
public String toString()
{
return "TIndustryIndex{" +
"industryIndexCode='" + industryIndexCode + '\'' +
", industryIndexName='" + industryIndexName + '\'' +
", componentCount=" + componentCount +
", tradeDate=" + tradeDate +
", openPrice=" + openPrice +
", closePrice=" + closePrice +
", volume=" + volume +
", turnover=" + turnover +
", totalMarketCap=" + totalMarketCap +
", freeCirculationCap=" + freeCirculationCap +
", priceChangeRate=" + priceChangeRate +
", peTtm=" + peTtm +
", peTtmMedian=" + peTtmMedian +
'}';
}
}

@ -0,0 +1,147 @@
package com.ruoyi.newstocksystem.domain;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.ruoyi.common.annotation.Excel;
import com.ruoyi.common.core.domain.BaseEntity;
import java.util.Date;
/**
*
* t_stock_basic
*
* @author lxy
* @date 2026-01-21
*/
public class TStockBasic extends BaseEntity
{
private static final long serialVersionUID = 1L;
/** 证券代码如000061.SZ、600000.SH */
@Excel(name = "证券代码")
private String stockCode;
/** 证券名称(如"农 产 品" */
@Excel(name = "证券名称")
private String stockName;
/** 首发上市日期 */
@JsonFormat(pattern = "yyyy-MM-dd")
@Excel(name = "首发上市日期", dateFormat = "yyyy-MM-dd")
private Date listingDate;
/** 上市天数(冗余存储,提升查询效率) */
@Excel(name = "上市天数")
private Integer listingDays;
/** 是否为ST股票1=是0=否) */
@Excel(name = "是否ST", readConverterExp = "1=是,0=否")
private Integer isSt;
/** 是否为*ST股票1=是0=否) */
@Excel(name = "是否*ST", readConverterExp = "1=是,0=否")
private Integer isStarSt;
/** 所属行业指数代码关联t_industry_index */
@Excel(name = "行业指数代码")
private String industryIndexCode;
/** 所属行业指数名称(冗余存储,减少关联查询) */
@Excel(name = "行业指数名称")
private String industryIndexName;
public String getStockCode()
{
return stockCode;
}
public void setStockCode(String stockCode)
{
this.stockCode = stockCode;
}
public String getStockName()
{
return stockName;
}
public void setStockName(String stockName)
{
this.stockName = stockName;
}
public Date getListingDate()
{
return listingDate;
}
public void setListingDate(Date listingDate)
{
this.listingDate = listingDate;
}
public Integer getListingDays()
{
return listingDays;
}
public void setListingDays(Integer listingDays)
{
this.listingDays = listingDays;
}
public Integer getIsSt()
{
return isSt;
}
public void setIsSt(Integer isSt)
{
this.isSt = isSt;
}
public Integer getIsStarSt()
{
return isStarSt;
}
public void setIsStarSt(Integer isStarSt)
{
this.isStarSt = isStarSt;
}
public String getIndustryIndexCode()
{
return industryIndexCode;
}
public void setIndustryIndexCode(String industryIndexCode)
{
this.industryIndexCode = industryIndexCode;
}
public String getIndustryIndexName()
{
return industryIndexName;
}
public void setIndustryIndexName(String industryIndexName)
{
this.industryIndexName = industryIndexName;
}
@Override
public String toString()
{
return "TStockBasic{" +
"stockCode='" + stockCode + '\'' +
", stockName='" + stockName + '\'' +
", listingDate=" + listingDate +
", listingDays=" + listingDays +
", isSt=" + isSt +
", isStarSt=" + isStarSt +
", industryIndexCode='" + industryIndexCode + '\'' +
", industryIndexName='" + industryIndexName + '\'' +
'}';
}
}

@ -0,0 +1,292 @@
package com.ruoyi.newstocksystem.domain;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.ruoyi.common.annotation.Excel;
import com.ruoyi.common.core.domain.BaseEntity;
import java.math.BigDecimal;
import java.util.Date;
/**
*
* t_stock_daily_trade
*
* @author lxy
* @date 2026-01-21
*/
public class TStockDailyTrade extends BaseEntity
{
private static final long serialVersionUID = 1L;
/** 证券代码关联t_stock_basic */
@Excel(name = "证券代码")
private String stockCode;
/** 交易日期 */
@JsonFormat(pattern = "yyyy-MM-dd")
@Excel(name = "交易日期", dateFormat = "yyyy-MM-dd")
private Date tradeDate;
/** 开盘价(单位:元) */
@Excel(name = "开盘价")
private BigDecimal openPrice;
/** 收盘价(单位:元) */
@Excel(name = "收盘价")
private BigDecimal closePrice;
/** 最高价(单位:元) */
@Excel(name = "最高价")
private BigDecimal highPrice;
/** 最低价(单位:元) */
@Excel(name = "最低价")
private BigDecimal lowPrice;
/** 当日涨跌幅(百分比) */
@Excel(name = "涨跌幅")
private BigDecimal priceChangeRate;
/** 成交量(单位:股) */
@Excel(name = "成交量")
private Long volume;
/** 成交额(单位:万元) */
@Excel(name = "成交额")
private BigDecimal turnover;
/** 自由流通市值(单位:万元) */
@Excel(name = "自由流通市值")
private BigDecimal freeCirculationCap;
/** 是否涨停1=是0=否) */
@Excel(name = "是否涨停", readConverterExp = "1=是,0=否")
private Integer isLimitUp;
/** 是否跌停1=是0=否) */
@Excel(name = "是否跌停", readConverterExp = "1=是,0=否")
private Integer isLimitDown;
/** 10日动量涨跌幅 */
@Excel(name = "10日动量")
private BigDecimal momentum10d;
/** 20日动量涨跌幅 */
@Excel(name = "20日动量")
private BigDecimal momentum20d;
/** 60日动量涨跌幅 */
@Excel(name = "60日动量")
private BigDecimal momentum60d;
/** 证券名称(查询时关联获取) */
private String stockName;
/** 行业指数代码(查询时关联获取) */
private String industryIndexCode;
/** 行业指数名称(查询时关联获取) */
private String industryIndexName;
public String getStockCode()
{
return stockCode;
}
public void setStockCode(String stockCode)
{
this.stockCode = stockCode;
}
public Date getTradeDate()
{
return tradeDate;
}
public void setTradeDate(Date tradeDate)
{
this.tradeDate = tradeDate;
}
public BigDecimal getOpenPrice()
{
return openPrice;
}
public void setOpenPrice(BigDecimal openPrice)
{
this.openPrice = openPrice;
}
public BigDecimal getClosePrice()
{
return closePrice;
}
public void setClosePrice(BigDecimal closePrice)
{
this.closePrice = closePrice;
}
public BigDecimal getHighPrice()
{
return highPrice;
}
public void setHighPrice(BigDecimal highPrice)
{
this.highPrice = highPrice;
}
public BigDecimal getLowPrice()
{
return lowPrice;
}
public void setLowPrice(BigDecimal lowPrice)
{
this.lowPrice = lowPrice;
}
public BigDecimal getPriceChangeRate()
{
return priceChangeRate;
}
public void setPriceChangeRate(BigDecimal priceChangeRate)
{
this.priceChangeRate = priceChangeRate;
}
public Long getVolume()
{
return volume;
}
public void setVolume(Long volume)
{
this.volume = volume;
}
public BigDecimal getTurnover()
{
return turnover;
}
public void setTurnover(BigDecimal turnover)
{
this.turnover = turnover;
}
public BigDecimal getFreeCirculationCap()
{
return freeCirculationCap;
}
public void setFreeCirculationCap(BigDecimal freeCirculationCap)
{
this.freeCirculationCap = freeCirculationCap;
}
public Integer getIsLimitUp()
{
return isLimitUp;
}
public void setIsLimitUp(Integer isLimitUp)
{
this.isLimitUp = isLimitUp;
}
public Integer getIsLimitDown()
{
return isLimitDown;
}
public void setIsLimitDown(Integer isLimitDown)
{
this.isLimitDown = isLimitDown;
}
public BigDecimal getMomentum10d()
{
return momentum10d;
}
public void setMomentum10d(BigDecimal momentum10d)
{
this.momentum10d = momentum10d;
}
public BigDecimal getMomentum20d()
{
return momentum20d;
}
public void setMomentum20d(BigDecimal momentum20d)
{
this.momentum20d = momentum20d;
}
public BigDecimal getMomentum60d()
{
return momentum60d;
}
public void setMomentum60d(BigDecimal momentum60d)
{
this.momentum60d = momentum60d;
}
public String getStockName()
{
return stockName;
}
public void setStockName(String stockName)
{
this.stockName = stockName;
}
public String getIndustryIndexCode()
{
return industryIndexCode;
}
public void setIndustryIndexCode(String industryIndexCode)
{
this.industryIndexCode = industryIndexCode;
}
public String getIndustryIndexName()
{
return industryIndexName;
}
public void setIndustryIndexName(String industryIndexName)
{
this.industryIndexName = industryIndexName;
}
@Override
public String toString()
{
return "TStockDailyTrade{" +
"stockCode='" + stockCode + '\'' +
", tradeDate=" + tradeDate +
", openPrice=" + openPrice +
", closePrice=" + closePrice +
", highPrice=" + highPrice +
", lowPrice=" + lowPrice +
", priceChangeRate=" + priceChangeRate +
", volume=" + volume +
", turnover=" + turnover +
", freeCirculationCap=" + freeCirculationCap +
", isLimitUp=" + isLimitUp +
", isLimitDown=" + isLimitDown +
", momentum10d=" + momentum10d +
", momentum20d=" + momentum20d +
", momentum60d=" + momentum60d +
'}';
}
}

@ -0,0 +1,158 @@
package com.ruoyi.newstocksystem.domain;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.ruoyi.common.annotation.Excel;
import com.ruoyi.common.core.domain.BaseEntity;
import java.util.Date;
/**
*
* t_stock_high_low_status
*
* @author lxy
* @date 2026-01-21
*/
public class TStockHighLowStatus extends BaseEntity
{
private static final long serialVersionUID = 1L;
/** 证券代码关联t_stock_basic */
@Excel(name = "证券代码")
private String stockCode;
/** 交易日期 */
@JsonFormat(pattern = "yyyy-MM-dd")
@Excel(name = "交易日期", dateFormat = "yyyy-MM-dd")
private Date tradeDate;
/** 是否创阶段新高1=是0=否) */
@Excel(name = "是否新高", readConverterExp = "1=是,0=否")
private Integer isNewHigh;
/** 区间最高价日(创新高时填充) */
@JsonFormat(pattern = "yyyy-MM-dd")
@Excel(name = "新高日期", dateFormat = "yyyy-MM-dd")
private Date newHighDate;
/** 是否创阶段新低1=是0=否) */
@Excel(name = "是否新低", readConverterExp = "1=是,0=否")
private Integer isNewLow;
/** 区间最低价日(创新低时填充) */
@JsonFormat(pattern = "yyyy-MM-dd")
@Excel(name = "新低日期", dateFormat = "yyyy-MM-dd")
private Date newLowDate;
/** 证券名称(查询时关联获取) */
private String stockName;
/** 行业指数代码(查询时关联获取) */
private String industryIndexCode;
/** 行业指数名称(查询时关联获取) */
private String industryIndexName;
public String getStockCode()
{
return stockCode;
}
public void setStockCode(String stockCode)
{
this.stockCode = stockCode;
}
public Date getTradeDate()
{
return tradeDate;
}
public void setTradeDate(Date tradeDate)
{
this.tradeDate = tradeDate;
}
public Integer getIsNewHigh()
{
return isNewHigh;
}
public void setIsNewHigh(Integer isNewHigh)
{
this.isNewHigh = isNewHigh;
}
public Date getNewHighDate()
{
return newHighDate;
}
public void setNewHighDate(Date newHighDate)
{
this.newHighDate = newHighDate;
}
public Integer getIsNewLow()
{
return isNewLow;
}
public void setIsNewLow(Integer isNewLow)
{
this.isNewLow = isNewLow;
}
public Date getNewLowDate()
{
return newLowDate;
}
public void setNewLowDate(Date newLowDate)
{
this.newLowDate = newLowDate;
}
public String getStockName()
{
return stockName;
}
public void setStockName(String stockName)
{
this.stockName = stockName;
}
public String getIndustryIndexCode()
{
return industryIndexCode;
}
public void setIndustryIndexCode(String industryIndexCode)
{
this.industryIndexCode = industryIndexCode;
}
public String getIndustryIndexName()
{
return industryIndexName;
}
public void setIndustryIndexName(String industryIndexName)
{
this.industryIndexName = industryIndexName;
}
@Override
public String toString()
{
return "TStockHighLowStatus{" +
"stockCode='" + stockCode + '\'' +
", tradeDate=" + tradeDate +
", isNewHigh=" + isNewHigh +
", newHighDate=" + newHighDate +
", isNewLow=" + isNewLow +
", newLowDate=" + newLowDate +
'}';
}
}

@ -0,0 +1,87 @@
package com.ruoyi.newstocksystem.mapper;
import com.ruoyi.newstocksystem.domain.TIndustryIndex;
import java.util.Date;
import java.util.List;
/**
* Mapper
*
* @author lxy
* @date 2026-01-21
*/
public interface TIndustryIndexMapper
{
/**
*
*
* @param industryIndexCode
* @param tradeDate
* @return
*/
public TIndustryIndex selectIndustryIndexByCodeAndDate(String industryIndexCode, Date tradeDate);
/**
*
*
* @param industryIndex
* @return
*/
public List<TIndustryIndex> selectIndustryIndexList(TIndustryIndex industryIndex);
/**
*
*
* @return
*/
public List<TIndustryIndex> selectDistinctIndustryIndexList();
/**
*
*
* @param industryIndex
* @return
*/
public int insertIndustryIndex(TIndustryIndex industryIndex);
/**
*
*
* @param industryIndex
* @return
*/
public int updateIndustryIndex(TIndustryIndex industryIndex);
/**
*
*
* @param industryIndexCode
* @param tradeDate
* @return
*/
public int deleteIndustryIndexByCodeAndDate(String industryIndexCode, Date tradeDate);
/**
*
*
* @param industryIndexList
* @return
*/
public int batchInsertIndustryIndex(List<TIndustryIndex> industryIndexList);
/**
* ON DUPLICATE KEY UPDATE
*
* @param industryIndexList
* @return
*/
public int batchUpsertIndustryIndex(List<TIndustryIndex> industryIndexList);
/**
*
*
* @return
*/
public List<String> selectTradeDates();
}

@ -0,0 +1,86 @@
package com.ruoyi.newstocksystem.mapper;
import com.ruoyi.newstocksystem.domain.TStockBasic;
import java.util.List;
/**
* Mapper
*
* @author lxy
* @date 2026-01-21
*/
public interface TStockBasicMapper
{
/**
*
*
* @param stockCode
* @return
*/
public TStockBasic selectStockBasicByCode(String stockCode);
/**
*
*
* @param stockBasic
* @return
*/
public List<TStockBasic> selectStockBasicList(TStockBasic stockBasic);
/**
*
*
* @param stockBasic
* @return
*/
public int insertStockBasic(TStockBasic stockBasic);
/**
*
*
* @param stockBasic
* @return
*/
public int updateStockBasic(TStockBasic stockBasic);
/**
*
*
* @param stockCode
* @return
*/
public int deleteStockBasicByCode(String stockCode);
/**
*
*
* @param stockCodes
* @return
*/
public int deleteStockBasicByCodes(String[] stockCodes);
/**
*
*
* @param stockBasicList
* @return
*/
public int batchInsertStockBasic(List<TStockBasic> stockBasicList);
/**
* ON DUPLICATE KEY UPDATE
*
* @param stockBasicList
* @return
*/
public int batchUpsertStockBasic(List<TStockBasic> stockBasicList);
/**
*
*
* @param industryIndexCode
* @return
*/
public List<TStockBasic> selectStockBasicByIndustryCode(String industryIndexCode);
}

@ -0,0 +1,105 @@
package com.ruoyi.newstocksystem.mapper;
import com.ruoyi.newstocksystem.domain.TStockDailyTrade;
import org.apache.ibatis.annotations.Param;
import java.util.Date;
import java.util.List;
/**
* Mapper
*
* @author lxy
* @date 2026-01-21
*/
public interface TStockDailyTradeMapper
{
/**
*
*
* @param stockCode
* @param tradeDate
* @return
*/
public TStockDailyTrade selectStockDailyTradeByCodeAndDate(@Param("stockCode") String stockCode, @Param("tradeDate") Date tradeDate);
/**
*
*
* @param stockDailyTrade
* @return
*/
public List<TStockDailyTrade> selectStockDailyTradeList(TStockDailyTrade stockDailyTrade);
/**
*
*
* @param stockDailyTrade
* @return
*/
public List<TStockDailyTrade> selectStockDailyTradeListWithBasic(TStockDailyTrade stockDailyTrade);
/**
*
*
* @param stockDailyTrade
* @return
*/
public int insertStockDailyTrade(TStockDailyTrade stockDailyTrade);
/**
*
*
* @param stockDailyTrade
* @return
*/
public int updateStockDailyTrade(TStockDailyTrade stockDailyTrade);
/**
*
*
* @param stockCode
* @param tradeDate
* @return
*/
public int deleteStockDailyTradeByCodeAndDate(@Param("stockCode") String stockCode, @Param("tradeDate") Date tradeDate);
/**
*
*
* @param stockDailyTradeList
* @return
*/
public int batchInsertStockDailyTrade(List<TStockDailyTrade> stockDailyTradeList);
/**
* ON DUPLICATE KEY UPDATE
*
* @param stockDailyTradeList
* @return
*/
public int batchUpsertStockDailyTrade(List<TStockDailyTrade> stockDailyTradeList);
/**
*
*
* @return
*/
public List<String> selectTradeDates();
/**
*
*
* @param stockDailyTrade
* @return
*/
public List<TStockDailyTrade> selectLimitUpStockList(TStockDailyTrade stockDailyTrade);
/**
*
*
* @param stockDailyTrade
* @return
*/
public List<TStockDailyTrade> selectStrongStockList(TStockDailyTrade stockDailyTrade);
}

@ -0,0 +1,98 @@
package com.ruoyi.newstocksystem.mapper;
import com.ruoyi.newstocksystem.domain.TStockHighLowStatus;
import org.apache.ibatis.annotations.Param;
import java.util.Date;
import java.util.List;
/**
* Mapper
*
* @author lxy
* @date 2026-01-21
*/
public interface TStockHighLowStatusMapper
{
/**
*
*
* @param stockCode
* @param tradeDate
* @return
*/
public TStockHighLowStatus selectStockHighLowStatusByCodeAndDate(@Param("stockCode") String stockCode, @Param("tradeDate") Date tradeDate);
/**
*
*
* @param stockHighLowStatus
* @return
*/
public List<TStockHighLowStatus> selectStockHighLowStatusList(TStockHighLowStatus stockHighLowStatus);
/**
*
*
* @param stockHighLowStatus
* @return
*/
public List<TStockHighLowStatus> selectStockHighLowStatusListWithBasic(TStockHighLowStatus stockHighLowStatus);
/**
*
*
* @param stockHighLowStatus
* @return
*/
public int insertStockHighLowStatus(TStockHighLowStatus stockHighLowStatus);
/**
*
*
* @param stockHighLowStatus
* @return
*/
public int updateStockHighLowStatus(TStockHighLowStatus stockHighLowStatus);
/**
*
*
* @param stockCode
* @param tradeDate
* @return
*/
public int deleteStockHighLowStatusByCodeAndDate(@Param("stockCode") String stockCode, @Param("tradeDate") Date tradeDate);
/**
*
*
* @param stockHighLowStatusList
* @return
*/
public int batchInsertStockHighLowStatus(List<TStockHighLowStatus> stockHighLowStatusList);
/**
* ON DUPLICATE KEY UPDATE
*
* @param stockHighLowStatusList
* @return
*/
public int batchUpsertStockHighLowStatus(List<TStockHighLowStatus> stockHighLowStatusList);
/**
*
*
* @param stockHighLowStatus
* @return
*/
public List<TStockHighLowStatus> selectNewHighStockList(TStockHighLowStatus stockHighLowStatus);
/**
*
*
* @param stockHighLowStatus
* @return
*/
public List<TStockHighLowStatus> selectNewLowStockList(TStockHighLowStatus stockHighLowStatus);
}

@ -0,0 +1,80 @@
package com.ruoyi.newstocksystem.service;
import com.ruoyi.newstocksystem.domain.TIndustryIndex;
import java.util.Date;
import java.util.List;
/**
* Service
*
* @author lxy
* @date 2026-01-21
*/
public interface IIndustryIndexService
{
/**
*
*
* @param industryIndexCode
* @param tradeDate
* @return
*/
public TIndustryIndex selectIndustryIndexByCodeAndDate(String industryIndexCode, Date tradeDate);
/**
*
*
* @param industryIndex
* @return
*/
public List<TIndustryIndex> selectIndustryIndexList(TIndustryIndex industryIndex);
/**
*
*
* @return
*/
public List<TIndustryIndex> selectDistinctIndustryIndexList();
/**
*
*
* @param industryIndex
* @return
*/
public int insertIndustryIndex(TIndustryIndex industryIndex);
/**
*
*
* @param industryIndex
* @return
*/
public int updateIndustryIndex(TIndustryIndex industryIndex);
/**
*
*
* @param industryIndexCode
* @param tradeDate
* @return
*/
public int deleteIndustryIndexByCodeAndDate(String industryIndexCode, Date tradeDate);
/**
*
*
* @param industryIndexList
* @param tradeDate
* @return
*/
public int importIndustryIndex(List<TIndustryIndex> industryIndexList, Date tradeDate);
/**
*
*
* @return
*/
public List<String> selectTradeDates();
}

@ -0,0 +1,78 @@
package com.ruoyi.newstocksystem.service;
import com.ruoyi.newstocksystem.domain.TStockBasic;
import java.util.List;
/**
* Service
*
* @author lxy
* @date 2026-01-21
*/
public interface IStockBasicService
{
/**
*
*
* @param stockCode
* @return
*/
public TStockBasic selectStockBasicByCode(String stockCode);
/**
*
*
* @param stockBasic
* @return
*/
public List<TStockBasic> selectStockBasicList(TStockBasic stockBasic);
/**
*
*
* @param stockBasic
* @return
*/
public int insertStockBasic(TStockBasic stockBasic);
/**
*
*
* @param stockBasic
* @return
*/
public int updateStockBasic(TStockBasic stockBasic);
/**
*
*
* @param stockCode
* @return
*/
public int deleteStockBasicByCode(String stockCode);
/**
*
*
* @param stockCodes
* @return
*/
public int deleteStockBasicByCodes(String[] stockCodes);
/**
*
*
* @param stockBasicList
* @return
*/
public int importStockBasic(List<TStockBasic> stockBasicList);
/**
*
*
* @param industryIndexCode
* @return
*/
public List<TStockBasic> selectStockBasicByIndustryCode(String industryIndexCode);
}

@ -0,0 +1,97 @@
package com.ruoyi.newstocksystem.service;
import com.ruoyi.newstocksystem.domain.TStockDailyTrade;
import java.util.Date;
import java.util.List;
/**
* Service
*
* @author lxy
* @date 2026-01-21
*/
public interface IStockDailyTradeService
{
/**
*
*
* @param stockCode
* @param tradeDate
* @return
*/
public TStockDailyTrade selectStockDailyTradeByCodeAndDate(String stockCode, Date tradeDate);
/**
*
*
* @param stockDailyTrade
* @return
*/
public List<TStockDailyTrade> selectStockDailyTradeList(TStockDailyTrade stockDailyTrade);
/**
*
*
* @param stockDailyTrade
* @return
*/
public List<TStockDailyTrade> selectStockDailyTradeListWithBasic(TStockDailyTrade stockDailyTrade);
/**
*
*
* @param stockDailyTrade
* @return
*/
public int insertStockDailyTrade(TStockDailyTrade stockDailyTrade);
/**
*
*
* @param stockDailyTrade
* @return
*/
public int updateStockDailyTrade(TStockDailyTrade stockDailyTrade);
/**
*
*
* @param stockCode
* @param tradeDate
* @return
*/
public int deleteStockDailyTradeByCodeAndDate(String stockCode, Date tradeDate);
/**
*
*
* @param stockDailyTradeList
* @param tradeDate
* @return
*/
public int importStockDailyTrade(List<TStockDailyTrade> stockDailyTradeList, Date tradeDate);
/**
*
*
* @return
*/
public List<String> selectTradeDates();
/**
*
*
* @param stockDailyTrade
* @return
*/
public List<TStockDailyTrade> selectLimitUpStockList(TStockDailyTrade stockDailyTrade);
/**
*
*
* @param stockDailyTrade
* @return
*/
public List<TStockDailyTrade> selectStrongStockList(TStockDailyTrade stockDailyTrade);
}

@ -0,0 +1,90 @@
package com.ruoyi.newstocksystem.service;
import com.ruoyi.newstocksystem.domain.TStockHighLowStatus;
import java.util.Date;
import java.util.List;
/**
* Service
*
* @author lxy
* @date 2026-01-21
*/
public interface IStockHighLowStatusService
{
/**
*
*
* @param stockCode
* @param tradeDate
* @return
*/
public TStockHighLowStatus selectStockHighLowStatusByCodeAndDate(String stockCode, Date tradeDate);
/**
*
*
* @param stockHighLowStatus
* @return
*/
public List<TStockHighLowStatus> selectStockHighLowStatusList(TStockHighLowStatus stockHighLowStatus);
/**
*
*
* @param stockHighLowStatus
* @return
*/
public List<TStockHighLowStatus> selectStockHighLowStatusListWithBasic(TStockHighLowStatus stockHighLowStatus);
/**
*
*
* @param stockHighLowStatus
* @return
*/
public int insertStockHighLowStatus(TStockHighLowStatus stockHighLowStatus);
/**
*
*
* @param stockHighLowStatus
* @return
*/
public int updateStockHighLowStatus(TStockHighLowStatus stockHighLowStatus);
/**
*
*
* @param stockCode
* @param tradeDate
* @return
*/
public int deleteStockHighLowStatusByCodeAndDate(String stockCode, Date tradeDate);
/**
*
*
* @param stockHighLowStatusList
* @param tradeDate
* @return
*/
public int importStockHighLowStatus(List<TStockHighLowStatus> stockHighLowStatusList, Date tradeDate);
/**
*
*
* @param stockHighLowStatus
* @return
*/
public List<TStockHighLowStatus> selectNewHighStockList(TStockHighLowStatus stockHighLowStatus);
/**
*
*
* @param stockHighLowStatus
* @return
*/
public List<TStockHighLowStatus> selectNewLowStockList(TStockHighLowStatus stockHighLowStatus);
}

@ -0,0 +1,99 @@
package com.ruoyi.newstocksystem.service.impl;
import java.util.Date;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.ruoyi.newstocksystem.domain.TIndustryIndex;
import com.ruoyi.newstocksystem.mapper.TIndustryIndexMapper;
import com.ruoyi.newstocksystem.service.IIndustryIndexService;
/**
* Service
*
* @author lxy
* @date 2026-01-21
*/
@Service
public class IndustryIndexServiceImpl implements IIndustryIndexService
{
@Autowired
private TIndustryIndexMapper industryIndexMapper;
@Override
public TIndustryIndex selectIndustryIndexByCodeAndDate(String industryIndexCode, Date tradeDate)
{
return industryIndexMapper.selectIndustryIndexByCodeAndDate(industryIndexCode, tradeDate);
}
@Override
public List<TIndustryIndex> selectIndustryIndexList(TIndustryIndex industryIndex)
{
return industryIndexMapper.selectIndustryIndexList(industryIndex);
}
@Override
public List<TIndustryIndex> selectDistinctIndustryIndexList()
{
return industryIndexMapper.selectDistinctIndustryIndexList();
}
@Override
public int insertIndustryIndex(TIndustryIndex industryIndex)
{
return industryIndexMapper.insertIndustryIndex(industryIndex);
}
@Override
public int updateIndustryIndex(TIndustryIndex industryIndex)
{
return industryIndexMapper.updateIndustryIndex(industryIndex);
}
@Override
public int deleteIndustryIndexByCodeAndDate(String industryIndexCode, Date tradeDate)
{
return industryIndexMapper.deleteIndustryIndexByCodeAndDate(industryIndexCode, tradeDate);
}
@Override
@Transactional
public int importIndustryIndex(List<TIndustryIndex> industryIndexList, Date tradeDate)
{
if (industryIndexList == null || industryIndexList.isEmpty())
{
return 0;
}
// 设置交易日期
for (TIndustryIndex industryIndex : industryIndexList)
{
if (industryIndex.getTradeDate() == null)
{
industryIndex.setTradeDate(tradeDate);
}
}
int count = 0;
int batchSize = 500;
// 分批导入数据
for (int i = 0; i < industryIndexList.size(); i += batchSize)
{
int end = Math.min(i + batchSize, industryIndexList.size());
List<TIndustryIndex> batchList = industryIndexList.subList(i, end);
count += industryIndexMapper.batchUpsertIndustryIndex(batchList);
}
return count;
}
@Override
public List<String> selectTradeDates()
{
return industryIndexMapper.selectTradeDates();
}
}

@ -0,0 +1,89 @@
package com.ruoyi.newstocksystem.service.impl;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.ruoyi.newstocksystem.domain.TStockBasic;
import com.ruoyi.newstocksystem.mapper.TStockBasicMapper;
import com.ruoyi.newstocksystem.service.IStockBasicService;
/**
* Service
*
* @author lxy
* @date 2026-01-21
*/
@Service
public class StockBasicServiceImpl implements IStockBasicService
{
@Autowired
private TStockBasicMapper stockBasicMapper;
@Override
public TStockBasic selectStockBasicByCode(String stockCode)
{
return stockBasicMapper.selectStockBasicByCode(stockCode);
}
@Override
public List<TStockBasic> selectStockBasicList(TStockBasic stockBasic)
{
return stockBasicMapper.selectStockBasicList(stockBasic);
}
@Override
public int insertStockBasic(TStockBasic stockBasic)
{
return stockBasicMapper.insertStockBasic(stockBasic);
}
@Override
public int updateStockBasic(TStockBasic stockBasic)
{
return stockBasicMapper.updateStockBasic(stockBasic);
}
@Override
public int deleteStockBasicByCode(String stockCode)
{
return stockBasicMapper.deleteStockBasicByCode(stockCode);
}
@Override
public int deleteStockBasicByCodes(String[] stockCodes)
{
return stockBasicMapper.deleteStockBasicByCodes(stockCodes);
}
@Override
@Transactional
public int importStockBasic(List<TStockBasic> stockBasicList)
{
if (stockBasicList == null || stockBasicList.isEmpty())
{
return 0;
}
int count = 0;
int batchSize = 500;
// 分批导入数据(使用 upsert 方式,自动处理新增和更新)
for (int i = 0; i < stockBasicList.size(); i += batchSize)
{
int end = Math.min(i + batchSize, stockBasicList.size());
List<TStockBasic> batchList = stockBasicList.subList(i, end);
count += stockBasicMapper.batchUpsertStockBasic(batchList);
}
return count;
}
@Override
public List<TStockBasic> selectStockBasicByIndustryCode(String industryIndexCode)
{
return stockBasicMapper.selectStockBasicByIndustryCode(industryIndexCode);
}
}

@ -0,0 +1,120 @@
package com.ruoyi.newstocksystem.service.impl;
import java.util.Date;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.ruoyi.newstocksystem.domain.TStockDailyTrade;
import com.ruoyi.newstocksystem.mapper.TStockDailyTradeMapper;
import com.ruoyi.newstocksystem.service.IStockDailyTradeService;
/**
* Service
*
* @author lxy
* @date 2026-01-21
*/
@Service
public class StockDailyTradeServiceImpl implements IStockDailyTradeService
{
@Autowired
private TStockDailyTradeMapper stockDailyTradeMapper;
@Override
public TStockDailyTrade selectStockDailyTradeByCodeAndDate(String stockCode, Date tradeDate)
{
return stockDailyTradeMapper.selectStockDailyTradeByCodeAndDate(stockCode, tradeDate);
}
@Override
public List<TStockDailyTrade> selectStockDailyTradeList(TStockDailyTrade stockDailyTrade)
{
return stockDailyTradeMapper.selectStockDailyTradeList(stockDailyTrade);
}
@Override
public List<TStockDailyTrade> selectStockDailyTradeListWithBasic(TStockDailyTrade stockDailyTrade)
{
return stockDailyTradeMapper.selectStockDailyTradeListWithBasic(stockDailyTrade);
}
@Override
public int insertStockDailyTrade(TStockDailyTrade stockDailyTrade)
{
return stockDailyTradeMapper.insertStockDailyTrade(stockDailyTrade);
}
@Override
public int updateStockDailyTrade(TStockDailyTrade stockDailyTrade)
{
return stockDailyTradeMapper.updateStockDailyTrade(stockDailyTrade);
}
@Override
public int deleteStockDailyTradeByCodeAndDate(String stockCode, Date tradeDate)
{
return stockDailyTradeMapper.deleteStockDailyTradeByCodeAndDate(stockCode, tradeDate);
}
@Override
@Transactional
public int importStockDailyTrade(List<TStockDailyTrade> stockDailyTradeList, Date tradeDate)
{
if (stockDailyTradeList == null || stockDailyTradeList.isEmpty())
{
return 0;
}
// 设置交易日期
for (TStockDailyTrade stockDailyTrade : stockDailyTradeList)
{
if (stockDailyTrade.getTradeDate() == null)
{
stockDailyTrade.setTradeDate(tradeDate);
}
// 设置默认值
if (stockDailyTrade.getIsLimitUp() == null)
{
stockDailyTrade.setIsLimitUp(0);
}
if (stockDailyTrade.getIsLimitDown() == null)
{
stockDailyTrade.setIsLimitDown(0);
}
}
int count = 0;
int batchSize = 500;
// 分批导入数据
for (int i = 0; i < stockDailyTradeList.size(); i += batchSize)
{
int end = Math.min(i + batchSize, stockDailyTradeList.size());
List<TStockDailyTrade> batchList = stockDailyTradeList.subList(i, end);
count += stockDailyTradeMapper.batchUpsertStockDailyTrade(batchList);
}
return count;
}
@Override
public List<String> selectTradeDates()
{
return stockDailyTradeMapper.selectTradeDates();
}
@Override
public List<TStockDailyTrade> selectLimitUpStockList(TStockDailyTrade stockDailyTrade)
{
return stockDailyTradeMapper.selectLimitUpStockList(stockDailyTrade);
}
@Override
public List<TStockDailyTrade> selectStrongStockList(TStockDailyTrade stockDailyTrade)
{
return stockDailyTradeMapper.selectStrongStockList(stockDailyTrade);
}
}

@ -0,0 +1,114 @@
package com.ruoyi.newstocksystem.service.impl;
import java.util.Date;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.ruoyi.newstocksystem.domain.TStockHighLowStatus;
import com.ruoyi.newstocksystem.mapper.TStockHighLowStatusMapper;
import com.ruoyi.newstocksystem.service.IStockHighLowStatusService;
/**
* Service
*
* @author lxy
* @date 2026-01-21
*/
@Service
public class StockHighLowStatusServiceImpl implements IStockHighLowStatusService
{
@Autowired
private TStockHighLowStatusMapper stockHighLowStatusMapper;
@Override
public TStockHighLowStatus selectStockHighLowStatusByCodeAndDate(String stockCode, Date tradeDate)
{
return stockHighLowStatusMapper.selectStockHighLowStatusByCodeAndDate(stockCode, tradeDate);
}
@Override
public List<TStockHighLowStatus> selectStockHighLowStatusList(TStockHighLowStatus stockHighLowStatus)
{
return stockHighLowStatusMapper.selectStockHighLowStatusList(stockHighLowStatus);
}
@Override
public List<TStockHighLowStatus> selectStockHighLowStatusListWithBasic(TStockHighLowStatus stockHighLowStatus)
{
return stockHighLowStatusMapper.selectStockHighLowStatusListWithBasic(stockHighLowStatus);
}
@Override
public int insertStockHighLowStatus(TStockHighLowStatus stockHighLowStatus)
{
return stockHighLowStatusMapper.insertStockHighLowStatus(stockHighLowStatus);
}
@Override
public int updateStockHighLowStatus(TStockHighLowStatus stockHighLowStatus)
{
return stockHighLowStatusMapper.updateStockHighLowStatus(stockHighLowStatus);
}
@Override
public int deleteStockHighLowStatusByCodeAndDate(String stockCode, Date tradeDate)
{
return stockHighLowStatusMapper.deleteStockHighLowStatusByCodeAndDate(stockCode, tradeDate);
}
@Override
@Transactional
public int importStockHighLowStatus(List<TStockHighLowStatus> stockHighLowStatusList, Date tradeDate)
{
if (stockHighLowStatusList == null || stockHighLowStatusList.isEmpty())
{
return 0;
}
// 设置交易日期
for (TStockHighLowStatus stockHighLowStatus : stockHighLowStatusList)
{
if (stockHighLowStatus.getTradeDate() == null)
{
stockHighLowStatus.setTradeDate(tradeDate);
}
// 设置默认值
if (stockHighLowStatus.getIsNewHigh() == null)
{
stockHighLowStatus.setIsNewHigh(0);
}
if (stockHighLowStatus.getIsNewLow() == null)
{
stockHighLowStatus.setIsNewLow(0);
}
}
int count = 0;
int batchSize = 500;
// 分批导入数据
for (int i = 0; i < stockHighLowStatusList.size(); i += batchSize)
{
int end = Math.min(i + batchSize, stockHighLowStatusList.size());
List<TStockHighLowStatus> batchList = stockHighLowStatusList.subList(i, end);
count += stockHighLowStatusMapper.batchUpsertStockHighLowStatus(batchList);
}
return count;
}
@Override
public List<TStockHighLowStatus> selectNewHighStockList(TStockHighLowStatus stockHighLowStatus)
{
return stockHighLowStatusMapper.selectNewHighStockList(stockHighLowStatus);
}
@Override
public List<TStockHighLowStatus> selectNewLowStockList(TStockHighLowStatus stockHighLowStatus)
{
return stockHighLowStatusMapper.selectNewLowStockList(stockHighLowStatus);
}
}

@ -0,0 +1,166 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.newstocksystem.mapper.TIndustryIndexMapper">
<resultMap type="com.ruoyi.newstocksystem.domain.TIndustryIndex" id="IndustryIndexResult">
<result property="industryIndexCode" column="industry_index_code" />
<result property="industryIndexName" column="industry_index_name" />
<result property="componentCount" column="component_count" />
<result property="tradeDate" column="trade_date" />
<result property="openPrice" column="open_price" />
<result property="closePrice" column="close_price" />
<result property="volume" column="volume" />
<result property="turnover" column="turnover" />
<result property="totalMarketCap" column="total_market_cap" />
<result property="freeCirculationCap" column="free_circulation_cap" />
<result property="priceChangeRate" column="price_change_rate" />
<result property="peTtm" column="pe_ttm" />
<result property="peTtmMedian" column="pe_ttm_median" />
<result property="createTime" column="create_time" />
<result property="updateTime" column="update_time" />
</resultMap>
<sql id="selectIndustryIndexVo">
select industry_index_code, industry_index_name, component_count, trade_date,
open_price, close_price, volume, turnover, total_market_cap,
free_circulation_cap, price_change_rate, pe_ttm, pe_ttm_median,
create_time, update_time
from t_industry_index
</sql>
<select id="selectIndustryIndexByCodeAndDate" resultMap="IndustryIndexResult">
<include refid="selectIndustryIndexVo" />
where industry_index_code = #{param1} and trade_date = #{param2}
</select>
<select id="selectIndustryIndexList" parameterType="com.ruoyi.newstocksystem.domain.TIndustryIndex" resultMap="IndustryIndexResult">
<include refid="selectIndustryIndexVo" />
<where>
<if test="industryIndexCode != null and industryIndexCode != ''">
and industry_index_code = #{industryIndexCode}
</if>
<if test="industryIndexName != null and industryIndexName != ''">
and industry_index_name like concat('%', #{industryIndexName}, '%')
</if>
<if test="tradeDate != null">
and trade_date = #{tradeDate}
</if>
<if test="params.beginTradeDate != null and params.beginTradeDate != ''">
and trade_date &gt;= #{params.beginTradeDate}
</if>
<if test="params.endTradeDate != null and params.endTradeDate != ''">
and trade_date &lt;= #{params.endTradeDate}
</if>
</where>
order by trade_date desc, industry_index_code asc
</select>
<select id="selectDistinctIndustryIndexList" resultMap="IndustryIndexResult">
select distinct industry_index_code, industry_index_name
from t_industry_index
order by industry_index_code
</select>
<select id="selectTradeDates" resultType="String">
select distinct DATE_FORMAT(trade_date, '%Y-%m-%d') as trade_date
from t_industry_index
order by trade_date desc
</select>
<insert id="insertIndustryIndex" parameterType="com.ruoyi.newstocksystem.domain.TIndustryIndex">
insert into t_industry_index
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="industryIndexCode != null and industryIndexCode != ''">industry_index_code,</if>
<if test="industryIndexName != null and industryIndexName != ''">industry_index_name,</if>
<if test="componentCount != null">component_count,</if>
<if test="tradeDate != null">trade_date,</if>
<if test="openPrice != null">open_price,</if>
<if test="closePrice != null">close_price,</if>
<if test="volume != null">volume,</if>
<if test="turnover != null">turnover,</if>
<if test="totalMarketCap != null">total_market_cap,</if>
<if test="freeCirculationCap != null">free_circulation_cap,</if>
<if test="priceChangeRate != null">price_change_rate,</if>
<if test="peTtm != null">pe_ttm,</if>
<if test="peTtmMedian != null">pe_ttm_median,</if>
create_time,
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="industryIndexCode != null and industryIndexCode != ''">#{industryIndexCode},</if>
<if test="industryIndexName != null and industryIndexName != ''">#{industryIndexName},</if>
<if test="componentCount != null">#{componentCount},</if>
<if test="tradeDate != null">#{tradeDate},</if>
<if test="openPrice != null">#{openPrice},</if>
<if test="closePrice != null">#{closePrice},</if>
<if test="volume != null">#{volume},</if>
<if test="turnover != null">#{turnover},</if>
<if test="totalMarketCap != null">#{totalMarketCap},</if>
<if test="freeCirculationCap != null">#{freeCirculationCap},</if>
<if test="priceChangeRate != null">#{priceChangeRate},</if>
<if test="peTtm != null">#{peTtm},</if>
<if test="peTtmMedian != null">#{peTtmMedian},</if>
NOW(),
</trim>
</insert>
<update id="updateIndustryIndex" parameterType="com.ruoyi.newstocksystem.domain.TIndustryIndex">
update t_industry_index
<trim prefix="set" suffixOverrides=",">
<if test="industryIndexName != null and industryIndexName != ''">industry_index_name = #{industryIndexName},</if>
<if test="componentCount != null">component_count = #{componentCount},</if>
<if test="openPrice != null">open_price = #{openPrice},</if>
<if test="closePrice != null">close_price = #{closePrice},</if>
<if test="volume != null">volume = #{volume},</if>
<if test="turnover != null">turnover = #{turnover},</if>
<if test="totalMarketCap != null">total_market_cap = #{totalMarketCap},</if>
<if test="freeCirculationCap != null">free_circulation_cap = #{freeCirculationCap},</if>
<if test="priceChangeRate != null">price_change_rate = #{priceChangeRate},</if>
<if test="peTtm != null">pe_ttm = #{peTtm},</if>
<if test="peTtmMedian != null">pe_ttm_median = #{peTtmMedian},</if>
update_time = NOW(),
</trim>
where industry_index_code = #{industryIndexCode} and trade_date = #{tradeDate}
</update>
<delete id="deleteIndustryIndexByCodeAndDate">
delete from t_industry_index where industry_index_code = #{param1} and trade_date = #{param2}
</delete>
<insert id="batchInsertIndustryIndex" parameterType="java.util.List">
insert into t_industry_index(industry_index_code, industry_index_name, component_count, trade_date,
open_price, close_price, volume, turnover, total_market_cap,
free_circulation_cap, price_change_rate, pe_ttm, pe_ttm_median, create_time)
values
<foreach collection="list" item="item" separator=",">
(#{item.industryIndexCode}, #{item.industryIndexName}, #{item.componentCount}, #{item.tradeDate},
#{item.openPrice}, #{item.closePrice}, #{item.volume}, #{item.turnover}, #{item.totalMarketCap},
#{item.freeCirculationCap}, #{item.priceChangeRate}, #{item.peTtm}, #{item.peTtmMedian}, NOW())
</foreach>
</insert>
<insert id="batchUpsertIndustryIndex" parameterType="java.util.List">
insert into t_industry_index(industry_index_code, industry_index_name, component_count, trade_date,
open_price, close_price, volume, turnover, total_market_cap,
free_circulation_cap, price_change_rate, pe_ttm, pe_ttm_median, create_time)
values
<foreach collection="list" item="item" separator=",">
(#{item.industryIndexCode}, #{item.industryIndexName}, #{item.componentCount}, #{item.tradeDate},
#{item.openPrice}, #{item.closePrice}, #{item.volume}, #{item.turnover}, #{item.totalMarketCap},
#{item.freeCirculationCap}, #{item.priceChangeRate}, #{item.peTtm}, #{item.peTtmMedian}, NOW())
</foreach>
ON DUPLICATE KEY UPDATE
industry_index_name = VALUES(industry_index_name),
component_count = VALUES(component_count),
open_price = VALUES(open_price),
close_price = VALUES(close_price),
volume = VALUES(volume),
turnover = VALUES(turnover),
total_market_cap = VALUES(total_market_cap),
free_circulation_cap = VALUES(free_circulation_cap),
price_change_rate = VALUES(price_change_rate),
pe_ttm = VALUES(pe_ttm),
pe_ttm_median = VALUES(pe_ttm_median),
update_time = NOW()
</insert>
</mapper>

@ -0,0 +1,141 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.newstocksystem.mapper.TStockBasicMapper">
<resultMap type="com.ruoyi.newstocksystem.domain.TStockBasic" id="StockBasicResult">
<id property="stockCode" column="stock_code" />
<result property="stockName" column="stock_name" />
<result property="listingDate" column="listing_date" />
<result property="listingDays" column="listing_days" />
<result property="isSt" column="is_st" />
<result property="isStarSt" column="is_star_st" />
<result property="industryIndexCode" column="industry_index_code" />
<result property="industryIndexName" column="industry_index_name" />
<result property="createTime" column="create_time" />
<result property="updateTime" column="update_time" />
</resultMap>
<sql id="selectStockBasicVo">
select stock_code, stock_name, listing_date, listing_days, is_st, is_star_st,
industry_index_code, industry_index_name, create_time, update_time
from t_stock_basic
</sql>
<select id="selectStockBasicByCode" parameterType="String" resultMap="StockBasicResult">
<include refid="selectStockBasicVo" />
where stock_code = #{stockCode}
</select>
<select id="selectStockBasicList" parameterType="com.ruoyi.newstocksystem.domain.TStockBasic" resultMap="StockBasicResult">
<include refid="selectStockBasicVo" />
<where>
<if test="stockCode != null and stockCode != ''">
and stock_code like concat('%', #{stockCode}, '%')
</if>
<if test="stockName != null and stockName != ''">
and stock_name like concat('%', #{stockName}, '%')
</if>
<if test="isSt != null">
and is_st = #{isSt}
</if>
<if test="isStarSt != null">
and is_star_st = #{isStarSt}
</if>
<if test="industryIndexCode != null and industryIndexCode != ''">
and industry_index_code = #{industryIndexCode}
</if>
<if test="industryIndexName != null and industryIndexName != ''">
and industry_index_name like concat('%', #{industryIndexName}, '%')
</if>
</where>
order by stock_code asc
</select>
<select id="selectStockBasicByIndustryCode" parameterType="String" resultMap="StockBasicResult">
<include refid="selectStockBasicVo" />
where industry_index_code = #{industryIndexCode}
order by stock_code asc
</select>
<insert id="insertStockBasic" parameterType="com.ruoyi.newstocksystem.domain.TStockBasic">
insert into t_stock_basic
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="stockCode != null and stockCode != ''">stock_code,</if>
<if test="stockName != null and stockName != ''">stock_name,</if>
<if test="listingDate != null">listing_date,</if>
<if test="listingDays != null">listing_days,</if>
<if test="isSt != null">is_st,</if>
<if test="isStarSt != null">is_star_st,</if>
<if test="industryIndexCode != null and industryIndexCode != ''">industry_index_code,</if>
<if test="industryIndexName != null and industryIndexName != ''">industry_index_name,</if>
create_time,
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="stockCode != null and stockCode != ''">#{stockCode},</if>
<if test="stockName != null and stockName != ''">#{stockName},</if>
<if test="listingDate != null">#{listingDate},</if>
<if test="listingDays != null">#{listingDays},</if>
<if test="isSt != null">#{isSt},</if>
<if test="isStarSt != null">#{isStarSt},</if>
<if test="industryIndexCode != null and industryIndexCode != ''">#{industryIndexCode},</if>
<if test="industryIndexName != null and industryIndexName != ''">#{industryIndexName},</if>
NOW(),
</trim>
</insert>
<update id="updateStockBasic" parameterType="com.ruoyi.newstocksystem.domain.TStockBasic">
update t_stock_basic
<trim prefix="set" suffixOverrides=",">
<if test="stockName != null and stockName != ''">stock_name = #{stockName},</if>
<if test="listingDate != null">listing_date = #{listingDate},</if>
<if test="listingDays != null">listing_days = #{listingDays},</if>
<if test="isSt != null">is_st = #{isSt},</if>
<if test="isStarSt != null">is_star_st = #{isStarSt},</if>
<if test="industryIndexCode != null and industryIndexCode != ''">industry_index_code = #{industryIndexCode},</if>
<if test="industryIndexName != null and industryIndexName != ''">industry_index_name = #{industryIndexName},</if>
update_time = NOW(),
</trim>
where stock_code = #{stockCode}
</update>
<delete id="deleteStockBasicByCode" parameterType="String">
delete from t_stock_basic where stock_code = #{stockCode}
</delete>
<delete id="deleteStockBasicByCodes" parameterType="String">
delete from t_stock_basic where stock_code in
<foreach item="stockCode" collection="array" open="(" separator="," close=")">
#{stockCode}
</foreach>
</delete>
<insert id="batchInsertStockBasic" parameterType="java.util.List">
insert into t_stock_basic(stock_code, stock_name, listing_date, listing_days,
is_st, is_star_st, industry_index_code, industry_index_name, create_time)
values
<foreach collection="list" item="item" separator=",">
(#{item.stockCode}, #{item.stockName}, #{item.listingDate}, #{item.listingDays},
#{item.isSt}, #{item.isStarSt}, #{item.industryIndexCode}, #{item.industryIndexName}, NOW())
</foreach>
</insert>
<insert id="batchUpsertStockBasic" parameterType="java.util.List">
insert into t_stock_basic(stock_code, stock_name, listing_date, listing_days,
is_st, is_star_st, industry_index_code, industry_index_name, create_time)
values
<foreach collection="list" item="item" separator=",">
(#{item.stockCode}, #{item.stockName}, #{item.listingDate}, #{item.listingDays},
#{item.isSt}, #{item.isStarSt}, #{item.industryIndexCode}, #{item.industryIndexName}, NOW())
</foreach>
ON DUPLICATE KEY UPDATE
stock_name = VALUES(stock_name),
listing_date = VALUES(listing_date),
listing_days = VALUES(listing_days),
is_st = VALUES(is_st),
is_star_st = VALUES(is_star_st),
industry_index_code = VALUES(industry_index_code),
industry_index_name = VALUES(industry_index_name),
update_time = NOW()
</insert>
</mapper>

@ -0,0 +1,242 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.newstocksystem.mapper.TStockDailyTradeMapper">
<resultMap type="com.ruoyi.newstocksystem.domain.TStockDailyTrade" id="StockDailyTradeResult">
<result property="stockCode" column="stock_code" />
<result property="tradeDate" column="trade_date" />
<result property="openPrice" column="open_price" />
<result property="closePrice" column="close_price" />
<result property="highPrice" column="high_price" />
<result property="lowPrice" column="low_price" />
<result property="priceChangeRate" column="price_change_rate" />
<result property="volume" column="volume" />
<result property="turnover" column="turnover" />
<result property="freeCirculationCap" column="free_circulation_cap" />
<result property="isLimitUp" column="is_limit_up" />
<result property="isLimitDown" column="is_limit_down" />
<result property="momentum10d" column="momentum_10d" />
<result property="momentum20d" column="momentum_20d" />
<result property="momentum60d" column="momentum_60d" />
<result property="createTime" column="create_time" />
</resultMap>
<resultMap type="com.ruoyi.newstocksystem.domain.TStockDailyTrade" id="StockDailyTradeWithBasicResult" extends="StockDailyTradeResult">
<result property="stockName" column="stock_name" />
<result property="industryIndexCode" column="industry_index_code" />
<result property="industryIndexName" column="industry_index_name" />
</resultMap>
<sql id="selectStockDailyTradeVo">
select stock_code, trade_date, open_price, close_price, high_price, low_price,
price_change_rate, volume, turnover, free_circulation_cap,
is_limit_up, is_limit_down, momentum_10d, momentum_20d, momentum_60d, create_time
from t_stock_daily_trade
</sql>
<sql id="selectStockDailyTradeWithBasicVo">
select t.stock_code, t.trade_date, t.open_price, t.close_price, t.high_price, t.low_price,
t.price_change_rate, t.volume, t.turnover, t.free_circulation_cap,
t.is_limit_up, t.is_limit_down, t.momentum_10d, t.momentum_20d, t.momentum_60d, t.create_time,
b.stock_name, b.industry_index_code, b.industry_index_name
from t_stock_daily_trade t
left join t_stock_basic b on t.stock_code = b.stock_code
</sql>
<select id="selectStockDailyTradeByCodeAndDate" resultMap="StockDailyTradeResult">
<include refid="selectStockDailyTradeVo" />
where stock_code = #{stockCode} and trade_date = #{tradeDate}
</select>
<select id="selectStockDailyTradeList" parameterType="com.ruoyi.newstocksystem.domain.TStockDailyTrade" resultMap="StockDailyTradeResult">
<include refid="selectStockDailyTradeVo" />
<where>
<if test="stockCode != null and stockCode != ''">
and stock_code = #{stockCode}
</if>
<if test="tradeDate != null">
and trade_date = #{tradeDate}
</if>
<if test="isLimitUp != null">
and is_limit_up = #{isLimitUp}
</if>
<if test="isLimitDown != null">
and is_limit_down = #{isLimitDown}
</if>
<if test="params.beginTradeDate != null and params.beginTradeDate != ''">
and trade_date &gt;= #{params.beginTradeDate}
</if>
<if test="params.endTradeDate != null and params.endTradeDate != ''">
and trade_date &lt;= #{params.endTradeDate}
</if>
</where>
order by trade_date desc, stock_code asc
</select>
<select id="selectStockDailyTradeListWithBasic" parameterType="com.ruoyi.newstocksystem.domain.TStockDailyTrade" resultMap="StockDailyTradeWithBasicResult">
<include refid="selectStockDailyTradeWithBasicVo" />
<where>
<if test="stockCode != null and stockCode != ''">
and t.stock_code like concat('%', #{stockCode}, '%')
</if>
<if test="stockName != null and stockName != ''">
and b.stock_name like concat('%', #{stockName}, '%')
</if>
<if test="tradeDate != null">
and t.trade_date = #{tradeDate}
</if>
<if test="industryIndexCode != null and industryIndexCode != ''">
and b.industry_index_code = #{industryIndexCode}
</if>
<if test="isLimitUp != null">
and t.is_limit_up = #{isLimitUp}
</if>
<if test="isLimitDown != null">
and t.is_limit_down = #{isLimitDown}
</if>
<if test="params.beginTradeDate != null and params.beginTradeDate != ''">
and t.trade_date &gt;= #{params.beginTradeDate}
</if>
<if test="params.endTradeDate != null and params.endTradeDate != ''">
and t.trade_date &lt;= #{params.endTradeDate}
</if>
</where>
order by t.trade_date desc, t.stock_code asc
</select>
<select id="selectTradeDates" resultType="String">
select distinct DATE_FORMAT(trade_date, '%Y-%m-%d') as trade_date
from t_stock_daily_trade
order by trade_date desc
</select>
<select id="selectLimitUpStockList" parameterType="com.ruoyi.newstocksystem.domain.TStockDailyTrade" resultMap="StockDailyTradeWithBasicResult">
<include refid="selectStockDailyTradeWithBasicVo" />
<where>
t.is_limit_up = 1
<if test="tradeDate != null">
and t.trade_date = #{tradeDate}
</if>
<if test="industryIndexCode != null and industryIndexCode != ''">
and b.industry_index_code = #{industryIndexCode}
</if>
</where>
order by t.price_change_rate desc
</select>
<select id="selectStrongStockList" parameterType="com.ruoyi.newstocksystem.domain.TStockDailyTrade" resultMap="StockDailyTradeWithBasicResult">
<include refid="selectStockDailyTradeWithBasicVo" />
<where>
<if test="tradeDate != null">
and t.trade_date = #{tradeDate}
</if>
<if test="industryIndexCode != null and industryIndexCode != ''">
and b.industry_index_code = #{industryIndexCode}
</if>
</where>
order by t.momentum_20d desc, t.momentum_10d desc
</select>
<insert id="insertStockDailyTrade" parameterType="com.ruoyi.newstocksystem.domain.TStockDailyTrade">
insert into t_stock_daily_trade
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="stockCode != null and stockCode != ''">stock_code,</if>
<if test="tradeDate != null">trade_date,</if>
<if test="openPrice != null">open_price,</if>
<if test="closePrice != null">close_price,</if>
<if test="highPrice != null">high_price,</if>
<if test="lowPrice != null">low_price,</if>
<if test="priceChangeRate != null">price_change_rate,</if>
<if test="volume != null">volume,</if>
<if test="turnover != null">turnover,</if>
<if test="freeCirculationCap != null">free_circulation_cap,</if>
<if test="isLimitUp != null">is_limit_up,</if>
<if test="isLimitDown != null">is_limit_down,</if>
<if test="momentum10d != null">momentum_10d,</if>
<if test="momentum20d != null">momentum_20d,</if>
<if test="momentum60d != null">momentum_60d,</if>
create_time,
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="stockCode != null and stockCode != ''">#{stockCode},</if>
<if test="tradeDate != null">#{tradeDate},</if>
<if test="openPrice != null">#{openPrice},</if>
<if test="closePrice != null">#{closePrice},</if>
<if test="highPrice != null">#{highPrice},</if>
<if test="lowPrice != null">#{lowPrice},</if>
<if test="priceChangeRate != null">#{priceChangeRate},</if>
<if test="volume != null">#{volume},</if>
<if test="turnover != null">#{turnover},</if>
<if test="freeCirculationCap != null">#{freeCirculationCap},</if>
<if test="isLimitUp != null">#{isLimitUp},</if>
<if test="isLimitDown != null">#{isLimitDown},</if>
<if test="momentum10d != null">#{momentum10d},</if>
<if test="momentum20d != null">#{momentum20d},</if>
<if test="momentum60d != null">#{momentum60d},</if>
NOW(),
</trim>
</insert>
<update id="updateStockDailyTrade" parameterType="com.ruoyi.newstocksystem.domain.TStockDailyTrade">
update t_stock_daily_trade
<trim prefix="set" suffixOverrides=",">
<if test="openPrice != null">open_price = #{openPrice},</if>
<if test="closePrice != null">close_price = #{closePrice},</if>
<if test="highPrice != null">high_price = #{highPrice},</if>
<if test="lowPrice != null">low_price = #{lowPrice},</if>
<if test="priceChangeRate != null">price_change_rate = #{priceChangeRate},</if>
<if test="volume != null">volume = #{volume},</if>
<if test="turnover != null">turnover = #{turnover},</if>
<if test="freeCirculationCap != null">free_circulation_cap = #{freeCirculationCap},</if>
<if test="isLimitUp != null">is_limit_up = #{isLimitUp},</if>
<if test="isLimitDown != null">is_limit_down = #{isLimitDown},</if>
<if test="momentum10d != null">momentum_10d = #{momentum10d},</if>
<if test="momentum20d != null">momentum_20d = #{momentum20d},</if>
<if test="momentum60d != null">momentum_60d = #{momentum60d},</if>
</trim>
where stock_code = #{stockCode} and trade_date = #{tradeDate}
</update>
<delete id="deleteStockDailyTradeByCodeAndDate">
delete from t_stock_daily_trade where stock_code = #{stockCode} and trade_date = #{tradeDate}
</delete>
<insert id="batchInsertStockDailyTrade" parameterType="java.util.List">
insert into t_stock_daily_trade(stock_code, trade_date, open_price, close_price, high_price, low_price,
price_change_rate, volume, turnover, free_circulation_cap,
is_limit_up, is_limit_down, momentum_10d, momentum_20d, momentum_60d, create_time)
values
<foreach collection="list" item="item" separator=",">
(#{item.stockCode}, #{item.tradeDate}, #{item.openPrice}, #{item.closePrice}, #{item.highPrice}, #{item.lowPrice},
#{item.priceChangeRate}, #{item.volume}, #{item.turnover}, #{item.freeCirculationCap},
#{item.isLimitUp}, #{item.isLimitDown}, #{item.momentum10d}, #{item.momentum20d}, #{item.momentum60d}, NOW())
</foreach>
</insert>
<insert id="batchUpsertStockDailyTrade" parameterType="java.util.List">
insert into t_stock_daily_trade(stock_code, trade_date, open_price, close_price, high_price, low_price,
price_change_rate, volume, turnover, free_circulation_cap,
is_limit_up, is_limit_down, momentum_10d, momentum_20d, momentum_60d, create_time)
values
<foreach collection="list" item="item" separator=",">
(#{item.stockCode}, #{item.tradeDate}, #{item.openPrice}, #{item.closePrice}, #{item.highPrice}, #{item.lowPrice},
#{item.priceChangeRate}, #{item.volume}, #{item.turnover}, #{item.freeCirculationCap},
#{item.isLimitUp}, #{item.isLimitDown}, #{item.momentum10d}, #{item.momentum20d}, #{item.momentum60d}, NOW())
</foreach>
ON DUPLICATE KEY UPDATE
open_price = VALUES(open_price),
close_price = VALUES(close_price),
high_price = VALUES(high_price),
low_price = VALUES(low_price),
price_change_rate = VALUES(price_change_rate),
volume = VALUES(volume),
turnover = VALUES(turnover),
free_circulation_cap = VALUES(free_circulation_cap),
is_limit_up = VALUES(is_limit_up),
is_limit_down = VALUES(is_limit_down),
momentum_10d = VALUES(momentum_10d),
momentum_20d = VALUES(momentum_20d),
momentum_60d = VALUES(momentum_60d)
</insert>
</mapper>

@ -0,0 +1,180 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.newstocksystem.mapper.TStockHighLowStatusMapper">
<resultMap type="com.ruoyi.newstocksystem.domain.TStockHighLowStatus" id="StockHighLowStatusResult">
<result property="stockCode" column="stock_code" />
<result property="tradeDate" column="trade_date" />
<result property="isNewHigh" column="is_new_high" />
<result property="newHighDate" column="new_high_date" />
<result property="isNewLow" column="is_new_low" />
<result property="newLowDate" column="new_low_date" />
<result property="createTime" column="create_time" />
</resultMap>
<resultMap type="com.ruoyi.newstocksystem.domain.TStockHighLowStatus" id="StockHighLowStatusWithBasicResult" extends="StockHighLowStatusResult">
<result property="stockName" column="stock_name" />
<result property="industryIndexCode" column="industry_index_code" />
<result property="industryIndexName" column="industry_index_name" />
</resultMap>
<sql id="selectStockHighLowStatusVo">
select stock_code, trade_date, is_new_high, new_high_date, is_new_low, new_low_date, create_time
from t_stock_high_low_status
</sql>
<sql id="selectStockHighLowStatusWithBasicVo">
select h.stock_code, h.trade_date, h.is_new_high, h.new_high_date, h.is_new_low, h.new_low_date, h.create_time,
b.stock_name, b.industry_index_code, b.industry_index_name
from t_stock_high_low_status h
left join t_stock_basic b on h.stock_code = b.stock_code
</sql>
<select id="selectStockHighLowStatusByCodeAndDate" resultMap="StockHighLowStatusResult">
<include refid="selectStockHighLowStatusVo" />
where stock_code = #{stockCode} and trade_date = #{tradeDate}
</select>
<select id="selectStockHighLowStatusList" parameterType="com.ruoyi.newstocksystem.domain.TStockHighLowStatus" resultMap="StockHighLowStatusResult">
<include refid="selectStockHighLowStatusVo" />
<where>
<if test="stockCode != null and stockCode != ''">
and stock_code = #{stockCode}
</if>
<if test="tradeDate != null">
and trade_date = #{tradeDate}
</if>
<if test="isNewHigh != null">
and is_new_high = #{isNewHigh}
</if>
<if test="isNewLow != null">
and is_new_low = #{isNewLow}
</if>
<if test="params.beginTradeDate != null and params.beginTradeDate != ''">
and trade_date &gt;= #{params.beginTradeDate}
</if>
<if test="params.endTradeDate != null and params.endTradeDate != ''">
and trade_date &lt;= #{params.endTradeDate}
</if>
</where>
order by trade_date desc, stock_code asc
</select>
<select id="selectStockHighLowStatusListWithBasic" parameterType="com.ruoyi.newstocksystem.domain.TStockHighLowStatus" resultMap="StockHighLowStatusWithBasicResult">
<include refid="selectStockHighLowStatusWithBasicVo" />
<where>
<if test="stockCode != null and stockCode != ''">
and h.stock_code like concat('%', #{stockCode}, '%')
</if>
<if test="stockName != null and stockName != ''">
and b.stock_name like concat('%', #{stockName}, '%')
</if>
<if test="tradeDate != null">
and h.trade_date = #{tradeDate}
</if>
<if test="industryIndexCode != null and industryIndexCode != ''">
and b.industry_index_code = #{industryIndexCode}
</if>
<if test="isNewHigh != null">
and h.is_new_high = #{isNewHigh}
</if>
<if test="isNewLow != null">
and h.is_new_low = #{isNewLow}
</if>
<if test="params.beginTradeDate != null and params.beginTradeDate != ''">
and h.trade_date &gt;= #{params.beginTradeDate}
</if>
<if test="params.endTradeDate != null and params.endTradeDate != ''">
and h.trade_date &lt;= #{params.endTradeDate}
</if>
</where>
order by h.trade_date desc, h.stock_code asc
</select>
<select id="selectNewHighStockList" parameterType="com.ruoyi.newstocksystem.domain.TStockHighLowStatus" resultMap="StockHighLowStatusWithBasicResult">
<include refid="selectStockHighLowStatusWithBasicVo" />
<where>
h.is_new_high = 1
<if test="tradeDate != null">
and h.trade_date = #{tradeDate}
</if>
<if test="industryIndexCode != null and industryIndexCode != ''">
and b.industry_index_code = #{industryIndexCode}
</if>
</where>
order by h.trade_date desc, h.stock_code asc
</select>
<select id="selectNewLowStockList" parameterType="com.ruoyi.newstocksystem.domain.TStockHighLowStatus" resultMap="StockHighLowStatusWithBasicResult">
<include refid="selectStockHighLowStatusWithBasicVo" />
<where>
h.is_new_low = 1
<if test="tradeDate != null">
and h.trade_date = #{tradeDate}
</if>
<if test="industryIndexCode != null and industryIndexCode != ''">
and b.industry_index_code = #{industryIndexCode}
</if>
</where>
order by h.trade_date desc, h.stock_code asc
</select>
<insert id="insertStockHighLowStatus" parameterType="com.ruoyi.newstocksystem.domain.TStockHighLowStatus">
insert into t_stock_high_low_status
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="stockCode != null and stockCode != ''">stock_code,</if>
<if test="tradeDate != null">trade_date,</if>
<if test="isNewHigh != null">is_new_high,</if>
<if test="newHighDate != null">new_high_date,</if>
<if test="isNewLow != null">is_new_low,</if>
<if test="newLowDate != null">new_low_date,</if>
create_time,
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="stockCode != null and stockCode != ''">#{stockCode},</if>
<if test="tradeDate != null">#{tradeDate},</if>
<if test="isNewHigh != null">#{isNewHigh},</if>
<if test="newHighDate != null">#{newHighDate},</if>
<if test="isNewLow != null">#{isNewLow},</if>
<if test="newLowDate != null">#{newLowDate},</if>
NOW(),
</trim>
</insert>
<update id="updateStockHighLowStatus" parameterType="com.ruoyi.newstocksystem.domain.TStockHighLowStatus">
update t_stock_high_low_status
<trim prefix="set" suffixOverrides=",">
<if test="isNewHigh != null">is_new_high = #{isNewHigh},</if>
<if test="newHighDate != null">new_high_date = #{newHighDate},</if>
<if test="isNewLow != null">is_new_low = #{isNewLow},</if>
<if test="newLowDate != null">new_low_date = #{newLowDate},</if>
</trim>
where stock_code = #{stockCode} and trade_date = #{tradeDate}
</update>
<delete id="deleteStockHighLowStatusByCodeAndDate">
delete from t_stock_high_low_status where stock_code = #{stockCode} and trade_date = #{tradeDate}
</delete>
<insert id="batchInsertStockHighLowStatus" parameterType="java.util.List">
insert into t_stock_high_low_status(stock_code, trade_date, is_new_high, new_high_date, is_new_low, new_low_date, create_time)
values
<foreach collection="list" item="item" separator=",">
(#{item.stockCode}, #{item.tradeDate}, #{item.isNewHigh}, #{item.newHighDate}, #{item.isNewLow}, #{item.newLowDate}, NOW())
</foreach>
</insert>
<insert id="batchUpsertStockHighLowStatus" parameterType="java.util.List">
insert into t_stock_high_low_status(stock_code, trade_date, is_new_high, new_high_date, is_new_low, new_low_date, create_time)
values
<foreach collection="list" item="item" separator=",">
(#{item.stockCode}, #{item.tradeDate}, #{item.isNewHigh}, #{item.newHighDate}, #{item.isNewLow}, #{item.newLowDate}, NOW())
</foreach>
ON DUPLICATE KEY UPDATE
is_new_high = VALUES(is_new_high),
new_high_date = VALUES(new_high_date),
is_new_low = VALUES(is_new_low),
new_low_date = VALUES(new_low_date)
</insert>
</mapper>

@ -7,7 +7,7 @@ spring:
# 主库数据源
master:
# url: jdbc:mysql://localhost:3306/ry?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
url: jdbc:mysql://192.168.0.222:3306/ry_refactor0118?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
url: jdbc:mysql://192.168.0.222:3306/ry_refactor0120?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
username: root
password: 1qazse42W3
# 从库数据源

@ -0,0 +1,197 @@
import request from '@/utils/request'
// 股票行情数据 API
export default {
// ========================= 行业指数相关 =========================
// 查询行业指数列表
listIndustryIndex(query) {
return request({
url: '/newstocksystem/stockdata/industryIndex/list',
method: 'get',
params: query
})
},
// 查询所有行业指数基础信息(去重)
getDistinctIndustryIndexList() {
return request({
url: '/newstocksystem/stockdata/industryIndex/distinctList',
method: 'get'
})
},
// 导出行业指数数据
exportIndustryIndex(query) {
return request({
url: '/newstocksystem/stockdata/industryIndex/export',
method: 'post',
params: query,
responseType: 'blob'
})
},
// 查询行业指数交易日期列表
getIndustryIndexTradeDates() {
return request({
url: '/newstocksystem/stockdata/industryIndex/tradeDates',
method: 'get'
})
},
// ========================= 个股基础信息相关 =========================
// 查询个股基础信息列表
listStockBasic(query) {
return request({
url: '/newstocksystem/stockdata/stockBasic/list',
method: 'get',
params: query
})
},
// 根据证券代码获取个股基础信息
getStockBasicInfo(stockCode) {
return request({
url: `/newstocksystem/stockdata/stockBasic/${stockCode}`,
method: 'get'
})
},
// 导出个股基础信息
exportStockBasic(query) {
return request({
url: '/newstocksystem/stockdata/stockBasic/export',
method: 'post',
params: query,
responseType: 'blob'
})
},
// 新增个股基础信息
addStockBasic(data) {
return request({
url: '/newstocksystem/stockdata/stockBasic',
method: 'post',
data: data
})
},
// 修改个股基础信息
updateStockBasic(data) {
return request({
url: '/newstocksystem/stockdata/stockBasic',
method: 'put',
data: data
})
},
// 删除个股基础信息
deleteStockBasic(stockCodes) {
return request({
url: `/newstocksystem/stockdata/stockBasic/${stockCodes}`,
method: 'delete'
})
},
// ========================= 个股每日交易数据相关 =========================
// 查询个股每日交易数据列表
listStockDailyTrade(query) {
return request({
url: '/newstocksystem/stockdata/stockDailyTrade/list',
method: 'get',
params: query
})
},
// 查询个股每日交易数据列表(包含基础信息)
listStockDailyTradeWithBasic(query) {
return request({
url: '/newstocksystem/stockdata/stockDailyTrade/listWithBasic',
method: 'get',
params: query
})
},
// 导出个股每日交易数据
exportStockDailyTrade(query) {
return request({
url: '/newstocksystem/stockdata/stockDailyTrade/export',
method: 'post',
params: query,
responseType: 'blob'
})
},
// 查询个股交易日期列表
getStockDailyTradeDates() {
return request({
url: '/newstocksystem/stockdata/stockDailyTrade/tradeDates',
method: 'get'
})
},
// 查询涨停股列表
listLimitUpStocks(query) {
return request({
url: '/newstocksystem/stockdata/stockDailyTrade/limitUpList',
method: 'get',
params: query
})
},
// 查询强势股列表
listStrongStocks(query) {
return request({
url: '/newstocksystem/stockdata/stockDailyTrade/strongList',
method: 'get',
params: query
})
},
// ========================= 个股新高新低状态相关 =========================
// 查询个股新高新低状态列表
listStockHighLowStatus(query) {
return request({
url: '/newstocksystem/stockdata/stockHighLow/list',
method: 'get',
params: query
})
},
// 查询个股新高新低状态列表(包含基础信息)
listStockHighLowStatusWithBasic(query) {
return request({
url: '/newstocksystem/stockdata/stockHighLow/listWithBasic',
method: 'get',
params: query
})
},
// 查询创新高股票列表
listNewHighStocks(query) {
return request({
url: '/newstocksystem/stockdata/stockHighLow/newHighList',
method: 'get',
params: query
})
},
// 查询创新低股票列表
listNewLowStocks(query) {
return request({
url: '/newstocksystem/stockdata/stockHighLow/newLowList',
method: 'get',
params: query
})
}
}
// 导入接口 URL 常量
export const IMPORT_URLS = {
industryIndex: '/newstocksystem/stockdata/industryIndex/importData',
stockBasic: '/newstocksystem/stockdata/stockBasic/importData',
stockDailyTrade: '/newstocksystem/stockdata/stockDailyTrade/importData'
}

@ -0,0 +1,560 @@
<template>
<div class="app-container">
<!-- 数据导入区域 -->
<el-card class="box-card" style="margin-bottom: 15px;">
<div slot="header" class="clearfix">
<span>数据导入</span>
</div>
<el-row :gutter="20">
<el-col :span="8">
<el-button type="primary" icon="el-icon-upload2" @click="handleImport('industryIndex')">
导入行业指数数据
</el-button>
</el-col>
<el-col :span="8">
<el-button type="success" icon="el-icon-upload2" @click="handleImport('stockBasic')">
导入个股基础信息
</el-button>
</el-col>
<el-col :span="8">
<el-button type="warning" icon="el-icon-upload2" @click="handleImport('stockDailyTrade')">
导入每日交易数据
</el-button>
</el-col>
</el-row>
</el-card>
<!-- Tab 页面 -->
<el-tabs v-model="activeTab" type="border-card" @tab-click="handleTabClick">
<!-- 每日交易数据 Tab -->
<el-tab-pane label="每日交易数据" name="dailyTrade">
<el-form :model="dailyTradeQuery" ref="dailyTradeForm" size="small" :inline="true" label-width="80px">
<el-form-item label="证券代码" prop="stockCode">
<el-input v-model="dailyTradeQuery.stockCode" placeholder="请输入证券代码" clearable @keyup.enter.native="queryDailyTrade" />
</el-form-item>
<el-form-item label="证券名称" prop="stockName">
<el-input v-model="dailyTradeQuery.stockName" placeholder="请输入证券名称" clearable @keyup.enter.native="queryDailyTrade" />
</el-form-item>
<el-form-item label="交易日期" prop="tradeDate">
<el-date-picker v-model="dailyTradeQuery.tradeDate" type="date" value-format="yyyy-MM-dd" placeholder="选择交易日期" clearable />
</el-form-item>
<el-form-item label="行业" prop="industryIndexCode">
<el-select v-model="dailyTradeQuery.industryIndexCode" placeholder="请选择行业" clearable filterable>
<el-option v-for="item in industryOptions" :key="item.industryIndexCode" :label="item.industryIndexName" :value="item.industryIndexCode" />
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="queryDailyTrade"></el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetDailyTradeQuery"></el-button>
</el-form-item>
</el-form>
<el-table v-loading="dailyTradeLoading" :data="dailyTradeList" border fit highlight-current-row>
<el-table-column label="证券代码" align="center" prop="stockCode" width="120" />
<el-table-column label="证券名称" align="center" prop="stockName" width="100" />
<el-table-column label="交易日期" align="center" prop="tradeDate" width="110" />
<el-table-column label="开盘价" align="center" prop="openPrice" width="90" />
<el-table-column label="收盘价" align="center" prop="closePrice" width="90" />
<el-table-column label="最高价" align="center" prop="highPrice" width="90" />
<el-table-column label="最低价" align="center" prop="lowPrice" width="90" />
<el-table-column label="涨跌幅(%)" align="center" prop="priceChangeRate" width="100">
<template slot-scope="scope">
<span :class="getChangeClass(scope.row.priceChangeRate)">
{{ formatPercent(scope.row.priceChangeRate) }}
</span>
</template>
</el-table-column>
<el-table-column label="成交量" align="center" prop="volume" width="110" />
<el-table-column label="成交额(万)" align="center" prop="turnover" width="110" />
<el-table-column label="涨停" align="center" prop="isLimitUp" width="60">
<template slot-scope="scope">
<el-tag v-if="scope.row.isLimitUp === 1" type="danger" size="mini"></el-tag>
</template>
</el-table-column>
<el-table-column label="10日动量" align="center" prop="momentum10d" width="90">
<template slot-scope="scope">
<span :class="getChangeClass(scope.row.momentum10d)">
{{ formatPercent(scope.row.momentum10d) }}
</span>
</template>
</el-table-column>
<el-table-column label="20日动量" align="center" prop="momentum20d" width="90">
<template slot-scope="scope">
<span :class="getChangeClass(scope.row.momentum20d)">
{{ formatPercent(scope.row.momentum20d) }}
</span>
</template>
</el-table-column>
<el-table-column label="行业" align="center" prop="industryIndexName" min-width="100" />
</el-table>
<pagination v-show="dailyTradeTotal > 0" :total="dailyTradeTotal" :page.sync="dailyTradeQuery.pageNum" :limit.sync="dailyTradeQuery.pageSize" @pagination="getDailyTradeList" />
</el-tab-pane>
<!-- 股票基础数据 Tab -->
<el-tab-pane label="股票基础数据" name="stockBasic">
<el-form :model="stockBasicQuery" ref="stockBasicForm" size="small" :inline="true" label-width="80px">
<el-form-item label="证券代码" prop="stockCode">
<el-input v-model="stockBasicQuery.stockCode" placeholder="请输入证券代码" clearable @keyup.enter.native="queryStockBasic" />
</el-form-item>
<el-form-item label="证券名称" prop="stockName">
<el-input v-model="stockBasicQuery.stockName" placeholder="请输入证券名称" clearable @keyup.enter.native="queryStockBasic" />
</el-form-item>
<el-form-item label="行业" prop="industryIndexCode">
<el-select v-model="stockBasicQuery.industryIndexCode" placeholder="请选择行业" clearable filterable>
<el-option v-for="item in industryOptions" :key="item.industryIndexCode" :label="item.industryIndexName" :value="item.industryIndexCode" />
</el-select>
</el-form-item>
<el-form-item label="ST股票" prop="isSt">
<el-select v-model="stockBasicQuery.isSt" placeholder="请选择" clearable>
<el-option label="是" :value="1" />
<el-option label="否" :value="0" />
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="queryStockBasic"></el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetStockBasicQuery"></el-button>
</el-form-item>
</el-form>
<el-table v-loading="stockBasicLoading" :data="stockBasicList" border fit highlight-current-row>
<el-table-column label="证券代码" align="center" prop="stockCode" width="130" />
<el-table-column label="证券名称" align="center" prop="stockName" width="120" />
<el-table-column label="上市日期" align="center" prop="listingDate" width="120" />
<el-table-column label="上市天数" align="center" prop="listingDays" width="100" />
<el-table-column label="ST" align="center" prop="isSt" width="60">
<template slot-scope="scope">
<el-tag v-if="scope.row.isSt === 1" type="warning" size="mini">ST</el-tag>
</template>
</el-table-column>
<el-table-column label="*ST" align="center" prop="isStarSt" width="60">
<template slot-scope="scope">
<el-tag v-if="scope.row.isStarSt === 1" type="danger" size="mini">*ST</el-tag>
</template>
</el-table-column>
<el-table-column label="行业代码" align="center" prop="industryIndexCode" width="130" />
<el-table-column label="行业名称" align="center" prop="industryIndexName" min-width="120" />
<el-table-column label="创建时间" align="center" prop="createTime" width="160" />
</el-table>
<pagination v-show="stockBasicTotal > 0" :total="stockBasicTotal" :page.sync="stockBasicQuery.pageNum" :limit.sync="stockBasicQuery.pageSize" @pagination="getStockBasicList" />
</el-tab-pane>
<!-- 行业指数数据 Tab -->
<el-tab-pane label="行业指数数据" name="industryIndex">
<el-form :model="industryIndexQuery" ref="industryIndexForm" size="small" :inline="true" label-width="80px">
<el-form-item label="行业代码" prop="industryIndexCode">
<el-input v-model="industryIndexQuery.industryIndexCode" placeholder="请输入行业代码" clearable @keyup.enter.native="queryIndustryIndex" />
</el-form-item>
<el-form-item label="行业名称" prop="industryIndexName">
<el-input v-model="industryIndexQuery.industryIndexName" placeholder="请输入行业名称" clearable @keyup.enter.native="queryIndustryIndex" />
</el-form-item>
<el-form-item label="交易日期" prop="tradeDate">
<el-date-picker v-model="industryIndexQuery.tradeDate" type="date" value-format="yyyy-MM-dd" placeholder="选择交易日期" clearable />
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="queryIndustryIndex"></el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetIndustryIndexQuery"></el-button>
</el-form-item>
</el-form>
<el-table v-loading="industryIndexLoading" :data="industryIndexList" border fit highlight-current-row>
<el-table-column label="行业代码" align="center" prop="industryIndexCode" width="130" />
<el-table-column label="行业名称" align="center" prop="industryIndexName" width="120" />
<el-table-column label="成份个数" align="center" prop="componentCount" width="90" />
<el-table-column label="交易日期" align="center" prop="tradeDate" width="110" />
<el-table-column label="开盘价" align="center" prop="openPrice" width="100" />
<el-table-column label="收盘价" align="center" prop="closePrice" width="100" />
<el-table-column label="涨跌幅(%)" align="center" prop="priceChangeRate" width="100">
<template slot-scope="scope">
<span :class="getChangeClass(scope.row.priceChangeRate)">
{{ formatPercent(scope.row.priceChangeRate) }}
</span>
</template>
</el-table-column>
<el-table-column label="成交量" align="center" prop="volume" width="120" />
<el-table-column label="成交额(万)" align="center" prop="turnover" width="120" />
<el-table-column label="总市值(万)" align="center" prop="totalMarketCap" width="120" />
<el-table-column label="PE(TTM)" align="center" prop="peTtm" width="90" />
<el-table-column label="PE中位值" align="center" prop="peTtmMedian" width="90" />
</el-table>
<pagination v-show="industryIndexTotal > 0" :total="industryIndexTotal" :page.sync="industryIndexQuery.pageNum" :limit.sync="industryIndexQuery.pageSize" @pagination="getIndustryIndexList" />
</el-tab-pane>
</el-tabs>
<!-- 导入对话框 -->
<el-dialog :title="upload.title" :visible.sync="upload.open" width="500px" append-to-body>
<el-upload
ref="uploadRef"
:limit="1"
accept=".xlsx, .xls"
:headers="uploadHeaders"
:action="upload.url"
:data="upload.data"
:auto-upload="false"
:on-change="handleFileChange"
:on-success="handleUploadSuccess"
:on-error="handleUploadError"
drag
>
<i class="el-icon-upload"></i>
<div class="el-upload__text">将文件拖到此处<em>点击上传</em></div>
<div class="el-upload__tip text-center" slot="tip">
<span>仅允许导入xlsxxls格式文件</span>
</div>
</el-upload>
<el-form :model="upload" style="margin-top: 15px;">
<el-form-item label="是否更新已存在数据">
<el-checkbox v-model="upload.updateSupport"></el-checkbox>
</el-form-item>
<el-form-item v-if="upload.type !== 'stockBasic'" label="交易日期" prop="tradeDate">
<el-date-picker
v-model="upload.tradeDate"
type="date"
value-format="yyyy-MM-dd"
placeholder="选择交易日期"
style="width: 100%;"
/>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitUpload"> </el-button>
<el-button @click="upload.open = false"> </el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { getToken } from '@/utils/auth'
import request from '@/utils/request'
import stockdataApi, { IMPORT_URLS } from '@/api/newstocksystem/stockdata'
export default {
name: 'StockData',
data() {
return {
// Tab
activeTab: 'dailyTrade',
//
industryOptions: [],
// ========================= =========================
dailyTradeLoading: false,
dailyTradeList: [],
dailyTradeTotal: 0,
dailyTradeQuery: {
pageNum: 1,
pageSize: 10,
stockCode: null,
stockName: null,
tradeDate: null,
industryIndexCode: null
},
// ========================= =========================
stockBasicLoading: false,
stockBasicList: [],
stockBasicTotal: 0,
stockBasicQuery: {
pageNum: 1,
pageSize: 10,
stockCode: null,
stockName: null,
industryIndexCode: null,
isSt: null
},
// ========================= =========================
industryIndexLoading: false,
industryIndexList: [],
industryIndexTotal: 0,
industryIndexQuery: {
pageNum: 1,
pageSize: 10,
industryIndexCode: null,
industryIndexName: null,
tradeDate: null
},
// ========================= =========================
upload: {
open: false,
title: '',
type: '', // industryIndex, stockBasic, stockDailyTrade
url: '',
updateSupport: false,
tradeDate: null
},
fileList: []
}
},
computed: {
uploadHeaders() {
return { Authorization: 'Bearer ' + getToken() }
}
},
created() {
this.getIndustryOptions()
this.getDailyTradeList()
},
methods: {
// ========================= =========================
/** 获取行业选项列表 */
getIndustryOptions() {
stockdataApi.getDistinctIndustryIndexList().then(response => {
this.industryOptions = response.data || []
})
},
/** Tab 切换 */
handleTabClick(tab) {
if (tab.name === 'dailyTrade' && this.dailyTradeList.length === 0) {
this.getDailyTradeList()
} else if (tab.name === 'stockBasic' && this.stockBasicList.length === 0) {
this.getStockBasicList()
} else if (tab.name === 'industryIndex' && this.industryIndexList.length === 0) {
this.getIndustryIndexList()
}
},
/** 格式化百分比 */
formatPercent(value) {
if (value === null || value === undefined) return '-'
return (value * 100).toFixed(2) + '%'
},
/** 获取涨跌样式类 */
getChangeClass(value) {
if (value === null || value === undefined) return ''
if (value > 0) return 'text-red'
if (value < 0) return 'text-green'
return ''
},
// ========================= =========================
/** 获取每日交易数据列表 */
getDailyTradeList() {
this.dailyTradeLoading = true
stockdataApi.listStockDailyTradeWithBasic(this.dailyTradeQuery).then(response => {
this.dailyTradeList = response.rows
this.dailyTradeTotal = response.total
this.dailyTradeLoading = false
}).catch(() => {
this.dailyTradeLoading = false
})
},
/** 查询每日交易数据 */
queryDailyTrade() {
this.dailyTradeQuery.pageNum = 1
this.getDailyTradeList()
},
/** 重置每日交易数据查询 */
resetDailyTradeQuery() {
this.$refs.dailyTradeForm.resetFields()
this.dailyTradeQuery = {
pageNum: 1,
pageSize: 10,
stockCode: null,
stockName: null,
tradeDate: null,
industryIndexCode: null
}
this.getDailyTradeList()
},
// ========================= =========================
/** 获取股票基础数据列表 */
getStockBasicList() {
this.stockBasicLoading = true
stockdataApi.listStockBasic(this.stockBasicQuery).then(response => {
this.stockBasicList = response.rows
this.stockBasicTotal = response.total
this.stockBasicLoading = false
}).catch(() => {
this.stockBasicLoading = false
})
},
/** 查询股票基础数据 */
queryStockBasic() {
this.stockBasicQuery.pageNum = 1
this.getStockBasicList()
},
/** 重置股票基础数据查询 */
resetStockBasicQuery() {
this.$refs.stockBasicForm.resetFields()
this.stockBasicQuery = {
pageNum: 1,
pageSize: 10,
stockCode: null,
stockName: null,
industryIndexCode: null,
isSt: null
}
this.getStockBasicList()
},
// ========================= =========================
/** 获取行业指数数据列表 */
getIndustryIndexList() {
this.industryIndexLoading = true
stockdataApi.listIndustryIndex(this.industryIndexQuery).then(response => {
this.industryIndexList = response.rows
this.industryIndexTotal = response.total
this.industryIndexLoading = false
}).catch(() => {
this.industryIndexLoading = false
})
},
/** 查询行业指数数据 */
queryIndustryIndex() {
this.industryIndexQuery.pageNum = 1
this.getIndustryIndexList()
},
/** 重置行业指数数据查询 */
resetIndustryIndexQuery() {
this.$refs.industryIndexForm.resetFields()
this.industryIndexQuery = {
pageNum: 1,
pageSize: 10,
industryIndexCode: null,
industryIndexName: null,
tradeDate: null
}
this.getIndustryIndexList()
},
// ========================= =========================
/** 打开导入对话框 */
handleImport(type) {
this.upload.type = type
this.upload.open = true
this.upload.updateSupport = false
this.upload.tradeDate = null
this.fileList = []
if (type === 'industryIndex') {
this.upload.title = '导入行业指数数据'
this.upload.url = process.env.VUE_APP_BASE_API + IMPORT_URLS.industryIndex
} else if (type === 'stockBasic') {
this.upload.title = '导入个股基础信息'
this.upload.url = process.env.VUE_APP_BASE_API + IMPORT_URLS.stockBasic
} else if (type === 'stockDailyTrade') {
this.upload.title = '导入每日交易数据'
this.upload.url = process.env.VUE_APP_BASE_API + IMPORT_URLS.stockDailyTrade
}
//
this.$nextTick(() => {
if (this.$refs.uploadRef) {
this.$refs.uploadRef.clearFiles()
}
})
},
/** 文件选择变化 */
handleFileChange(file, fileList) {
this.fileList = fileList
},
/** 提交上传 */
submitUpload() {
if (this.fileList.length === 0) {
this.$message.error('请选择要上传的文件')
return
}
if (this.upload.type !== 'stockBasic' && !this.upload.tradeDate) {
this.$message.error('请选择交易日期')
return
}
const formData = new FormData()
formData.append('file', this.fileList[0].raw)
formData.append('updateSupport', this.upload.updateSupport)
if (this.upload.tradeDate) {
formData.append('tradeDate', this.upload.tradeDate)
}
this.upload.open = false
request({
url: this.upload.url,
method: 'post',
data: formData,
headers: {
'Content-Type': 'multipart/form-data'
}
}).then(response => {
this.$message.success(response.msg || '导入成功')
this.refreshCurrentTab()
}).catch(error => {
this.$message.error('导入失败:' + (error.message || '未知错误'))
})
},
/** 上传成功回调 */
handleUploadSuccess(response) {
this.upload.open = false
this.$message.success(response.msg || '导入成功')
this.refreshCurrentTab()
},
/** 上传失败回调 */
handleUploadError() {
this.$message.error('导入失败')
},
/** 刷新当前Tab数据 */
refreshCurrentTab() {
if (this.upload.type === 'industryIndex') {
this.getIndustryIndexList()
this.getIndustryOptions()
} else if (this.upload.type === 'stockBasic') {
this.getStockBasicList()
} else if (this.upload.type === 'stockDailyTrade') {
this.getDailyTradeList()
}
}
}
}
</script>
<style scoped>
.app-container {
padding: 15px;
}
.box-card {
margin-bottom: 15px;
}
.text-red {
color: #f56c6c;
}
.text-green {
color: #67c23a;
}
.clearfix:before,
.clearfix:after {
display: table;
content: "";
}
.clearfix:after {
clear: both;
}
</style>
Loading…
Cancel
Save