This commit is contained in:
HuangHai
2026-01-26 09:15:45 +08:00
parent 6b6a32c902
commit d9bb1d1f83
17 changed files with 70 additions and 358 deletions

View File

@@ -472,105 +472,6 @@ namespace WordAddIn
}
}
/// <summary>
/// 【智能扩写】按钮点击事件处理。
/// 功能描述:
/// 1. 获取用户选中的文本(或剪贴板内容)。
/// 2. 弹出选项窗体,允许用户输入自定义扩写提示词。
/// 3. 调用 AI 扩写接口,传入原文、用户提示和全文上下文。
/// 4. 将 AI 生成的扩写内容替换原有选区,或插入到光标位置。
/// </summary>
/// <param name="control">触发事件的 Ribbon 控件</param>
public async void OnExpandClick(Office.IRibbonControl control)
{
if (!EnsureLoggedIn()) return;
LoadingForm loading = null;
try
{
var selection = Globals.ThisAddIn.Application.Selection;
// 1. 判断是否有选中文本
// wdSelectionNormal 表示有选区,否则检查 Text 属性
bool hasSelection = selection.Type == Word.WdSelectionType.wdSelectionNormal ||
(!string.IsNullOrEmpty(selection.Text) && selection.Text.Length > 1);
if (!hasSelection)
{
// 2. 尝试从剪贴板读取
IDataObject data = Clipboard.GetDataObject();
if (data != null && data.GetDataPresent(DataFormats.Text))
{
string clipboardText = (string)data.GetData(DataFormats.Text);
if (string.IsNullOrWhiteSpace(clipboardText))
{
MessageBox.Show("剪贴板中内容为空,请先选择一段需要扩写的文字,或者复制文字到剪贴板。");
return;
}
}
else
{
MessageBox.Show("请先选择一段需要扩写的文字,或者复制文字到剪贴板。");
return;
}
}
string originalText;
if (hasSelection)
{
originalText = selection.Text.Trim();
}
else
{
// 使用剪贴板内容
IDataObject data = Clipboard.GetDataObject();
originalText = (string)data.GetData(DataFormats.Text);
}
if (string.IsNullOrWhiteSpace(originalText))
{
MessageBox.Show("获取文字失败,请重试。");
return;
}
// 3. 弹出选项设置窗体,让用户输入自定义扩写提示词
string customPrompt = null;
using (var optionsForm = new ExpandOptionsForm())
{
if (optionsForm.ShowDialog() != DialogResult.OK)
{
return; // 用户取消
}
customPrompt = optionsForm.SelectedPrompt;
}
loading = new LoadingForm("AI 正在扩写中,请稍候...");
loading.Show();
loading.Refresh();
// 4. 在后台线程运行 AI 请求,防止阻塞 UI
// 传入 GetCombinedContext() 以利用文档背景和参考资料
string expandedText = await Task.Run(() => _aiService.ExpandText(originalText, customPrompt, GetCombinedContext()));
if (!string.IsNullOrEmpty(expandedText))
{
// 5. 智能插入:尝试保持格式
SmartInsert(selection, expandedText);
}
}
catch (Exception ex)
{
MessageBox.Show("扩写失败: " + ex.Message);
}
finally
{
if (loading != null)
{
loading.CloseSafe();
loading.Dispose();
}
}
}
/// <summary>
/// 【素材写作】按钮点击事件处理。
@@ -674,8 +575,7 @@ namespace WordAddIn
/// <summary>
/// 智能插入辅助方法。
/// 使用 TypeText 方法插入文本,以保持当前光标处的格式。
/// 如果 TypeText 失败,则回退到直接赋值 Text 属性。
/// 插入文本并强制应用“正文”样式,确保格式统一。
/// </summary>
/// <param name="selection">Word 选区对象</param>
/// <param name="text">要插入的文本</param>
@@ -683,8 +583,19 @@ namespace WordAddIn
{
try
{
// 使用 TypeText 插入,让 Word 自动应用当前光标位置的格式
selection.TypeText(text);
// 获取当前 Range
Word.Range range = selection.Range;
// 插入文本
range.Text = text;
// 强制应用“正文”样式 (wdStyleNormal)
// 这样可以避免插入的内容受到当前光标位置样式(如标题样式)的影响
range.set_Style(Word.WdBuiltinStyle.wdStyleNormal);
// 将光标移动到插入内容之后,方便用户继续操作
range.Collapse(Word.WdCollapseDirection.wdCollapseEnd);
range.Select();
}
catch (Exception ex)
{
@@ -1060,6 +971,9 @@ namespace WordAddIn
var selection = Globals.ThisAddIn.Application.Selection;
var inlineShape = selection.InlineShapes.AddPicture(FileName: tempPath, LinkToFile: false, SaveWithDocument: true);
// 强制将图片所在的段落设为“正文”样式
inlineShape.Range.Paragraphs[1].set_Style(Word.WdBuiltinStyle.wdStyleNormal);
// 简单的图片调整
inlineShape.LockAspectRatio = Microsoft.Office.Core.MsoTriState.msoTrue;
if (inlineShape.Width > 400)

View File

@@ -12,7 +12,6 @@
<button id="btnReferenceGenerate" label="素材写作" size="large" onAction="OnReferenceGenerateClick" imageMso="ReviewCompareTwoVersions" />
<button id="btnPolish" label="润色加工" size="large" onAction="OnPolishClick" imageMso="Spelling" />
<button id="btnElevate" label="深度升华" size="large" onAction="OnElevateClick" imageMso="SmartArtInsert" />
<button id="btnExpand" label="智能扩写" size="large" onAction="OnExpandClick" imageMso="ReviewNewComment" />
<button id="btnFormat" label="格式美化" imageMso="FontColorCycle" size="large" onAction="OnFormatClick" />
<button id="btnImage" label="生成配图" size="large" onAction="OnImageClick" imageMso="PictureInsertFromFile" />
</group>

View File

@@ -41,38 +41,6 @@ namespace WordAddIn
_httpClient.DefaultRequestHeaders.Add("Authorization", $"Bearer {ApiKey}");
}
/// <summary>
/// 智能扩写:将简短的文本扩充为细节丰富、逻辑通顺的段落。
/// </summary>
/// <param name="originalText">需要扩写的原文</param>
/// <param name="customInstruction">用户自定义的扩写要求(如“更幽默一点”、“强调数据支持”等),可选</param>
/// <param name="documentContext">文档全文上下文(摘要、风格等),用于保持文风一致,可选</param>
/// <returns>扩写后的纯文本内容</returns>
public async Task<string> ExpandText(string originalText, string customInstruction = null, string documentContext = null)
{
// 构造 User 指令
string instruction = string.IsNullOrWhiteSpace(customInstruction)
? "请将以下内容扩写成一段正式、通顺的段落,保持原意但增加细节"
: customInstruction;
// 构造 System Prompt
// 强制要求不使用 Markdown,方便直接插入 Word
string systemPrompt = "你是一个专业的文档编辑助手。请直接输出扩写后的纯文本内容,不要使用任何Markdown标记(如#、**、- 等)。直接使用自然段落。";
// 注入文档上下文(如果有)
if (!string.IsNullOrWhiteSpace(documentContext))
{
systemPrompt += $"\n\n【全文背景与排版规则】:你已通读全文,以下是文档的整体上下文信息和排版规则,请在扩写时保持与全文主题和风格的一致性,并参考排版规则生成对应的层级结构:\n{documentContext}";
}
var messages = new List<Message>
{
new Message { role = "system", content = systemPrompt },
new Message { role = "user", content = $"{instruction}:\n\n{originalText}" }
};
return await GetChatCompletion(messages);
}
/// <summary>
/// 润色加工:优化文本的语言表达,提升流畅度和专业性。

View File

@@ -1,182 +0,0 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
namespace WordAddIn
{
/// <summary>
/// 智能扩写设置窗体。
/// 功能描述:
/// 1. 提供多种预设的扩写模板(如"商务正式"、"细腻情感"等)。
/// 2. 允许用户修改预设模板或输入完全自定义的扩写要求。
/// 3. 返回用户的最终选择 (SelectedPrompt) 给调用方。
/// </summary>
public class ExpandOptionsForm : Form
{
/// <summary>
/// 用户最终确认的扩写要求。
/// </summary>
public string SelectedPrompt { get; private set; }
private ComboBox cmbTemplates;
private TextBox txtCustomPrompt;
private Button btnOk;
private Button btnCancel;
private Label lblTemplate;
private Label lblCustom;
private readonly Dictionary<string, string> _templates = new Dictionary<string, string>
{
{ "默认扩写", "请将以下内容扩写成一段正式、通顺的段落,保持原意但增加细节。" },
{ "细腻情感", "请对选中文本进行扩写,重点从心理活动、情绪变化和感官体验三个维度进行细腻描写。" },
{ "商务正式", "请将选中文本改写为商务职场风格,使用专业术语,语气正式且客观。" },
{ "生动故事", "请将选中文本扩写为一个生动的小故事,增加对话和场景描写,使其引人入胜。" },
{ "学术严谨", "请将选中文本扩写为学术风格,逻辑严密,用词精准,适合用于论文或报告。" },
{ "诗意唯美", "请用优美、诗意的语言扩写选中文本,多用修辞手法,营造唯美的意境。" }
};
public ExpandOptionsForm()
{
InitializeComponent();
InitializeTemplates();
}
/// <summary>
/// 初始化窗体组件。
/// </summary>
private void InitializeComponent()
{
this.lblTemplate = new System.Windows.Forms.Label();
this.lblCustom = new System.Windows.Forms.Label();
this.cmbTemplates = new System.Windows.Forms.ComboBox();
this.txtCustomPrompt = new System.Windows.Forms.TextBox();
this.btnOk = new System.Windows.Forms.Button();
this.btnCancel = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// lblTemplate
//
this.lblTemplate.AutoSize = true;
this.lblTemplate.Location = new System.Drawing.Point(20, 20);
this.lblTemplate.Name = "lblTemplate";
this.lblTemplate.Size = new System.Drawing.Size(83, 12);
this.lblTemplate.TabIndex = 0;
this.lblTemplate.Text = "选择预设模板:";
//
// lblCustom
//
this.lblCustom.AutoSize = true;
this.lblCustom.Location = new System.Drawing.Point(20, 80);
this.lblCustom.Name = "lblCustom";
this.lblCustom.Size = new System.Drawing.Size(107, 12);
this.lblCustom.TabIndex = 2;
this.lblCustom.Text = "扩写要求 (可修改):";
//
// cmbTemplates
//
this.cmbTemplates.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.cmbTemplates.FormattingEnabled = true;
this.cmbTemplates.Location = new System.Drawing.Point(20, 45);
this.cmbTemplates.Name = "cmbTemplates";
this.cmbTemplates.Size = new System.Drawing.Size(440, 20);
this.cmbTemplates.TabIndex = 1;
this.cmbTemplates.SelectedIndexChanged += new System.EventHandler(this.CmbTemplates_SelectedIndexChanged);
//
// txtCustomPrompt
//
this.txtCustomPrompt.Location = new System.Drawing.Point(20, 105);
this.txtCustomPrompt.Multiline = true;
this.txtCustomPrompt.Name = "txtCustomPrompt";
this.txtCustomPrompt.ScrollBars = System.Windows.Forms.ScrollBars.Vertical;
this.txtCustomPrompt.Size = new System.Drawing.Size(440, 120);
this.txtCustomPrompt.TabIndex = 3;
//
// btnOk
//
this.btnOk.DialogResult = System.Windows.Forms.DialogResult.OK;
this.btnOk.Location = new System.Drawing.Point(260, 250);
this.btnOk.Name = "btnOk";
this.btnOk.Size = new System.Drawing.Size(90, 35);
this.btnOk.TabIndex = 4;
this.btnOk.Text = "开始扩写";
this.btnOk.UseVisualStyleBackColor = true;
this.btnOk.Click += new System.EventHandler(this.BtnOk_Click);
//
// btnCancel
//
this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
this.btnCancel.Location = new System.Drawing.Point(370, 250);
this.btnCancel.Name = "btnCancel";
this.btnCancel.Size = new System.Drawing.Size(90, 35);
this.btnCancel.TabIndex = 5;
this.btnCancel.Text = "取消";
this.btnCancel.UseVisualStyleBackColor = true;
//
// ExpandOptionsForm
//
this.AcceptButton = this.btnOk;
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.CancelButton = this.btnCancel;
this.ClientSize = new System.Drawing.Size(500, 311);
this.Controls.Add(this.btnCancel);
this.Controls.Add(this.btnOk);
this.Controls.Add(this.txtCustomPrompt);
this.Controls.Add(this.lblCustom);
this.Controls.Add(this.cmbTemplates);
this.Controls.Add(this.lblTemplate);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
this.MaximizeBox = false;
this.MinimizeBox = false;
this.Name = "ExpandOptionsForm";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "智能扩写设置";
this.ResumeLayout(false);
this.PerformLayout();
}
/// <summary>
/// 初始化模板下拉列表。
/// </summary>
private void InitializeTemplates()
{
foreach (var key in _templates.Keys)
{
cmbTemplates.Items.Add(key);
}
if (cmbTemplates.Items.Count > 0)
{
cmbTemplates.SelectedIndex = 0;
}
}
/// <summary>
/// 模板选择改变事件。
/// 当用户选择不同模板时,自动填充对应的 Prompt 到文本框中。
/// </summary>
private void CmbTemplates_SelectedIndexChanged(object sender, EventArgs e)
{
if (cmbTemplates.SelectedItem != null && _templates.ContainsKey(cmbTemplates.SelectedItem.ToString()))
{
txtCustomPrompt.Text = _templates[cmbTemplates.SelectedItem.ToString()];
}
}
/// <summary>
/// 确定按钮点击事件。
/// 验证输入有效性,并保存结果。
/// </summary>
private void BtnOk_Click(object sender, EventArgs e)
{
SelectedPrompt = txtCustomPrompt.Text.Trim();
if (string.IsNullOrEmpty(SelectedPrompt))
{
MessageBox.Show("扩写要求不能为空。", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
this.DialogResult = DialogResult.None; // Prevent closing
return;
}
}
}
}

View File

@@ -245,9 +245,6 @@
<Compile Include="Models.cs">
<SubType>Code</SubType>
</Compile>
<Compile Include="ExpandOptionsForm.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="ImageOptionsForm.cs">
<SubType>Form</SubType>
</Compile>