feat: 实现双前端架构 - Blazor+Known 和 Vue3
Task 4.3 更新 - 双前端项目: 1. Blazor + Known 3.5.7 (管理端): - 添加 Known 3.5.7 NuGet 包 - 更新 Program.cs 配置 Known 服务 - 保留 Blazor Server 架构 2. Vue3 + Element Plus (用户端): - 创建 CodePlay.Web Vue3 项目 - 基于 vue-next-admin 风格设计 - 技术栈:Vue 3.4 + TypeScript + Vite 5 - 集成 Element Plus UI 组件库 - 使用 Pinia 状态管理 - 配置 Vue Router 路由 - 实现 Converter 代码转换页面 - 配置反向代理到后端 API (端口 5000) 项目结构: - CodePlay.WebUI/ - Blazor + Known 管理端 - CodePlay.Web/ - Vue3 + Element Plus 用户端 - CodePlay.Web/ - 包含完整的 Vue3 项目结构 - src/views/Converter.vue - 主转换页面 - src/router/ - 路由配置 - src/App.vue - 根组件 - 支持 npm run dev 启动开发服务器 前端特性: - 响应式布局 (El-Row/El-Col) - 代码编辑器 (双栏对比) - 语言选择器 - 验证轮次配置 - TODO 和问题列表展示 - 一键复制结果 - 实时错误提示 Co-authored-by: monkeycode-ai <monkeycode-ai@chaitin.com>
This commit is contained in:
@@ -1,197 +0,0 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using CodePlay.Core.Models;
|
||||
using CodePlay.Core.Common;
|
||||
using CodePlay.Core.Services;
|
||||
|
||||
namespace CodePlay.Web.Controllers;
|
||||
|
||||
/// <summary>
|
||||
/// 代码转换控制器
|
||||
/// </summary>
|
||||
[ApiController]
|
||||
[Route("api/[controller]")]
|
||||
public class ConversionController : ControllerBase
|
||||
{
|
||||
private readonly ConversionService _conversionService;
|
||||
private readonly ILogger<ConversionController> _logger;
|
||||
|
||||
public ConversionController(
|
||||
ConversionService conversionService,
|
||||
ILogger<ConversionController> logger)
|
||||
{
|
||||
_conversionService = conversionService;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 执行代码转换
|
||||
/// </summary>
|
||||
/// <param name="request">转换请求</param>
|
||||
/// <param name="cancellationToken">取消令牌</param>
|
||||
/// <returns>转换结果</returns>
|
||||
[HttpPost]
|
||||
[ProducesResponseType(typeof(ConversionResult), StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status400BadRequest)]
|
||||
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status500InternalServerError)]
|
||||
public async Task<ActionResult<ConversionResult>> ConvertAsync(
|
||||
[FromBody] ConversionRequest request,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
try
|
||||
{
|
||||
// 验证请求
|
||||
if (string.IsNullOrWhiteSpace(request.SourceCode))
|
||||
{
|
||||
return BadRequest(new ProblemDetails
|
||||
{
|
||||
Title = "Invalid Request",
|
||||
Detail = "Source code is required",
|
||||
Status = 400
|
||||
});
|
||||
}
|
||||
|
||||
if (request.SourceLanguage == LanguageType.None ||
|
||||
request.TargetLanguage == LanguageType.None)
|
||||
{
|
||||
return BadRequest(new ProblemDetails
|
||||
{
|
||||
Title = "Invalid Request",
|
||||
Detail = "Source and target languages must be specified",
|
||||
Status = 400
|
||||
});
|
||||
}
|
||||
|
||||
if (request.SourceLanguage == request.TargetLanguage)
|
||||
{
|
||||
return BadRequest(new ProblemDetails
|
||||
{
|
||||
Title = "Invalid Request",
|
||||
Detail = "Source and target languages must be different",
|
||||
Status = 400
|
||||
});
|
||||
}
|
||||
|
||||
if (request.ValidationRounds < 1 || request.ValidationRounds > 3)
|
||||
{
|
||||
return BadRequest(new ProblemDetails
|
||||
{
|
||||
Title = "Invalid Request",
|
||||
Detail = "Validation rounds must be between 1 and 3",
|
||||
Status = 400
|
||||
});
|
||||
}
|
||||
|
||||
_logger.LogInformation(
|
||||
"Starting conversion from {SourceLanguage} to {TargetLanguage}",
|
||||
request.SourceLanguage,
|
||||
request.TargetLanguage);
|
||||
|
||||
// 执行转换
|
||||
var result = await _conversionService.ConvertAsync(request, cancellationToken);
|
||||
|
||||
if (result.Success)
|
||||
{
|
||||
_logger.LogInformation(
|
||||
"Conversion completed successfully. Lines: {Lines}, Classes: {Classes}, Methods: {Methods}",
|
||||
result.Report?.LinesConverted,
|
||||
result.Report?.ClassesConverted,
|
||||
result.Report?.MethodsConverted);
|
||||
|
||||
return Ok(result);
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.LogWarning(
|
||||
"Conversion failed: {Error}",
|
||||
result.ErrorMessage);
|
||||
|
||||
return StatusCode(500, new ProblemDetails
|
||||
{
|
||||
Title = "Conversion Failed",
|
||||
Detail = result.ErrorMessage,
|
||||
Status = 500
|
||||
});
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Unexpected error during conversion");
|
||||
|
||||
return StatusCode(500, new ProblemDetails
|
||||
{
|
||||
Title = "Internal Server Error",
|
||||
Detail = "An unexpected error occurred during conversion",
|
||||
Status = 500
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取支持的语言转换列表
|
||||
/// </summary>
|
||||
/// <returns>支持的语言对列表</returns>
|
||||
[HttpGet("supported")]
|
||||
[ProducesResponseType(typeof(List<LanguagePairDto>), StatusCodes.Status200OK)]
|
||||
public ActionResult<List<LanguagePairDto>> GetSupportedConversions()
|
||||
{
|
||||
var supported = _conversionService.GetSupportedConversions()
|
||||
.Select(p => new LanguagePairDto
|
||||
{
|
||||
SourceLanguage = p.Source.ToString(),
|
||||
TargetLanguage = p.Target.ToString(),
|
||||
Supported = true
|
||||
})
|
||||
.ToList();
|
||||
|
||||
return Ok(supported);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 检查指定的语言转换是否支持
|
||||
/// </summary>
|
||||
[HttpGet("supported/{source}/{target}")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||
public ActionResult<bool> IsConversionSupported(
|
||||
string source,
|
||||
string target)
|
||||
{
|
||||
if (!Enum.TryParse<LanguageType>(source, out var sourceLang) ||
|
||||
!Enum.TryParse<LanguageType>(target, out var targetLang))
|
||||
{
|
||||
return BadRequest("Invalid language type");
|
||||
}
|
||||
|
||||
var isSupported = _conversionService.IsConversionSupported(sourceLang, targetLang);
|
||||
|
||||
if (isSupported)
|
||||
{
|
||||
return Ok(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
return NotFound("Conversion not supported");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 语言对 DTO
|
||||
/// </summary>
|
||||
public class LanguagePairDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 源语言
|
||||
/// </summary>
|
||||
public string SourceLanguage { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 目标语言
|
||||
/// </summary>
|
||||
public string TargetLanguage { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 是否支持
|
||||
/// </summary>
|
||||
public bool Supported { get; set; }
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace CodePlay.Web.Controllers;
|
||||
|
||||
[ApiController]
|
||||
[Route("[controller]")]
|
||||
public class WeatherForecastController : ControllerBase
|
||||
{
|
||||
private static readonly string[] Summaries = new[]
|
||||
{
|
||||
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
|
||||
};
|
||||
|
||||
private readonly ILogger<WeatherForecastController> _logger;
|
||||
|
||||
public WeatherForecastController(ILogger<WeatherForecastController> logger)
|
||||
{
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
[HttpGet(Name = "GetWeatherForecast")]
|
||||
public IEnumerable<WeatherForecast> Get()
|
||||
{
|
||||
return Enumerable.Range(1, 5).Select(index => new WeatherForecast
|
||||
{
|
||||
Date = DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
|
||||
TemperatureC = Random.Shared.Next(-20, 55),
|
||||
Summary = Summaries[Random.Shared.Next(Summaries.Length)]
|
||||
})
|
||||
.ToArray();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user