Skip to content

Commit bd1443f

Browse files
🔧 refactor(commands): 重构命令类系统并增加代码文档
- 【重构】将通用的命令处理方法从`GenerateCommitCommand`移至`BaseCommand` - 【文档】为所有重要方法和类添加JSDoc注释说明 - 【重构】优化错误处理和配置验证逻辑 - 【优化】统一命令执行流程和模型选择逻辑 - 【改进】将重复的配置处理逻辑抽象到基类中 - 【维护】删除`SelectModelCommand`中重复的模型选择器方法
1 parent 2989f03 commit bd1443f

File tree

3 files changed

+287
-26
lines changed

3 files changed

+287
-26
lines changed

src/commands/BaseCommand.ts

+206-4
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,44 @@ import * as vscode from "vscode";
22
import { NotificationHandler } from "../utils/NotificationHandler";
33
import { ConfigurationManager } from "../config/ConfigurationManager";
44
import { LocalizationManager } from "../utils/LocalizationManager";
5+
import { AIProviderFactory } from "../ai/AIProviderFactory";
6+
import { SCMFactory } from "../scm/SCMProvider";
7+
import { ModelPickerService } from "../services/ModelPickerService";
58

9+
/**
10+
* 基础命令类,提供通用的命令执行功能
11+
*/
612
export abstract class BaseCommand {
13+
/** VSCode扩展上下文 */
714
protected context: vscode.ExtensionContext;
815

16+
/**
17+
* 创建命令实例
18+
* @param context - VSCode扩展上下文
19+
*/
920
constructor(context: vscode.ExtensionContext) {
1021
this.context = context;
1122
}
1223

24+
/**
25+
* 验证配置是否有效
26+
* @returns 配置是否有效
27+
*/
1328
protected async validateConfig(): Promise<boolean> {
14-
// if (!(await ConfigurationManager.getInstance().validateConfiguration())) {
15-
// NotificationHandler.error("command.execution.failed");
16-
// return false;
17-
// }
29+
if (!(await ConfigurationManager.getInstance().validateConfiguration())) {
30+
NotificationHandler.error(
31+
LocalizationManager.getInstance().getMessage("command.execution.failed")
32+
);
33+
return false;
34+
}
1835
return true;
1936
}
2037

38+
/**
39+
* 处理执行过程中的错误
40+
* @param error - 错误对象
41+
* @param errorMessage - 错误消息模板
42+
*/
2143
protected async handleError(
2244
error: unknown,
2345
errorMessage: string
@@ -30,5 +52,185 @@ export abstract class BaseCommand {
3052
}
3153
}
3254

55+
/**
56+
* 处理AI配置
57+
* @returns AI提供商和模型信息,如果配置无效则返回undefined
58+
*/
59+
protected async handleConfiguration(): Promise<
60+
{ provider: string; model: string } | undefined
61+
> {
62+
const config = ConfigurationManager.getInstance();
63+
if (!(await config.validateConfiguration())) {
64+
return;
65+
}
66+
67+
const configuration = config.getConfiguration();
68+
let provider = configuration.base.provider;
69+
let model = configuration.base.model;
70+
71+
if (!provider || !model) {
72+
return this.selectAndUpdateModelConfiguration(provider, model);
73+
}
74+
75+
return { provider, model };
76+
}
77+
78+
/**
79+
* 获取模型并更新配置
80+
* @param provider - AI提供商名称
81+
* @param model - 模型名称
82+
* @returns 更新后的提供商、模型和AI实例信息
83+
* @throws Error 当无法获取模型列表或找不到指定模型时
84+
*/
85+
protected async getModelAndUpdateConfiguration(
86+
provider = "Ollama",
87+
model = "Ollama"
88+
) {
89+
const locManager = LocalizationManager.getInstance();
90+
let aiProvider = AIProviderFactory.getProvider(provider);
91+
let models = await aiProvider.getModels();
92+
93+
if (!models || models.length === 0) {
94+
const { provider: newProvider, model: newModel } =
95+
await this.selectAndUpdateModelConfiguration(provider, model);
96+
provider = newProvider;
97+
model = newModel;
98+
99+
aiProvider = AIProviderFactory.getProvider(provider);
100+
models = await aiProvider.getModels();
101+
102+
if (!models || models.length === 0) {
103+
throw new Error(locManager.getMessage("model.list.empty"));
104+
}
105+
}
106+
107+
let selectedModel = models.find((m) => m.name === model);
108+
109+
if (!selectedModel) {
110+
const { provider: newProvider, model: newModel } =
111+
await this.selectAndUpdateModelConfiguration(provider, model);
112+
provider = newProvider;
113+
model = newModel;
114+
115+
aiProvider = AIProviderFactory.getProvider(provider);
116+
models = await aiProvider.getModels();
117+
selectedModel = models.find((m) => m.name === model);
118+
119+
if (!selectedModel) {
120+
throw new Error(locManager.getMessage("model.notFound"));
121+
}
122+
}
123+
124+
return { provider, model, selectedModel, aiProvider };
125+
}
126+
127+
/**
128+
* 选择模型并更新配置
129+
* @param provider - 当前AI提供商
130+
* @param model - 当前模型名称
131+
* @returns 更新后的提供商和模型信息
132+
*/
133+
protected async selectAndUpdateModelConfiguration(
134+
provider = "Ollama",
135+
model = "Ollama"
136+
) {
137+
const modelSelection = await this.showModelPicker(provider, model);
138+
if (!modelSelection) {
139+
return { provider, model };
140+
}
141+
142+
const config = ConfigurationManager.getInstance();
143+
await config.updateAIConfiguration(
144+
modelSelection.provider,
145+
modelSelection.model
146+
);
147+
return { provider: modelSelection.provider, model: modelSelection.model };
148+
}
149+
150+
/**
151+
* 显示模型选择器
152+
* @param currentProvider - 当前AI提供商
153+
* @param currentModel - 当前模型名称
154+
* @returns 用户选择的提供商和模型信息
155+
*/
156+
protected async showModelPicker(
157+
currentProvider: string,
158+
currentModel: string
159+
) {
160+
return ModelPickerService.showModelPicker(currentProvider, currentModel);
161+
}
162+
163+
/**
164+
* 获取选中的文件列表
165+
* @param resourceStates - 源代码管理资源状态
166+
* @returns 文件路径列表
167+
*/
168+
protected getSelectedFiles(
169+
resourceStates?:
170+
| vscode.SourceControlResourceState
171+
| vscode.SourceControlResourceState[]
172+
): string[] | undefined {
173+
if (!resourceStates) {
174+
return undefined;
175+
}
176+
177+
const states = Array.isArray(resourceStates)
178+
? resourceStates
179+
: [resourceStates];
180+
return [
181+
...new Set(
182+
states
183+
.map(
184+
(state) =>
185+
(state as any)?._resourceUri?.fsPath || state?.resourceUri?.fsPath
186+
)
187+
.filter(Boolean)
188+
),
189+
];
190+
}
191+
192+
/** 获取本地化管理器实例 */
193+
protected get locManager(): LocalizationManager {
194+
return LocalizationManager.getInstance();
195+
}
196+
197+
/**
198+
* 检测并获取SCM提供程序
199+
* @returns SCM提供程序实例
200+
*/
201+
protected async detectSCMProvider() {
202+
const scmProvider = await SCMFactory.detectSCM();
203+
if (!scmProvider) {
204+
NotificationHandler.error(this.locManager.getMessage("scm.not.detected"));
205+
return;
206+
}
207+
return scmProvider;
208+
}
209+
210+
/**
211+
* 获取提交信息
212+
* @param scmProvider - SCM提供程序实例
213+
* @returns 提交信息
214+
*/
215+
protected async getCommitInput(scmProvider: any) {
216+
return await scmProvider.getCommitInput();
217+
}
218+
219+
/**
220+
* 获取扩展配置
221+
* @returns 配置管理器实例和当前配置
222+
*/
223+
protected getExtConfig() {
224+
const config = ConfigurationManager.getInstance();
225+
return {
226+
config,
227+
configuration: config.getConfiguration(),
228+
};
229+
}
230+
231+
/**
232+
* 执行命令
233+
* @param args - 命令参数
234+
*/
33235
abstract execute(...args: any[]): Promise<void>;
34236
}

0 commit comments

Comments
 (0)