diff --git a/add_newstocks_menu.sql b/add_newstocks_menu.sql new file mode 100644 index 0000000..f424d28 --- /dev/null +++ b/add_newstocks_menu.sql @@ -0,0 +1,109 @@ +-- 为新的行情数据页面添加菜单配置 + +-- 1. 首先查询股票系统的父菜单ID +SELECT menu_id, menu_name, parent_id FROM sys_menu WHERE menu_name = '股票系统'; + +-- 2. 假设股票系统的父菜单ID为某个值,添加新的行情数据菜单项 +-- 请根据实际查询结果修改parent_id的值 + +-- 插入新的行情数据菜单项 +INSERT INTO sys_menu ( + menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by +) VALUES ( + '新行情数据', + (SELECT menu_id FROM sys_menu WHERE menu_name = '股票系统'), + '10', + 'newstocks', + 'stocksystem/newstocks', + '1', + '0', + 'C', + '0', + '0', + 'stocksystem:newstocks:list', + 'chart', + 'admin' +); + +-- 3. 为新的行情数据页面添加按钮权限 +-- 获取新插入的菜单ID +SET @menu_id = LAST_INSERT_ID(); + +-- 插入新增按钮权限 +INSERT INTO sys_menu ( + menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by +) VALUES ( + '新增', + @menu_id, + '1', + '#', + NULL, + '1', + '0', + 'F', + '0', + '0', + 'stocksystem:newstocks:add', + '#', + 'admin' +); + +-- 插入修改按钮权限 +INSERT INTO sys_menu ( + menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by +) VALUES ( + '修改', + @menu_id, + '2', + '#', + NULL, + '1', + '0', + 'F', + '0', + '0', + 'stocksystem:newstocks:edit', + '#', + 'admin' +); + +-- 插入删除按钮权限 +INSERT INTO sys_menu ( + menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by +) VALUES ( + '删除', + @menu_id, + '3', + '#', + NULL, + '1', + '0', + 'F', + '0', + '0', + 'stocksystem:newstocks:remove', + '#', + 'admin' +); + +-- 插入导出按钮权限 +INSERT INTO sys_menu ( + menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by +) VALUES ( + '导出', + @menu_id, + '4', + '#', + NULL, + '1', + '0', + 'F', + '0', + '0', + 'stocksystem:newstocks:export', + '#', + 'admin' +); + +-- 4. 查询结果 +SELECT * FROM sys_menu WHERE menu_name LIKE '%新行情数据%' OR parent_id = @menu_id; \ No newline at end of file diff --git a/erDiagram.mmd b/erDiagram.mmd new file mode 100644 index 0000000..384650b --- /dev/null +++ b/erDiagram.mmd @@ -0,0 +1,147 @@ +erDiagram +stock_industry { +INT industry_id PK +TINYINT industry_level +VARCHAR(20) industry_code UK +VARCHAR(50) industry_name +VARCHAR(20) parent_code +} + +stock_basic { +INT id PK +VARCHAR(10) code UK +VARCHAR(20) name +INT industry_id FK +DATE list_date +VARCHAR(10) market_type +TINYINT status +} + +stock_financial { +INT id PK +VARCHAR(10) code FK +DATE period +DECIMAL net_profit_yoy +DECIMAL net_profit_qoq +DECIMAL roe +DECIMAL eps +DECIMAL net_profit +DECIMAL basic_eps +DECIMAL bps +DECIMAL total_assets +DECIMAL total_liabilities +DECIMAL operating_income +DATETIME create_time +} + +stock_index { +INT id PK +VARCHAR(10) code +VARCHAR(20) name +DATE trade_date +DECIMAL open +DECIMAL close +DECIMAL high +DECIMAL low +DECIMAL change_rate +BIGINT volume +DECIMAL amount +DATETIME create_time +} + +stocks { +INT id PK +VARCHAR(10) code FK +DATE trade_date +DECIMAL open +DECIMAL close +DECIMAL change_rate +INT trade_days +BIGINT volume +DECIMAL amount +DECIMAL change_rate_10 +DECIMAL change_rate_20 +DECIMAL change_rate_60 +DECIMAL avg_volume_20 +DECIMAL free_float_market_value +DECIMAL total_market_value +DECIMAL agencies_hold +DATETIME create_time +} + +stock_trend { +INT id PK +VARCHAR(10) code FK +DATE trade_date +DECIMAL ma5 +DECIMAL ma10 +DECIMAL ma20 +DECIMAL ma60 +DECIMAL macd +DECIMAL kdj_k +DECIMAL kdj_d +DECIMAL kdj_j +DECIMAL rsi +DECIMAL volume_ratio +DECIMAL turnover_rate +DATETIME create_time +} + +stock_limit { +INT id PK +VARCHAR(10) code FK +DATE trade_date +TINYINT limit_type +DECIMAL limit_price +DECIMAL open_price +DECIMAL close_price +BIGINT volume +DECIMAL amount +DATETIME create_time +} + +stock_new_record { +INT id PK +VARCHAR(10) code FK +DATE trade_date +TINYINT record_type +DECIMAL price +INT days +DATETIME create_time +} + +trade_dates { +INT id PK +DATE trade_date UK +TINYINT is_trading +SMALLINT year +TINYINT month +TINYINT day +TINYINT weekday +TINYINT is_weekend +TINYINT is_holiday +DATETIME create_time +} + +industry_trend { +INT id PK +INT industry_id FK +DATE trade_date +DECIMAL avg_change_rate +INT up_stocks_count +INT down_stocks_count +INT flat_stocks_count +INT limit_up_count +INT limit_down_count +DECIMAL total_market_value +DECIMAL avg_turnover_rate +DATETIME create_time +} + +stock_basic ||--o{ stock_industry : belongs_to +stock_financial ||--o{ stock_basic : belongs_to +stocks ||--o{ stock_basic : belongs_to +stock_trend ||--o{ stock_basic : belongs_to +stock_limit ||--o{ stock_basic : belongs_to +stock_new_record ||--o{ stock_basic : belongs_to +industry_trend ||--o{ stock_industry : belongs_to \ No newline at end of file diff --git a/newstocks_import_template.xlsx b/newstocks_import_template.xlsx new file mode 100644 index 0000000..c830ba7 --- /dev/null +++ b/newstocks_import_template.xlsx @@ -0,0 +1,6 @@ +股票代码,股票名称,行业ID,行业名称,行业级别,行业代码,父行业代码,首发上市日期,市场类型,状态,交易日期,开盘价,收盘价,涨跌停类型,涨跌停价格,当日涨跌幅,可交易日数,成交量,成交额,10日区间涨跌幅,20日区间涨跌幅,60日区间涨跌幅,20日区间平均成交量,自由流通市值,总市值,机构持仓合计 +600000,浦发银行,1,银行,1,BK0475,0,1999-11-10,SH,1,2026-01-18,8.50,8.65,0,0,1.76,240,12500000,108125000,5.20,8.75,15.30,11000000,280000000000,320000000000,25.50 +600519,贵州茅台,2,白酒,1,BK0477,0,2001-08-27,SH,1,2026-01-18,1850.00,1880.50,1,1880.50,1.65,240,25000,47012500,4.80,7.20,12.50,22000,2400000000000,2600000000000,45.80 +000001,平安银行,1,银行,1,BK0475,0,1991-04-03,SZ,1,2026-01-18,12.80,13.05,0,0,1.92,240,8500000,110925000,6.10,9.30,18.70,7800000,350000000000,380000000000,30.20 +000858,五粮液,2,白酒,1,BK0477,0,1998-04-27,SZ,1,2026-01-18,168.50,172.20,1,172.20,2.20,240,1500000,258300000,5.50,8.10,14.20,1350000,850000000000,920000000000,38.50 +601318,中国平安,3,保险,1,BK0474,0,2007-03-01,SH,1,2026-01-18,48.20,49.50,-1,49.50,2.71,240,3200000,158400000,7.30,10.50,20.10,2900000,420000000000,480000000000,32.80 \ No newline at end of file diff --git a/newstocks_template.xlsx b/newstocks_template.xlsx new file mode 100644 index 0000000..f426e5e Binary files /dev/null and b/newstocks_template.xlsx differ diff --git a/ruoyi-ui/src/api/stocksystem/newstocks.js b/ruoyi-ui/src/api/stocksystem/newstocks.js new file mode 100644 index 0000000..9da4d84 --- /dev/null +++ b/ruoyi-ui/src/api/stocksystem/newstocks.js @@ -0,0 +1,120 @@ +import request from '@/utils/request' + +// 导出API +export default { + // 查询行情数据列表 + listNewStocks(query) { + return request({ + url: '/stocksystem/newstocks/list', + method: 'get', + params: query + }) + }, + + // 查询行情数据列表含基础数据 + listNewStocksB(query) { + return request({ + url: '/stocksystem/newstocks/listB', + method: 'get', + params: query + }) + }, + + // 查询强势股列表 + listNewStrongStocks(query) { + return request({ + url: '/stocksystem/newstocks/listStrongStocks', + method: 'get', + params: query + }) + }, + + // 查询涨停股列表 + listNewLimitStocks(query) { + return request({ + url: '/stocksystem/newstocks/listLimitStocks', + method: 'get', + params: query + }) + }, + + // 获取行情数据详细信息 + getNewStocks(id) { + return request({ + url: `/stocksystem/newstocks/${id}`, + method: 'get' + }) + }, + + // 新增行情数据 + addNewStocks(data) { + return request({ + url: '/stocksystem/newstocks', + method: 'post', + data: data + }) + }, + + // 修改行情数据 + updateNewStocks(data) { + return request({ + url: '/stocksystem/newstocks', + method: 'put', + data: data + }) + }, + + // 删除行情数据 + deleteNewStocks(ids) { + return request({ + url: `/stocksystem/newstocks/${ids}`, + method: 'delete' + }) + }, + + // 导出行情数据 + exportNewStocks(query) { + return request({ + url: '/stocksystem/newstocks/export', + method: 'post', + params: query, + responseType: 'blob' + }) + }, + + // 导入行情数据 + importNewStocks(data) { + return request({ + url: '/stocksystem/newstocks/importData', + method: 'post', + data: data + }) + }, + + // 分析行情数据 + analyzeNewStocks(data) { + return request({ + url: '/stocksystem/newstocks/analyze', + method: 'post', + data: data + }) + }, + + // 获取联想的数据(股票代码) + stockQueryData(query) { + return request({ + url: '/stocksystem/newstocks/stockQueryData', + method: 'get', + params: { query } + }) + }, + + // 获取联想的数据(股票名称) + stockNameQueryData(query) { + return request({ + url: '/stocksystem/newstocks/stockNameQueryData', + method: 'get', + params: { query } + }) + } +} \ No newline at end of file diff --git a/ruoyi-ui/src/views/stocksystem/newstocks.vue b/ruoyi-ui/src/views/stocksystem/newstocks.vue new file mode 100644 index 0000000..1758494 --- /dev/null +++ b/ruoyi-ui/src/views/stocksystem/newstocks.vue @@ -0,0 +1,532 @@ + + + + + diff --git a/stock-system-data-relationships.md b/stock-system-data-relationships.md new file mode 100644 index 0000000..1520aed --- /dev/null +++ b/stock-system-data-relationships.md @@ -0,0 +1,583 @@ +# Stock-System 数据结构关系文档 + +## 1. 文档简介 + +本文档详细梳理了 RuoYi-Vue 项目中 stock-system 模块的所有写入数据库的数据结构及其相互关系。该模块主要用于管理和分析股票相关数据,包括基础信息、交易数据、财务数据和分析指标等。 + +## 2. 核心数据实体 + +### 2.1 股票基础信息 (StockBasic) +- **表名**: `stock_basis` +- **核心字段**: + - `id`: 主键 + - `code`: 股票代码 (关联其他表的关键字段) + - `name`: 股票名称 + - `blemind2`: 所属东财行业指数2级 + - `blemind3`: 所属东财行业指数3级 + - `listdate`: 首发上市日期 + +### 2.2 股票财务数据 (StockFinancial) +- **表名**: `stock_financial` +- **核心字段**: + - `id`: 主键 + - `code`: 股票代码 (关联 StockBasic) + - `period`: 报告期 + - `jlrtbzzl`: 净利润同比增长率 + - `jlrhbzzl`: 净利润环比增长率 + - `jzcsylroe`: 净资产收益率ROE + - `epsbasic`: 每股收益EPS + - `jlr`: 净利润 + - `jbmgsy`: 基本每股收益 + - `mgjzc`: 每股净资产BPS + +### 2.3 股票指数数据 (StockIndex) +- **表名**: `stock_index` +- **核心字段**: + - `id`: 主键 + - `code`: 指数代码 + - `name`: 指数名称 + - `tradeDay`: 交易日期 + - `open`: 开盘价 + - `close`: 收盘价 + - `high`: 最高价 + - `low`: 最低价 + - `differrange`: 涨跌幅 + - `volume`: 成交量 + - `amount`: 成交额 + - `limitupnum`: 涨停家数 + - `limitdownnum`: 跌停家数 + - `mv`: 总市值 + - `pettm`: 市盈率PE + +### 2.4 股票交易数据 (Stocks) +- **表名**: `stocks` +- **核心字段**: + - `id`: 主键 + - `code`: 股票代码 (关联 StockBasic) + - `name`: 股票名称 + - `blemind2`: 所属东财行业指数2级 + - `blemind3`: 所属东财行业指数3级 + - `listdate`: 首发上市日期 + - `tradeDay`: 交易日期 + - `open`: 开盘价 + - `close`: 收盘价 + - `high`: 最高价 + - `low`: 最低价 + - `differrange`: 当日涨跌幅 + - `volumn`: 成交量 + - `amount`: 成交额 + - `differrange3/5/10/15/20/30/60`: 不同周期涨跌幅 + - `islimit`: 是否涨停 + - `isdrop`: 是否跌停 + +### 2.5 股票趋势数据 (StocksInTrend) +- **表名**: `stocks_in_trend` +- **核心字段**: + - `id`: 主键 + - `code`: 股票代码 (关联 StockBasic) + - `tradeDay`: 交易日期 + - `sort`: 排名 + - `type`: 动量数据类型 (10日、20日) + - `name`: 股票名称 + - `blemind2`: 所属东财行业指数2级 + - `blemind3`: 所属东财行业指数3级 + - `open`: 开盘价 + - `close`: 收盘价 + - `differrange`: 当日涨跌幅 + - `differrange10/20/60`: 不同周期涨跌幅 + - `backdifferrange10/20/60`: 不同周期最大回撤 + +### 2.6 股票涨跌停数据 (StocksLimit) +- **表名**: `stocks_limit` +- **核心字段**: + - `id`: 主键 + - `code`: 股票代码 (关联 StockBasic) + - `tradeDay`: 交易日期 + - `islimit`: 是否涨停 + - `isdrop`: 是否跌停 + - `blemind2`: 所属东财行业指数2级 + +### 2.7 股票创新高/新低数据 (StocksNewRecord) +- **表名**: `stocks_new_record` +- **核心字段**: + - `id`: 主键 + - `code`: 股票代码 (关联 StockBasic) + - `tradeDay`: 交易日期 + - `isHigh`: 是否300天新高 + - `isLow`: 是否300天新低 + - `blemind2`: 所属东财行业指数2级 + +### 2.8 交易日数据 (TradeDates) +- **表名**: `trade_dates` +- **核心字段**: + - `date`: 交易日期 + - `week`: 周 + - `trade`: 是否可交易 + +### 2.9 行业趋势分析数据 (Trends) +- **表名**: `trends` +- **核心字段**: + - `id`: 主键 + - `tradeDay`: 交易日期 + - `blemind2`: 所属东财行业指数2级 + - `stocksCount`: 动量个股数量 + - `trendValue`: 动量值 + - `trendValueChange`: 动量值变化 + - `sort`: 板块排名 + - `sortChange`: 板块排名变化 + - `type`: 动量数据类型 (10日、20日) + +## 3. 数据结构关系图 + +``` +┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ +│ StockBasic │────>│ StockFinancial │────>│ Stocks │ +└─────────────────┘ └─────────────────┘ └─────────────────┘ + │ │ │ + │ │ │ + ▼ ▼ ▼ +┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ +│ StockIndex │ │ StocksInTrend │────>│ Trends │ +└─────────────────┘ └─────────────────┘ └─────────────────┘ + │ │ + │ │ + ▼ ▼ +┌─────────────────┐ ┌─────────────────┐ +│ TradeDates │ │ StocksLimit │ +└─────────────────┘ └─────────────────┘ + │ + │ + ▼ + ┌─────────────────┐ + │ StocksNewRecord │ + └─────────────────┘ +``` + +## 4. 详细关系说明 + +### 4.1 基础数据层 +- **StockBasic**: 核心基础表,存储股票基本信息,是其他表的关联基础 +- **TradeDates**: 提供交易日信息,为其他表的时间维度提供参考 + +### 4.2 交易数据层 +- **Stocks**: 存储股票每日交易数据,关联 StockBasic 和 StockFinancial +- **StockIndex**: 存储指数交易数据,反映市场整体情况 +- **StockFinancial**: 存储股票财务数据,与 Stocks 表关联 + +### 4.3 分析数据层 +- **StocksInTrend**: 基于 Stocks 表数据,计算股票趋势指标 +- **StocksLimit**: 基于 Stocks 表数据,记录股票涨跌停情况 +- **StocksNewRecord**: 基于 Stocks 表数据,记录股票创新高/新低情况 +- **Trends**: 基于 StocksInTrend 表数据,分析行业趋势 + +## 5. 核心关键字段关系 + +### 5.1 股票标识关联 +- **code**: 股票代码,贯穿所有股票相关表,是表间关联的核心字段 +- **name**: 股票名称,辅助标识股票 + +### 5.2 时间维度关联 +- **tradeDay**: 交易日期,所有交易和分析数据的时间维度 +- **period**: 财务数据的报告期 +- **date**: 交易日历日期 + +### 5.3 行业分类关联 +- **blemind2**: 东财行业指数2级分类,用于行业分析 +- **blemind3**: 东财行业指数3级分类,更细分的行业分析 + +### 5.4 分析指标关联 +- **differrange**: 涨跌幅,核心分析指标 +- **type**: 动量数据类型,区分不同周期的分析数据 +- **sort**: 排名,用于趋势分析 +- **trendValue**: 动量值,行业趋势分析的核心指标 + +## 6. 数据存储特点 + +### 6.1 时间序列数据 +- 所有交易和分析数据都按交易日存储,形成时间序列 +- 支持多周期分析(3日、5日、10日、15日、20日、30日、60日) + +### 6.2 多维度分析 +- 提供了不同周期的涨跌幅数据 +- 支持按行业分类进行分析 +- 包含多种技术指标(如动量值、最大回撤等) + +### 6.3 数据层次结构 +- **基础数据层**: 存储静态基础信息 +- **交易数据层**: 存储动态交易数据 +- **分析数据层**: 基于基础和交易数据生成的分析结果 + +### 6.4 关联完整性 +- 通过股票代码 (`code`) 和交易日期 (`tradeDay`) 建立了完整的数据关联体系 +- 各表之间的关联关系清晰,数据流向明确 + +## 7. 数据流向 + +1. **基础数据流入**: + - StockBasic 表导入股票基础信息 + - TradeDates 表导入交易日历 + +2. **交易数据流入**: + - Stocks 表导入每日交易数据 + - StockIndex 表导入指数数据 + - StockFinancial 表导入财务报表数据 + +3. **分析数据生成**: + - 基于 Stocks 表数据计算生成 StocksInTrend、StocksLimit、StocksNewRecord + - 基于 StocksInTrend 表数据计算生成 Trends + +## 8. 总结 + +Stock-System 模块采用了层次化的数据结构设计,从基础数据、交易数据到分析数据,形成了完整的数据链路。通过股票代码和交易日期两个核心维度,将各个表关联起来,构建了一个功能完备的股票数据管理系统。 + +该系统不仅存储了基础的股票信息和交易数据,还通过计算生成了丰富的分析指标,为股票分析和投资决策提供了全面的数据支持。数据结构设计合理,关联关系清晰,能够满足股票数据管理和分析的各种需求。 + +## 9. 接口与实现文件 + +### 9.1 股票基础信息 (StockBasic) 相关接口 + +#### 后端接口 +| 接口路径 | 方法 | 功能描述 | 实现文件 | +|---------|------|---------|--------| +| /stocksystem/stockbasic/list | GET | 查询基础数据列表 | stock-system/src/main/java/com/ruoyi/stocksystem/controller/StockBasicController.java | +| /stocksystem/stockbasic/export | POST | 导出基础数据列表 | stock-system/src/main/java/com/ruoyi/stocksystem/controller/StockBasicController.java | +| /stocksystem/stockbasic/{id} | GET | 获取基础数据详细信息 | stock-system/src/main/java/com/ruoyi/stocksystem/controller/StockBasicController.java | +| /stocksystem/stockbasic | POST | 新增基础数据 | stock-system/src/main/java/com/ruoyi/stocksystem/controller/StockBasicController.java | +| /stocksystem/stockbasic | PUT | 修改基础数据 | stock-system/src/main/java/com/ruoyi/stocksystem/controller/StockBasicController.java | +| /stocksystem/stockbasic/{ids} | DELETE | 删除基础数据 | stock-system/src/main/java/com/ruoyi/stocksystem/controller/StockBasicController.java | + +**实现类**: stock-system/src/main/java/com/ruoyi/stocksystem/domain/service/impl/StockBasicServiceImpl.java + +#### 前端调用 +**文件路径**: ruoyi-ui/src/api/stocksystem/stockbasic.js + +| 方法名 | 接口路径 | 功能描述 | +|-------|---------|--------| +| listStockbasic | /stocksystem/stockbasic/list | 查询基础数据列表 | +| getStockbasic | /stocksystem/stockbasic/{id} | 查询基础数据详细 | +| addStockbasic | /stocksystem/stockbasic | 新增基础数据 | +| updateStockbasic | /stocksystem/stockbasic | 修改基础数据 | +| delStockbasic | /stocksystem/stockbasic/{id} | 删除基础数据 | + +### 9.2 股票财务数据 (StockFinancial) 相关接口 + +#### 后端接口 +| 接口路径 | 方法 | 功能描述 | 实现文件 | +|---------|------|---------|--------| +| /stocksystem/financial/list | GET | 查询A股财务数据列表 | stock-system/src/main/java/com/ruoyi/stocksystem/controller/StockFinancialController.java | +| /stocksystem/financial/export | POST | 导出A股财务数据列表 | stock-system/src/main/java/com/ruoyi/stocksystem/controller/StockFinancialController.java | +| /stocksystem/financial/{id} | GET | 获取A股财务数据详细信息 | stock-system/src/main/java/com/ruoyi/stocksystem/controller/StockFinancialController.java | +| /stocksystem/financial | POST | 新增A股财务数据 | stock-system/src/main/java/com/ruoyi/stocksystem/controller/StockFinancialController.java | +| /stocksystem/financial | PUT | 修改A股财务数据 | stock-system/src/main/java/com/ruoyi/stocksystem/controller/StockFinancialController.java | +| /stocksystem/financial/{ids} | DELETE | 删除A股财务数据 | stock-system/src/main/java/com/ruoyi/stocksystem/controller/StockFinancialController.java | +| /stocksystem/financial/importData | POST | 导入财报数据 | stock-system/src/main/java/com/ruoyi/stocksystem/controller/StockFinancialController.java | + +**实现类**: stock-system/src/main/java/com/ruoyi/stocksystem/domain/service/impl/StockFinancialServiceImpl.java + +#### 前端调用 +**文件路径**: ruoyi-ui/src/api/stocksystem/financial.js + +| 方法名 | 接口路径 | 功能描述 | +|-------|---------|--------| +| listFinancial | /stocksystem/financial/list | 查询A股财务数据列表 | +| getFinancial | /stocksystem/financial/{id} | 查询A股财务数据详细 | +| addFinancial | /stocksystem/financial | 新增A股财务数据 | +| updateFinancial | /stocksystem/financial | 修改A股财务数据 | +| delFinancial | /stocksystem/financial/{id} | 删除A股财务数据 | + +### 9.3 股票指数数据 (StockIndex) 相关接口 + +#### 后端接口 +| 接口路径 | 方法 | 功能描述 | 实现文件 | +|---------|------|---------|--------| +| /stocksystem/stockindex/list | GET | 查询指数交易行情列表 | stock-system/src/main/java/com/ruoyi/stocksystem/controller/StockIndexController.java | +| /stocksystem/stockindex/export | POST | 导出指数交易行情列表 | stock-system/src/main/java/com/ruoyi/stocksystem/controller/StockIndexController.java | +| /stocksystem/stockindex/importData | POST | 导入指数数据 | stock-system/src/main/java/com/ruoyi/stocksystem/controller/StockIndexController.java | +| /stocksystem/stockindex/{id} | GET | 获取指数交易行情详细信息 | stock-system/src/main/java/com/ruoyi/stocksystem/controller/StockIndexController.java | +| /stocksystem/stockindex | POST | 新增指数交易行情 | stock-system/src/main/java/com/ruoyi/stocksystem/controller/StockIndexController.java | +| /stocksystem/stockindex | PUT | 修改指数交易行情 | stock-system/src/main/java/com/ruoyi/stocksystem/controller/StockIndexController.java | +| /stocksystem/stockindex/{ids} | DELETE | 删除指数交易行情 | stock-system/src/main/java/com/ruoyi/stocksystem/controller/StockIndexController.java | + +**实现类**: stock-system/src/main/java/com/ruoyi/stocksystem/domain/service/impl/StockIndexServiceImpl.java + +#### 前端调用 +**文件路径**: ruoyi-ui/src/api/stocksystem/stockindex.js + +| 方法名 | 接口路径 | 功能描述 | +|-------|---------|--------| +| listStockindex | /stocksystem/stockindex/list | 查询指数交易行情列表 | +| getStockindex | /stocksystem/stockindex/{id} | 查询指数交易行情详细 | +| addStockindex | /stocksystem/stockindex | 新增指数交易行情 | +| updateStockindex | /stocksystem/stockindex | 修改指数交易行情 | +| delStockindex | /stocksystem/stockindex/{id} | 删除指数交易行情 | + +### 9.4 股票交易数据 (Stocks) 相关接口 + +#### 后端接口 +| 接口路径 | 方法 | 功能描述 | 实现文件 | +|---------|------|---------|--------| +| /stocksystem/stocks/list | GET | 查询行情数据列表 | stock-system/src/main/java/com/ruoyi/stocksystem/controller/StocksController.java | +| /stocksystem/stocks/listB | GET | 查询行情数据列表含基础数据 | stock-system/src/main/java/com/ruoyi/stocksystem/controller/StocksController.java | +| /stocksystem/stocks/listStrongStocks | GET | 查询强势股列表 | stock-system/src/main/java/com/ruoyi/stocksystem/controller/StocksController.java | +| /stocksystem/stocks/listLimitStocks | GET | 查询涨停股列表 | stock-system/src/main/java/com/ruoyi/stocksystem/controller/StocksController.java | +| /stocksystem/stocks/listDropStocks | GET | 查询跌停股列表 | stock-system/src/main/java/com/ruoyi/stocksystem/controller/StocksController.java | +| /stocksystem/stocks/distribution | GET | 查询涨跌分布 | stock-system/src/main/java/com/ruoyi/stocksystem/controller/StocksController.java | +| /stocksystem/stocks/stockindestocksdistribution | GET | 查询板块涨跌分布 | stock-system/src/main/java/com/ruoyi/stocksystem/controller/StocksController.java | +| /stocksystem/stocks/stockHistory | GET | 查询个股历史数据(k线) | stock-system/src/main/java/com/ruoyi/stocksystem/controller/StocksController.java | +| /stocksystem/stocks/stockIndexHistory | GET | 查询板块历史数据(k线) | stock-system/src/main/java/com/ruoyi/stocksystem/controller/StocksController.java | +| /stocksystem/stocks/groupLimitlist | GET | 查询每日涨跌停板列表 | stock-system/src/main/java/com/ruoyi/stocksystem/controller/StocksController.java | +| /stocksystem/stocks/stockQueryData | GET | 获取联想的数据(股票代码) | stock-system/src/main/java/com/ruoyi/stocksystem/controller/StocksController.java | +| /stocksystem/stocks/stockNameQueryData | GET | 获取联想的数据(股票名称) | stock-system/src/main/java/com/ruoyi/stocksystem/controller/StocksController.java | +| /stocksystem/stocks/stockIndexsNameQueryData | GET | 获取联想的数据(指数名称) | stock-system/src/main/java/com/ruoyi/stocksystem/controller/StocksController.java | +| /stocksystem/stocks/getTradeDay | GET | 获取最近的交易日 | stock-system/src/main/java/com/ruoyi/stocksystem/controller/StocksController.java | +| /stocksystem/stocks/export | POST | 导出行情数据列表 | stock-system/src/main/java/com/ruoyi/stocksystem/controller/StocksController.java | +| /stocksystem/stocks/importData | POST | 导入行情数据 | stock-system/src/main/java/com/ruoyi/stocksystem/controller/StocksController.java | + +**实现类**: stock-system/src/main/java/com/ruoyi/stocksystem/domain/service/impl/StocksServiceImpl.java + +#### 前端调用 +**文件路径**: ruoyi-ui/src/api/stocksystem/stocks.js + +| 方法名 | 接口路径 | 功能描述 | +|-------|---------|--------| +| listStocks | /stocksystem/stocks/listB | 查询行情数据列表含基础数据 | +| getStocks | /stocksystem/stocks/{id} | 查询行情数据详细 | +| analysis | /stocksystem/stocks/analysis | 分析行情数据 | +| addStocks | /stocksystem/stocks | 新增行情数据 | +| updateStocks | /stocksystem/stocks | 修改行情数据 | +| delStocks | /stocksystem/stocks/{id} | 删除行情数据 | + +### 9.5 股票趋势数据 (StocksInTrend) 相关接口 + +#### 后端接口 +| 接口路径 | 方法 | 功能描述 | 实现文件 | +|---------|------|---------|--------| +| /stocksystem/trendStocks/list | GET | 查询动量个股列表 | stock-system/src/main/java/com/ruoyi/stocksystem/controller/StocksInTrendController.java | +| /stocksystem/trendStocks/export | POST | 导出动量个股列表 | stock-system/src/main/java/com/ruoyi/stocksystem/controller/StocksInTrendController.java | +| /stocksystem/trendStocks/{id} | GET | 获取动量个股详细信息 | stock-system/src/main/java/com/ruoyi/stocksystem/controller/StocksInTrendController.java | +| /stocksystem/trendStocks | POST | 新增动量个股 | stock-system/src/main/java/com/ruoyi/stocksystem/controller/StocksInTrendController.java | +| /stocksystem/trendStocks | PUT | 修改动量个股 | stock-system/src/main/java/com/ruoyi/stocksystem/controller/StocksInTrendController.java | +| /stocksystem/trendStocks/{ids} | DELETE | 删除动量个股 | stock-system/src/main/java/com/ruoyi/stocksystem/controller/StocksInTrendController.java | + +**实现类**: stock-system/src/main/java/com/ruoyi/stocksystem/domain/service/impl/StocksInTrendServiceImpl.java + +#### 前端调用 +**文件路径**: ruoyi-ui/src/api/stocksystem/trendStocks.js + +| 方法名 | 接口路径 | 功能描述 | +|-------|---------|--------| +| listTrendStocks | /stocksystem/trendStocks/list | 查询动量个股列表 | +| getTrendStocks | /stocksystem/trendStocks/{id} | 查询动量个股详细 | +| addTrendStocks | /stocksystem/trendStocks | 新增动量个股 | +| updateTrendStocks | /stocksystem/trendStocks | 修改动量个股 | +| delTrendStocks | /stocksystem/trendStocks/{id} | 删除动量个股 | + +### 9.6 股票涨跌停数据 (StocksLimit) 相关接口 + +#### 后端接口 +| 接口路径 | 方法 | 功能描述 | 实现文件 | +|---------|------|---------|--------| +| /stocksystem/stockslimit/list | GET | 查询每日涨跌停板列表 | stock-system/src/main/java/com/ruoyi/stocksystem/controller/StocksLimitController.java | +| /stocksystem/stockslimit/grouplist | GET | 查询每日涨跌停板列表(按板块分组) | stock-system/src/main/java/com/ruoyi/stocksystem/controller/StocksLimitController.java | +| /stocksystem/stockslimit/export | POST | 导出每日涨跌停板列表 | stock-system/src/main/java/com/ruoyi/stocksystem/controller/StocksLimitController.java | +| /stocksystem/stockslimit/importData | POST | 导入涨跌停数据 | stock-system/src/main/java/com/ruoyi/stocksystem/controller/StocksLimitController.java | +| /stocksystem/stockslimit/{id} | GET | 获取每日涨跌停板详细信息 | stock-system/src/main/java/com/ruoyi/stocksystem/controller/StocksLimitController.java | +| /stocksystem/stockslimit | POST | 新增每日涨跌停板 | stock-system/src/main/java/com/ruoyi/stocksystem/controller/StocksLimitController.java | +| /stocksystem/stockslimit | PUT | 修改每日涨跌停板 | stock-system/src/main/java/com/ruoyi/stocksystem/controller/StocksLimitController.java | +| /stocksystem/stockslimit/{ids} | DELETE | 删除每日涨跌停板 | stock-system/src/main/java/com/ruoyi/stocksystem/controller/StocksLimitController.java | + +**实现类**: stock-system/src/main/java/com/ruoyi/stocksystem/domain/service/impl/StocksLimitServiceImpl.java + +#### 前端调用 +**文件路径**: ruoyi-ui/src/api/stocksystem/stockslimit.js + +| 方法名 | 接口路径 | 功能描述 | +|-------|---------|--------| +| listStockslimit | /stocksystem/stockslimit/list | 查询每日涨跌停板列表 | +| getStockslimit | /stocksystem/stockslimit/{id} | 查询每日涨跌停板详细 | +| addStockslimit | /stocksystem/stockslimit | 新增每日涨跌停板 | +| updateStockslimit | /stocksystem/stockslimit | 修改每日涨跌停板 | +| delStockslimit | /stocksystem/stockslimit/{id} | 删除每日涨跌停板 | + +### 9.7 股票创新高/新低数据 (StocksNewRecord) 相关接口 + +#### 后端接口 +| 接口路径 | 方法 | 功能描述 | 实现文件 | +|---------|------|---------|--------| +| /stocksystem/newrecord/list | GET | 查询每日创新高新低列表 | stock-system/src/main/java/com/ruoyi/stocksystem/controller/StocksNewRecordController.java | +| /stocksystem/newrecord/export | POST | 导出每日创新高新低列表 | stock-system/src/main/java/com/ruoyi/stocksystem/controller/StocksNewRecordController.java | +| /stocksystem/newrecord/grouplist | GET | 查询每日新高新低列表(按板块分组) | stock-system/src/main/java/com/ruoyi/stocksystem/controller/StocksNewRecordController.java | +| /stocksystem/newrecord/getAllNewRecords | GET | 查询每日新高新低列表 | stock-system/src/main/java/com/ruoyi/stocksystem/controller/StocksNewRecordController.java | +| /stocksystem/newrecord/importData | POST | 导入创新高新低数据 | stock-system/src/main/java/com/ruoyi/stocksystem/controller/StocksNewRecordController.java | +| /stocksystem/newrecord/{id} | GET | 获取每日创新高新低详细信息 | stock-system/src/main/java/com/ruoyi/stocksystem/controller/StocksNewRecordController.java | +| /stocksystem/newrecord | POST | 新增每日创新高新低 | stock-system/src/main/java/com/ruoyi/stocksystem/controller/StocksNewRecordController.java | +| /stocksystem/newrecord | PUT | 修改每日创新高新低 | stock-system/src/main/java/com/ruoyi/stocksystem/controller/StocksNewRecordController.java | +| /stocksystem/newrecord/{ids} | DELETE | 删除每日创新高新低 | stock-system/src/main/java/com/ruoyi/stocksystem/controller/StocksNewRecordController.java | + +**实现类**: stock-system/src/main/java/com/ruoyi/stocksystem/domain/service/impl/StocksNewRecordServiceImpl.java + +#### 前端调用 +**文件路径**: ruoyi-ui/src/api/stocksystem/newrecord.js + +| 方法名 | 接口路径 | 功能描述 | +|-------|---------|--------| +| listNewrecord | /stocksystem/newrecord/list | 查询每日创新高新低列表 | +| getNewrecord | /stocksystem/newrecord/{id} | 查询每日创新高新低详细 | +| addNewrecord | /stocksystem/newrecord | 新增每日创新高新低 | +| updateNewrecord | /stocksystem/newrecord | 修改每日创新高新低 | +| delNewrecord | /stocksystem/newrecord/{id} | 删除每日创新高新低 | + +### 9.8 交易日数据 (TradeDates) 相关接口 + +#### 后端接口 +| 接口路径 | 方法 | 功能描述 | 实现文件 | +|---------|------|---------|--------| +| /stocksystem/tradedates/list | GET | 查询可交易日期列表 | stock-system/src/main/java/com/ruoyi/stocksystem/controller/TradeDatesController.java | +| /stocksystem/tradedates/export | POST | 导出可交易日期列表 | stock-system/src/main/java/com/ruoyi/stocksystem/controller/TradeDatesController.java | +| /stocksystem/tradedates/{date} | GET | 获取可交易日期详细信息 | stock-system/src/main/java/com/ruoyi/stocksystem/controller/TradeDatesController.java | +| /stocksystem/tradedates | POST | 新增可交易日期 | stock-system/src/main/java/com/ruoyi/stocksystem/controller/TradeDatesController.java | +| /stocksystem/tradedates | PUT | 修改可交易日期 | stock-system/src/main/java/com/ruoyi/stocksystem/controller/TradeDatesController.java | +| /stocksystem/tradedates/{dates} | DELETE | 删除可交易日期 | stock-system/src/main/java/com/ruoyi/stocksystem/controller/TradeDatesController.java | + +**实现类**: stock-system/src/main/java/com/ruoyi/stocksystem/domain/service/impl/TradeDatesServiceImpl.java + +#### 前端调用 +**注**: 交易日数据的前端调用主要通过其他模块间接使用,例如在获取最近交易日时调用 /stocksystem/stocks/getTradeDay 接口。 + +### 9.9 行业趋势分析数据 (Trends) 相关接口 + +#### 后端接口 +| 接口路径 | 方法 | 功能描述 | 实现文件 | +|---------|------|---------|--------| +| /stocksystem/trends/list | GET | 查询动量结果列表 | stock-system/src/main/java/com/ruoyi/stocksystem/controller/TrendsController.java | +| /stocksystem/trends/querylist | GET | 查询动量结果列表 | stock-system/src/main/java/com/ruoyi/stocksystem/controller/TrendsController.java | +| /stocksystem/trends/querytrendstockslist | GET | 查询动量个股列表 | stock-system/src/main/java/com/ruoyi/stocksystem/controller/TrendsController.java | +| /stocksystem/trends/listSection | GET | 查询行业趋势数据 | stock-system/src/main/java/com/ruoyi/stocksystem/controller/TrendsController.java | +| /stocksystem/trends/listTradeVolume | GET | 查询行业交易量数据 | stock-system/src/main/java/com/ruoyi/stocksystem/controller/TrendsController.java | +| /stocksystem/trends/listStockIndexLimitUp | GET | 查询行业涨停家数数据 | stock-system/src/main/java/com/ruoyi/stocksystem/controller/TrendsController.java | +| /stocksystem/trends/listStockIndexLimitDown | GET | 查询行业跌停家数数据 | stock-system/src/main/java/com/ruoyi/stocksystem/controller/TrendsController.java | +| /stocksystem/trends/listStockIndexHighRocord | GET | 查询行业创新高数据 | stock-system/src/main/java/com/ruoyi/stocksystem/controller/TrendsController.java | +| /stocksystem/trends/listStockIndexLowRocord | GET | 查询行业创新低数据 | stock-system/src/main/java/com/ruoyi/stocksystem/controller/TrendsController.java | +| /stocksystem/trends/listSectionByBlemind | GET | 查询板块动量值 | stock-system/src/main/java/com/ruoyi/stocksystem/controller/TrendsController.java | +| /stocksystem/trends/export | POST | 导出动量结果列表 | stock-system/src/main/java/com/ruoyi/stocksystem/controller/TrendsController.java | +| /stocksystem/trends/{id} | GET | 获取动量结果详细信息 | stock-system/src/main/java/com/ruoyi/stocksystem/controller/TrendsController.java | +| /stocksystem/trends | POST | 新增动量结果 | stock-system/src/main/java/com/ruoyi/stocksystem/controller/TrendsController.java | +| /stocksystem/trends | PUT | 修改动量结果 | stock-system/src/main/java/com/ruoyi/stocksystem/controller/TrendsController.java | +| /stocksystem/trends/{ids} | DELETE | 删除动量结果 | stock-system/src/main/java/com/ruoyi/stocksystem/controller/TrendsController.java | + +**实现类**: stock-system/src/main/java/com/ruoyi/stocksystem/domain/service/impl/TrendsServiceImpl.java + +#### 前端调用 +**文件路径**: ruoyi-ui/src/api/stocksystem/trends.js + +| 方法名 | 接口路径 | 功能描述 | +|-------|---------|--------| +| listTrends | /stocksystem/trends/list | 查询动量结果列表 | +| listTrendsSection | /stocksystem/trends/listSection | 查询时间段内动量结果列表 | +| listTradeVolume | /stocksystem/trends/listTradeVolume | 查询行业交易量数据 | +| listStockIndexLimitUp | /stocksystem/trends/listStockIndexLimitUp | 查询指数内涨停板数量 | +| listStockIndexLimitDown | /stocksystem/trends/listStockIndexLimitDown | 查询板块内跌停板数量 | +| listStockIndexHighRocord | /stocksystem/trends/listStockIndexHighRocord | 查询创新高板块 | +| listStockIndexLowRocord | /stocksystem/trends/listStockIndexLowRocord | 查询创新低板块 | +| listSectionByBlemind | /stocksystem/trends/listSectionByBlemind | 查询板块动量值 | +| listStockHistory | /stocksystem/stocks/stockHistory | 查询个股历史k线数据 | +| listStockIndexHistory | /stocksystem/stocks/stockIndexHistory | 板块历史k线数据 | +| getTrends | /stocksystem/trends/{id} | 查询动量结果详细 | +| addTrends | /stocksystem/trends | 新增动量结果 | +| updateTrends | /stocksystem/trends | 修改动量结果 | +| delTrends | /stocksystem/trends/{id} | 删除动量结果 | + +## 10. Redis 缓存使用分析 + +### 10.1 缓存键定义 + +所有缓存键常量定义在 `com.ruoyi.common.constant.Constants` 类中,主要包括: + +| 缓存键常量 | 含义 | 过期时间 | +|----------|------|--------| +| `EXPIRED_TIME` | 默认过期时间 | 3天(60*60*24*3秒) | +| `TRENDS` | 动量趋势数据 | - | +| `HOME_HIGH_DISTRIBUTE` | 首页新高分布 | - | +| `HOME_LOW_DISTRIBUTE` | 首页新低分布 | - | +| `HOME_TRENDS_STOCKS` | 首页动量趋势个股 | - | +| `TRENDS_SECTION_BLEMIND` | 板块趋势值 | - | +| `HOME_STRONG_STOCKS` | 首页强势个股 | - | +| `HOME_LIMIT_STOCKS` | 首页涨停个股 | - | +| `HOME_DROP_LIMIT_STOCKS` | 首页跌停个股 | - | +| `HOME_STOCKS_DISTRIBUTE` | 首页涨跌分布 | - | +| `STOCKINDEX_STOCKS_DISTRIBUTE` | 板块涨跌分布 | - | +| `STOCK_CODE_QUERY` | 个股代码联想 | - | +| `STOCK_NAME_QUERY` | 个股名称联想 | - | +| `STOCKINDEX_NAME_QUERY` | 板块名称联想 | - | + +### 10.2 缓存使用场景 + +#### 10.2.1 股票交易数据 (Stocks) 缓存 + +| 接口 | 缓存键 | 功能描述 | 过期时间 | +|-----|-------|---------|--------| +| /stocksystem/stocks/listStrongStocks | HOME_STRONG_STOCKS + 日期 + "_" + 类型 | 查询强势股 | 3天 | +| /stocksystem/stocks/listLimitStocks | HOME_LIMIT_STOCKS + 日期 + "_" + 类型 | 查询涨停股 | 3天 | +| /stocksystem/stocks/listDropStocks | HOME_DROP_LIMIT_STOCKS + 日期 + "_" + 类型 | 查询跌停股 | 3天 | +| /stocksystem/stocks/distribution | HOME_STOCKS_DISTRIBUTE + 日期 + "_" + 类型 | 查询涨跌分布 | 3天 | +| /stocksystem/stocks/stockindestocksdistribution | STOCKINDEX_STOCKS_DISTRIBUTE + 日期 + "_" + 板块 | 查询板块涨跌分布 | 3天 | +| /stocksystem/stocks/groupLimitlist | 动态生成 | 查询每日涨跌停板列表 | 3天 | +| /stocksystem/stocks/stockQueryData | STOCK_CODE_QUERY | 获取个股代码联想数据 | 12小时 | +| /stocksystem/stocks/stockNameQueryData | STOCK_NAME_QUERY | 获取个股名称联想数据 | 12小时 | +| /stocksystem/stocks/stockIndexsNameQueryData | STOCKINDEX_NAME_QUERY | 获取板块名称联想数据 | 12小时 | +| /stocksystem/stocks/getTradeDay | 动态生成 | 获取最近交易日 | - | + +#### 10.2.2 股票创新高/新低数据 (StocksNewRecord) 缓存 + +| 接口 | 缓存键 | 功能描述 | 过期时间 | +|-----|-------|---------|--------| +| /stocksystem/newrecord/grouplist | HOME_HIGH_DISTRIBUTE/HOME_LOW_DISTRIBUTE + 日期 | 查询每日新高新低列表 | 3天 | + +#### 10.2.3 行业趋势分析数据 (Trends) 缓存 + +| 接口 | 缓存键 | 功能描述 | 过期时间 | +|-----|-------|---------|--------| +| /stocksystem/trends/querytrendstockslist | HOME_TRENDS_STOCKS + 日期 + "_" + 类型 | 查询动量趋势个股 | 3天 | +| /stocksystem/trends/listSection | TRENDS + 日期 + "_" + 类型 | 查询行情数据列表含基础数据 | 3天 | +| /stocksystem/trends/listSectionByBlemind | TRENDS_SECTION_BLEMIND + 日期 + "_" + 板块 + "_" + 类型 | 查询板块动量值 | 3天 | + +### 10.3 缓存使用模式 + +各控制器采用统一的缓存使用模式: + +1. **生成缓存键**:根据业务参数(如日期、类型、板块等)动态生成缓存键 +2. **查询缓存**:使用 `redisCache.getCacheList()` 或 `redisCache.getCacheObject()` 查询缓存 +3. **缓存命中处理**:如果缓存存在,直接返回缓存数据 +4. **缓存未命中处理**: + - 查询数据库获取数据 + - 使用 `redisCache.setCacheList()` 或 `redisCache.setCacheObject()` 将数据存入缓存 + - 使用 `redisCache.expire()` 设置缓存过期时间 +5. **特殊情况**:当存在搜索条件时,通常不走缓存,也不缓存结果 + +## 11. 附录 + +### 11.1 数据实体对应文件路径 + +| 数据实体 | 文件路径 | +|---------|--------| +| StockBasic | stock-system/src/main/java/com/ruoyi/stocksystem/domain/StockBasic.java | +| StockFinancial | stock-system/src/main/java/com/ruoyi/stocksystem/domain/StockFinancial.java | +| StockIndex | stock-system/src/main/java/com/ruoyi/stocksystem/domain/StockIndex.java | +| Stocks | stock-system/src/main/java/com/ruoyi/stocksystem/domain/Stocks.java | +| StocksInTrend | stock-system/src/main/java/com/ruoyi/stocksystem/domain/StocksInTrend.java | +| StocksLimit | stock-system/src/main/java/com/ruoyi/stocksystem/domain/StocksLimit.java | +| StocksNewRecord | stock-system/src/main/java/com/ruoyi/stocksystem/domain/StocksNewRecord.java | +| TradeDates | stock-system/src/main/java/com/ruoyi/stocksystem/domain/TradeDates.java | +| Trends | stock-system/src/main/java/com/ruoyi/stocksystem/domain/Trends.java | + +### 11.2 技术实现特点 + +- 采用了典型的 MVC 架构 +- 使用 MyBatis 作为 ORM 框架与数据库交互 +- 支持 Excel 导入导出功能 +- 提供了丰富的分析指标和查询功能 +- 数据结构设计符合金融行业特点,支持高频数据处理 +- 集成了 Redis 缓存,提高查询性能 +- 提供了丰富的统计分析接口,支持多维度数据查询 +- 缓存键设计合理,分层清晰,便于管理和维护 +- 缓存过期时间设置合理,平衡了性能和数据新鲜度 diff --git a/stock-system-optimized-schema.sql b/stock-system-optimized-schema.sql new file mode 100644 index 0000000..71dda27 --- /dev/null +++ b/stock-system-optimized-schema.sql @@ -0,0 +1,230 @@ +-- Stock-System 优化后的数据库表结构 + +-- 设置字符集 +SET NAMES utf8mb4; +SET FOREIGN_KEY_CHECKS = 0; + +-- 1. 基础数据表 + +-- 1.1 行业表 +DROP TABLE IF EXISTS `new_stock_industry`; +CREATE TABLE `new_stock_industry` ( + `industry_id` INT NOT NULL AUTO_INCREMENT COMMENT '行业ID', + `industry_level` TINYINT NOT NULL COMMENT '行业级别(1-3)', + `industry_code` VARCHAR(20) NOT NULL COMMENT '行业代码', + `industry_name` VARCHAR(50) NOT NULL COMMENT '行业名称', + `parent_code` VARCHAR(20) NULL COMMENT '父行业代码', + PRIMARY KEY (`industry_id`) USING BTREE, + UNIQUE INDEX `idx_industry_code` (`industry_code`) USING BTREE, + INDEX `idx_industry_level` (`industry_level`) USING BTREE, + INDEX `idx_parent_code` (`parent_code`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '行业分类表' ROW_FORMAT = Dynamic; + +-- 1.2 股票基础信息表 +DROP TABLE IF EXISTS `new_stock_basic`; +CREATE TABLE `new_stock_basic` ( + `id` INT NOT NULL AUTO_INCREMENT COMMENT '主键ID', + `code` VARCHAR(10) NOT NULL COMMENT '股票代码', + `name` VARCHAR(20) NOT NULL COMMENT '股票名称', + `industry_id` INT NULL COMMENT '所属行业ID(关联new_stock_industry)', + `list_date` DATE NULL COMMENT '首发上市日期', + `market_type` VARCHAR(10) NULL COMMENT '市场类型(SZ/SH)', + `status` TINYINT DEFAULT 1 COMMENT '状态(1-正常,0-暂停上市)', + PRIMARY KEY (`id`) USING BTREE, + UNIQUE INDEX `idx_code` (`code`) USING BTREE, + INDEX `idx_industry_id` (`industry_id`) USING BTREE, + INDEX `idx_list_date` (`list_date`) USING BTREE, + INDEX `idx_market_type` (`market_type`) USING BTREE, + CONSTRAINT `fk_stock_basic_industry` FOREIGN KEY (`industry_id`) REFERENCES `new_stock_industry` (`industry_id`) ON DELETE SET NULL ON UPDATE CASCADE +) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '股票基础信息表' ROW_FORMAT = Dynamic; + +-- 2. 财务数据表 + +-- 2.1 财务数据表 +DROP TABLE IF EXISTS `new_stock_financial`; +CREATE TABLE `new_stock_financial` ( + `id` INT NOT NULL AUTO_INCREMENT COMMENT '主键ID', + `code` VARCHAR(10) NOT NULL COMMENT '股票代码(关联new_stock_basic)', + `period` DATE NOT NULL COMMENT '报告期', + `net_profit_yoy` DECIMAL(15,4) NULL COMMENT '净利润同比增长率', + `net_profit_qoq` DECIMAL(15,4) NULL COMMENT '净利润环比增长率', + `roe` DECIMAL(10,4) NULL COMMENT '净资产收益率ROE', + `eps` DECIMAL(10,4) NULL COMMENT '每股收益EPS', + `net_profit` DECIMAL(20,4) NULL COMMENT '净利润', + `basic_eps` DECIMAL(10,4) NULL COMMENT '基本每股收益', + `bps` DECIMAL(10,4) NULL COMMENT '每股净资产BPS', + `total_assets` DECIMAL(20,4) NULL COMMENT '总资产', + `total_liabilities` DECIMAL(20,4) NULL COMMENT '总负债', + `operating_income` DECIMAL(20,4) NULL COMMENT '营业收入', + `create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + PRIMARY KEY (`id`) USING BTREE, + UNIQUE INDEX `idx_code_period` (`code`, `period`) USING BTREE, + INDEX `idx_period` (`period`) USING BTREE, + INDEX `idx_roe` (`roe`) USING BTREE, + INDEX `idx_eps` (`eps`) USING BTREE, + CONSTRAINT `fk_stock_financial_basic` FOREIGN KEY (`code`) REFERENCES `new_stock_basic` (`code`) ON DELETE CASCADE ON UPDATE CASCADE +) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '股票财务数据表' ROW_FORMAT = Dynamic; + +-- 3. 指数数据表 + +-- 3.1 指数数据表 +DROP TABLE IF EXISTS `new_stock_index`; +CREATE TABLE `new_stock_index` ( + `id` INT NOT NULL AUTO_INCREMENT COMMENT '主键ID', + `code` VARCHAR(10) NOT NULL COMMENT '指数代码', + `name` VARCHAR(20) NOT NULL COMMENT '指数名称', + `trade_date` DATE NOT NULL COMMENT '交易日期', + `open` DECIMAL(10,2) NULL COMMENT '开盘价', + `close` DECIMAL(10,2) NULL COMMENT '收盘价', + `high` DECIMAL(10,2) NULL COMMENT '最高价', + `low` DECIMAL(10,2) NULL COMMENT '最低价', + `change_rate` DECIMAL(8,4) NULL COMMENT '涨跌幅', + `volume` BIGINT NULL COMMENT '成交量', + `amount` DECIMAL(20,2) NULL COMMENT '成交额', + `create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + PRIMARY KEY (`id`) USING BTREE, + UNIQUE INDEX `idx_code_trade_date` (`code`, `trade_date`) USING BTREE, + INDEX `idx_trade_date` (`trade_date`) USING BTREE, + INDEX `idx_change_rate` (`change_rate`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '股票指数数据表' ROW_FORMAT = Dynamic; + +-- 4. 交易数据表 + +-- 4.1 交易数据表 +DROP TABLE IF EXISTS `new_stocks`; +CREATE TABLE `new_stocks` ( + `id` INT NOT NULL AUTO_INCREMENT COMMENT '主键ID', + `code` VARCHAR(10) NOT NULL COMMENT '股票代码(关联new_stock_basic)', + `trade_date` DATE NOT NULL COMMENT '交易日期', + `open` DECIMAL(10,2) NULL COMMENT '开盘价', + `close` DECIMAL(10,2) NULL COMMENT '收盘价', + `change_rate` DECIMAL(8,4) NULL COMMENT '当日涨跌幅', + `trade_days` INT NULL COMMENT '可交易日数', + `volume` BIGINT NULL COMMENT '成交量', + `amount` DECIMAL(20,2) NULL COMMENT '成交额', + `change_rate_10` DECIMAL(8,4) NULL COMMENT '10日区间涨跌幅', + `change_rate_20` DECIMAL(8,4) NULL COMMENT '20日区间涨跌幅', + `change_rate_60` DECIMAL(8,4) NULL COMMENT '60日区间涨跌幅', + `avg_volume_20` DECIMAL(20,2) NULL COMMENT '20日区间平均成交量', + `free_float_market_value` DECIMAL(20,2) NULL COMMENT '自由流通市值', + `total_market_value` DECIMAL(20,2) NULL COMMENT '总市值', + `agencies_hold` DECIMAL(10,4) NULL COMMENT '机构持仓合计', + `create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + PRIMARY KEY (`id`) USING BTREE, + UNIQUE INDEX `idx_code_trade_date` (`code`, `trade_date`) USING BTREE, + INDEX `idx_trade_date` (`trade_date`) USING BTREE, + INDEX `idx_change_rate` (`change_rate`) USING BTREE, + INDEX `idx_total_market_value` (`total_market_value`) USING BTREE, + CONSTRAINT `fk_stocks_basic` FOREIGN KEY (`code`) REFERENCES `new_stock_basic` (`code`) ON DELETE CASCADE ON UPDATE CASCADE +) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '股票每日交易数据表' ROW_FORMAT = Dynamic; + +-- 5. 趋势数据表 + +-- 5.1 趋势数据表 +DROP TABLE IF EXISTS `new_stock_trend`; +CREATE TABLE `new_stock_trend` ( + `id` INT NOT NULL AUTO_INCREMENT COMMENT '主键ID', + `code` VARCHAR(10) NOT NULL COMMENT '股票代码(关联new_stock_basic)', + `trade_date` DATE NOT NULL COMMENT '交易日期', + `ma5` DECIMAL(10,2) NULL COMMENT '5日均线', + `ma10` DECIMAL(10,2) NULL COMMENT '10日均线', + `ma20` DECIMAL(10,2) NULL COMMENT '20日均线', + `ma60` DECIMAL(10,2) NULL COMMENT '60日均线', + `macd` DECIMAL(8,4) NULL COMMENT 'MACD值', + `kdj_k` DECIMAL(8,4) NULL COMMENT 'KDJ-K值', + `kdj_d` DECIMAL(8,4) NULL COMMENT 'KDJ-D值', + `kdj_j` DECIMAL(8,4) NULL COMMENT 'KDJ-J值', + `rsi` DECIMAL(8,4) NULL COMMENT 'RSI值', + `volume_ratio` DECIMAL(8,4) NULL COMMENT '量比', + `turnover_rate` DECIMAL(8,4) NULL COMMENT '换手率', + `create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + PRIMARY KEY (`id`) USING BTREE, + UNIQUE INDEX `idx_code_trade_date` (`code`, `trade_date`) USING BTREE, + INDEX `idx_trade_date` (`trade_date`) USING BTREE, + CONSTRAINT `fk_stock_trend_basic` FOREIGN KEY (`code`) REFERENCES `new_stock_basic` (`code`) ON DELETE CASCADE ON UPDATE CASCADE +) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '股票趋势数据表' ROW_FORMAT = Dynamic; + +-- 5.2 涨跌停数据表 +DROP TABLE IF EXISTS `new_stock_limit`; +CREATE TABLE `new_stock_limit` ( + `id` INT NOT NULL AUTO_INCREMENT COMMENT '主键ID', + `code` VARCHAR(10) NOT NULL COMMENT '股票代码(关联new_stock_basic)', + `trade_date` DATE NOT NULL COMMENT '交易日期', + `limit_type` TINYINT NOT NULL COMMENT '涨跌停类型(1-涨停,-1-跌停)', + `limit_price` DECIMAL(10,2) NULL COMMENT '涨跌停价格', + `open_price` DECIMAL(10,2) NULL COMMENT '开盘价', + `close_price` DECIMAL(10,2) NULL COMMENT '收盘价', + `volume` BIGINT NULL COMMENT '成交量', + `amount` DECIMAL(20,2) NULL COMMENT '成交额', + `create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + PRIMARY KEY (`id`) USING BTREE, + UNIQUE INDEX `idx_code_trade_date` (`code`, `trade_date`) USING BTREE, + INDEX `idx_trade_date` (`trade_date`) USING BTREE, + INDEX `idx_limit_type` (`limit_type`) USING BTREE, + CONSTRAINT `fk_stock_limit_basic` FOREIGN KEY (`code`) REFERENCES `new_stock_basic` (`code`) ON DELETE CASCADE ON UPDATE CASCADE +) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '股票涨跌停数据表' ROW_FORMAT = Dynamic; + +-- 5.3 创新高/新低数据表 +DROP TABLE IF EXISTS `new_stock_new_record`; +CREATE TABLE `new_stock_new_record` ( + `id` INT NOT NULL AUTO_INCREMENT COMMENT '主键ID', + `code` VARCHAR(10) NOT NULL COMMENT '股票代码(关联new_stock_basic)', + `trade_date` DATE NOT NULL COMMENT '交易日期', + `record_type` TINYINT NOT NULL COMMENT '记录类型(1-创新高,-1-创新低)', + `price` DECIMAL(10,2) NOT NULL COMMENT '价格', + `days` INT NULL COMMENT '创新高/新低天数', + `create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + PRIMARY KEY (`id`) USING BTREE, + UNIQUE INDEX `idx_code_trade_date` (`code`, `trade_date`) USING BTREE, + INDEX `idx_trade_date` (`trade_date`) USING BTREE, + INDEX `idx_record_type` (`record_type`) USING BTREE, + CONSTRAINT `fk_stock_new_record_basic` FOREIGN KEY (`code`) REFERENCES `new_stock_basic` (`code`) ON DELETE CASCADE ON UPDATE CASCADE +) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '股票创新高/新低数据表' ROW_FORMAT = Dynamic; + +-- 6. 交易日数据 + +-- 6.1 交易日历表 +DROP TABLE IF EXISTS `new_trade_dates`; +CREATE TABLE `new_trade_dates` ( + `id` INT NOT NULL AUTO_INCREMENT COMMENT '主键ID', + `trade_date` DATE NOT NULL COMMENT '交易日日期', + `is_trading` TINYINT DEFAULT 1 COMMENT '是否交易日(1-是,0-否)', + `year` SMALLINT NOT NULL COMMENT '年份', + `month` TINYINT NOT NULL COMMENT '月份', + `day` TINYINT NOT NULL COMMENT '日期', + `weekday` TINYINT NOT NULL COMMENT '星期几(1-7)', + `is_weekend` TINYINT DEFAULT 0 COMMENT '是否周末(1-是,0-否)', + `is_holiday` TINYINT DEFAULT 0 COMMENT '是否节假日(1-是,0-否)', + `create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + PRIMARY KEY (`id`) USING BTREE, + UNIQUE INDEX `idx_trade_date` (`trade_date`) USING BTREE, + INDEX `idx_year_month` (`year`, `month`) USING BTREE, + INDEX `idx_is_trading` (`is_trading`) USING BTREE, + INDEX `idx_weekday` (`weekday`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '交易日历表' ROW_FORMAT = Dynamic; + +-- 7. 行业趋势分析数据 + +-- 7.1 行业趋势表 +DROP TABLE IF EXISTS `new_industry_trend`; +CREATE TABLE `new_industry_trend` ( + `id` INT NOT NULL AUTO_INCREMENT COMMENT '主键ID', + `industry_id` INT NOT NULL COMMENT '行业ID(关联new_stock_industry)', + `trade_date` DATE NOT NULL COMMENT '交易日期', + `avg_change_rate` DECIMAL(8,4) NULL COMMENT '行业平均涨跌幅', + `up_stocks_count` INT NULL COMMENT '上涨股票数', + `down_stocks_count` INT NULL COMMENT '下跌股票数', + `flat_stocks_count` INT NULL COMMENT '平盘股票数', + `limit_up_count` INT NULL COMMENT '涨停股票数', + `limit_down_count` INT NULL COMMENT '跌停股票数', + `total_market_value` DECIMAL(25,2) NULL COMMENT '行业总市值', + `avg_turnover_rate` DECIMAL(8,4) NULL COMMENT '行业平均换手率', + `create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + PRIMARY KEY (`id`) USING BTREE, + UNIQUE INDEX `idx_industry_trade_date` (`industry_id`, `trade_date`) USING BTREE, + INDEX `idx_trade_date` (`trade_date`) USING BTREE, + INDEX `idx_avg_change_rate` (`avg_change_rate`) USING BTREE, + CONSTRAINT `fk_industry_trend_industry` FOREIGN KEY (`industry_id`) REFERENCES `new_stock_industry` (`industry_id`) ON DELETE CASCADE ON UPDATE CASCADE +) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '行业趋势分析表' ROW_FORMAT = Dynamic; + +SET FOREIGN_KEY_CHECKS = 1; \ No newline at end of file diff --git a/stock-system/src/main/java/com/ruoyi/stocksystem/controller/NewStocksController.java b/stock-system/src/main/java/com/ruoyi/stocksystem/controller/NewStocksController.java new file mode 100644 index 0000000..a382d1b --- /dev/null +++ b/stock-system/src/main/java/com/ruoyi/stocksystem/controller/NewStocksController.java @@ -0,0 +1,194 @@ +package com.ruoyi.stocksystem.controller; + +import java.util.List; +import javax.servlet.http.HttpServletResponse; + +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.stocksystem.domain.NewStockBasic; +import com.ruoyi.stocksystem.domain.NewStocks; +import com.ruoyi.stocksystem.domain.service.INewStockBasicService; +import org.springframework.security.access.prepost.PreAuthorize; +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.stocksystem.domain.service.INewStocksService; +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-18 + */ +@RestController +@RequestMapping("/stocksystem/newstocks") +public class NewStocksController extends BaseController +{ + @Autowired + private INewStocksService newStocksService; + + @Autowired + private INewStockBasicService newStockBasicService; + + /** + * 查询行情数据列表 + */ + @GetMapping("/list") + public TableDataInfo list(NewStocks newStocks) + { + startPage(); + List list = newStocksService.selectNewStocksList(newStocks); + return getDataTable(list); + } + + /** + * 查询行情数据列表含基础数据 + */ + @GetMapping("/listB") + public TableDataInfo listB(NewStocks newStocks) + { + startPage(); + List list = newStocksService.selectNewStocksListB(newStocks); + return getDataTable(list); + } + + /** + * 查询强势股列表 + */ + @GetMapping("/listStrongStocks") + public TableDataInfo listStrongStocks(NewStocks newStocks) + { + startPage(); + List list = newStocksService.selectNewStrongStocksList(newStocks); + return getDataTable(list); + } + + /** + * 查询涨停股列表 + */ + @GetMapping("/listLimitStocks") + public TableDataInfo listLimitStocks(NewStocks newStocks) + { + startPage(); + List list = newStocksService.selectNewLimitStocksList(newStocks); + return getDataTable(list); + } + + /** + * 导出行情数据列表 + */ + @PostMapping("/export") + public void export(HttpServletResponse response, NewStocks newStocks) + { + List list = newStocksService.selectNewStocksList(newStocks); + ExcelUtil util = new ExcelUtil(NewStocks.class); + util.exportExcel(response, list, "行情数据数据"); + } + + /** + * 获取行情数据详细信息 + */ + @GetMapping(value = "/{id}") + public AjaxResult getInfo(@PathVariable("id") Integer id) + { + return AjaxResult.success(newStocksService.selectNewStocksById(id)); + } + + /** + * 新增行情数据 + */ + @PostMapping + public AjaxResult add(@RequestBody NewStocks newStocks) + { + return toAjax(newStocksService.insertNewStocks(newStocks)); + } + + /** + * 修改行情数据 + */ + @PutMapping + public AjaxResult edit(@RequestBody NewStocks newStocks) + { + return toAjax(newStocksService.updateNewStocks(newStocks)); + } + + /** + * 删除行情数据 + */ + @DeleteMapping("/{ids}") + public AjaxResult remove(@PathVariable Integer[] ids) + { + return toAjax(newStocksService.deleteNewStocksByIds(ids)); + } + + /** + * 导入行情数据 + */ + @PostMapping("/importData") + public AjaxResult importData(MultipartFile file, boolean updateSupport, String tradeDate) + { + ExcelUtil util = new ExcelUtil(NewStocks.class); + try + { + List newStocksList = util.importExcel(file.getInputStream()); + int successNum = newStocksService.importNewStocks(newStocksList, tradeDate); + return AjaxResult.success("导入成功 " + successNum + " 条数据"); + } + catch (Exception e) + { + return AjaxResult.error("导入失败:" + e.getMessage()); + } + } + + /** + * 分析行情数据 + */ + @PostMapping("/analyze") + public AjaxResult analyze(@RequestBody NewStocks newStocks) + { + Object result = newStocksService.analyzeNewStocks(newStocks); + return AjaxResult.success(result); + } + + /** + * 获取联想的数据(股票代码) + */ + @GetMapping("/stockQueryData") + public AjaxResult stockQueryData(String query) + { + NewStockBasic newStockBasic = new NewStockBasic(); + if (StringUtils.isNotEmpty(query)) + { + newStockBasic.setCode(query); + } + List list = newStockBasicService.selectNewStockBasicList(newStockBasic); + return AjaxResult.success(list); + } + + /** + * 获取联想的数据(股票名称) + */ + @GetMapping("/stockNameQueryData") + public AjaxResult stockNameQueryData(String query) + { + NewStockBasic newStockBasic = new NewStockBasic(); + if (StringUtils.isNotEmpty(query)) + { + newStockBasic.setName(query); + } + List list = newStockBasicService.selectNewStockBasicList(newStockBasic); + return AjaxResult.success(list); + } +} diff --git a/stock-system/src/main/java/com/ruoyi/stocksystem/domain/NewStockBasic.java b/stock-system/src/main/java/com/ruoyi/stocksystem/domain/NewStockBasic.java new file mode 100644 index 0000000..2aa523e --- /dev/null +++ b/stock-system/src/main/java/com/ruoyi/stocksystem/domain/NewStockBasic.java @@ -0,0 +1,109 @@ +package com.ruoyi.stocksystem.domain; + +import com.fasterxml.jackson.annotation.JsonFormat; +import com.ruoyi.common.core.domain.BaseEntity; + +import java.util.Date; + +/** + * 股票基础信息实体类 + * + * @author lxy + * @date 2026-01-18 + */ +public class NewStockBasic extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 主键ID */ + private Integer id; + + /** 股票代码 */ + private String code; + + /** 股票名称 */ + private String name; + + /** 所属行业ID */ + private Integer industryId; + + /** 首发上市日期 */ + @JsonFormat(pattern = "yyyy-MM-dd") + private Date listDate; + + /** 市场类型(SZ/SH) */ + private String marketType; + + /** 状态(1-正常,0-暂停上市) */ + private Integer status; + + public void setId(Integer id) + { + this.id = id; + } + + public Integer getId() + { + return id; + } + + public void setCode(String code) + { + this.code = code; + } + + public String getCode() + { + return code; + } + + public void setName(String name) + { + this.name = name; + } + + public String getName() + { + return name; + } + + public void setIndustryId(Integer industryId) + { + this.industryId = industryId; + } + + public Integer getIndustryId() + { + return industryId; + } + + public void setListDate(Date listDate) + { + this.listDate = listDate; + } + + public Date getListDate() + { + return listDate; + } + + public void setMarketType(String marketType) + { + this.marketType = marketType; + } + + public String getMarketType() + { + return marketType; + } + + public void setStatus(Integer status) + { + this.status = status; + } + + public Integer getStatus() + { + return status; + } +} \ No newline at end of file diff --git a/stock-system/src/main/java/com/ruoyi/stocksystem/domain/NewStockIndustry.java b/stock-system/src/main/java/com/ruoyi/stocksystem/domain/NewStockIndustry.java new file mode 100644 index 0000000..54d59a3 --- /dev/null +++ b/stock-system/src/main/java/com/ruoyi/stocksystem/domain/NewStockIndustry.java @@ -0,0 +1,79 @@ +package com.ruoyi.stocksystem.domain; + +import com.ruoyi.common.core.domain.BaseEntity; + +/** + * 行业分类实体类 + * + * @author lxy + * @date 2026-01-18 + */ +public class NewStockIndustry extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 行业ID */ + private Integer industryId; + + /** 行业级别(1-3) */ + private Integer industryLevel; + + /** 行业代码 */ + private String industryCode; + + /** 行业名称 */ + private String industryName; + + /** 父行业代码 */ + private String parentCode; + + public void setIndustryId(Integer industryId) + { + this.industryId = industryId; + } + + public Integer getIndustryId() + { + return industryId; + } + + public void setIndustryLevel(Integer industryLevel) + { + this.industryLevel = industryLevel; + } + + public Integer getIndustryLevel() + { + return industryLevel; + } + + public void setIndustryCode(String industryCode) + { + this.industryCode = industryCode; + } + + public String getIndustryCode() + { + return industryCode; + } + + public void setIndustryName(String industryName) + { + this.industryName = industryName; + } + + public String getIndustryName() + { + return industryName; + } + + public void setParentCode(String parentCode) + { + this.parentCode = parentCode; + } + + public String getParentCode() + { + return parentCode; + } +} \ No newline at end of file diff --git a/stock-system/src/main/java/com/ruoyi/stocksystem/domain/NewStocks.java b/stock-system/src/main/java/com/ruoyi/stocksystem/domain/NewStocks.java new file mode 100644 index 0000000..bacff2f --- /dev/null +++ b/stock-system/src/main/java/com/ruoyi/stocksystem/domain/NewStocks.java @@ -0,0 +1,379 @@ +package com.ruoyi.stocksystem.domain; + +import com.fasterxml.jackson.annotation.JsonFormat; +import com.ruoyi.common.annotation.Excel; +import com.ruoyi.common.core.domain.BaseEntity; + +import java.util.Date; +import java.math.BigDecimal; + +/** + * 行情数据实体类 + * + * @author lxy + * @date 2026-01-18 + */ +public class NewStocks extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 主键ID */ + private Integer id; + + /** 股票代码 */ + @Excel(name = "证券代码", sort = 1, type = Excel.Type.ALL) + private String code; + + /** 交易日期 */ + @JsonFormat(pattern = "yyyy-MM-dd") + @Excel(name = "交易日期", sort = 2, type = Excel.Type.ALL, dateFormat = "yyyy-MM-dd") + private Date tradeDate; + + /** 开盘价 */ + @Excel(name = "开盘价", sort = 3, type = Excel.Type.ALL) + private BigDecimal open; + + /** 收盘价 */ + @Excel(name = "收盘价", sort = 4, type = Excel.Type.ALL) + private BigDecimal close; + + /** 当日涨跌幅 */ + @Excel(name = "当日涨跌幅", sort = 5, type = Excel.Type.ALL) + private BigDecimal changeRate; + + /** 可交易日数 */ + @Excel(name = "可交易日数", sort = 6, type = Excel.Type.ALL) + private Integer tradeDays; + + /** 成交量 */ + @Excel(name = "成交量", sort = 7, type = Excel.Type.ALL) + private Long volume; + + /** 成交额 */ + @Excel(name = "成交额", sort = 8, type = Excel.Type.ALL) + private BigDecimal amount; + + /** 10日区间涨跌幅 */ + @Excel(name = "10日区间涨跌幅", sort = 9, type = Excel.Type.ALL) + private BigDecimal changeRate10; + + /** 20日区间涨跌幅 */ + @Excel(name = "20日区间涨跌幅", sort = 10, type = Excel.Type.ALL) + private BigDecimal changeRate20; + + /** 60日区间涨跌幅 */ + @Excel(name = "60日区间涨跌幅", sort = 11, type = Excel.Type.ALL) + private BigDecimal changeRate60; + + /** 20日区间平均成交量 */ + @Excel(name = "20日区间平均成交量", sort = 12, type = Excel.Type.ALL) + private BigDecimal avgVolume20; + + /** 自由流通市值 */ + @Excel(name = "自由流通市值", sort = 13, type = Excel.Type.ALL) + private BigDecimal freeFloatMarketValue; + + /** 总市值 */ + @Excel(name = "总市值", sort = 14, type = Excel.Type.ALL) + private BigDecimal totalMarketValue; + + /** 机构持仓合计 */ + @Excel(name = "机构持仓合计", sort = 15, type = Excel.Type.ALL) + private BigDecimal agenciesHold; + + // 关联字段,非数据库字段 + @Excel(name = "证券名称", sort = 16, type = Excel.Type.ALL) + private String name; + @Excel(name = "行业ID", sort = 17, type = Excel.Type.ALL) + private Integer industryId; + @Excel(name = "所属东财行业指数2级", sort = 18, type = Excel.Type.ALL) + private String industryName; + @Excel(name = "行业级别", sort = 19, type = Excel.Type.ALL) + private Integer industryLevel; + @Excel(name = "所属东财行业指数代码\\n\" +\n" + + " \"[行业类别]2级\"", sort = 20, type = Excel.Type.ALL) + private String industryCode; + @Excel(name = "父行业代码", sort = 21, type = Excel.Type.ALL) + private String parentCode; + @JsonFormat(pattern = "yyyy-MM-dd") + @Excel(name = "上市日期", sort = 22, type = Excel.Type.ALL, dateFormat = "yyyy-MM-dd") + private Date listDate; + @Excel(name = "市场类型", sort = 23, type = Excel.Type.ALL) + private String marketType; + @Excel(name = "状态", sort = 24, type = Excel.Type.ALL) + private Integer status; + @Excel(name = "涨跌停类型", sort = 25, type = Excel.Type.ALL) + private Integer limitType; + @Excel(name = "涨跌停价格", sort = 26, type = Excel.Type.ALL) + private BigDecimal limitPrice; + + public void setId(Integer id) + { + this.id = id; + } + + public Integer getId() + { + return id; + } + + public void setCode(String code) + { + this.code = code; + } + + public String getCode() + { + return code; + } + + public void setTradeDate(Date tradeDate) + { + this.tradeDate = tradeDate; + } + + public Date getTradeDate() + { + return tradeDate; + } + + public void setOpen(BigDecimal open) + { + this.open = open; + } + + public BigDecimal getOpen() + { + return open; + } + + public void setClose(BigDecimal close) + { + this.close = close; + } + + public BigDecimal getClose() + { + return close; + } + + public void setChangeRate(BigDecimal changeRate) + { + this.changeRate = changeRate; + } + + public BigDecimal getChangeRate() + { + return changeRate; + } + + public void setTradeDays(Integer tradeDays) + { + this.tradeDays = tradeDays; + } + + public Integer getTradeDays() + { + return tradeDays; + } + + public void setVolume(Long volume) + { + this.volume = volume; + } + + public Long getVolume() + { + return volume; + } + + public void setAmount(BigDecimal amount) + { + this.amount = amount; + } + + public BigDecimal getAmount() + { + return amount; + } + + public void setChangeRate10(BigDecimal changeRate10) + { + this.changeRate10 = changeRate10; + } + + public BigDecimal getChangeRate10() + { + return changeRate10; + } + + public void setChangeRate20(BigDecimal changeRate20) + { + this.changeRate20 = changeRate20; + } + + public BigDecimal getChangeRate20() + { + return changeRate20; + } + + public void setChangeRate60(BigDecimal changeRate60) + { + this.changeRate60 = changeRate60; + } + + public BigDecimal getChangeRate60() + { + return changeRate60; + } + + public void setAvgVolume20(BigDecimal avgVolume20) + { + this.avgVolume20 = avgVolume20; + } + + public BigDecimal getAvgVolume20() + { + return avgVolume20; + } + + public void setFreeFloatMarketValue(BigDecimal freeFloatMarketValue) + { + this.freeFloatMarketValue = freeFloatMarketValue; + } + + public BigDecimal getFreeFloatMarketValue() + { + return freeFloatMarketValue; + } + + public void setTotalMarketValue(BigDecimal totalMarketValue) + { + this.totalMarketValue = totalMarketValue; + } + + public BigDecimal getTotalMarketValue() + { + return totalMarketValue; + } + + public void setAgenciesHold(BigDecimal agenciesHold) + { + this.agenciesHold = agenciesHold; + } + + public BigDecimal getAgenciesHold() + { + return agenciesHold; + } + + public String getName() + { + return name; + } + + public void setName(String name) + { + this.name = name; + } + + public Integer getIndustryId() + { + return industryId; + } + + public void setIndustryId(Integer industryId) + { + this.industryId = industryId; + } + + public String getIndustryName() + { + return industryName; + } + + public void setIndustryName(String industryName) + { + this.industryName = industryName; + } + + public Integer getIndustryLevel() + { + return industryLevel; + } + + public void setIndustryLevel(Integer industryLevel) + { + this.industryLevel = industryLevel; + } + + public String getIndustryCode() + { + return industryCode; + } + + public void setIndustryCode(String industryCode) + { + this.industryCode = industryCode; + } + + public String getParentCode() + { + return parentCode; + } + + public void setParentCode(String parentCode) + { + this.parentCode = parentCode; + } + + public Date getListDate() + { + return listDate; + } + + public void setListDate(Date listDate) + { + this.listDate = listDate; + } + + public String getMarketType() + { + return marketType; + } + + public void setMarketType(String marketType) + { + this.marketType = marketType; + } + + public Integer getStatus() + { + return status; + } + + public void setStatus(Integer status) + { + this.status = status; + } + + public Integer getLimitType() + { + return limitType; + } + + public void setLimitType(Integer limitType) + { + this.limitType = limitType; + } + + public BigDecimal getLimitPrice() + { + return limitPrice; + } + + public void setLimitPrice(BigDecimal limitPrice) + { + this.limitPrice = limitPrice; + } +} \ No newline at end of file diff --git a/stock-system/src/main/java/com/ruoyi/stocksystem/domain/service/INewStockBasicService.java b/stock-system/src/main/java/com/ruoyi/stocksystem/domain/service/INewStockBasicService.java new file mode 100644 index 0000000..fc2c85b --- /dev/null +++ b/stock-system/src/main/java/com/ruoyi/stocksystem/domain/service/INewStockBasicService.java @@ -0,0 +1,78 @@ +package com.ruoyi.stocksystem.domain.service; + +import java.util.List; + +import com.ruoyi.stocksystem.domain.NewStockBasic; + +/** + * 股票基础信息Service接口 + * + * @author lxy + * @date 2026-01-18 + */ +public interface INewStockBasicService +{ + /** + * 查询股票基础信息 + * + * @param id 股票基础信息主键 + * @return 股票基础信息 + */ + public NewStockBasic selectNewStockBasicById(Integer id); + + /** + * 根据股票代码查询股票基础信息 + * + * @param code 股票代码 + * @return 股票基础信息 + */ + public NewStockBasic selectNewStockBasicByCode(String code); + + /** + * 查询股票基础信息列表 + * + * @param newStockBasic 股票基础信息 + * @return 股票基础信息集合 + */ + public List selectNewStockBasicList(NewStockBasic newStockBasic); + + /** + * 新增股票基础信息 + * + * @param newStockBasic 股票基础信息 + * @return 结果 + */ + public int insertNewStockBasic(NewStockBasic newStockBasic); + + /** + * 修改股票基础信息 + * + * @param newStockBasic 股票基础信息 + * @return 结果 + */ + public int updateNewStockBasic(NewStockBasic newStockBasic); + + /** + * 删除股票基础信息 + * + * @param id 股票基础信息主键 + * @return 结果 + */ + public int deleteNewStockBasicById(Integer id); + + /** + * 批量删除股票基础信息 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + public int deleteNewStockBasicByIds(Integer[] ids); + + /** + * 批量新增股票基础信息 + * + * @param newStockBasicList 股票基础信息集合 + * @return 结果 + */ + public int batchInsertNewStockBasic(List newStockBasicList); +} \ No newline at end of file diff --git a/stock-system/src/main/java/com/ruoyi/stocksystem/domain/service/INewStockIndustryService.java b/stock-system/src/main/java/com/ruoyi/stocksystem/domain/service/INewStockIndustryService.java new file mode 100644 index 0000000..69552aa --- /dev/null +++ b/stock-system/src/main/java/com/ruoyi/stocksystem/domain/service/INewStockIndustryService.java @@ -0,0 +1,78 @@ +package com.ruoyi.stocksystem.domain.service; + +import java.util.List; + +import com.ruoyi.stocksystem.domain.NewStockIndustry; + +/** + * 行业分类Service接口 + * + * @author lxy + * @date 2026-01-18 + */ +public interface INewStockIndustryService +{ + /** + * 查询行业分类 + * + * @param industryId 行业分类主键 + * @return 行业分类 + */ + public NewStockIndustry selectNewStockIndustryById(Integer industryId); + + /** + * 根据行业代码查询行业分类 + * + * @param industryCode 行业代码 + * @return 行业分类 + */ + public NewStockIndustry selectNewStockIndustryByCode(String industryCode); + + /** + * 查询行业分类列表 + * + * @param newStockIndustry 行业分类 + * @return 行业分类集合 + */ + public List selectNewStockIndustryList(NewStockIndustry newStockIndustry); + + /** + * 新增行业分类 + * + * @param newStockIndustry 行业分类 + * @return 结果 + */ + public int insertNewStockIndustry(NewStockIndustry newStockIndustry); + + /** + * 修改行业分类 + * + * @param newStockIndustry 行业分类 + * @return 结果 + */ + public int updateNewStockIndustry(NewStockIndustry newStockIndustry); + + /** + * 删除行业分类 + * + * @param industryId 行业分类主键 + * @return 结果 + */ + public int deleteNewStockIndustryById(Integer industryId); + + /** + * 批量删除行业分类 + * + * @param industryIds 需要删除的数据主键集合 + * @return 结果 + */ + public int deleteNewStockIndustryByIds(Integer[] industryIds); + + /** + * 批量新增行业分类 + * + * @param newStockIndustryList 行业分类集合 + * @return 结果 + */ + public int batchInsertNewStockIndustry(List newStockIndustryList); +} \ No newline at end of file diff --git a/stock-system/src/main/java/com/ruoyi/stocksystem/domain/service/INewStocksService.java b/stock-system/src/main/java/com/ruoyi/stocksystem/domain/service/INewStocksService.java new file mode 100644 index 0000000..643312f --- /dev/null +++ b/stock-system/src/main/java/com/ruoyi/stocksystem/domain/service/INewStocksService.java @@ -0,0 +1,111 @@ +package com.ruoyi.stocksystem.domain.service; + +import java.util.List; + +import com.ruoyi.stocksystem.domain.NewStocks; + +/** + * 行情数据Service接口 + * + * @author lxy + * @date 2026-01-18 + */ +public interface INewStocksService +{ + /** + * 查询行情数据 + * + * @param id 行情数据主键 + * @return 行情数据 + */ + public NewStocks selectNewStocksById(Integer id); + + /** + * 查询行情数据列表 + * + * @param newStocks 行情数据 + * @return 行情数据集合 + */ + public List selectNewStocksList(NewStocks newStocks); + + /** + * 查询行情数据列表含基础数据 + * + * @param newStocks 行情数据 + * @return 行情数据集合 + */ + public List selectNewStocksListB(NewStocks newStocks); + + /** + * 查询强势股列表 + * + * @param newStocks 行情数据 + * @return 行情数据集合 + */ + public List selectNewStrongStocksList(NewStocks newStocks); + + /** + * 查询涨停股列表 + * + * @param newStocks 行情数据 + * @return 行情数据集合 + */ + public List selectNewLimitStocksList(NewStocks newStocks); + + /** + * 新增行情数据 + * + * @param newStocks 行情数据 + * @return 结果 + */ + public int insertNewStocks(NewStocks newStocks); + + /** + * 批量新增行情数据 + * + * @param newStocksList 行情数据集合 + * @return 结果 + */ + public int batchInsertNewStocks(List newStocksList); + + /** + * 修改行情数据 + * + * @param newStocks 行情数据 + * @return 结果 + */ + public int updateNewStocks(NewStocks newStocks); + + /** + * 删除行情数据 + * + * @param id 行情数据主键 + * @return 结果 + */ + public int deleteNewStocksById(Integer id); + + /** + * 批量删除行情数据 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + public int deleteNewStocksByIds(Integer[] ids); + + /** + * 导入行情数据 + * + * @param newStocksList 行情数据集合 + * @param tradeDate 交易日期 + * @return 结果 + */ + public int importNewStocks(List newStocksList, String tradeDate); + + /** + * 分析行情数据 + * + * @param newStocks 行情数据 + * @return 分析结果 + */ + public Object analyzeNewStocks(NewStocks newStocks); +} \ No newline at end of file diff --git a/stock-system/src/main/java/com/ruoyi/stocksystem/domain/service/impl/NewStockBasicServiceImpl.java b/stock-system/src/main/java/com/ruoyi/stocksystem/domain/service/impl/NewStockBasicServiceImpl.java new file mode 100644 index 0000000..fad81ce --- /dev/null +++ b/stock-system/src/main/java/com/ruoyi/stocksystem/domain/service/impl/NewStockBasicServiceImpl.java @@ -0,0 +1,124 @@ +package com.ruoyi.stocksystem.domain.service.impl; + +import java.util.ArrayList; +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.stocksystem.domain.NewStockBasic; +import com.ruoyi.stocksystem.domain.service.INewStockBasicService; +import com.ruoyi.stocksystem.mapper.NewStockBasicMapper; + +/** + * 股票基础信息Service实现类 + * + * @author lxy + * @date 2026-01-18 + */ +@Service +public class NewStockBasicServiceImpl implements INewStockBasicService +{ + @Autowired + private NewStockBasicMapper newStockBasicMapper; + + @Override + public NewStockBasic selectNewStockBasicById(Integer id) + { + return newStockBasicMapper.selectNewStockBasicById(id); + } + + @Override + public NewStockBasic selectNewStockBasicByCode(String code) + { + return newStockBasicMapper.selectNewStockBasicByCode(code); + } + + @Override + public List selectNewStockBasicList(NewStockBasic newStockBasic) + { + return newStockBasicMapper.selectNewStockBasicList(newStockBasic); + } + + @Override + public int insertNewStockBasic(NewStockBasic newStockBasic) + { + return newStockBasicMapper.insertNewStockBasic(newStockBasic); + } + + @Override + public int updateNewStockBasic(NewStockBasic newStockBasic) + { + return newStockBasicMapper.updateNewStockBasic(newStockBasic); + } + + @Override + public int deleteNewStockBasicById(Integer id) + { + return newStockBasicMapper.deleteNewStockBasicById(id); + } + + @Override + public int deleteNewStockBasicByIds(Integer[] ids) + { + return newStockBasicMapper.deleteNewStockBasicByIds(ids); + } + + @Override + @Transactional + public int batchInsertNewStockBasic(List newStockBasicList) + { + // 分离新增和更新的数据 + List insertList = new ArrayList<>(); + List updateList = new ArrayList<>(); + + for (NewStockBasic newStockBasic : newStockBasicList) + { + // 先查询是否已存在 + NewStockBasic existing = newStockBasicMapper.selectNewStockBasicByCode(newStockBasic.getCode()); + if (existing == null) + { + // 新增数据 + insertList.add(newStockBasic); + } + else + { + // 更新数据 + newStockBasic.setId(existing.getId()); + updateList.add(newStockBasic); + } + } + + int count = 0; + + // 批量新增(每1000条一批) + if (!insertList.isEmpty()) + { + int batchSize = 1000; + for (int i = 0; i < insertList.size(); i += batchSize) + { + int end = Math.min(i + batchSize, insertList.size()); + List batchList = insertList.subList(i, end); + count += newStockBasicMapper.batchInsertNewStockBasic(batchList); + } + } + + // 批量更新(每1000条一批) + if (!updateList.isEmpty()) + { + int batchSize = 1000; + for (int i = 0; i < updateList.size(); i += batchSize) + { + int end = Math.min(i + batchSize, updateList.size()); + List batchList = updateList.subList(i, end); + for (NewStockBasic newStockBasic : batchList) + { + count += newStockBasicMapper.updateNewStockBasic(newStockBasic); + } + } + } + + return count; + } +} \ No newline at end of file diff --git a/stock-system/src/main/java/com/ruoyi/stocksystem/domain/service/impl/NewStockIndustryServiceImpl.java b/stock-system/src/main/java/com/ruoyi/stocksystem/domain/service/impl/NewStockIndustryServiceImpl.java new file mode 100644 index 0000000..2a68ed0 --- /dev/null +++ b/stock-system/src/main/java/com/ruoyi/stocksystem/domain/service/impl/NewStockIndustryServiceImpl.java @@ -0,0 +1,124 @@ +package com.ruoyi.stocksystem.domain.service.impl; + +import java.util.ArrayList; +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.stocksystem.domain.NewStockIndustry; +import com.ruoyi.stocksystem.domain.service.INewStockIndustryService; +import com.ruoyi.stocksystem.mapper.NewStockIndustryMapper; + +/** + * 行业分类Service实现类 + * + * @author lxy + * @date 2026-01-18 + */ +@Service +public class NewStockIndustryServiceImpl implements INewStockIndustryService +{ + @Autowired + private NewStockIndustryMapper newStockIndustryMapper; + + @Override + public NewStockIndustry selectNewStockIndustryById(Integer industryId) + { + return newStockIndustryMapper.selectNewStockIndustryById(industryId); + } + + @Override + public NewStockIndustry selectNewStockIndustryByCode(String industryCode) + { + return newStockIndustryMapper.selectNewStockIndustryByCode(industryCode); + } + + @Override + public List selectNewStockIndustryList(NewStockIndustry newStockIndustry) + { + return newStockIndustryMapper.selectNewStockIndustryList(newStockIndustry); + } + + @Override + public int insertNewStockIndustry(NewStockIndustry newStockIndustry) + { + return newStockIndustryMapper.insertNewStockIndustry(newStockIndustry); + } + + @Override + public int updateNewStockIndustry(NewStockIndustry newStockIndustry) + { + return newStockIndustryMapper.updateNewStockIndustry(newStockIndustry); + } + + @Override + public int deleteNewStockIndustryById(Integer industryId) + { + return newStockIndustryMapper.deleteNewStockIndustryById(industryId); + } + + @Override + public int deleteNewStockIndustryByIds(Integer[] industryIds) + { + return newStockIndustryMapper.deleteNewStockIndustryByIds(industryIds); + } + + @Override + @Transactional + public int batchInsertNewStockIndustry(List newStockIndustryList) + { + // 分离新增和更新的数据 + List insertList = new ArrayList<>(); + List updateList = new ArrayList<>(); + + for (NewStockIndustry newStockIndustry : newStockIndustryList) + { + // 先查询是否已存在 + NewStockIndustry existing = newStockIndustryMapper.selectNewStockIndustryByCode(newStockIndustry.getIndustryCode()); + if (existing == null) + { + // 新增数据 + insertList.add(newStockIndustry); + } + else + { + // 更新数据 + newStockIndustry.setIndustryId(existing.getIndustryId()); + updateList.add(newStockIndustry); + } + } + + int count = 0; + + // 批量新增(每1000条一批) + if (!insertList.isEmpty()) + { + int batchSize = 1000; + for (int i = 0; i < insertList.size(); i += batchSize) + { + int end = Math.min(i + batchSize, insertList.size()); + List batchList = insertList.subList(i, end); + count += newStockIndustryMapper.batchInsertNewStockIndustry(batchList); + } + } + + // 批量更新(每1000条一批) + if (!updateList.isEmpty()) + { + int batchSize = 1000; + for (int i = 0; i < updateList.size(); i += batchSize) + { + int end = Math.min(i + batchSize, updateList.size()); + List batchList = updateList.subList(i, end); + for (NewStockIndustry industry : batchList) + { + count += newStockIndustryMapper.updateNewStockIndustry(industry); + } + } + } + + return count; + } +} \ No newline at end of file diff --git a/stock-system/src/main/java/com/ruoyi/stocksystem/domain/service/impl/NewStocksServiceImpl.java b/stock-system/src/main/java/com/ruoyi/stocksystem/domain/service/impl/NewStocksServiceImpl.java new file mode 100644 index 0000000..a6014b6 --- /dev/null +++ b/stock-system/src/main/java/com/ruoyi/stocksystem/domain/service/impl/NewStocksServiceImpl.java @@ -0,0 +1,326 @@ +package com.ruoyi.stocksystem.domain.service.impl; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.common.utils.DateUtils; + +import com.ruoyi.stocksystem.domain.NewStockBasic; +import com.ruoyi.stocksystem.domain.NewStockIndustry; +import com.ruoyi.stocksystem.domain.NewStocks; +import com.ruoyi.stocksystem.domain.service.INewStockBasicService; +import com.ruoyi.stocksystem.domain.service.INewStockIndustryService; +import com.ruoyi.stocksystem.domain.service.INewStocksService; +import com.ruoyi.stocksystem.mapper.NewStocksMapper; + +/** + * 行情数据Service实现类 + * + * @author lxy + * @date 2026-01-18 + */ +@Service +public class NewStocksServiceImpl implements INewStocksService +{ + @Autowired + private NewStocksMapper newStocksMapper; + + @Autowired + private INewStockBasicService newStockBasicService; + + @Autowired + private INewStockIndustryService newStockIndustryService; + + @Override + public NewStocks selectNewStocksById(Integer id) + { + return newStocksMapper.selectNewStocksById(id); + } + + @Override + public List selectNewStocksList(NewStocks newStocks) + { + return newStocksMapper.selectNewStocksList(newStocks); + } + + @Override + public List selectNewStocksListB(NewStocks newStocks) + { + return newStocksMapper.selectNewStocksListB(newStocks); + } + + @Override + public List selectNewStrongStocksList(NewStocks newStocks) + { + return newStocksMapper.selectNewStrongStocksList(newStocks); + } + + @Override + public List selectNewLimitStocksList(NewStocks newStocks) + { + return newStocksMapper.selectNewLimitStocksList(newStocks); + } + + @Override + public int insertNewStocks(NewStocks newStocks) + { + return newStocksMapper.insertNewStocks(newStocks); + } + + @Override + public int batchInsertNewStocks(List newStocksList) + { + // 数据验证,确保没有tradeDate为null的记录 + List validList = new ArrayList<>(); + for (NewStocks stock : newStocksList) + { + if (stock.getTradeDate() != null && !StringUtils.isEmpty(stock.getCode())) + { + validList.add(stock); + } + } + if (validList.isEmpty()) + { + return 0; + } + return newStocksMapper.batchInsertNewStocks(validList); + } + + @Override + public int updateNewStocks(NewStocks newStocks) + { + return newStocksMapper.updateNewStocks(newStocks); + } + + @Override + public int deleteNewStocksById(Integer id) + { + return newStocksMapper.deleteNewStocksById(id); + } + + @Override + public int deleteNewStocksByIds(Integer[] ids) + { + return newStocksMapper.deleteNewStocksByIds(ids); + } + + @Override + @Transactional + public int importNewStocks(List newStocksList, String tradeDate) + { + int count = 0; + List newStockBasicList = new ArrayList<>(); + List newStockIndustryList = new ArrayList<>(); + List updateBasicList = new ArrayList<>(); + List validStocksList = new ArrayList<>(); + + // 一次性读取所有行业数据到内存中 + List allIndustries = newStockIndustryService.selectNewStockIndustryList(new NewStockIndustry()); + Map industryMap = new HashMap<>(); + for (NewStockIndustry industry : allIndustries) + { + industryMap.put(industry.getIndustryId(), industry); + } + + // 一次性读取所有基础数据到内存中 + List allBasics = newStockBasicService.selectNewStockBasicList(new NewStockBasic()); + Map basicMap = new HashMap<>(); + for (NewStockBasic basic : allBasics) + { + basicMap.put(basic.getCode(), basic); + } + + // 数据验证和处理 + for (NewStocks newStocks : newStocksList) + { + // 如果传入了tradeDate参数,则使用传入的日期 + if (StringUtils.isNotEmpty(tradeDate)) + { + newStocks.setTradeDate(DateUtils.parseDate(tradeDate)); + } + + // 验证tradeDate不为null + if (newStocks.getTradeDate() == null) + { + continue; // 跳过tradeDate为null的记录 + } + + // 验证code不为null或空 + if (StringUtils.isEmpty(newStocks.getCode())) + { + continue; // 跳过code为空的记录 + } + + validStocksList.add(newStocks); + } + + // 先处理行业数据 + for (NewStocks newStocks : validStocksList) + { + // 检查行业数据是否存在(在内存中检查) + if (newStocks.getIndustryId() != null) + { + if (!industryMap.containsKey(newStocks.getIndustryId())) + { + // 不存在,创建新的行业数据 + NewStockIndustry newStockIndustry = new NewStockIndustry(); + newStockIndustry.setIndustryId(newStocks.getIndustryId()); + newStockIndustry.setIndustryName(newStocks.getIndustryName()); + newStockIndustry.setIndustryCode(newStocks.getIndustryCode()); + newStockIndustry.setIndustryLevel(newStocks.getIndustryLevel()); + newStockIndustry.setParentCode(newStocks.getParentCode()); + newStockIndustryList.add(newStockIndustry); + // 更新内存中的行业数据映射 + industryMap.put(newStocks.getIndustryId(), newStockIndustry); + } + } + } + + // 批量新增行业数据(每1000条一批) + if (!newStockIndustryList.isEmpty()) + { + int batchSize = 1000; + for (int i = 0; i < newStockIndustryList.size(); i += batchSize) + { + int end = Math.min(i + batchSize, newStockIndustryList.size()); + List batchList = newStockIndustryList.subList(i, end); + newStockIndustryService.batchInsertNewStockIndustry(batchList); + } + } + + // 处理基础数据 + for (NewStocks newStocks : validStocksList) + { + // 检查基础数据是否存在(在内存中检查) + NewStockBasic existing = basicMap.get(newStocks.getCode()); + if (existing == null) + { + // 不存在,创建新的基础数据 + NewStockBasic newStockBasic = new NewStockBasic(); + newStockBasic.setCode(newStocks.getCode()); + newStockBasic.setName(newStocks.getName()); + newStockBasic.setIndustryId(newStocks.getIndustryId()); + newStockBasic.setMarketType(newStocks.getMarketType()); + newStockBasic.setListDate(newStocks.getListDate()); + newStockBasic.setStatus(newStocks.getStatus() != null ? newStocks.getStatus() : 1); // 默认为正常状态 + newStockBasicList.add(newStockBasic); + // 更新内存中的基础数据映射 + basicMap.put(newStocks.getCode(), newStockBasic); + } + else + { + // 存在并且只有name更改时才需要进行更新,更新基础数据 + if(!newStocks.getName().equals(existing.getName())) { + existing.setName(newStocks.getName()); + existing.setIndustryId(newStocks.getIndustryId()); + existing.setMarketType(newStocks.getMarketType()); + existing.setListDate(newStocks.getListDate()); + existing.setStatus(newStocks.getStatus() != null ? newStocks.getStatus() : 1); + updateBasicList.add(existing); + } + } + } + + // 批量新增基础数据(每1000条一批) + if (!newStockBasicList.isEmpty()) + { + int batchSize = 1000; + for (int i = 0; i < newStockBasicList.size(); i += batchSize) + { + int end = Math.min(i + batchSize, newStockBasicList.size()); + List batchList = newStockBasicList.subList(i, end); + newStockBasicService.batchInsertNewStockBasic(batchList); + } + } + + // 批量更新基础数据(每1000条一批) + if (!updateBasicList.isEmpty()) + { + int batchSize = 1000; + for (int i = 0; i < updateBasicList.size(); i += batchSize) + { + int end = Math.min(i + batchSize, updateBasicList.size()); + List batchList = updateBasicList.subList(i, end); + for (NewStockBasic basic : batchList) + { + newStockBasicService.updateNewStockBasic(basic); + } + } + } + + // 批量新增行情数据(每1000条一批) + int batchSize = 1000; + for (int i = 0; i < validStocksList.size(); i += batchSize) + { + int end = Math.min(i + batchSize, validStocksList.size()); + List batchList = validStocksList.subList(i, end); + // 再次验证batchList中的记录 + List filteredBatchList = new ArrayList<>(); + for (NewStocks stock : batchList) + { + if (stock.getTradeDate() != null && !StringUtils.isEmpty(stock.getCode())) + { + filteredBatchList.add(stock); + } + } + if (!filteredBatchList.isEmpty()) + { + count += newStocksMapper.batchInsertNewStocks(filteredBatchList); + } + } + + return count; + } + + @Override + public Object analyzeNewStocks(NewStocks newStocks) + { + Map result = new HashMap<>(); + + // 查询行情数据列表 + List stocksList = newStocksMapper.selectNewStocksList(newStocks); + + // 计算基本统计数据 + if (!stocksList.isEmpty()) + { + double avgChangeRate = 0; + double totalChangeRate = 0; + int upCount = 0; + int downCount = 0; + + for (NewStocks stock : stocksList) + { + double changeRate = stock.getChangeRate() != null ? stock.getChangeRate().doubleValue() : 0; + totalChangeRate += changeRate; + if (changeRate > 0) + { + upCount++; + } + else if (changeRate < 0) + { + downCount++; + } + } + + avgChangeRate = totalChangeRate / stocksList.size(); + + result.put("totalStocks", stocksList.size()); + result.put("avgChangeRate", avgChangeRate); + result.put("upCount", upCount); + result.put("downCount", downCount); + result.put("flatCount", stocksList.size() - upCount - downCount); + result.put("upRatio", upCount * 100.0 / stocksList.size()); + result.put("downRatio", downCount * 100.0 / stocksList.size()); + } + + result.put("stocksList", stocksList); + return result; + } +} \ No newline at end of file diff --git a/stock-system/src/main/java/com/ruoyi/stocksystem/mapper/NewStockBasicMapper.java b/stock-system/src/main/java/com/ruoyi/stocksystem/mapper/NewStockBasicMapper.java new file mode 100644 index 0000000..08f587c --- /dev/null +++ b/stock-system/src/main/java/com/ruoyi/stocksystem/mapper/NewStockBasicMapper.java @@ -0,0 +1,78 @@ +package com.ruoyi.stocksystem.mapper; + +import com.ruoyi.stocksystem.domain.NewStockBasic; + +import java.util.List; + +/** + * 股票基础信息Mapper接口 + * + * @author lxy + * @date 2026-01-18 + */ +public interface NewStockBasicMapper +{ + /** + * 查询股票基础信息 + * + * @param id 股票基础信息主键 + * @return 股票基础信息 + */ + public NewStockBasic selectNewStockBasicById(Integer id); + + /** + * 根据股票代码查询股票基础信息 + * + * @param code 股票代码 + * @return 股票基础信息 + */ + public NewStockBasic selectNewStockBasicByCode(String code); + + /** + * 查询股票基础信息列表 + * + * @param newStockBasic 股票基础信息 + * @return 股票基础信息集合 + */ + public List selectNewStockBasicList(NewStockBasic newStockBasic); + + /** + * 新增股票基础信息 + * + * @param newStockBasic 股票基础信息 + * @return 结果 + */ + public int insertNewStockBasic(NewStockBasic newStockBasic); + + /** + * 修改股票基础信息 + * + * @param newStockBasic 股票基础信息 + * @return 结果 + */ + public int updateNewStockBasic(NewStockBasic newStockBasic); + + /** + * 删除股票基础信息 + * + * @param id 股票基础信息主键 + * @return 结果 + */ + public int deleteNewStockBasicById(Integer id); + + /** + * 批量删除股票基础信息 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + public int deleteNewStockBasicByIds(Integer[] ids); + + /** + * 批量新增股票基础信息 + * + * @param newStockBasicList 股票基础信息集合 + * @return 结果 + */ + public int batchInsertNewStockBasic(List newStockBasicList); +} \ No newline at end of file diff --git a/stock-system/src/main/java/com/ruoyi/stocksystem/mapper/NewStockIndustryMapper.java b/stock-system/src/main/java/com/ruoyi/stocksystem/mapper/NewStockIndustryMapper.java new file mode 100644 index 0000000..31505fe --- /dev/null +++ b/stock-system/src/main/java/com/ruoyi/stocksystem/mapper/NewStockIndustryMapper.java @@ -0,0 +1,78 @@ +package com.ruoyi.stocksystem.mapper; + +import com.ruoyi.stocksystem.domain.NewStockIndustry; + +import java.util.List; + +/** + * 行业分类Mapper接口 + * + * @author lxy + * @date 2026-01-18 + */ +public interface NewStockIndustryMapper +{ + /** + * 查询行业分类 + * + * @param industryId 行业分类主键 + * @return 行业分类 + */ + public NewStockIndustry selectNewStockIndustryById(Integer industryId); + + /** + * 根据行业代码查询行业分类 + * + * @param industryCode 行业代码 + * @return 行业分类 + */ + public NewStockIndustry selectNewStockIndustryByCode(String industryCode); + + /** + * 查询行业分类列表 + * + * @param newStockIndustry 行业分类 + * @return 行业分类集合 + */ + public List selectNewStockIndustryList(NewStockIndustry newStockIndustry); + + /** + * 新增行业分类 + * + * @param newStockIndustry 行业分类 + * @return 结果 + */ + public int insertNewStockIndustry(NewStockIndustry newStockIndustry); + + /** + * 修改行业分类 + * + * @param newStockIndustry 行业分类 + * @return 结果 + */ + public int updateNewStockIndustry(NewStockIndustry newStockIndustry); + + /** + * 删除行业分类 + * + * @param industryId 行业分类主键 + * @return 结果 + */ + public int deleteNewStockIndustryById(Integer industryId); + + /** + * 批量删除行业分类 + * + * @param industryIds 需要删除的数据主键集合 + * @return 结果 + */ + public int deleteNewStockIndustryByIds(Integer[] industryIds); + + /** + * 批量新增行业分类 + * + * @param newStockIndustryList 行业分类集合 + * @return 结果 + */ + public int batchInsertNewStockIndustry(List newStockIndustryList); +} \ No newline at end of file diff --git a/stock-system/src/main/java/com/ruoyi/stocksystem/mapper/NewStocksMapper.java b/stock-system/src/main/java/com/ruoyi/stocksystem/mapper/NewStocksMapper.java new file mode 100644 index 0000000..30e6a2d --- /dev/null +++ b/stock-system/src/main/java/com/ruoyi/stocksystem/mapper/NewStocksMapper.java @@ -0,0 +1,103 @@ +package com.ruoyi.stocksystem.mapper; + +import com.ruoyi.stocksystem.domain.NewStocks; + +import java.util.List; + +/** + * 行情数据Mapper接口 + * + * @author lxy + * @date 2026-01-18 + */ +public interface NewStocksMapper +{ + /** + * 查询行情数据 + * + * @param id 行情数据主键 + * @return 行情数据 + */ + public NewStocks selectNewStocksById(Integer id); + + /** + * 查询行情数据列表 + * + * @param newStocks 行情数据 + * @return 行情数据集合 + */ + public List selectNewStocksList(NewStocks newStocks); + + /** + * 查询行情数据列表含基础数据 + * + * @param newStocks 行情数据 + * @return 行情数据集合 + */ + public List selectNewStocksListB(NewStocks newStocks); + + /** + * 查询强势股列表 + * + * @param newStocks 行情数据 + * @return 行情数据集合 + */ + public List selectNewStrongStocksList(NewStocks newStocks); + + /** + * 查询涨停股列表 + * + * @param newStocks 行情数据 + * @return 行情数据集合 + */ + public List selectNewLimitStocksList(NewStocks newStocks); + + /** + * 新增行情数据 + * + * @param newStocks 行情数据 + * @return 结果 + */ + public int insertNewStocks(NewStocks newStocks); + + /** + * 批量新增行情数据 + * + * @param newStocksList 行情数据集合 + * @return 结果 + */ + public int batchInsertNewStocks(List newStocksList); + + /** + * 修改行情数据 + * + * @param newStocks 行情数据 + * @return 结果 + */ + public int updateNewStocks(NewStocks newStocks); + + /** + * 删除行情数据 + * + * @param id 行情数据主键 + * @return 结果 + */ + public int deleteNewStocksById(Integer id); + + /** + * 批量删除行情数据 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + public int deleteNewStocksByIds(Integer[] ids); + + /** + * 根据股票代码和交易日期查询行情数据 + * + * @param code 股票代码 + * @param tradeDate 交易日期 + * @return 行情数据 + */ + public NewStocks selectNewStocksByCodeAndDate(String code, String tradeDate); +} \ No newline at end of file diff --git a/stock-system/src/main/resources/mapper/stocksystem/NewStockBasicMapper.xml b/stock-system/src/main/resources/mapper/stocksystem/NewStockBasicMapper.xml new file mode 100644 index 0000000..14013f9 --- /dev/null +++ b/stock-system/src/main/resources/mapper/stocksystem/NewStockBasicMapper.xml @@ -0,0 +1,97 @@ + + + + + + + + + + + + + + + + select id, code, name, industry_id, list_date, market_type, status + from new_stock_basic + + + + + + + + + + insert into new_stock_basic( + code, name, industry_id, list_date, market_type, status + ) values ( + #{code}, #{name}, #{industryId}, #{listDate}, #{marketType}, #{status} + ) + + + + insert into new_stock_basic( + code, name, industry_id, list_date, market_type, status + ) values + + ( + #{item.code}, #{item.name}, #{item.industryId}, #{item.listDate}, #{item.marketType}, #{item.status} + ) + + + + + update new_stock_basic + + name = #{name}, + industry_id = #{industryId}, + list_date = #{listDate}, + market_type = #{marketType}, + status = #{status}, + + where code = #{code} + + + + delete from new_stock_basic where id = #{id} + + + + delete from new_stock_basic where code = #{code} + + + + delete from new_stock_basic where id in + + #{id} + + + + \ No newline at end of file diff --git a/stock-system/src/main/resources/mapper/stocksystem/NewStockIndustryMapper.xml b/stock-system/src/main/resources/mapper/stocksystem/NewStockIndustryMapper.xml new file mode 100644 index 0000000..8ff688a --- /dev/null +++ b/stock-system/src/main/resources/mapper/stocksystem/NewStockIndustryMapper.xml @@ -0,0 +1,79 @@ + + + + + + + + + + + + + + select industry_id, industry_level, industry_code, industry_name, parent_code + from new_stock_industry + + + + + + + + insert into new_stock_industry( + industry_id, industry_level, industry_code, industry_name, parent_code + ) values ( + #{industryId}, #{industryLevel}, #{industryCode}, #{industryName}, #{parentCode} + ) + + + + insert into new_stock_industry( + industry_id, industry_level, industry_code, industry_name, parent_code + ) values + + ( + #{item.industryId}, #{item.industryLevel}, #{item.industryCode}, #{item.industryName}, #{item.parentCode} + ) + + + + + update new_stock_industry + + industry_level = #{industryLevel}, + industry_code = #{industryCode}, + industry_name = #{industryName}, + parent_code = #{parentCode}, + + where industry_id = #{industryId} + + + + delete from new_stock_industry where industry_id = #{industryId} + + + + delete from new_stock_industry where industry_id in + + #{industryId} + + + + \ No newline at end of file diff --git a/stock-system/src/main/resources/mapper/stocksystem/NewStocksMapper.xml b/stock-system/src/main/resources/mapper/stocksystem/NewStocksMapper.xml new file mode 100644 index 0000000..6f8ddb7 --- /dev/null +++ b/stock-system/src/main/resources/mapper/stocksystem/NewStocksMapper.xml @@ -0,0 +1,147 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + select id, code, trade_date, open, close, change_rate, trade_days, volume, amount, change_rate_10, change_rate_20, change_rate_60, avg_volume_20, free_float_market_value, total_market_value, agencies_hold + from new_stocks + + + + + + + + + + + + + + insert into new_stocks( + code, trade_date, open, close, change_rate, trade_days, volume, amount, change_rate_10, change_rate_20, change_rate_60, avg_volume_20, free_float_market_value, total_market_value, agencies_hold + ) values ( + #{code}, #{tradeDate}, #{open}, #{close}, #{changeRate}, #{tradeDays}, #{volume}, #{amount}, #{changeRate10}, #{changeRate20}, #{changeRate60}, #{avgVolume20}, #{freeFloatMarketValue}, #{totalMarketValue}, #{agenciesHold} + ) + + + + insert into new_stocks( + code, trade_date, open, close, change_rate, trade_days, volume, amount, change_rate_10, change_rate_20, change_rate_60, avg_volume_20, free_float_market_value, total_market_value, agencies_hold + ) values + + ( + #{item.code}, #{item.tradeDate}, #{item.open}, #{item.close}, #{item.changeRate}, #{item.tradeDays}, #{item.volume}, #{item.amount}, #{item.changeRate10}, #{item.changeRate20}, #{item.changeRate60}, #{item.avgVolume20}, #{item.freeFloatMarketValue}, #{item.totalMarketValue}, #{item.agenciesHold} + ) + + + + + update new_stocks + + code = #{code}, + trade_date = #{tradeDate}, + open = #{open}, + close = #{close}, + change_rate = #{changeRate}, + trade_days = #{tradeDays}, + volume = #{volume}, + amount = #{amount}, + change_rate_10 = #{changeRate10}, + change_rate_20 = #{changeRate20}, + change_rate_60 = #{changeRate60}, + avg_volume_20 = #{avgVolume20}, + free_float_market_value = #{freeFloatMarketValue}, + total_market_value = #{totalMarketValue}, + agencies_hold = #{agenciesHold}, + + where id = #{id} + + + + delete from new_stocks where id = #{id} + + + + delete from new_stocks where id in + + #{id} + + + + + + \ No newline at end of file