You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

124 lines
3.3 KiB

import { Request, Response } from 'express';
import { stockService } from '../services/stockService';
import { asyncHandler, NotFoundError, BadRequestError } from '../middleware/errorHandler';
import { ApiResponse } from '../types';
import { searchKeywordSchema, periodSchema } from '../utils/validator';
export const stockController = {
// 搜索股票
search: asyncHandler(async (req: Request, res: Response) => {
const { keyword, type } = req.query;
if (!keyword || typeof keyword !== 'string') {
throw new BadRequestError('搜索关键词不能为空');
}
const validatedKeyword = searchKeywordSchema.parse(keyword);
let sectors: any[] = [];
let stocks: any[] = [];
if (!type || type === 'all' || type === 'sector') {
sectors = await stockService.searchSectors(validatedKeyword);
}
if (!type || type === 'all' || type === 'stock') {
stocks = await stockService.searchStocks(validatedKeyword);
}
const response: ApiResponse = {
code: 200,
message: 'success',
data: {
sectors,
stocks,
},
};
res.json(response);
}),
// 获取股票详情
getStockDetail: asyncHandler(async (req: Request, res: Response) => {
const { stock_code } = req.params;
const stock = await stockService.getStockDetail(stock_code);
if (!stock) {
throw new NotFoundError('股票不存在');
}
const response: ApiResponse = {
code: 200,
message: 'success',
data: stock,
};
res.json(response);
}),
// 获取股票K线数据
getStockKLine: asyncHandler(async (req: Request, res: Response) => {
const { stock_code } = req.params;
const period = periodSchema.parse(req.query.period || 'day');
const days = parseInt(req.query.days as string) || 60;
const klines = await stockService.getKLineData(stock_code, period, days);
const response: ApiResponse = {
code: 200,
message: 'success',
data: klines,
};
res.json(response);
}),
// 获取新高股票
getNewHighStocks: asyncHandler(async (req: Request, res: Response) => {
const days = parseInt(req.query.days as string) || 20;
const limit = parseInt(req.query.limit as string) || 20;
const stocks = await stockService.getNewHighStocks(days, limit);
const response: ApiResponse = {
code: 200,
message: 'success',
data: stocks,
};
res.json(response);
}),
// 获取新低股票
getNewLowStocks: asyncHandler(async (req: Request, res: Response) => {
const days = parseInt(req.query.days as string) || 20;
const limit = parseInt(req.query.limit as string) || 20;
const stocks = await stockService.getNewLowStocks(days, limit);
const response: ApiResponse = {
code: 200,
message: 'success',
data: stocks,
};
res.json(response);
}),
// 获取动量股推荐
getMomentumRecommendation: asyncHandler(async (req: Request, res: Response) => {
const limit = parseInt(req.query.limit as string) || 15;
const stocks = await stockService.getMomentumStocks(limit);
const response: ApiResponse = {
code: 200,
message: 'success',
data: stocks,
};
res.json(response);
}),
};