Skip to content

Commit

Permalink
Merge pull request #458 from gittig11/feature/stocks-new-folder
Browse files Browse the repository at this point in the history
feat: 新增股票分组功能
  • Loading branch information
giscafer authored Aug 27, 2024
2 parents 91db509 + 3afd173 commit 39d4e80
Show file tree
Hide file tree
Showing 9 changed files with 192 additions and 48 deletions.
37 changes: 36 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,19 @@
"title": "添加股票",
"icon": "$(add)"
},
{
"command": "leek-fund.addStockGroup",
"title": "添加股票分组",
"icon": "$(diff-added)"
},
{
"command": "leek-fund.renameStockGroup",
"title": "修改分组名称"
},
{
"command": "leek-fund.removeStockGroup",
"title": "删除分组"
},
{
"command": "leek-fund.setStockPrice",
"title": "设置股票成本价",
Expand Down Expand Up @@ -333,7 +346,7 @@
"group": "navigation"
},
{
"command": "leek-fund.addStock",
"command": "leek-fund.addStockGroup",
"when": "view == leekFundView.stock",
"group": "navigation"
},
Expand Down Expand Up @@ -409,6 +422,11 @@
"when": "view == leekFundView.fund && viewItem == category",
"group": "inline"
},
{
"command": "leek-fund.addStock",
"when": "view == leekFundView.stock && viewItem == category",
"group": "inline"
},
{
"command": "leek-fund.deleteFund",
"when": "view == leekFundView.fund && viewItem != category",
Expand All @@ -424,6 +442,16 @@
"when": "view == leekFundView.fund && viewItem == category",
"group": "group7"
},
{
"command": "leek-fund.removeStockGroup",
"when": "view == leekFundView.stock && viewItem == category",
"group": "group8"
},
{
"command": "leek-fund.renameStockGroup",
"when": "view == leekFundView.stock && viewItem == category",
"group": "group8"
},
{
"command": "leek-fund.setStockTop",
"when": "view == leekFundView.stock && viewItem != category && viewItem!=nodata",
Expand Down Expand Up @@ -519,6 +547,13 @@
],
"description": "配置需要监控的股票代码(建议通过界面新增)"
},
"leek-fund.stockGroups": {
"type": "array",
"default": [
"My Stocks"
],
"description": "配置股票分组名称(建议通过界面新增)"
},
"leek-fund.stockPrice": {
"type": "object",
"default": {},
Expand Down
55 changes: 29 additions & 26 deletions src/explorer/stockProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,35 +34,19 @@ export class StockProvider implements TreeDataProvider<LeekTreeItem> {

getChildren(element?: LeekTreeItem | undefined): LeekTreeItem[] | Thenable<LeekTreeItem[]> {
if (!element) {
// Root view
const stockCodes = LeekFundConfig.getConfig('leek-fund.stocks') || [];
return this.service.getData(stockCodes, this.order).then(() => {
return this.getRootNodes();
});
return this.getRootNodes(globalState.stockGroups, globalState.stockLists);
} else {
const resultPromise = Promise.resolve(this.service.stockList || []);
switch (
element.id // First-level
) {
case StockCategory.A:
return this.getAStockNodes(resultPromise);
case StockCategory.HK:
return this.getHkStockNodes(resultPromise);
case StockCategory.US:
return this.getUsStockNodes(resultPromise);
case StockCategory.Future:
return this.getFutureStockNodes(resultPromise);
case StockCategory.OverseaFuture:
return this.getOverseaFutureStockNodes(resultPromise);
case StockCategory.NODATA:
return this.getNoDataStockNodes(resultPromise);
default:
return [];
// return this.getChildrenNodesById(element.id);
}
return this.getChildrenNodes(element, globalState.stockLists);
}
}

getChildrenNodes(element: LeekTreeItem, stockLists: Array<Array<string>>): Promise<Array<LeekTreeItem>> {
const groupId = element.id || '';
const index: number = parseInt(groupId.replace('stockGroup_', ''));
const stockCodes: Array<string> = stockLists[index];
return this.service.getData(stockCodes, this.order, groupId);
}

getParent(): LeekTreeItem | undefined {
return undefined;
}
Expand Down Expand Up @@ -90,7 +74,26 @@ export class StockProvider implements TreeDataProvider<LeekTreeItem> {
}
}

getRootNodes(): LeekTreeItem[] {
getRootNodes(stockGroups: Array<string>, stockLists: Array<Array<string>>): Array<LeekTreeItem> {
let nodes: Array<LeekTreeItem> = [];
stockLists.forEach((value, index) => {
nodes.push(
new LeekTreeItem(
Object.assign({ contextValue: 'category' }, defaultFundInfo, {
id: `stockGroup_${index}`,
name: `${stockGroups[index]}${value.length > 0 ? `(${value.length})` : ''}`,
isStock: true,
}),
undefined,
true
)
);
});
return nodes;
}

// hide
getRootNodes1(): LeekTreeItem[] {
const nodes = [
new LeekTreeItem(
Object.assign({ contextValue: 'category' }, defaultFundInfo, {
Expand Down
20 changes: 13 additions & 7 deletions src/explorer/stockService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,11 @@ export default class StockService extends LeekService {
return this.token;
}

async getData(codes: Array<string>, order: number): Promise<Array<LeekTreeItem>> {
async getData(
codes: Array<string>,
order: number,
groupId: string,
): Promise<Array<LeekTreeItem>> {
// console.log('fetching stock data…');
if ((codes && codes.length === 0) || !codes) {
return [];
Expand Down Expand Up @@ -70,8 +74,8 @@ export default class StockService extends LeekService {

let stockList: Array<LeekTreeItem> = [];
const result = await Promise.allSettled([
this.getStockData(stockCodes),
this.getHKStockData(hkCodes),
this.getStockData(stockCodes, groupId),
this.getHKStockData(hkCodes, groupId),
]);
result.forEach((item) => {
if (item.status === 'fulfilled') {
Expand All @@ -88,7 +92,7 @@ export default class StockService extends LeekService {
return res;
}

async getStockData(codes: Array<string>): Promise<Array<LeekTreeItem>> {
async getStockData(codes: Array<string>, groupId: string): Promise<Array<LeekTreeItem>> {
if ((codes && codes.length === 0) || !codes) {
return [];
}
Expand Down Expand Up @@ -124,7 +128,7 @@ export default class StockService extends LeekService {
return [];
}
for (const code of codes) {
stockList = stockList.concat(await this.getStockData(new Array(code)));
stockList = stockList.concat(await this.getStockData(new Array(code), groupId));
}
} else {
const splitData = resp.data.split(';\n');
Expand Down Expand Up @@ -349,6 +353,7 @@ export default class StockService extends LeekService {
} catch (err) {
console.error(err);
}
stockItem.id = `${groupId}_${code}`;
stockItem.showLabel = this.showLabel;
stockItem.isStock = true;
stockItem.type = type;
Expand All @@ -365,7 +370,7 @@ export default class StockService extends LeekService {
// 接口不支持的
noDataStockCount += 1;
stockItem = {
id: code,
id: `${groupId}_${code}`,
name: `接口不支持该股票 ${code}`,
showLabel: this.showLabel,
isStock: true,
Expand Down Expand Up @@ -399,7 +404,7 @@ export default class StockService extends LeekService {
return stockList;
}

async getHKStockData(codes: Array<string>): Promise<Array<LeekTreeItem>> {
async getHKStockData(codes: Array<string>, groupId: string): Promise<Array<LeekTreeItem>> {
if ((codes && codes.length === 0) || !codes) {
return [];
}
Expand Down Expand Up @@ -463,6 +468,7 @@ export default class StockService extends LeekService {
if (Number(open) <= 0) {
price = yestclose;
}
stockItem.id = `${groupId}_${stockItem.code}`;
stockItem.showLabel = this.showLabel;
stockItem.isStock = true;
stockItem.type = 'hk';
Expand Down
20 changes: 18 additions & 2 deletions src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,10 +100,13 @@ export function activate(context: ExtensionContext) {
const manualRequest = () => {
const fundLists = LeekFundConfig.getConfig('leek-fund.funds') || [];
fundLists.forEach((value: Array<string>, index: number) => {
fundService.getData(value, SortType.NORMAL, `fundGroup_${index}`);
Array.isArray(value) && fundService.getData(value, SortType.NORMAL, `fundGroup_${index}`);
});

stockService.getData(LeekFundConfig.getConfig('leek-fund.stocks'), SortType.NORMAL);
const stockLists = LeekFundConfig.getConfig('leek-fund.stocks') || [];
stockLists.forEach((value: Array<string>, index: number) => {
Array.isArray(value) && stockService.getData(value, SortType.NORMAL, `stockGroup_${index}`);
});
};

manualRequest();
Expand Down Expand Up @@ -253,6 +256,19 @@ function setGlobalVariable() {
} else {
globalState.fundLists = fundLists;
}

globalState.stockGroups = LeekFundConfig.getConfig('leek-fund.stockGroups') || [];

const stockLists = LeekFundConfig.getConfig('leek-fund.stocks') || [];
if (typeof stockLists[0] === 'string' || stockLists[0] instanceof String) {
// 迁移用户的股票代码到分组模式
const newStockLists = [stockLists];
globalState.stockLists = newStockLists;
LeekFundConfig.setConfig('leek-fund.stocks', newStockLists);
LeekFundConfig.setConfig('leek-fund.stockGroups', ['My Stocks']);
} else {
globalState.stockLists = stockLists;
}
}

// this method is called when your extension is deactivated
Expand Down
5 changes: 5 additions & 0 deletions src/globalState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ let isDevelopment = false; // 是否开发环境
let fundGroups: Array<string> = [];
let fundLists: Array<Array<string>> = [];

let stockGroups: Array<string> = [];
let stockLists: Array<Array<string>> = [];

let stockPrice = {}; // 缓存数据
let stockPriceCacheDate = '2020-10-30';
export default {
Expand Down Expand Up @@ -69,6 +72,8 @@ export default {
isDevelopment,
fundGroups,
fundLists,
stockGroups,
stockLists,

stockPrice,
stockPriceCacheDate,
Expand Down
2 changes: 1 addition & 1 deletion src/output/flash-news/impl/Jin10FlushService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ export default class Jin10FlushService extends NewsFlushServiceAbstractClass {

ws.addEventListener('error', (err: any) => {
globalState.telemetry.sendEvent('error:jin10Service', { error: err });
console.log("🚀 ~ 金十快讯 ws 错误:Jin10FlushService ~ ws.addEventListener ~ err:", err)
console.log("🚀 ~ 金十快讯 ws 错误:Jin10FlushService ~ ws.addEventListener ~ err:", err);
});

ws.addEventListener('close', () => {
Expand Down
32 changes: 30 additions & 2 deletions src/registerCommand.ts
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,8 @@ export function registerViewEvent(

// Stock operation
commands.registerCommand('leek-fund.refreshStock', () => {
globalState.stockGroups = LeekFundConfig.getConfig('leek-fund.stockGroups', []);
globalState.stockLists = LeekFundConfig.getConfig('leek-fund.stocks', []);
stockProvider.refresh();
const handler = window.setStatusBarMessage(`股票数据已刷新`);
setTimeout(() => {
Expand All @@ -154,7 +156,7 @@ export function registerViewEvent(
}
leekCenterView(stockService, fundService);
});
commands.registerCommand('leek-fund.addStock', () => {
commands.registerCommand('leek-fund.addStock', (target) => {
// vscode QuickPick 不支持动态查询,只能用此方式解决
// https://github.com/microsoft/vscode/issues/23633
const qp = window.createQuickPick();
Expand Down Expand Up @@ -185,7 +187,7 @@ export function registerViewEvent(
}
// 存储到配置的时候是接口的参数格式,接口请求时不需要再转换
const newCode = code.replace('gb', 'gb_').replace('us', 'usr_');
LeekFundConfig.updateStockCfg(newCode, () => {
LeekFundConfig.addStockCfg(target.id, newCode, () => {
stockProvider.refresh();
});
qp.hide();
Expand All @@ -196,6 +198,32 @@ export function registerViewEvent(
stockProvider.changeOrder();
stockProvider.refresh();
});
commands.registerCommand('leek-fund.addStockGroup', () => {
window.showInputBox({ placeHolder: '请输入股票分组名称' }).then((name) => {
if (!name) {
return;
}
LeekFundConfig.addStockGroupCfg(name, () => {
stockProvider.refresh();
});
});
});
commands.registerCommand('leek-fund.removeStockGroup', (target) => {
LeekFundConfig.removeStockGroupCfg(target.id, () => {
stockService.stockList = [];
stockProvider.refresh();
});
});
commands.registerCommand('leek-fund.renameStockGroup', (target) => {
window.showInputBox({ placeHolder: '请输入股票分组名称' }).then((name) => {
if (!name) {
return;
}
LeekFundConfig.renameStockGroupCfg(target.id, name, () => {
stockProvider.refresh();
});
});
});

/**
* WebView
Expand Down
Loading

0 comments on commit 39d4e80

Please sign in to comment.