Skip to content

Commit 531f9f6

Browse files
committed
chore: code basic layout
1 parent c2d3cbd commit 531f9f6

10 files changed

+268
-28
lines changed

package.json

+21-7
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,29 @@
99
"categories": [
1010
"Other"
1111
],
12-
"activationEvents": [],
12+
"activationEvents": ["onView:home"],
1313
"main": "./dist/extension.js",
1414
"contributes": {
15-
"commands": [
16-
{
17-
"command": "leetcode-practice-vscode.helloWorld",
18-
"title": "Hello World"
19-
}
20-
]
15+
"viewsContainers": {
16+
"activitybar": [],
17+
"panel": [],
18+
"sidebar": [
19+
{
20+
"id": "leetcode-practice",
21+
"title": "leetcode-practice",
22+
"icon": "resources/logo.webp"
23+
}
24+
]
25+
},
26+
"views": {
27+
"leetcode-practice": [
28+
{
29+
"id": "home",
30+
"name": "Leetcode Practice"
31+
}
32+
]
33+
},
34+
"commands": []
2135
},
2236
"scripts": {
2337
"vscode:prepublish": "yarn run package",

resources/logo.webp

192 KB
Binary file not shown.

src/extension.ts

+4-21
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,9 @@
1-
// The module 'vscode' contains the VS Code extensibility API
2-
// Import the module and reference it with the alias vscode in your code below
31
import * as vscode from 'vscode';
4-
5-
// This method is called when your extension is activated
6-
// Your extension is activated the very first time the command is executed
2+
import {LeetcodeService} from "./services/leetcode.service";
3+
import {UiService} from "./services/ui.service";
74
export function activate(context: vscode.ExtensionContext) {
8-
9-
// Use the console to output diagnostic information (console.log) and errors (console.error)
10-
// This line of code will only be executed once when your extension is activated
11-
console.log('Congratulations, your extension "leetcode-practice-vscode" is now active!');
12-
13-
// The command has been defined in the package.json file
14-
// Now provide the implementation of the command with registerCommand
15-
// The commandId parameter must match the command field in package.json
16-
const disposable = vscode.commands.registerCommand('leetcode-practice-vscode.helloWorld', () => {
17-
// The code you place here will be executed every time your command is executed
18-
// Display a message box to the user
19-
vscode.window.showInformationMessage('Hello World from leetcode-practice!');
20-
});
21-
22-
context.subscriptions.push(disposable);
5+
UiService.init();
6+
LeetcodeService.init();
237
}
248

25-
// This method is called when your extension is deactivated
269
export function deactivate() {}

src/model/problem.interface.ts

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
export interface Problem{
2+
title: string,
3+
difficulty: string,
4+
tags: string[],
5+
url: string
6+
}

src/services/ai.service.ts

Whitespace-only changes.

src/services/leetcode.service.ts

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import {NpmUtil} from "../utils/npm.util";
2+
import {LoggerUtil} from "../utils/logger.util";
3+
4+
export class LeetcodeService{
5+
/**
6+
* 初始化
7+
*/
8+
static init(){
9+
LeetcodeService.checkDept();
10+
}
11+
12+
static checkDept(){
13+
if(!NpmUtil.isGlobalPackageInstalled('leetcode-practice')){
14+
LoggerUtil.info('检测到未安装 leetcode-practice, 正在安装...');
15+
NpmUtil.installGlobalPackage('leetcode-practice');
16+
}
17+
}
18+
}

src/services/ui.service.ts

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import {HomeProvider} from "../ui/home/home";
2+
import * as vscode from "vscode";
3+
4+
export class UiService{
5+
static init(){
6+
const homeProvider = new HomeProvider();
7+
vscode.window.registerTreeDataProvider('home', homeProvider);
8+
}
9+
}

src/ui/home/home.ts

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import * as vscode from "vscode";
2+
3+
export class HomeProvider implements vscode.TreeDataProvider<any>{
4+
private _onDidChangeTreeData: vscode.EventEmitter<TreeItem | undefined> = new vscode.EventEmitter<TreeItem | undefined>();
5+
readonly onDidChangeTreeData: vscode.Event<TreeItem | undefined> = this._onDidChangeTreeData.event;
6+
7+
getTreeItem(element: TreeItem): vscode.TreeItem {
8+
return element;
9+
}
10+
11+
getChildren(element?: TreeItem): TreeItem[] {
12+
if (!element) {
13+
return [new TreeItem('Item 1'), new TreeItem('Item 2')];
14+
}
15+
return [];
16+
}
17+
}
18+
class TreeItem extends vscode.TreeItem {
19+
constructor(label: string) {
20+
super(label);
21+
this.tooltip = `Tooltip for ${label}`;
22+
this.description = `Description of ${label}`;
23+
}
24+
}

src/utils/logger.util.ts

+67
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
import * as vscode from 'vscode';
2+
3+
export class LoggerUtil {
4+
/**
5+
* 显示信息提示
6+
* @param message 要显示的信息
7+
* @param items 可选的操作项
8+
*/
9+
static info(message: string, ...items: string[]): Thenable<string | undefined> {
10+
return vscode.window.showInformationMessage(message, ...items);
11+
}
12+
13+
/**
14+
* 显示警告提示
15+
* @param message 要显示的警告信息
16+
* @param items 可选的操作项
17+
*/
18+
static warn(message: string, ...items: string[]): Thenable<string | undefined> {
19+
return vscode.window.showWarningMessage(message, ...items);
20+
}
21+
22+
/**
23+
* 显示错误提示
24+
* @param message 要显示的错误信息
25+
* @param items 可选的操作项
26+
*/
27+
static error(message: string, ...items: string[]): Thenable<string | undefined> {
28+
return vscode.window.showErrorMessage(message, ...items);
29+
}
30+
31+
/**
32+
* 记录到输出面板
33+
* @param message 要记录的信息
34+
* @param logType 日志类型 (info | warn | error)
35+
*/
36+
static log(message: string, logType: 'info' | 'warn' | 'error' = 'info'): void {
37+
const outputChannel = LoggerUtil.getOutputChannel();
38+
const timestamp = new Date().toISOString();
39+
const formattedMessage = `[${logType.toUpperCase()}] [${timestamp}] ${message}`;
40+
outputChannel.appendLine(formattedMessage);
41+
if (logType === 'error') {
42+
outputChannel.show(true); // 错误信息时自动展示输出面板
43+
}
44+
}
45+
46+
/**
47+
* 清空输出面板
48+
*/
49+
static clear(): void {
50+
const outputChannel = LoggerUtil.getOutputChannel();
51+
outputChannel.clear();
52+
}
53+
54+
/**
55+
* 获取或创建日志输出面板
56+
* @returns 输出面板实例
57+
*/
58+
private static getOutputChannel(): vscode.OutputChannel {
59+
if (!this.outputChannel) {
60+
this.outputChannel = vscode.window.createOutputChannel('LoggerUtil');
61+
}
62+
return this.outputChannel;
63+
}
64+
65+
// 输出面板实例(单例模式)
66+
private static outputChannel: vscode.OutputChannel;
67+
}

src/utils/npm.util.ts

+119
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
import { execSync } from 'child_process';
2+
3+
export class NpmUtil {
4+
/**
5+
* 获取当前项目的 npm 版本
6+
* @returns 当前项目的 npm 版本号
7+
*/
8+
static getNpmVersion(): string {
9+
return process.env.npm_package_version || 'Unknown';
10+
}
11+
12+
/**
13+
* 获取全局 npm 版本号
14+
* @returns 全局 npm 的版本号
15+
*/
16+
static getGlobalNpmVersion(): string {
17+
try {
18+
const version = execSync('npm --version', { encoding: 'utf-8' }).trim();
19+
return version;
20+
} catch (error) {
21+
console.error('获取全局 npm 版本失败:', error);
22+
return 'Unknown';
23+
}
24+
}
25+
26+
/**
27+
* 检查是否安装了某个依赖
28+
* @param packageName 要检查的依赖名称
29+
* @returns 是否安装了该依赖
30+
*/
31+
static isPackageInstalled(packageName: string): boolean {
32+
try {
33+
require.resolve(packageName);
34+
return true;
35+
} catch {
36+
return false;
37+
}
38+
}
39+
40+
/**
41+
* 安装某个 npm 包(本地)
42+
* @param packageName 要安装的 npm 包名称
43+
*/
44+
static installPackage(packageName: string): void {
45+
try {
46+
execSync(`npm install ${packageName}`, { stdio: 'inherit' });
47+
console.log(`成功安装依赖: ${packageName}`);
48+
} catch (error) {
49+
console.error(`安装依赖 ${packageName} 失败:`, error);
50+
}
51+
}
52+
53+
/**
54+
* 卸载某个 npm 包(本地)
55+
* @param packageName 要卸载的 npm 包名称
56+
*/
57+
static uninstallPackage(packageName: string): void {
58+
try {
59+
execSync(`npm uninstall ${packageName}`, { stdio: 'inherit' });
60+
console.log(`成功卸载依赖: ${packageName}`);
61+
} catch (error) {
62+
console.error(`卸载依赖 ${packageName} 失败:`, error);
63+
}
64+
}
65+
66+
/**
67+
* 获取当前项目的依赖列表
68+
* @returns 当前项目的依赖及其版本
69+
*/
70+
static getDependencies(): Record<string, string> {
71+
try {
72+
const packageJson = require(`${process.cwd()}/package.json`);
73+
return packageJson.dependencies || {};
74+
} catch (error) {
75+
console.error('读取 package.json 失败:', error);
76+
return {};
77+
}
78+
}
79+
80+
/**
81+
* 检查全局是否安装了某个 npm 包
82+
* @param packageName 要检查的 npm 包名称
83+
* @returns 是否安装了该全局包
84+
*/
85+
static isGlobalPackageInstalled(packageName: string): boolean {
86+
try {
87+
const result = execSync(`npm list -g ${packageName}`, { encoding: 'utf-8' });
88+
return result.includes(packageName);
89+
} catch {
90+
return false;
91+
}
92+
}
93+
94+
/**
95+
* 安装全局 npm 包
96+
* @param packageName 要安装的 npm 包名称
97+
*/
98+
static installGlobalPackage(packageName: string): void {
99+
try {
100+
execSync(`npm install -g ${packageName}`, { stdio: 'inherit' });
101+
console.log(`成功安装全局依赖: ${packageName}`);
102+
} catch (error) {
103+
console.error(`安装全局依赖 ${packageName} 失败:`, error);
104+
}
105+
}
106+
107+
/**
108+
* 卸载全局 npm 包
109+
* @param packageName 要卸载的 npm 包名称
110+
*/
111+
static uninstallGlobalPackage(packageName: string): void {
112+
try {
113+
execSync(`npm uninstall -g ${packageName}`, { stdio: 'inherit' });
114+
console.log(`成功卸载全局依赖: ${packageName}`);
115+
} catch (error) {
116+
console.error(`卸载全局依赖 ${packageName} 失败:`, error);
117+
}
118+
}
119+
}

0 commit comments

Comments
 (0)