From 73b304df3b6507f66fc8cca19fcd83b29d00ce06 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 4 Apr 2026 10:34:43 +0000 Subject: [PATCH 1/5] Initial plan From b6ac1695e91d6fa38895bce846aea6a09dfad5c5 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 4 Apr 2026 10:55:35 +0000 Subject: [PATCH 2/5] feat: Add AI Chat feature to AgentsManager for natural language task orchestration - Add AiChatAppService.cs with AI-powered chat endpoint that: - Analyzes user intent using AI with structured Prompt-based responses - Finds suitable existing ChatGroups or suggests creating new ones - Programmatically invokes ChatGroupAppService.SetChatGroup and ChatGroupService.RunChatGroupInThread (FunctionRender pattern) - Runs tasks in background thread (EventBus pattern) - Add AiChatRequest.cs with request models (AiChat_SendMessageRequest, AiChat_SuggestedGroupDto, AiChat_RunExistingGroupRequest) - Add AiChatResponse.cs with response models (AiChat_SendMessageResponse, AiChatResponseType) - Register AiChatAppService in Register.cs - Add AI Chat tab (fourth) to Index.cshtml with chat UI featuring: - Message list with user/AI messages - Confirmation buttons for group creation/task execution - AI model selector - Add AI Chat JavaScript methods in index.js: - sendAiChatMessage() - sends message and handles AI response - confirmCreateAndRunGroup() - confirms group creation and task start - confirmRunExistingGroup() - runs existing group - cancelSuggestion() / clearAiChat() - utility functions - loadAiChatModelList() - loads available AI models - Add AI Chat CSS styles to index.css Agent-Logs-Url: https://github.com/NeuCharFramework/NcfPackageSources/sessions/2b0ded12-8dc2-4c02-8ed9-a726706e8edb Co-authored-by: JeffreySu <2281927+JeffreySu@users.noreply.github.com> --- .../Admin/Pages/AgentsManager/Index.cshtml | 68 + .../OHS/Local/AppService/AiChatAppService.cs | 425 +++ .../OHS/Local/PL/AiChatRequest.cs | 107 + .../OHS/Local/PL/AiChatResponse.cs | 72 + .../Senparc.Xncf.AgentsManager/Register.cs | 4 + .../wwwroot/css/AgentsManager/index.css | 82 +- .../wwwroot/js/AgentsManager/index.js | 262 +- .../BuildXncfAppService.Generated.cs | 2728 ++++++++--------- 8 files changed, 2382 insertions(+), 1366 deletions(-) create mode 100644 src/Extensions/Senparc.Xncf.AgentsManager/OHS/Local/AppService/AiChatAppService.cs create mode 100644 src/Extensions/Senparc.Xncf.AgentsManager/OHS/Local/PL/AiChatRequest.cs create mode 100644 src/Extensions/Senparc.Xncf.AgentsManager/OHS/Local/PL/AiChatResponse.cs diff --git a/src/Extensions/Senparc.Xncf.AgentsManager/Areas/Admin/Pages/AgentsManager/Index.cshtml b/src/Extensions/Senparc.Xncf.AgentsManager/Areas/Admin/Pages/AgentsManager/Index.cshtml index d0d1ba497..8d89cd1b6 100644 --- a/src/Extensions/Senparc.Xncf.AgentsManager/Areas/Admin/Pages/AgentsManager/Index.cshtml +++ b/src/Extensions/Senparc.Xncf.AgentsManager/Areas/Admin/Pages/AgentsManager/Index.cshtml @@ -1101,6 +1101,74 @@ + @* AI 对话标签页 *@ + +
+ @* AI 对话头部工具栏 *@ +
+ AI 模型: + + + + 清空对话 + 💡 通过自然语言描述你的任务,AI 将自动匹配或创建智能体组来执行 +
+ @* 消息列表区域 *@ +
+
+ +

和 AI 对话来启动 Agents 任务

+

例如:帮我分析一段代码,或者写一篇文章

+
+ +
+ @* 输入区域 *@ +
+ + +
+ 发送 +
Ctrl+Enter
+
+
+
+
@* 抽屉 新增|编辑 智能体 540px *@ diff --git a/src/Extensions/Senparc.Xncf.AgentsManager/OHS/Local/AppService/AiChatAppService.cs b/src/Extensions/Senparc.Xncf.AgentsManager/OHS/Local/AppService/AiChatAppService.cs new file mode 100644 index 000000000..cc1a7f298 --- /dev/null +++ b/src/Extensions/Senparc.Xncf.AgentsManager/OHS/Local/AppService/AiChatAppService.cs @@ -0,0 +1,425 @@ +using Microsoft.Extensions.DependencyInjection; +using Microsoft.SemanticKernel.ChatCompletion; +using Senparc.AI; +using Senparc.AI.Entities; +using Senparc.AI.Kernel; +using Senparc.AI.Kernel.Handlers; +using Senparc.CO2NET; +using Senparc.CO2NET.WebApi; +using Senparc.Ncf.Core.AppServices; +using Senparc.Ncf.Core.Exceptions; +using Senparc.Xncf.AgentsManager.Domain.Services; +using Senparc.Xncf.AgentsManager.Models.DatabaseModel; +using Senparc.Xncf.AgentsManager.Models.DatabaseModel.Models; +using Senparc.Xncf.AgentsManager.Models.DatabaseModel.Models.Dto; +using Senparc.Xncf.AgentsManager.OHS.Local.PL; +using Senparc.Xncf.AIKernel.Domain.Models.DatabaseModel.Dto; +using Senparc.Xncf.AIKernel.Domain.Services; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Text.Json; +using System.Threading.Tasks; + +namespace Senparc.Xncf.AgentsManager.OHS.Local.AppService +{ + /// + /// AI 对话 AppService,用于通过自然语言对话启动 AgentsManager 任务 + /// + public class AiChatAppService : AppServiceBase + { + private readonly ChatGroupService _chatGroupService; + private readonly ChatGroupMemberService _chatGroupMemberService; + private readonly AgentsTemplateService _agentsTemplateService; + private readonly AIModelService _aiModelService; + + public AiChatAppService( + IServiceProvider serviceProvider, + ChatGroupService chatGroupService, + ChatGroupMemberService chatGroupMemberService, + AgentsTemplateService agentsTemplateService, + AIModelService aiModelService) : base(serviceProvider) + { + _chatGroupService = chatGroupService; + _chatGroupMemberService = chatGroupMemberService; + _agentsTemplateService = agentsTemplateService; + _aiModelService = aiModelService; + } + + /// + /// 发送 AI 对话消息,AI 将理解用户意图并自动匹配或建议创建 ChatGroup 来运行任务 + /// + [ApiBind(ApiRequestMethod = ApiRequestMethod.Post)] + public async Task> SendMessage(AiChat_SendMessageRequest request) + { + return await this.GetResponseAsync(async (response, logger) => + { + if (string.IsNullOrWhiteSpace(request.UserMessage)) + { + throw new NcfExceptionBase("消息内容不能为空"); + } + + // 获取 AI 设置 + var aiSetting = Senparc.AI.Config.SenparcAiSetting; + if (request.AiModelId > 0) + { + var aiModel = await _aiModelService.GetObjectAsync(z => z.Id == request.AiModelId); + if (aiModel == null) + { + throw new NcfExceptionBase($"当前选择的 AI 模型不存在:{request.AiModelId}"); + } + var aiModelDto = _aiModelService.Mapper.Map(aiModel); + aiSetting = _aiModelService.BuildSenparcAiSetting(aiModelDto); + } + + // 获取所有可用的 AgentTemplate 列表 + var agentTemplates = await _agentsTemplateService.GetFullListAsync(z => z.Enable, z => z.Id, Ncf.Core.Enums.OrderingType.Ascending); + var agentTemplateList = agentTemplates.Select(z => new + { + z.Id, + z.Name, + z.Description, + z.SystemMessage + }).ToList(); + + // 获取所有现有 ChatGroup 列表 + var chatGroups = await _chatGroupService.GetFullListAsync(z => true, z => z.Id, Ncf.Core.Enums.OrderingType.Ascending); + var chatGroupList = new List(); + foreach (var cg in chatGroups) + { + var members = await _chatGroupMemberService.GetFullListAsync(z => z.ChatGroupId == cg.Id); + var memberIds = members.Select(z => z.AgentTemplateId).ToList(); + var memberNames = agentTemplates.Where(a => memberIds.Contains(a.Id)).Select(a => a.Name).ToList(); + chatGroupList.Add(new + { + cg.Id, + cg.Name, + cg.Description, + AdminAgentTemplateId = cg.AdminAgentTemplateId, + EnterAgentTemplateId = cg.EnterAgentTemplateId, + Members = string.Join("、", memberNames) + }); + } + + // 构建系统 Prompt + var systemPrompt = BuildSystemPrompt(agentTemplateList, chatGroupList); + + // 构建消息历史 + var promptConfigParameter = new PromptConfigParameter() + { + MaxTokens = 2000, + Temperature = 0.3, + TopP = 0.5, + }; + + var semanticAiHandler = new SemanticAiHandler((SenparcAiSetting)aiSetting); + var iWantToRun = semanticAiHandler.ChatConfig( + promptConfigParameter, + userId: $"AiChat_{Guid.NewGuid():N}", + maxHistoryStore: 20, + chatSystemMessage: systemPrompt, + senparcAiSetting: (SenparcAiSetting)aiSetting); + + // 将历史对话注入 + var hisgoryArgName = "history"; + var chatHistoryFromKernel = iWantToRun.StoredAiArguments.KernelArguments[hisgoryArgName] as ChatHistory; + if (chatHistoryFromKernel != null && request.ChatHistory?.Count > 0) + { + foreach (var msg in request.ChatHistory) + { + if (msg.Role == "user") + chatHistoryFromKernel.AddUserMessage(msg.Content); + else if (msg.Role == "assistant") + chatHistoryFromKernel.AddAssistantMessage(msg.Content); + } + iWantToRun.StoredAiArguments.KernelArguments[hisgoryArgName] = chatHistoryFromKernel; + } + + // 调用 AI + var aiResult = await semanticAiHandler.ChatAsync(iWantToRun, request.UserMessage, historyArgName: hisgoryArgName); + var aiResponseText = aiResult.OutputString; + + // 解析 AI 返回的结构化结果 + var responseDto = ParseAiResponse(aiResponseText, agentTemplates, request.AiModelId); + + return responseDto; + }); + } + + /// + /// 用户确认后,自动创建 ChatGroup 并运行任务(通过 FunctionRender 对应方法调用) + /// + [ApiBind(ApiRequestMethod = ApiRequestMethod.Post)] + public async Task> ConfirmCreateAndRunGroup(AiChat_SuggestedGroupDto suggestedGroup) + { + return await this.GetResponseAsync(async (response, logger) => + { + if (suggestedGroup == null) + { + throw new NcfExceptionBase("建议的 ChatGroup 信息不能为空"); + } + + // 通过 FunctionRender 机制调用 SetChatGroup 方法(复用已有逻辑) + var chatGroupAppService = base.GetRequiredService(); + + var chatGroupDto = new ChatGroupDto( + suggestedGroup.Name, + true, + ChatGroupState.Unstart, + suggestedGroup.Description, + suggestedGroup.AdminAgentTemplateId, + suggestedGroup.EnterAgentTemplateId); + + // 调用 ChatGroupAppService 中的 SetChatGroup 方法(与 FunctionRender 方法对应) + var setGroupResponse = await chatGroupAppService.SetChatGroup(chatGroupDto, suggestedGroup.MemberAgentTemplateIds ?? new List()); + + if (setGroupResponse.Success == false) + { + throw new NcfExceptionBase($"创建 ChatGroup 失败:{setGroupResponse.ErrorMessage}"); + } + + var newGroupId = setGroupResponse.Data?.ChatGroupDto?.Id ?? 0; + if (newGroupId == 0) + { + throw new NcfExceptionBase("创建 ChatGroup 成功但未获取到 ID"); + } + + // 获取 AI 设置 + var aiSetting = Senparc.AI.Config.SenparcAiSetting; + if (suggestedGroup.AiModelId > 0) + { + var aiModel = await _aiModelService.GetObjectAsync(z => z.Id == suggestedGroup.AiModelId); + if (aiModel != null) + { + var aiModelDto = _aiModelService.Mapper.Map(aiModel); + aiSetting = _aiModelService.BuildSenparcAiSetting(aiModelDto); + } + } + + // 通过 FunctionRender 机制调用 RunGroup 方法(复用已有逻辑) + var runRequest = new ChatGroup_RunGroupRequest + { + Name = $"AI对话任务-{DateTime.Now:yyyyMMddHHmmss}", + ChatGroupId = newGroupId, + AiModelId = suggestedGroup.AiModelId, + PromptCommand = suggestedGroup.TaskCommand, + Description = $"由 AI 对话自动创建并启动的任务", + Personality = true + }; + + // 使用 EventBus 模式,在独立线程中运行任务(不阻塞) + var _ = Task.Run(async () => + { + await _chatGroupService.RunChatGroupInThread(runRequest); + }); + + var taskName = runRequest.Name; + + return new AiChat_SendMessageResponse + { + AiMessage = $"✅ 已成功创建组「{suggestedGroup.Name}」并启动任务「{taskName}」!任务正在后台运行中,您可以切换到「任务」标签页查看进度。", + ResponseType = AiChatResponseType.TaskStarted, + StartedGroupId = newGroupId, + StartedTaskName = taskName + }; + }); + } + + /// + /// 直接运行已有 ChatGroup 的任务(不创建新组) + /// + [ApiBind(ApiRequestMethod = ApiRequestMethod.Post)] + public async Task> RunExistingGroup(AiChat_RunExistingGroupRequest request) + { + return await this.GetResponseAsync(async (response, logger) => + { + var chatGroup = await _chatGroupService.GetObjectAsync(z => z.Id == request.ChatGroupId); + if (chatGroup == null) + { + throw new NcfExceptionBase($"未找到 ChatGroup(ID:{request.ChatGroupId})"); + } + + var runRequest = new ChatGroup_RunGroupRequest + { + Name = $"AI对话任务-{DateTime.Now:yyyyMMddHHmmss}", + ChatGroupId = request.ChatGroupId, + AiModelId = request.AiModelId, + PromptCommand = request.TaskCommand, + Description = "由 AI 对话自动启动的任务", + Personality = true + }; + + // 使用 EventBus 模式,在独立线程中运行任务(不阻塞) + var _ = Task.Run(async () => + { + await _chatGroupService.RunChatGroupInThread(runRequest); + }); + + return new AiChat_SendMessageResponse + { + AiMessage = $"✅ 已使用组「{chatGroup.Name}」启动任务「{runRequest.Name}」!任务正在后台运行中,您可以切换到「任务」标签页查看进度。", + ResponseType = AiChatResponseType.TaskStarted, + StartedGroupId = request.ChatGroupId, + StartedTaskName = runRequest.Name + }; + }); + } + + #region 私有辅助方法 + + /// + /// 构建系统 Prompt + /// + private string BuildSystemPrompt( + IEnumerable agentTemplates, + IEnumerable chatGroups) + { + var agentJson = JsonSerializer.Serialize(agentTemplates, new JsonSerializerOptions { WriteIndented = false }); + var groupJson = JsonSerializer.Serialize(chatGroups, new JsonSerializerOptions { WriteIndented = false }); + + var sb = new StringBuilder(); + sb.AppendLine("你是一个 AgentsManager 任务助手,帮助用户通过自然语言启动 AI 多智能体协作任务。"); + sb.AppendLine(); + sb.AppendLine("## 可用的智能体(AgentTemplate)列表:"); + sb.AppendLine(agentJson); + sb.AppendLine(); + sb.AppendLine("## 现有的智能体组(ChatGroup)列表:"); + sb.AppendLine(groupJson); + sb.AppendLine(); + sb.AppendLine("## 你的职责:"); + sb.AppendLine("1. 理解用户的任务需求"); + sb.AppendLine("2. 判断现有 ChatGroup 是否适合执行该任务:"); + sb.AppendLine(" - 如果有合适的组,返回 JSON 格式:{\"action\":\"run_existing\",\"groupId\":组ID,\"reason\":\"原因\",\"taskCommand\":\"任务命令\"}"); + sb.AppendLine(" - 如果没有合适的组,分析需要哪些智能体,返回 JSON 格式:{\"action\":\"create_group\",\"reason\":\"为什么需要创建新组\",\"suggestion\":{\"name\":\"建议的组名称\",\"description\":\"组说明\",\"adminAgentTemplateId\":群主ID,\"enterAgentTemplateId\":对接人ID,\"memberIds\":[成员ID列表],\"taskCommand\":\"任务命令\"}}"); + sb.AppendLine("3. 如果用户的输入不是任务需求(如闲聊、问候),正常回复,返回 JSON 格式:{\"action\":\"message\",\"content\":\"你的回复内容\"}"); + sb.AppendLine(); + sb.AppendLine("## 重要说明:"); + sb.AppendLine("- adminAgentTemplateId 通常选择名称包含\"主\"或者排在首位的智能体"); + sb.AppendLine("- enterAgentTemplateId 是负责接收用户命令的智能体(对接人)"); + sb.AppendLine("- memberIds 包含所有参与任务的智能体 ID"); + sb.AppendLine("- 请严格按照 JSON 格式返回,不要添加任何 Markdown 代码块标记或额外说明"); + sb.Append("- 只返回纯 JSON,不要有其他文字"); + return sb.ToString(); + } + + /// + /// 解析 AI 返回结果 + /// + private AiChat_SendMessageResponse ParseAiResponse( + string aiResponseText, + IEnumerable agentTemplates, + int aiModelId) + { + try + { + // 清理可能的 Markdown 代码块标记 + var cleanedText = aiResponseText + .Replace("```json", "") + .Replace("```", "") + .Trim(); + + var jsonDoc = JsonDocument.Parse(cleanedText); + var root = jsonDoc.RootElement; + + var action = root.GetProperty("action").GetString(); + + switch (action) + { + case "run_existing": + var groupId = root.GetProperty("groupId").GetInt32(); + var reason = root.TryGetProperty("reason", out var reasonEl) ? reasonEl.GetString() : ""; + var taskCmd = root.TryGetProperty("taskCommand", out var tcEl) ? tcEl.GetString() : ""; + return new AiChat_SendMessageResponse + { + AiMessage = $"已找到合适的组来执行您的任务。{reason}\n\n任务命令:{taskCmd}", + ResponseType = AiChatResponseType.SuggestRunTask, + SuggestedGroupId = groupId, + SuggestedGroup = new AiChat_SuggestedGroupDto + { + TaskCommand = taskCmd, + AiModelId = aiModelId + } + }; + + case "create_group": + var createReason = root.TryGetProperty("reason", out var crEl) ? crEl.GetString() : ""; + var suggestion = root.GetProperty("suggestion"); + + var suggestedName = suggestion.TryGetProperty("name", out var nameEl) ? nameEl.GetString() : "新智能体组"; + var suggestedDesc = suggestion.TryGetProperty("description", out var descEl) ? descEl.GetString() : ""; + var adminId = suggestion.TryGetProperty("adminAgentTemplateId", out var adminEl) ? adminEl.GetInt32() : 0; + var enterId = suggestion.TryGetProperty("enterAgentTemplateId", out var enterEl) ? enterEl.GetInt32() : 0; + var memberIds = new List(); + if (suggestion.TryGetProperty("memberIds", out var memberIdsEl)) + { + foreach (var idEl in memberIdsEl.EnumerateArray()) + { + memberIds.Add(idEl.GetInt32()); + } + } + var createTaskCmd = suggestion.TryGetProperty("taskCommand", out var ctcEl) ? ctcEl.GetString() : ""; + + // 获取智能体名称列表用于展示 + var agentList = agentTemplates.ToList(); + var memberNames = agentList.Where(a => memberIds.Contains(a.Id)).Select(a => a.Name).ToList(); + var adminName = agentList.FirstOrDefault(a => a.Id == adminId)?.Name ?? $"ID:{adminId}"; + var enterName = agentList.FirstOrDefault(a => a.Id == enterId)?.Name ?? $"ID:{enterId}"; + + var sb = new StringBuilder(); + sb.AppendLine($"当前没有合适的组来执行您的任务。{createReason}"); + sb.AppendLine(); + sb.AppendLine($"**建议创建新组:**"); + sb.AppendLine($"- **组名称**:{suggestedName}"); + if (!string.IsNullOrEmpty(suggestedDesc)) + sb.AppendLine($"- **说明**:{suggestedDesc}"); + sb.AppendLine($"- **群主**:{adminName}"); + sb.AppendLine($"- **对接人**:{enterName}"); + if (memberNames.Count > 0) + sb.AppendLine($"- **成员**:{string.Join("、", memberNames)}"); + sb.AppendLine($"- **任务命令**:{createTaskCmd}"); + sb.AppendLine(); + sb.AppendLine("是否确认创建该组并运行任务?"); + + return new AiChat_SendMessageResponse + { + AiMessage = sb.ToString(), + ResponseType = AiChatResponseType.SuggestCreateGroup, + SuggestedGroup = new AiChat_SuggestedGroupDto + { + Name = suggestedName, + Description = suggestedDesc, + AdminAgentTemplateId = adminId, + EnterAgentTemplateId = enterId, + MemberAgentTemplateIds = memberIds, + TaskCommand = createTaskCmd, + AiModelId = aiModelId + } + }; + + case "message": + default: + var content = root.TryGetProperty("content", out var contentEl) + ? contentEl.GetString() + : aiResponseText; + return new AiChat_SendMessageResponse + { + AiMessage = content, + ResponseType = AiChatResponseType.Message + }; + } + } + catch + { + // 解析失败时,将原始文本作为普通消息返回 + return new AiChat_SendMessageResponse + { + AiMessage = aiResponseText, + ResponseType = AiChatResponseType.Message + }; + } + } + + #endregion + } +} diff --git a/src/Extensions/Senparc.Xncf.AgentsManager/OHS/Local/PL/AiChatRequest.cs b/src/Extensions/Senparc.Xncf.AgentsManager/OHS/Local/PL/AiChatRequest.cs new file mode 100644 index 000000000..653692d23 --- /dev/null +++ b/src/Extensions/Senparc.Xncf.AgentsManager/OHS/Local/PL/AiChatRequest.cs @@ -0,0 +1,107 @@ +using System.Collections.Generic; + +namespace Senparc.Xncf.AgentsManager.OHS.Local.PL +{ + /// + /// AI 对话消息记录 + /// + public class AiChatMessageDto + { + /// + /// 角色:user / assistant + /// + public string Role { get; set; } + + /// + /// 消息内容 + /// + public string Content { get; set; } + } + + /// + /// 发送 AI Chat 消息的请求 + /// + public class AiChat_SendMessageRequest + { + /// + /// 用户输入的消息 + /// + public string UserMessage { get; set; } + + /// + /// 历史对话记录 + /// + public List ChatHistory { get; set; } = new List(); + + /// + /// 使用的 AI 模型 ID(0 表示使用默认配置) + /// + public int AiModelId { get; set; } = 0; + + /// + /// 待确认的 ChatGroup 建议信息(在用户确认后自动创建并运行) + /// + public AiChat_SuggestedGroupDto PendingGroup { get; set; } + } + + /// + /// AI 建议创建的 ChatGroup 信息 + /// + public class AiChat_SuggestedGroupDto { + /// + /// 建议的组名称 + /// + public string Name { get; set; } + + /// + /// 组说明 + /// + public string Description { get; set; } + + /// + /// 群主 AgentTemplate ID + /// + public int AdminAgentTemplateId { get; set; } + + /// + /// 对接人 AgentTemplate ID + /// + public int EnterAgentTemplateId { get; set; } + + /// + /// 成员 AgentTemplate ID 列表 + /// + public List MemberAgentTemplateIds { get; set; } = new List(); + + /// + /// 用户的任务命令(用于运行时传入) + /// + public string TaskCommand { get; set; } + + /// + /// 使用的 AI 模型 ID + /// + public int AiModelId { get; set; } + } + + /// + /// 运行已有 ChatGroup 的请求 + /// + public class AiChat_RunExistingGroupRequest + { + /// + /// ChatGroup ID + /// + public int ChatGroupId { get; set; } + + /// + /// 任务命令 + /// + public string TaskCommand { get; set; } + + /// + /// AI 模型 ID(0 表示使用默认配置) + /// + public int AiModelId { get; set; } = 0; + } +} diff --git a/src/Extensions/Senparc.Xncf.AgentsManager/OHS/Local/PL/AiChatResponse.cs b/src/Extensions/Senparc.Xncf.AgentsManager/OHS/Local/PL/AiChatResponse.cs new file mode 100644 index 000000000..4ed009ab4 --- /dev/null +++ b/src/Extensions/Senparc.Xncf.AgentsManager/OHS/Local/PL/AiChatResponse.cs @@ -0,0 +1,72 @@ +using Senparc.Xncf.AgentsManager.Models.DatabaseModel.Models.Dto; +using System.Collections.Generic; + +namespace Senparc.Xncf.AgentsManager.OHS.Local.PL +{ + /// + /// AI Chat 消息类型 + /// + public enum AiChatResponseType + { + /// + /// 普通回复 + /// + Message = 0, + + /// + /// 建议创建新组(等待用户确认) + /// + SuggestCreateGroup = 1, + + /// + /// 已找到合适的组,建议直接运行任务 + /// + SuggestRunTask = 2, + + /// + /// 已开始创建并运行任务 + /// + TaskStarted = 3, + + /// + /// 错误 + /// + Error = 4 + } + + /// + /// AI Chat 发送消息的响应 + /// + public class AiChat_SendMessageResponse + { + /// + /// AI 回复内容(用于展示给用户) + /// + public string AiMessage { get; set; } + + /// + /// 响应类型 + /// + public AiChatResponseType ResponseType { get; set; } + + /// + /// 建议创建的 ChatGroup 信息(当 ResponseType 为 SuggestCreateGroup 时有值) + /// + public AiChat_SuggestedGroupDto SuggestedGroup { get; set; } + + /// + /// 建议运行的 ChatGroup ID(当 ResponseType 为 SuggestRunTask 时有值) + /// + public int? SuggestedGroupId { get; set; } + + /// + /// 已启动的任务所属 ChatGroup ID(当 ResponseType 为 TaskStarted 时有值) + /// + public int? StartedGroupId { get; set; } + + /// + /// 已启动任务的名称 + /// + public string StartedTaskName { get; set; } + } +} diff --git a/src/Extensions/Senparc.Xncf.AgentsManager/Register.cs b/src/Extensions/Senparc.Xncf.AgentsManager/Register.cs index dfabc6254..ea55518ab 100644 --- a/src/Extensions/Senparc.Xncf.AgentsManager/Register.cs +++ b/src/Extensions/Senparc.Xncf.AgentsManager/Register.cs @@ -17,6 +17,7 @@ using Senparc.Xncf.AgentsManager.Models.DatabaseModel; using Senparc.Xncf.AgentsManager.Models.DatabaseModel.Models; using Senparc.Xncf.AgentsManager.Models.DatabaseModel.Models.Dto; +using Senparc.Xncf.AgentsManager.OHS.Local.AppService; using Senparc.Xncf.XncfBuilder.OHS.Local; using System; using System.Linq; @@ -108,6 +109,9 @@ public override IServiceCollection AddXncfModule(IServiceCollection services, IC services.AddScoped(); services.AddScoped(); + //AI Chat + services.AddScoped(); + //测试 services.AddScoped(); diff --git a/src/Extensions/Senparc.Xncf.AgentsManager/wwwroot/css/AgentsManager/index.css b/src/Extensions/Senparc.Xncf.AgentsManager/wwwroot/css/AgentsManager/index.css index 38e3303a4..289b0791f 100644 --- a/src/Extensions/Senparc.Xncf.AgentsManager/wwwroot/css/AgentsManager/index.css +++ b/src/Extensions/Senparc.Xncf.AgentsManager/wwwroot/css/AgentsManager/index.css @@ -1824,4 +1824,84 @@ height:100%; .mcp-endpoint-actions { display: flex; align-items: center; -} \ No newline at end of file +} +/* AI 对话标签页样式 */ +.aiChatMessagesList { + display: flex; + flex-direction: column; + gap: 16px; +} + +.aiChatMessage { + display: flex; + gap: 10px; + align-items: flex-start; + max-width: 85%; +} + +.aiChatMessage-user { + flex-direction: row-reverse; + margin-left: auto; +} + +.aiChatMessage-ai { + flex-direction: row; + margin-right: auto; +} + +.aiChatMessage-bubble { + background: #f0f2f5; + border-radius: 12px; + padding: 10px 14px; + font-size: 14px; + line-height: 1.6; + max-width: 100%; + word-break: break-word; +} + +.aiChatMessage-user .aiChatMessage-bubble { + background: #409eff; + color: #fff; +} + +.aiChatMessage-avatar img { + width: 32px; + height: 32px; + border-radius: 50%; + object-fit: cover; +} + +.aiChatMessage-loading { + display: flex; + align-items: center; + gap: 4px; + padding: 12px 16px; +} + +.aiChatMessage-loading span { + width: 8px; + height: 8px; + border-radius: 50%; + background: #409eff; + animation: aiChatDot 1.2s infinite; + display: inline-block; +} + +.aiChatMessage-loading span:nth-child(2) { + animation-delay: 0.2s; +} + +.aiChatMessage-loading span:nth-child(3) { + animation-delay: 0.4s; +} + +@keyframes aiChatDot { + 0%, 80%, 100% { transform: scale(0.6); opacity: 0.4; } + 40% { transform: scale(1); opacity: 1; } +} + +.aiChatAction { + border-top: 1px solid rgba(0,0,0,0.08); + padding-top: 8px; + margin-top: 8px; +} diff --git a/src/Extensions/Senparc.Xncf.AgentsManager/wwwroot/js/AgentsManager/index.js b/src/Extensions/Senparc.Xncf.AgentsManager/wwwroot/js/AgentsManager/index.js index 9d84dbd3e..88fcc9385 100644 --- a/src/Extensions/Senparc.Xncf.AgentsManager/wwwroot/js/AgentsManager/index.js +++ b/src/Extensions/Senparc.Xncf.AgentsManager/wwwroot/js/AgentsManager/index.js @@ -390,6 +390,14 @@ var app = new Vue({ mcpEndpointEditMode: false, mcpEndpointOriginalName: '', currentMcpTools: [], // 当前查看的MCP工具列表 + // AI 对话 ---start + aiChatMessages: [], // 对话消息列表 + aiChatInput: '', // 当前输入 + aiChatLoading: false, // 加载状态 + aiChatConfirming: false, // 确认操作加载状态 + aiChatModelId: null, // 使用的 AI 模型 ID(null 表示默认) + aiChatModelList: [], // 可选 AI 模型列表 + // AI 对话 ---end }; }, computed: { @@ -1528,6 +1536,10 @@ var app = new Vue({ if (this.tabsActiveName === 'third') { this.gettaskListData('task') } + // AI 对话 + if (this.tabsActiveName === 'fourth') { + this.loadAiChatModelList() + } }, // 筛选输入变化 @@ -3364,6 +3376,254 @@ Vue.component('load-more-select', { }) } - } + }, + + // ========= AI 对话相关方法 ========= + + // 加载 AI 模型列表 + async loadAiChatModelList() { + try { + const res = await serviceAM.post('/api/Senparc.Xncf.AIKernel/AIModelAppService/Xncf.AIKernel_AIModelAppService.GetListAsync', { + pageIndex: 0, + pageSize: 0 + }) + const data = res?.data ?? {} + if (data.success) { + // 只显示 Chat 类型的模型(configModelType === 1) + this.aiChatModelList = (data.data ?? []).filter(m => m.configModelType === 1) + } + } catch (e) { + console.error('加载 AI 模型列表失败', e) + } + }, + + // 发送 AI 对话消息 + async sendAiChatMessage() { + const userInput = (this.aiChatInput || '').trim() + if (!userInput) return + if (this.aiChatLoading) return + + // 添加用户消息 + this.aiChatMessages.push({ + role: 'user', + content: userInput, + contentHtml: userInput.replace(/\n/g, '
') + }) + this.aiChatInput = '' + + // 滚动到底部 + this.$nextTick(() => { + const el = this.$refs.aiChatMessages + if (el) el.scrollTop = el.scrollHeight + }) + + this.aiChatLoading = true + + try { + // 构建历史记录(只发送 user/assistant 角色) + const chatHistory = this.aiChatMessages + .filter(m => m.role === 'user' || m.role === 'assistant') + .slice(0, -1) // 不包含最新的用户消息 + .map(m => ({ role: m.role, content: m.content })) + + const payload = { + userMessage: userInput, + chatHistory: chatHistory, + aiModelId: this.aiChatModelId || 0 + } + + const res = await serviceAM.post( + '/api/Senparc.Xncf.AgentsManager/AiChatAppService/Xncf.AgentsManager_AiChatAppService.SendMessage', + payload + ) + + const data = res?.data ?? {} + if (data.success) { + const aiData = data.data ?? {} + const aiMessage = aiData.aiMessage || '(无响应)' + const responseType = aiData.responseType ?? 0 + const suggestedGroup = aiData.suggestedGroup || null + const suggestedGroupId = aiData.suggestedGroupId || null + + // 渲染 Markdown + let contentHtml = aiMessage + if (typeof marked !== 'undefined') { + try { contentHtml = marked.parse(aiMessage) } catch (e) { } + } + + // 添加 AI 消息 + this.aiChatMessages.push({ + role: 'assistant', + content: aiMessage, + contentHtml: contentHtml, + responseType: responseType, + suggestedGroup: suggestedGroup, + suggestedGroupId: suggestedGroupId, + confirmed: false + }) + } else { + this.aiChatMessages.push({ + role: 'assistant', + content: data.errorMessage || '请求失败,请稍后重试', + contentHtml: data.errorMessage || '请求失败,请稍后重试', + responseType: 4 + }) + } + } catch (e) { + this.aiChatMessages.push({ + role: 'assistant', + content: '网络错误,请稍后重试:' + (e.message || ''), + contentHtml: '网络错误,请稍后重试:' + (e.message || ''), + responseType: 4 + }) + } finally { + this.aiChatLoading = false + this.$nextTick(() => { + const el = this.$refs.aiChatMessages + if (el) el.scrollTop = el.scrollHeight + }) + } + }, + + // 用户确认创建新组并运行任务(通过 FunctionRender 对应方法) + async confirmCreateAndRunGroup(msg, idx) { + if (!msg.suggestedGroup) return + this.aiChatConfirming = true + try { + const res = await serviceAM.post( + '/api/Senparc.Xncf.AgentsManager/AiChatAppService/Xncf.AgentsManager_AiChatAppService.ConfirmCreateAndRunGroup', + msg.suggestedGroup + ) + const data = res?.data ?? {} + if (data.success) { + const aiData = data.data ?? {} + const aiMessage = aiData.aiMessage || '✅ 任务已启动!' + let contentHtml = aiMessage + if (typeof marked !== 'undefined') { + try { contentHtml = marked.parse(aiMessage) } catch (e) { } + } + // 标记当前消息为已确认 + this.$set(this.aiChatMessages[idx], 'confirmed', true) + // 添加确认成功的 AI 回复 + this.aiChatMessages.push({ + role: 'assistant', + content: aiMessage, + contentHtml: contentHtml, + responseType: 3, + startedGroupId: aiData.startedGroupId, + startedTaskName: aiData.startedTaskName + }) + // 使用 EventBus 通知:切换到任务标签页 + this.$nextTick(() => { + this.$message({ message: '任务已启动,可切换到「任务」标签页查看进度', type: 'success', duration: 3000 }) + }) + } else { + this.aiChatMessages.push({ + role: 'assistant', + content: '创建失败:' + (data.errorMessage || '未知错误'), + contentHtml: '创建失败:' + (data.errorMessage || '未知错误'), + responseType: 4 + }) + } + } catch (e) { + this.aiChatMessages.push({ + role: 'assistant', + content: '操作失败:' + (e.message || ''), + contentHtml: '操作失败:' + (e.message || ''), + responseType: 4 + }) + } finally { + this.aiChatConfirming = false + this.$nextTick(() => { + const el = this.$refs.aiChatMessages + if (el) el.scrollTop = el.scrollHeight + }) + } + }, + + // 用户确认运行已有组 + async confirmRunExistingGroup(msg, idx) { + if (!msg.suggestedGroupId) return + this.aiChatConfirming = true + try { + // 获取最近一条用户消息作为任务命令 + const lastUserMsg = [...this.aiChatMessages].reverse().find(m => m.role === 'user') + const taskCommand = (msg.suggestedGroup && msg.suggestedGroup.taskCommand) || (lastUserMsg && lastUserMsg.content) || '' + + const res = await serviceAM.post( + '/api/Senparc.Xncf.AgentsManager/AiChatAppService/Xncf.AgentsManager_AiChatAppService.RunExistingGroup', + { + chatGroupId: msg.suggestedGroupId, + taskCommand: taskCommand, + aiModelId: this.aiChatModelId || 0 + } + ) + const data = res?.data ?? {} + if (data.success) { + const aiData = data.data ?? {} + const aiMessage = aiData.aiMessage || '✅ 任务已启动!' + let contentHtml = aiMessage + if (typeof marked !== 'undefined') { + try { contentHtml = marked.parse(aiMessage) } catch (e) { } + } + this.$set(this.aiChatMessages[idx], 'confirmed', true) + this.aiChatMessages.push({ + role: 'assistant', + content: aiMessage, + contentHtml: contentHtml, + responseType: 3, + startedGroupId: aiData.startedGroupId, + startedTaskName: aiData.startedTaskName + }) + this.$nextTick(() => { + this.$message({ message: '任务已启动,可切换到「任务」标签页查看进度', type: 'success', duration: 3000 }) + }) + } else { + this.aiChatMessages.push({ + role: 'assistant', + content: '启动失败:' + (data.errorMessage || '未知错误'), + contentHtml: '启动失败:' + (data.errorMessage || '未知错误'), + responseType: 4 + }) + } + } catch (e) { + this.aiChatMessages.push({ + role: 'assistant', + content: '操作失败:' + (e.message || ''), + contentHtml: '操作失败:' + (e.message || ''), + responseType: 4 + }) + } finally { + this.aiChatConfirming = false + this.$nextTick(() => { + const el = this.$refs.aiChatMessages + if (el) el.scrollTop = el.scrollHeight + }) + } + }, + + // 取消 AI 建议 + cancelSuggestion(idx) { + this.$set(this.aiChatMessages[idx], 'confirmed', true) + this.aiChatMessages.push({ + role: 'assistant', + content: '已取消。如有其他需要,请继续描述您的任务。', + contentHtml: '已取消。如有其他需要,请继续描述您的任务。', + responseType: 0 + }) + }, + + // 清空对话 + clearAiChat() { + this.$confirm('确认清空全部对话记录?', '提示', { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: 'warning' + }).then(() => { + this.aiChatMessages = [] + this.aiChatInput = '' + }).catch(() => {}) + }, + }, }) diff --git a/src/Extensions/Senparc.Xncf.XncfBuilder/Senparc.Xncf.XncfBuilder/Generated/Senparc.Xncf.XncfBuilder.DynamicContentGenerator/MultiFileCodeGenerator/BuildXncfAppService.Generated.cs b/src/Extensions/Senparc.Xncf.XncfBuilder/Senparc.Xncf.XncfBuilder/Generated/Senparc.Xncf.XncfBuilder.DynamicContentGenerator/MultiFileCodeGenerator/BuildXncfAppService.Generated.cs index fbd7b9527..f09d62519 100644 --- a/src/Extensions/Senparc.Xncf.XncfBuilder/Senparc.Xncf.XncfBuilder/Generated/Senparc.Xncf.XncfBuilder.DynamicContentGenerator/MultiFileCodeGenerator/BuildXncfAppService.Generated.cs +++ b/src/Extensions/Senparc.Xncf.XncfBuilder/Senparc.Xncf.XncfBuilder/Generated/Senparc.Xncf.XncfBuilder.DynamicContentGenerator/MultiFileCodeGenerator/BuildXncfAppService.Generated.cs @@ -14,73 +14,73 @@ namespace Senparc.Xncf.XncfBuilder.OHS.Local /// public partial class BuildXncfAppService { -public const string BackendTemplate = @$" -## Database EntityFramework DbContext class sample -File Name: Template_XncfNameSenparcEntities.cs -File Path: /Domain/Models/DatabaseModel -Code: -```csharp -{SenparcEntitiesTemplate} -``` - -## Database Entity class sample -File Name: Color.cs -File Path: /Domain/Models/DatabaseModel -Code: -```csharp -{ColorModelTemplate} -``` - -## Database Entity DTO class sample -File Name: ColorDto.cs -File Path: /Domain/Models/DatabaseModel/Dto -Code: -```csharp -{ColorDtoTemplate} -``` - -## Service class sample -File Name: Template_XncfNameService.cs -File Path: /Domain/Services -Code: -```csharp -{ColorServiceTemplate} -``` -"; - -public const string FrontendTemplate = @$" -## Page UI sample (front-end) -File Name: DatabaseSampleIndex.cshtml -File Path: < ModuleRootPath >/ Areas / Admin / Pages / Template_XncfName -Code: -```razorpage -{DatabaseSampleIndexViewTemplate} -``` - -## Page UI sample (back-end) -File Name: DatabaseSampleIndex.cshtml.cs -File Path: < ModuleRootPath >/ Areas / Admin / Pages / Template_XncfName -Code: -```csharp -{DatabaseSampleIndexCodeBehindTemplate} -``` - -## Page JavaScript file sample -File Name: databaseSampleIndex.js -File Path: < ModuleRootPath >/ wwwroot / js / Admin / Template_XncfName -Code: -```javascript -{DatabaseSampleIndexJsTemplate} -``` - -## Page CSS file sample -File Name: databaseSampleIndex.css -File Path: < ModuleRootPath >/ wwwroot / css / Admin / Template_XncfName -Code: -```css -{DatabaseSampleIndexCssTemplate} -``` -"; +public const string BackendTemplate = @$" +## Database EntityFramework DbContext class sample +File Name: Template_XncfNameSenparcEntities.cs +File Path: /Domain/Models/DatabaseModel +Code: +```csharp +{SenparcEntitiesTemplate} +``` + +## Database Entity class sample +File Name: Color.cs +File Path: /Domain/Models/DatabaseModel +Code: +```csharp +{ColorModelTemplate} +``` + +## Database Entity DTO class sample +File Name: ColorDto.cs +File Path: /Domain/Models/DatabaseModel/Dto +Code: +```csharp +{ColorDtoTemplate} +``` + +## Service class sample +File Name: Template_XncfNameService.cs +File Path: /Domain/Services +Code: +```csharp +{ColorServiceTemplate} +``` +"; + +public const string FrontendTemplate = @$" +## Page UI sample (front-end) +File Name: DatabaseSampleIndex.cshtml +File Path: < ModuleRootPath >/ Areas / Admin / Pages / Template_XncfName +Code: +```razorpage +{DatabaseSampleIndexViewTemplate} +``` + +## Page UI sample (back-end) +File Name: DatabaseSampleIndex.cshtml.cs +File Path: < ModuleRootPath >/ Areas / Admin / Pages / Template_XncfName +Code: +```csharp +{DatabaseSampleIndexCodeBehindTemplate} +``` + +## Page JavaScript file sample +File Name: databaseSampleIndex.js +File Path: < ModuleRootPath >/ wwwroot / js / Admin / Template_XncfName +Code: +```javascript +{DatabaseSampleIndexJsTemplate} +``` + +## Page CSS file sample +File Name: databaseSampleIndex.css +File Path: < ModuleRootPath >/ wwwroot / css / Admin / Template_XncfName +Code: +```css +{DatabaseSampleIndexCssTemplate} +``` +"; #region CODE Templates @@ -89,26 +89,26 @@ public partial class BuildXncfAppService /// 请求类代码 /// 类型: code /// - public const string RequestCode = @"using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Senparc.Xncf.XncfBuilder -{ - public class Request - { - public string? Method { get; set; } - public string? Path { get; set; } - public string? Body { get; set; } - - // 新增字段测试动态更新 - public Dictionary? Headers { get; set; } - public DateTime Timestamp { get; set; } = DateTime.Now; - } - -} + public const string RequestCode = @"using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Senparc.Xncf.XncfBuilder +{ + public class Request + { + public string? Method { get; set; } + public string? Path { get; set; } + public string? Body { get; set; } + + // 新增字段测试动态更新 + public Dictionary? Headers { get; set; } + public DateTime Timestamp { get; set; } = DateTime.Now; + } + +} "; #endregion @@ -119,237 +119,237 @@ public class Request /// Senparc实体类模板 /// 类型: backend_template /// - public const string SenparcEntitiesTemplate = @"using Microsoft.EntityFrameworkCore; -using Senparc.Ncf.Database; -using Senparc.Ncf.Core.Models; -using Senparc.Ncf.XncfBase.Database; - -namespace Template_OrgName.Xncf.Template_XncfName.Models -{ - public class Template_XncfNameSenparcEntities : XncfDatabaseDbContext - { - public Template_XncfNameSenparcEntities(DbContextOptions dbContextOptions) : base(dbContextOptions) - { - } - - public DbSet Colors { get; set; } - - //DOT REMOVE OR MODIFY THIS LINE 请勿移除或修改本行 - Entities Point - //ex. public DbSet Colors { get; set; } - - //如无特殊需需要,OnModelCreating 方法可以不用写,已经在 Register 中要求注册 - //protected override void OnModelCreating(ModelBuilder modelBuilder) - //{ - //} - } -} + public const string SenparcEntitiesTemplate = @"using Microsoft.EntityFrameworkCore; +using Senparc.Ncf.Database; +using Senparc.Ncf.Core.Models; +using Senparc.Ncf.XncfBase.Database; + +namespace Template_OrgName.Xncf.Template_XncfName.Models +{ + public class Template_XncfNameSenparcEntities : XncfDatabaseDbContext + { + public Template_XncfNameSenparcEntities(DbContextOptions dbContextOptions) : base(dbContextOptions) + { + } + + public DbSet Colors { get; set; } + + //DOT REMOVE OR MODIFY THIS LINE 请勿移除或修改本行 - Entities Point + //ex. public DbSet Colors { get; set; } + + //如无特殊需需要,OnModelCreating 方法可以不用写,已经在 Register 中要求注册 + //protected override void OnModelCreating(ModelBuilder modelBuilder) + //{ + //} + } +} "; /// /// 颜色模型模板 /// 类型: backend_template /// - public const string ColorModelTemplate = @"using Senparc.Ncf.Core.Models; -using Template_OrgName.Xncf.Template_XncfName.Domain.Models.DatabaseModel.Dto; -using System; -using System.ComponentModel.DataAnnotations.Schema; -using Template_OrgName.Xncf.Template_XncfName.Domain.Models.DatabaseModel.Dto; - -namespace Template_OrgName.Xncf.Template_XncfName -{ - /// - /// Color 实体类 - /// - [Table(Register.DATABASE_PREFIX + nameof(Color))]//必须添加前缀,防止全系统中发生冲突 - [Serializable] - public class Color : EntityBase - { - /// - /// 颜色码,0-255 - /// - public int Red { get; private set; } - /// - /// 颜色码,0-255 - /// - public int Green { get; private set; } - - /// - /// 颜色码,0-255 - /// - public int Blue { get; private set; } - - /// - /// 附加列,测试多次数据库 Migrate - /// - public string AdditionNote { get; private set; } - - private Color() { } - - public Color(int red, int green, int blue) - { - if (red < 0 || green < 0 || blue < 0) - { - Random();//随机 - } - else - { - Red = red; - Green = green; - Blue = blue; - } - } - - public Color(int red, int green, int blue, string additionNote) : this(red, green, blue) - { - AdditionNote = additionNote; - } - - public Color(ColorDto colorDto) - { - Red = colorDto.Red; - Green = colorDto.Green; - Blue = colorDto.Blue; - } - - public void Random() - { - //随机产生颜色代码 - var radom = new Random(); - Func getRadomColorCode = () => radom.Next(0, 255); - Red = getRadomColorCode(); - Green = getRadomColorCode(); - Blue = getRadomColorCode(); - } - - public void Brighten() - { - Red = Math.Min(255, Red + 10); - Green = Math.Min(255, Green + 10); - Blue = Math.Min(255, Blue + 10); - } - - public void Darken() - { - Red = Math.Max(0, Red - 10); - Green = Math.Max(0, Green - 10); - Blue = Math.Max(0, Blue - 10); - } - - public void Update(UpdateColorRequestDto dto) - { - Red = dto.Red; - Green = dto.Green; - Blue = dto.Blue; - AdditionNote = dto.AdditionNote; - } - } -} + public const string ColorModelTemplate = @"using Senparc.Ncf.Core.Models; +using Template_OrgName.Xncf.Template_XncfName.Domain.Models.DatabaseModel.Dto; +using System; +using System.ComponentModel.DataAnnotations.Schema; +using Template_OrgName.Xncf.Template_XncfName.Domain.Models.DatabaseModel.Dto; + +namespace Template_OrgName.Xncf.Template_XncfName +{ + /// + /// Color 实体类 + /// + [Table(Register.DATABASE_PREFIX + nameof(Color))]//必须添加前缀,防止全系统中发生冲突 + [Serializable] + public class Color : EntityBase + { + /// + /// 颜色码,0-255 + /// + public int Red { get; private set; } + /// + /// 颜色码,0-255 + /// + public int Green { get; private set; } + + /// + /// 颜色码,0-255 + /// + public int Blue { get; private set; } + + /// + /// 附加列,测试多次数据库 Migrate + /// + public string AdditionNote { get; private set; } + + private Color() { } + + public Color(int red, int green, int blue) + { + if (red < 0 || green < 0 || blue < 0) + { + Random();//随机 + } + else + { + Red = red; + Green = green; + Blue = blue; + } + } + + public Color(int red, int green, int blue, string additionNote) : this(red, green, blue) + { + AdditionNote = additionNote; + } + + public Color(ColorDto colorDto) + { + Red = colorDto.Red; + Green = colorDto.Green; + Blue = colorDto.Blue; + } + + public void Random() + { + //随机产生颜色代码 + var radom = new Random(); + Func getRadomColorCode = () => radom.Next(0, 255); + Red = getRadomColorCode(); + Green = getRadomColorCode(); + Blue = getRadomColorCode(); + } + + public void Brighten() + { + Red = Math.Min(255, Red + 10); + Green = Math.Min(255, Green + 10); + Blue = Math.Min(255, Blue + 10); + } + + public void Darken() + { + Red = Math.Max(0, Red - 10); + Green = Math.Max(0, Green - 10); + Blue = Math.Max(0, Blue - 10); + } + + public void Update(UpdateColorRequestDto dto) + { + Red = dto.Red; + Green = dto.Green; + Blue = dto.Blue; + AdditionNote = dto.AdditionNote; + } + } +} "; /// /// 颜色DTO模板 /// 类型: backend_template /// - public const string ColorDtoTemplate = @"using Senparc.Ncf.Core.Models; - -namespace Template_OrgName.Xncf.Template_XncfName.Domain.Models.DatabaseModel.Dto -{ - public class ColorDto : DtoBase - { - /// - /// 颜色码,0-255 - /// - public int Red { get; set; } - /// - /// 颜色码,0-255 - /// - public int Green { get; set; } - /// - /// 颜色码,0-255 - /// - public int Blue { get; set; } - - /// - /// 附加列,测试多次数据库 Migrate - /// - public string AdditionNote { get; set; } - - public ColorDto() { } - } -} + public const string ColorDtoTemplate = @"using Senparc.Ncf.Core.Models; + +namespace Template_OrgName.Xncf.Template_XncfName.Domain.Models.DatabaseModel.Dto +{ + public class ColorDto : DtoBase + { + /// + /// 颜色码,0-255 + /// + public int Red { get; set; } + /// + /// 颜色码,0-255 + /// + public int Green { get; set; } + /// + /// 颜色码,0-255 + /// + public int Blue { get; set; } + + /// + /// 附加列,测试多次数据库 Migrate + /// + public string AdditionNote { get; set; } + + public ColorDto() { } + } +} "; /// /// 颜色服务模板 /// 类型: backend_template /// - public const string ColorServiceTemplate = @"using Senparc.Ncf.Core.Enums; -using Senparc.Ncf.Repository; -using Senparc.Ncf.Service; -using Template_OrgName.Xncf.Template_XncfName.Domain.Models.DatabaseModel.Dto; -using System; -using System.Threading.Tasks; - -namespace Template_OrgName.Xncf.Template_XncfName.Domain.Services -{ - public class ColorService : ServiceBase - { - public ColorService(IRepositoryBase repo, IServiceProvider serviceProvider) - : base(repo, serviceProvider) - { - } - - public async Task CreateNewColor() - { - Color color = new Color(-1, -1, -1); - await base.SaveObjectAsync(color).ConfigureAwait(false); - ColorDto colorDto = base.Mapper.Map(color); - return colorDto; - } - - public async Task GetOrInitColor() - { - var color = await base.GetObjectAsync(z => true); - if (color == null)//如果是纯第一次安装,理论上不会有残留数据 - { - //创建默认颜色 - ColorDto colorDto = await this.CreateNewColor().ConfigureAwait(false); - return colorDto; - } - - return base.Mapper.Map(color); - } - - public async Task Brighten() - { - //TODO:异步方法需要添加排序功能 - var obj = await this.GetObjectAsync(z => true, z => z.Id, OrderingType.Descending); - obj.Brighten(); - await base.SaveObjectAsync(obj).ConfigureAwait(false); - return base.Mapper.Map(obj); - } - - public async Task Darken() - { - //TODO:异步方法需要添加排序功能 - var obj = await this.GetObjectAsync(z => true, z => z.Id, OrderingType.Descending); - obj.Darken(); - await base.SaveObjectAsync(obj).ConfigureAwait(false); - return base.Mapper.Map(obj); - } - - public async Task Random() - { - //TODO:异步方法需要添加排序功能 - var obj = await this.GetObjectAsync(z => true, z => z.Id, OrderingType.Descending); - obj.Random(); - await base.SaveObjectAsync(obj).ConfigureAwait(false); - return base.Mapper.Map(obj); - } - - //TODO: 更多业务方法可以写到这里 - } -} + public const string ColorServiceTemplate = @"using Senparc.Ncf.Core.Enums; +using Senparc.Ncf.Repository; +using Senparc.Ncf.Service; +using Template_OrgName.Xncf.Template_XncfName.Domain.Models.DatabaseModel.Dto; +using System; +using System.Threading.Tasks; + +namespace Template_OrgName.Xncf.Template_XncfName.Domain.Services +{ + public class ColorService : ServiceBase + { + public ColorService(IRepositoryBase repo, IServiceProvider serviceProvider) + : base(repo, serviceProvider) + { + } + + public async Task CreateNewColor() + { + Color color = new Color(-1, -1, -1); + await base.SaveObjectAsync(color).ConfigureAwait(false); + ColorDto colorDto = base.Mapper.Map(color); + return colorDto; + } + + public async Task GetOrInitColor() + { + var color = await base.GetObjectAsync(z => true); + if (color == null)//如果是纯第一次安装,理论上不会有残留数据 + { + //创建默认颜色 + ColorDto colorDto = await this.CreateNewColor().ConfigureAwait(false); + return colorDto; + } + + return base.Mapper.Map(color); + } + + public async Task Brighten() + { + //TODO:异步方法需要添加排序功能 + var obj = await this.GetObjectAsync(z => true, z => z.Id, OrderingType.Descending); + obj.Brighten(); + await base.SaveObjectAsync(obj).ConfigureAwait(false); + return base.Mapper.Map(obj); + } + + public async Task Darken() + { + //TODO:异步方法需要添加排序功能 + var obj = await this.GetObjectAsync(z => true, z => z.Id, OrderingType.Descending); + obj.Darken(); + await base.SaveObjectAsync(obj).ConfigureAwait(false); + return base.Mapper.Map(obj); + } + + public async Task Random() + { + //TODO:异步方法需要添加排序功能 + var obj = await this.GetObjectAsync(z => true, z => z.Id, OrderingType.Descending); + obj.Random(); + await base.SaveObjectAsync(obj).ConfigureAwait(false); + return base.Mapper.Map(obj); + } + + //TODO: 更多业务方法可以写到这里 + } +} "; #endregion @@ -360,431 +360,431 @@ public async Task Random() /// 数据库示例索引页面视图模板 /// 类型: frontend_template /// - public const string DatabaseSampleIndexViewTemplate = @"@page -@model Template_OrgName.Xncf.Template_XncfName.Areas.Template_XncfName.Pages.DatabaseSampleIndex -@{ - ViewData[""Title""] = ""Color 数据库管理""; - Layout = ""_Layout_Vue""; -} - -@section Style { - -} - -@section breadcrumbs { - 扩展模块 - Template_MenuName - Color 数据库管理 -} - -
-
- 添加颜色 - 刷新 - 调试信息 -
- - -
-

调试信息:

-

tableData长度: {{ tableData ? tableData.length : 'null/undefined' }}

-

total: {{ total }}

-

tableLoading: {{ tableLoading }}

-

Vue实例是否正常: {{ $el ? '是' : '否' }}

-
0""> - 第一条数据: -
{{ JSON.stringify(tableData[0], null, 2) }}
-
- - -
-
简化数据显示测试:
-
- ID: {{item.id}} | - RGB: {{item.red}},{{item.green}},{{item.blue}} | - 时间: {{item.addTime}} -
-

- 没有数据显示! -

-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - -
- - -
- - @* dialog for 添加颜色 *@ - - - - - - - - - - - - -
- RGB({{addForm.red}}, {{addForm.green}}, {{addForm.blue}}) -
-
- - - - - 随机颜色 - -
- - 取 消 - 确 定 - -
- - @* dialog for 编辑颜色 *@ - - - - - - - - - - - - -
- RGB({{editForm.red}}, {{editForm.green}}, {{editForm.blue}}) -
-
- - - - - 随机颜色 - -
- - 取 消 - 确 定 - -
-
- -@section scripts{ - + public const string DatabaseSampleIndexViewTemplate = @"@page +@model Template_OrgName.Xncf.Template_XncfName.Areas.Template_XncfName.Pages.DatabaseSampleIndex +@{ + ViewData[""Title""] = ""Color 数据库管理""; + Layout = ""_Layout_Vue""; +} + +@section Style { + +} + +@section breadcrumbs { + 扩展模块 + Template_MenuName + Color 数据库管理 +} + +
+
+ 添加颜色 + 刷新 + 调试信息 +
+ + +
+

调试信息:

+

tableData长度: {{ tableData ? tableData.length : 'null/undefined' }}

+

total: {{ total }}

+

tableLoading: {{ tableLoading }}

+

Vue实例是否正常: {{ $el ? '是' : '否' }}

+
0""> + 第一条数据: +
{{ JSON.stringify(tableData[0], null, 2) }}
+
+ + +
+
简化数据显示测试:
+
+ ID: {{item.id}} | + RGB: {{item.red}},{{item.green}},{{item.blue}} | + 时间: {{item.addTime}} +
+

+ 没有数据显示! +

+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ + @* dialog for 添加颜色 *@ + + + + + + + + + + + + +
+ RGB({{addForm.red}}, {{addForm.green}}, {{addForm.blue}}) +
+
+ + + + + 随机颜色 + +
+ + 取 消 + 确 定 + +
+ + @* dialog for 编辑颜色 *@ + + + + + + + + + + + + +
+ RGB({{editForm.red}}, {{editForm.green}}, {{editForm.blue}}) +
+
+ + + + + 随机颜色 + +
+ + 取 消 + 确 定 + +
+
+ +@section scripts{ + } "; /// /// 数据库示例索引页面代码后置模板 /// 类型: frontend_template /// - public const string DatabaseSampleIndexCodeBehindTemplate = @"using Microsoft.AspNetCore.Mvc; -using Senparc.Ncf.Service; -using Senparc.Ncf.Utility; -using Template_OrgName.Xncf.Template_XncfName.Domain.Services; -using System; -using System.Linq; -using System.Threading.Tasks; -using Template_OrgName.Xncf.Template_XncfName.Domain.Models.DatabaseModel.Dto; - -namespace Template_OrgName.Xncf.Template_XncfName.Areas.Template_XncfName.Pages -{ - public class DatabaseSampleIndex : Senparc.Ncf.AreaBase.Admin.AdminXncfModulePageModelBase - { - private readonly ColorService _colorService; - - public DatabaseSampleIndex(Lazy xncfModuleService, ColorService colorService) : base(xncfModuleService) - { - _colorService = colorService; - } - - public void OnGet() - { - } - - /// - /// 获取颜色列表(分页) - /// - /// 关键词 - /// 排序字段 - /// 页码 - /// 页大小 - /// - public async Task OnGetColorListAsync(string keyword, string orderField, int pageIndex, int pageSize) - { - try - { - // 调试信息 - System.Diagnostics.Debug.WriteLine($""ColorList API Called - PageIndex: {pageIndex}, PageSize: {pageSize}, OrderField: {orderField}""); - - var seh = new SenparcExpressionHelper(); - // 可以根据需要添加搜索条件 - // seh.ValueCompare.AndAlso(!string.IsNullOrEmpty(keyword), _ => _.Remark.Contains(keyword)); - var where = seh.BuildWhereExpression(); - var response = await _colorService.GetObjectListAsync(pageIndex, pageSize, where, orderField ?? ""Id desc""); - - // 调试信息 - System.Diagnostics.Debug.WriteLine($""Database Query Result - TotalCount: {response.TotalCount}, ItemCount: {response.Count()}""); - - var result = new - { - success = true, - message = ""数据获取成功"", - data = new { - totalCount = response.TotalCount, - pageIndex = response.PageIndex, - list = response.Select(_ => new - { - id = _.Id, - red = _.Red, - green = _.Green, - blue = _.Blue, - additionNote = _.AdditionNote, - addTime = _.AddTime, - lastUpdateTime = _.LastUpdateTime, - remark = _.Remark - }).ToList() - } - }; - - // 调试信息 - System.Diagnostics.Debug.WriteLine($""API Response - ListCount: {result.data.list.Count}""); - - return Ok(result); - } - catch (Exception ex) - { - System.Diagnostics.Debug.WriteLine($""ColorList API Error: {ex.Message}""); - return Ok(new { - success = false, - message = ""获取数据失败: "" + ex.Message, - totalCount = 0, - pageIndex = pageIndex, - list = new object[0] - }); - } - } - - /// - /// 创建新颜色 - /// - /// 创建颜色请求 - /// - public async Task OnPostCreateColorAsync([FromBody] CreateColorRequestDto request) - { - try - { - // 调试信息 - System.Diagnostics.Debug.WriteLine($""CreateColor API Called - Red: {request.Red}, Green: {request.Green}, Blue: {request.Blue}, AdditionNote: {request.AdditionNote}""); - - if (request == null) - { - return Ok(new { success = false, message = ""请求参数不能为空"" }); - } - - var color = new Color(request.Red, request.Green, request.Blue, request.AdditionNote); - await _colorService.SaveObjectAsync(color); - - return Ok(new { success = true, message = ""颜色创建成功"", data = new { color.Id, color.Red, color.Green, color.Blue, color.AdditionNote, color.AddTime, color.LastUpdateTime } }); - } - catch (Exception ex) - { - System.Diagnostics.Debug.WriteLine($""CreateColor API Error: {ex.Message}""); - return Ok(new { success = false, message = ""创建失败:"" + ex.Message }); - } - } - - /// - /// 更新颜色 - /// - /// 更新颜色请求 - /// - public async Task OnPostUpdateColorAsync([FromBody] UpdateColorRequestDto request) - { - try - { - // 调试信息 - System.Diagnostics.Debug.WriteLine($""UpdateColor API Called - Id: {request.Id}, Red: {request.Red}, Green: {request.Green}, Blue: {request.Blue}, AdditionNote: {request.AdditionNote}""); - - if (request == null) - { - return Ok(new { success = false, message = ""请求参数不能为空"" }); - } - - var color = await _colorService.GetObjectAsync(c => c.Id == request.Id); - if (color == null) - { - return Ok(new { success = false, message = ""颜色不存在"" }); - } - - // 更新 - color.Update(request); - - await _colorService.SaveObjectAsync(color); - - return Ok(new { success = true, message = ""颜色更新成功"", data = new { color.Id, color.Red, color.Green, color.Blue, color.AdditionNote, color.LastUpdateTime } }); - } - catch (Exception ex) - { - System.Diagnostics.Debug.WriteLine($""UpdateColor API Error: {ex.Message}""); - return Ok(new { success = false, message = ""更新失败:"" + ex.Message }); - } - } - - /// - /// 删除颜色 - /// - /// 删除颜色请求 - /// - public async Task OnPostDeleteColorAsync([FromBody] DeleteColorRequestDto request) - { - try - { - // 调试信息 - System.Diagnostics.Debug.WriteLine($""DeleteColor API Called - Id: {request.Id}""); - - if (request == null) - { - return Ok(new { success = false, message = ""请求参数不能为空"" }); - } - - var color = await _colorService.GetObjectAsync(c => c.Id == request.Id); - if (color == null) - { - return Ok(new { success = false, message = ""颜色不存在"" }); - } - - await _colorService.DeleteObjectAsync(color); - return Ok(new { success = true, message = ""颜色删除成功"" }); - } - catch (Exception ex) - { - System.Diagnostics.Debug.WriteLine($""DeleteColor API Error: {ex.Message}""); - return Ok(new { success = false, message = ""删除失败:"" + ex.Message }); - } - } - - /// - /// 随机化指定颜色 - /// - /// 随机化颜色请求 - /// - public async Task OnPostRandomizeColorAsync([FromBody] RandomizeColorRequestDto request) - { - try - { - // 调试信息 - System.Diagnostics.Debug.WriteLine($""RandomizeColor API Called - Id: {request.Id}""); - - if (request == null) - { - return Ok(new { success = false, message = ""请求参数不能为空"" }); - } - - var color = await _colorService.GetObjectAsync(c => c.Id == request.Id); - if (color == null) - { - return Ok(new { success = false, message = ""颜色不存在"" }); - } - - color.Random(); - await _colorService.SaveObjectAsync(color); - - return Ok(new { success = true, message = ""颜色随机化成功"", data = new { color.Id, color.Red, color.Green, color.Blue, color.AdditionNote, color.LastUpdateTime } }); - } - catch (Exception ex) - { - System.Diagnostics.Debug.WriteLine($""RandomizeColor API Error: {ex.Message}""); - return Ok(new { success = false, message = ""随机化失败:"" + ex.Message }); - } - } - - /// - /// 获取颜色详情 - /// - /// 颜色ID - /// - public async Task OnGetColorDetailAsync(int id) - { - try - { - var color = await _colorService.GetObjectAsync(c => c.Id == id); - if (color == null) - { - return Ok(new { success = false, message = ""颜色不存在"" }); - } - - return Ok(new { success = true, data = new { color.Id, color.Red, color.Green, color.Blue, color.AdditionNote, color.AddTime, color.LastUpdateTime, color.Remark } }); - } - catch (Exception ex) - { - return Ok(new { success = false, message = ""获取失败:"" + ex.Message }); - } - } - } + public const string DatabaseSampleIndexCodeBehindTemplate = @"using Microsoft.AspNetCore.Mvc; +using Senparc.Ncf.Service; +using Senparc.Ncf.Utility; +using Template_OrgName.Xncf.Template_XncfName.Domain.Services; +using System; +using System.Linq; +using System.Threading.Tasks; +using Template_OrgName.Xncf.Template_XncfName.Domain.Models.DatabaseModel.Dto; + +namespace Template_OrgName.Xncf.Template_XncfName.Areas.Template_XncfName.Pages +{ + public class DatabaseSampleIndex : Senparc.Ncf.AreaBase.Admin.AdminXncfModulePageModelBase + { + private readonly ColorService _colorService; + + public DatabaseSampleIndex(Lazy xncfModuleService, ColorService colorService) : base(xncfModuleService) + { + _colorService = colorService; + } + + public void OnGet() + { + } + + /// + /// 获取颜色列表(分页) + /// + /// 关键词 + /// 排序字段 + /// 页码 + /// 页大小 + /// + public async Task OnGetColorListAsync(string keyword, string orderField, int pageIndex, int pageSize) + { + try + { + // 调试信息 + System.Diagnostics.Debug.WriteLine($""ColorList API Called - PageIndex: {pageIndex}, PageSize: {pageSize}, OrderField: {orderField}""); + + var seh = new SenparcExpressionHelper(); + // 可以根据需要添加搜索条件 + // seh.ValueCompare.AndAlso(!string.IsNullOrEmpty(keyword), _ => _.Remark.Contains(keyword)); + var where = seh.BuildWhereExpression(); + var response = await _colorService.GetObjectListAsync(pageIndex, pageSize, where, orderField ?? ""Id desc""); + + // 调试信息 + System.Diagnostics.Debug.WriteLine($""Database Query Result - TotalCount: {response.TotalCount}, ItemCount: {response.Count()}""); + + var result = new + { + success = true, + message = ""数据获取成功"", + data = new { + totalCount = response.TotalCount, + pageIndex = response.PageIndex, + list = response.Select(_ => new + { + id = _.Id, + red = _.Red, + green = _.Green, + blue = _.Blue, + additionNote = _.AdditionNote, + addTime = _.AddTime, + lastUpdateTime = _.LastUpdateTime, + remark = _.Remark + }).ToList() + } + }; + + // 调试信息 + System.Diagnostics.Debug.WriteLine($""API Response - ListCount: {result.data.list.Count}""); + + return Ok(result); + } + catch (Exception ex) + { + System.Diagnostics.Debug.WriteLine($""ColorList API Error: {ex.Message}""); + return Ok(new { + success = false, + message = ""获取数据失败: "" + ex.Message, + totalCount = 0, + pageIndex = pageIndex, + list = new object[0] + }); + } + } + + /// + /// 创建新颜色 + /// + /// 创建颜色请求 + /// + public async Task OnPostCreateColorAsync([FromBody] CreateColorRequestDto request) + { + try + { + // 调试信息 + System.Diagnostics.Debug.WriteLine($""CreateColor API Called - Red: {request.Red}, Green: {request.Green}, Blue: {request.Blue}, AdditionNote: {request.AdditionNote}""); + + if (request == null) + { + return Ok(new { success = false, message = ""请求参数不能为空"" }); + } + + var color = new Color(request.Red, request.Green, request.Blue, request.AdditionNote); + await _colorService.SaveObjectAsync(color); + + return Ok(new { success = true, message = ""颜色创建成功"", data = new { color.Id, color.Red, color.Green, color.Blue, color.AdditionNote, color.AddTime, color.LastUpdateTime } }); + } + catch (Exception ex) + { + System.Diagnostics.Debug.WriteLine($""CreateColor API Error: {ex.Message}""); + return Ok(new { success = false, message = ""创建失败:"" + ex.Message }); + } + } + + /// + /// 更新颜色 + /// + /// 更新颜色请求 + /// + public async Task OnPostUpdateColorAsync([FromBody] UpdateColorRequestDto request) + { + try + { + // 调试信息 + System.Diagnostics.Debug.WriteLine($""UpdateColor API Called - Id: {request.Id}, Red: {request.Red}, Green: {request.Green}, Blue: {request.Blue}, AdditionNote: {request.AdditionNote}""); + + if (request == null) + { + return Ok(new { success = false, message = ""请求参数不能为空"" }); + } + + var color = await _colorService.GetObjectAsync(c => c.Id == request.Id); + if (color == null) + { + return Ok(new { success = false, message = ""颜色不存在"" }); + } + + // 更新 + color.Update(request); + + await _colorService.SaveObjectAsync(color); + + return Ok(new { success = true, message = ""颜色更新成功"", data = new { color.Id, color.Red, color.Green, color.Blue, color.AdditionNote, color.LastUpdateTime } }); + } + catch (Exception ex) + { + System.Diagnostics.Debug.WriteLine($""UpdateColor API Error: {ex.Message}""); + return Ok(new { success = false, message = ""更新失败:"" + ex.Message }); + } + } + + /// + /// 删除颜色 + /// + /// 删除颜色请求 + /// + public async Task OnPostDeleteColorAsync([FromBody] DeleteColorRequestDto request) + { + try + { + // 调试信息 + System.Diagnostics.Debug.WriteLine($""DeleteColor API Called - Id: {request.Id}""); + + if (request == null) + { + return Ok(new { success = false, message = ""请求参数不能为空"" }); + } + + var color = await _colorService.GetObjectAsync(c => c.Id == request.Id); + if (color == null) + { + return Ok(new { success = false, message = ""颜色不存在"" }); + } + + await _colorService.DeleteObjectAsync(color); + return Ok(new { success = true, message = ""颜色删除成功"" }); + } + catch (Exception ex) + { + System.Diagnostics.Debug.WriteLine($""DeleteColor API Error: {ex.Message}""); + return Ok(new { success = false, message = ""删除失败:"" + ex.Message }); + } + } + + /// + /// 随机化指定颜色 + /// + /// 随机化颜色请求 + /// + public async Task OnPostRandomizeColorAsync([FromBody] RandomizeColorRequestDto request) + { + try + { + // 调试信息 + System.Diagnostics.Debug.WriteLine($""RandomizeColor API Called - Id: {request.Id}""); + + if (request == null) + { + return Ok(new { success = false, message = ""请求参数不能为空"" }); + } + + var color = await _colorService.GetObjectAsync(c => c.Id == request.Id); + if (color == null) + { + return Ok(new { success = false, message = ""颜色不存在"" }); + } + + color.Random(); + await _colorService.SaveObjectAsync(color); + + return Ok(new { success = true, message = ""颜色随机化成功"", data = new { color.Id, color.Red, color.Green, color.Blue, color.AdditionNote, color.LastUpdateTime } }); + } + catch (Exception ex) + { + System.Diagnostics.Debug.WriteLine($""RandomizeColor API Error: {ex.Message}""); + return Ok(new { success = false, message = ""随机化失败:"" + ex.Message }); + } + } + + /// + /// 获取颜色详情 + /// + /// 颜色ID + /// + public async Task OnGetColorDetailAsync(int id) + { + try + { + var color = await _colorService.GetObjectAsync(c => c.Id == id); + if (color == null) + { + return Ok(new { success = false, message = ""颜色不存在"" }); + } + + return Ok(new { success = true, data = new { color.Id, color.Red, color.Green, color.Blue, color.AdditionNote, color.AddTime, color.LastUpdateTime, color.Remark } }); + } + catch (Exception ex) + { + return Ok(new { success = false, message = ""获取失败:"" + ex.Message }); + } + } + } } "; #endregion @@ -795,433 +795,433 @@ public async Task OnGetColorDetailAsync(int id) /// 数据库示例索引页面JavaScript模板 /// 类型: frontend_script /// - public const string DatabaseSampleIndexJsTemplate = @"var app = new Vue({ - el: ""#app"", - data() { - return { - page: { - page: 1, - size: 10 - }, - tableLoading: true, - tableData: [], - showDebug: false, - addFormDialogVisible: false, - addForm: { - red: 128, - green: 128, - blue: 128, - additionNote: '' - }, - editFormDialogVisible: false, - editForm: { - id: 0, - red: 128, - green: 128, - blue: 128, - additionNote: '' - }, - total: 0, - addRules: { - red: [ - { required: true, message: '请设置红色值', trigger: 'change' }, - { type: 'number', min: 0, max: 255, message: '红色值范围为0-255', trigger: 'change' } - ], - green: [ - { required: true, message: '请设置绿色值', trigger: 'change' }, - { type: 'number', min: 0, max: 255, message: '绿色值范围为0-255', trigger: 'change' } - ], - blue: [ - { required: true, message: '请设置蓝色值', trigger: 'change' }, - { type: 'number', min: 0, max: 255, message: '蓝色值范围为0-255', trigger: 'change' } - ] - }, - editRules: { - red: [ - { required: true, message: '请设置红色值', trigger: 'change' }, - { type: 'number', min: 0, max: 255, message: '红色值范围为0-255', trigger: 'change' } - ], - green: [ - { required: true, message: '请设置绿色值', trigger: 'change' }, - { type: 'number', min: 0, max: 255, message: '绿色值范围为0-255', trigger: 'change' } - ], - blue: [ - { required: true, message: '请设置蓝色值', trigger: 'change' }, - { type: 'number', min: 0, max: 255, message: '蓝色值范围为0-255', trigger: 'change' } - ] - } - } - }, - mounted() { - //wait page load - setTimeout(async () => { - await this.init(); - }, 100) - }, - methods: { - async init() { - await this.getDataList(); - }, - async handleSizeChange(val) { - this.page.size = val; - await this.getDataList(); - }, - async handleCurrentChange(val) { - this.page.page = val; - await this.getDataList(); - }, - async getDataList() { - this.tableLoading = true - await service.get('/Admin/Template_XncfName/DatabaseSampleIndex?handler=ColorList', { - params: { - pageIndex: this.page.page, - pageSize: this.page.size, - orderField: ""Id desc"", - keyword: """" - } - }) - .then(res => { - console.log('=== API Response Debug ==='); - console.log('Complete Response:', res); - console.log('Response Data:', res.data); - console.log('Response Data Type:', typeof res.data); - console.log('Has res.data.data?:', res.data && res.data.data); - console.log('Has res.data.data.list?:', res.data && res.data.data && res.data.data.list); - console.log('res.data.data.list value:', res.data && res.data.data ? res.data.data.list : 'nested data not found'); - console.log('=================='); - - // 尝试多种可能的数据结构 - let dataList = null; - let totalCount = 0; - let dataSource = ''; - - if (res.data && res.data.data && res.data.data.data && res.data.data.data.list) { - // NCF框架标准格式 + 新的API格式: {data: {data: {success, message, data: {list, totalCount}}}} - dataList = res.data.data.data.list; - totalCount = res.data.data.data.totalCount || 0; - dataSource = 'NCF标准格式: res.data.data.data.list'; - console.log('✅ 使用NCF标准格式: res.data.data.data.list'); - console.log('✅ List数据:', dataList); - console.log('✅ TotalCount:', totalCount); - } else if (res.data && res.data.data && res.data.data.list) { - // 简单格式: {data: {list, totalCount}} - dataList = res.data.data.list; - totalCount = res.data.data.totalCount || 0; - dataSource = '简单格式: res.data.data.list'; - console.log('✅ 使用简单格式: res.data.data.list'); - } else if (res.data && Array.isArray(res.data)) { - // 如果data直接是数组 - dataList = res.data; - totalCount = res.data.length; - dataSource = '数组格式: res.data (array)'; - console.log('✅ 使用数组格式: res.data (array)'); - } else if (res && res.list) { - // 如果list在顶层 - dataList = res.list; - totalCount = res.totalCount || 0; - dataSource = '顶层格式: res.list'; - console.log('✅ 使用顶层格式: res.list'); - } else { - console.error('❌ 无法识别的数据格式:', res); - console.log('🔍 尝试的路径:'); - console.log('- res.data.data.list:', res.data && res.data.data ? res.data.data.list : 'not found'); - console.log('- res.data.list:', res.data ? res.data.list : 'not found'); - console.log('- res.data (array):', res.data && Array.isArray(res.data) ? 'is array' : 'not array'); - console.log('- res.list:', res.list ? res.list : 'not found'); - dataList = []; - totalCount = 0; - dataSource = '无法识别格式'; - } - - console.log('🎯 Final dataList:', dataList); - console.log('🎯 Final totalCount:', totalCount); - console.log('🎯 Data source:', dataSource); - - // 数据赋值前的状态 - console.log('📋 赋值前 tableData:', this.tableData); - console.log('📋 赋值前 total:', this.total); - - this.tableData = dataList || []; - this.total = totalCount; - - // 数据赋值后的状态 - console.log('📋 赋值后 tableData:', this.tableData); - console.log('📋 赋值后 tableData.length:', this.tableData.length); - console.log('📋 赋值后 total:', this.total); - - // 强制Vue更新 - this.$forceUpdate(); - console.log('🔄 Vue已强制更新'); - - // 延迟检查数据是否正确绑定 - setTimeout(() => { - console.log('⏰ 延迟检查 tableData:', this.tableData); - console.log('⏰ 延迟检查 tableData.length:', this.tableData ? this.tableData.length : 'null'); - }, 100); - - this.tableLoading = false - }) - .catch(error => { - console.error('获取数据失败:', error); - this.tableLoading = false; - this.$message.error('获取数据失败: ' + (error.message || error)); - }); - }, - addColor() { - this.addFormDialogVisible = true; - }, - refreshList() { - this.getDataList(); - }, - async addColorSubmit() { - this.$refs.addForm.validate(async (valid) => { - if (valid) { - console.log('📤 发送创建请求:', { - red: this.addForm.red, - green: this.addForm.green, - blue: this.addForm.blue, - additionNote: this.addForm.additionNote - }); - - await service.post('/Admin/Template_XncfName/DatabaseSampleIndex?handler=CreateColor', { - red: this.addForm.red, - green: this.addForm.green, - blue: this.addForm.blue, - additionNote: this.addForm.additionNote - }, { - headers: { - 'Content-Type': 'application/json' - } - }) - .then(res => { - console.log('📥 创建响应:', res); - // 兼容NCF框架的嵌套响应格式 - const responseData = res.data.data || res.data; - this.$message({ - type: responseData.success ? 'success' : 'error', - message: responseData.message || '操作完成' - }); - if (responseData.success) { - this.getDataList() - this.clearAddForm() - this.addFormDialogVisible = false; - } - }) - .catch(error => { - console.error('创建失败:', error); - this.$message.error('创建失败'); - }); - } else { - return false; - } - }); - }, - clearAddForm() { - this.addForm = { - red: 128, - green: 128, - blue: 128, - additionNote: '' - }; - if (this.$refs.addForm) { - this.$refs.addForm.resetFields(); - } - }, - clearEditForm() { - this.editForm = { - id: 0, - red: 128, - green: 128, - blue: 128, - additionNote: '' - }; - if (this.$refs.editForm) { - this.$refs.editForm.resetFields(); - } - }, - async editColorSubmit() { - this.$refs.editForm.validate(async (valid) => { - if (valid) { - console.log('📤 发送更新请求:', { - id: this.editForm.id, - red: this.editForm.red, - green: this.editForm.green, - blue: this.editForm.blue, - additionNote: this.editForm.additionNote - }); - - await service.post('/Admin/Template_XncfName/DatabaseSampleIndex?handler=UpdateColor', { - id: this.editForm.id, - red: this.editForm.red, - green: this.editForm.green, - blue: this.editForm.blue, - additionNote: this.editForm.additionNote - }, { - headers: { - 'Content-Type': 'application/json' - } - }) - .then(res => { - console.log('📥 更新响应:', res); - // 兼容NCF框架的嵌套响应格式 - const responseData = res.data.data || res.data; - this.$message({ - type: responseData.success ? 'success' : 'error', - message: responseData.message || '操作完成' - }); - if (responseData.success) { - this.getDataList() - this.clearEditForm() - this.editFormDialogVisible = false; - } - }) - .catch(error => { - console.error('更新失败:', error); - this.$message.error('更新失败'); - }); - } else { - return false; - } - }); - }, - dateformatter(date) { - if (!date) return ''; - - try { - // 使用原生JavaScript格式化日期 - const d = new Date(date); - - // 检查日期是否有效 - if (isNaN(d.getTime())) { - return date; // 如果无法解析,返回原始值 - } - - // 格式化为 YYYY-MM-DD HH:mm:ss - const year = d.getFullYear(); - const month = String(d.getMonth() + 1).padStart(2, '0'); - const day = String(d.getDate()).padStart(2, '0'); - const hours = String(d.getHours()).padStart(2, '0'); - const minutes = String(d.getMinutes()).padStart(2, '0'); - const seconds = String(d.getSeconds()).padStart(2, '0'); - - return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`; - } catch (error) { - console.warn('日期格式化错误:', error, '原始值:', date); - return date; // 如果格式化失败,返回原始值 - } - }, - editColor(row) { - this.editForm = { - id: row.id, - red: row.red, - green: row.green, - blue: row.blue, - additionNote: row.additionNote || '' - }; - this.editFormDialogVisible = true; - }, - deleteColor(row) { - this.$confirm('此操作将永久删除该颜色, 是否继续?', '提示', { - confirmButtonText: '确定', - cancelButtonText: '取消', - type: 'warning' - }).then(async () => { - console.log('📤 发送删除请求:', { id: row.id }); - - await service.post('/Admin/Template_XncfName/DatabaseSampleIndex?handler=DeleteColor', { - id: row.id - }, { - headers: { - 'Content-Type': 'application/json' - } - }) - .then(res => { - console.log('📥 删除响应:', res); - // 兼容NCF框架的嵌套响应格式 - const responseData = res.data.data || res.data; - this.$message({ - type: responseData.success ? 'success' : 'error', - message: responseData.message || '操作完成' - }); - if (responseData.success) { - this.getDataList(); - } - }) - .catch(error => { - console.error('删除失败:', error); - this.$message.error('删除失败'); - }); - }).catch(() => { - this.$message({ - type: 'info', - message: '已取消删除' - }); - }); - }, - async randomizeColor(row) { - console.log('📤 发送随机化请求:', { id: row.id }); - - await service.post('/Admin/Template_XncfName/DatabaseSampleIndex?handler=RandomizeColor', { - id: row.id - }, { - headers: { - 'Content-Type': 'application/json' - } - }) - .then(res => { - console.log('📥 随机化响应:', res); - // 兼容NCF框架的嵌套响应格式 - const responseData = res.data.data || res.data; - this.$message({ - type: responseData.success ? 'success' : 'error', - message: responseData.message || '操作完成' - }); - if (responseData.success) { - this.getDataList(); - } - }) - .catch(error => { - console.error('随机化失败:', error); - this.$message.error('随机化失败'); - }); - }, - randomizeForm() { - this.addForm.red = Math.floor(Math.random() * 256); - this.addForm.green = Math.floor(Math.random() * 256); - this.addForm.blue = Math.floor(Math.random() * 256); - }, - randomizeEditForm() { - this.editForm.red = Math.floor(Math.random() * 256); - this.editForm.green = Math.floor(Math.random() * 256); - this.editForm.blue = Math.floor(Math.random() * 256); - }, - debugInfo() { - this.showDebug = !this.showDebug; - console.log('=== Vue Component Debug Info ==='); - console.log('Current tableData:', this.tableData); - console.log('tableData length:', this.tableData ? this.tableData.length : 'null/undefined'); - console.log('Total:', this.total); - console.log('Page:', this.page); - console.log('Table Loading:', this.tableLoading); - console.log('Show Debug:', this.showDebug); - console.log('Vue instance $el:', this.$el); - console.log('================================'); - - // 测试Vue响应性 - if (this.tableData && this.tableData.length === 0) { - console.log('测试:添加假数据'); - this.tableData = [ - {id: 999, red: 255, green: 0, blue: 0, addTime: new Date().toISOString(), lastUpdateTime: new Date().toISOString(), remark: 'test'} - ]; - this.total = 1; - setTimeout(() => { - console.log('2秒后清除假数据'); - this.tableData = []; - this.total = 0; - }, 2000); - } - } - } + public const string DatabaseSampleIndexJsTemplate = @"var app = new Vue({ + el: ""#app"", + data() { + return { + page: { + page: 1, + size: 10 + }, + tableLoading: true, + tableData: [], + showDebug: false, + addFormDialogVisible: false, + addForm: { + red: 128, + green: 128, + blue: 128, + additionNote: '' + }, + editFormDialogVisible: false, + editForm: { + id: 0, + red: 128, + green: 128, + blue: 128, + additionNote: '' + }, + total: 0, + addRules: { + red: [ + { required: true, message: '请设置红色值', trigger: 'change' }, + { type: 'number', min: 0, max: 255, message: '红色值范围为0-255', trigger: 'change' } + ], + green: [ + { required: true, message: '请设置绿色值', trigger: 'change' }, + { type: 'number', min: 0, max: 255, message: '绿色值范围为0-255', trigger: 'change' } + ], + blue: [ + { required: true, message: '请设置蓝色值', trigger: 'change' }, + { type: 'number', min: 0, max: 255, message: '蓝色值范围为0-255', trigger: 'change' } + ] + }, + editRules: { + red: [ + { required: true, message: '请设置红色值', trigger: 'change' }, + { type: 'number', min: 0, max: 255, message: '红色值范围为0-255', trigger: 'change' } + ], + green: [ + { required: true, message: '请设置绿色值', trigger: 'change' }, + { type: 'number', min: 0, max: 255, message: '绿色值范围为0-255', trigger: 'change' } + ], + blue: [ + { required: true, message: '请设置蓝色值', trigger: 'change' }, + { type: 'number', min: 0, max: 255, message: '蓝色值范围为0-255', trigger: 'change' } + ] + } + } + }, + mounted() { + //wait page load + setTimeout(async () => { + await this.init(); + }, 100) + }, + methods: { + async init() { + await this.getDataList(); + }, + async handleSizeChange(val) { + this.page.size = val; + await this.getDataList(); + }, + async handleCurrentChange(val) { + this.page.page = val; + await this.getDataList(); + }, + async getDataList() { + this.tableLoading = true + await service.get('/Admin/Template_XncfName/DatabaseSampleIndex?handler=ColorList', { + params: { + pageIndex: this.page.page, + pageSize: this.page.size, + orderField: ""Id desc"", + keyword: """" + } + }) + .then(res => { + console.log('=== API Response Debug ==='); + console.log('Complete Response:', res); + console.log('Response Data:', res.data); + console.log('Response Data Type:', typeof res.data); + console.log('Has res.data.data?:', res.data && res.data.data); + console.log('Has res.data.data.list?:', res.data && res.data.data && res.data.data.list); + console.log('res.data.data.list value:', res.data && res.data.data ? res.data.data.list : 'nested data not found'); + console.log('=================='); + + // 尝试多种可能的数据结构 + let dataList = null; + let totalCount = 0; + let dataSource = ''; + + if (res.data && res.data.data && res.data.data.data && res.data.data.data.list) { + // NCF框架标准格式 + 新的API格式: {data: {data: {success, message, data: {list, totalCount}}}} + dataList = res.data.data.data.list; + totalCount = res.data.data.data.totalCount || 0; + dataSource = 'NCF标准格式: res.data.data.data.list'; + console.log('✅ 使用NCF标准格式: res.data.data.data.list'); + console.log('✅ List数据:', dataList); + console.log('✅ TotalCount:', totalCount); + } else if (res.data && res.data.data && res.data.data.list) { + // 简单格式: {data: {list, totalCount}} + dataList = res.data.data.list; + totalCount = res.data.data.totalCount || 0; + dataSource = '简单格式: res.data.data.list'; + console.log('✅ 使用简单格式: res.data.data.list'); + } else if (res.data && Array.isArray(res.data)) { + // 如果data直接是数组 + dataList = res.data; + totalCount = res.data.length; + dataSource = '数组格式: res.data (array)'; + console.log('✅ 使用数组格式: res.data (array)'); + } else if (res && res.list) { + // 如果list在顶层 + dataList = res.list; + totalCount = res.totalCount || 0; + dataSource = '顶层格式: res.list'; + console.log('✅ 使用顶层格式: res.list'); + } else { + console.error('❌ 无法识别的数据格式:', res); + console.log('🔍 尝试的路径:'); + console.log('- res.data.data.list:', res.data && res.data.data ? res.data.data.list : 'not found'); + console.log('- res.data.list:', res.data ? res.data.list : 'not found'); + console.log('- res.data (array):', res.data && Array.isArray(res.data) ? 'is array' : 'not array'); + console.log('- res.list:', res.list ? res.list : 'not found'); + dataList = []; + totalCount = 0; + dataSource = '无法识别格式'; + } + + console.log('🎯 Final dataList:', dataList); + console.log('🎯 Final totalCount:', totalCount); + console.log('🎯 Data source:', dataSource); + + // 数据赋值前的状态 + console.log('📋 赋值前 tableData:', this.tableData); + console.log('📋 赋值前 total:', this.total); + + this.tableData = dataList || []; + this.total = totalCount; + + // 数据赋值后的状态 + console.log('📋 赋值后 tableData:', this.tableData); + console.log('📋 赋值后 tableData.length:', this.tableData.length); + console.log('📋 赋值后 total:', this.total); + + // 强制Vue更新 + this.$forceUpdate(); + console.log('🔄 Vue已强制更新'); + + // 延迟检查数据是否正确绑定 + setTimeout(() => { + console.log('⏰ 延迟检查 tableData:', this.tableData); + console.log('⏰ 延迟检查 tableData.length:', this.tableData ? this.tableData.length : 'null'); + }, 100); + + this.tableLoading = false + }) + .catch(error => { + console.error('获取数据失败:', error); + this.tableLoading = false; + this.$message.error('获取数据失败: ' + (error.message || error)); + }); + }, + addColor() { + this.addFormDialogVisible = true; + }, + refreshList() { + this.getDataList(); + }, + async addColorSubmit() { + this.$refs.addForm.validate(async (valid) => { + if (valid) { + console.log('📤 发送创建请求:', { + red: this.addForm.red, + green: this.addForm.green, + blue: this.addForm.blue, + additionNote: this.addForm.additionNote + }); + + await service.post('/Admin/Template_XncfName/DatabaseSampleIndex?handler=CreateColor', { + red: this.addForm.red, + green: this.addForm.green, + blue: this.addForm.blue, + additionNote: this.addForm.additionNote + }, { + headers: { + 'Content-Type': 'application/json' + } + }) + .then(res => { + console.log('📥 创建响应:', res); + // 兼容NCF框架的嵌套响应格式 + const responseData = res.data.data || res.data; + this.$message({ + type: responseData.success ? 'success' : 'error', + message: responseData.message || '操作完成' + }); + if (responseData.success) { + this.getDataList() + this.clearAddForm() + this.addFormDialogVisible = false; + } + }) + .catch(error => { + console.error('创建失败:', error); + this.$message.error('创建失败'); + }); + } else { + return false; + } + }); + }, + clearAddForm() { + this.addForm = { + red: 128, + green: 128, + blue: 128, + additionNote: '' + }; + if (this.$refs.addForm) { + this.$refs.addForm.resetFields(); + } + }, + clearEditForm() { + this.editForm = { + id: 0, + red: 128, + green: 128, + blue: 128, + additionNote: '' + }; + if (this.$refs.editForm) { + this.$refs.editForm.resetFields(); + } + }, + async editColorSubmit() { + this.$refs.editForm.validate(async (valid) => { + if (valid) { + console.log('📤 发送更新请求:', { + id: this.editForm.id, + red: this.editForm.red, + green: this.editForm.green, + blue: this.editForm.blue, + additionNote: this.editForm.additionNote + }); + + await service.post('/Admin/Template_XncfName/DatabaseSampleIndex?handler=UpdateColor', { + id: this.editForm.id, + red: this.editForm.red, + green: this.editForm.green, + blue: this.editForm.blue, + additionNote: this.editForm.additionNote + }, { + headers: { + 'Content-Type': 'application/json' + } + }) + .then(res => { + console.log('📥 更新响应:', res); + // 兼容NCF框架的嵌套响应格式 + const responseData = res.data.data || res.data; + this.$message({ + type: responseData.success ? 'success' : 'error', + message: responseData.message || '操作完成' + }); + if (responseData.success) { + this.getDataList() + this.clearEditForm() + this.editFormDialogVisible = false; + } + }) + .catch(error => { + console.error('更新失败:', error); + this.$message.error('更新失败'); + }); + } else { + return false; + } + }); + }, + dateformatter(date) { + if (!date) return ''; + + try { + // 使用原生JavaScript格式化日期 + const d = new Date(date); + + // 检查日期是否有效 + if (isNaN(d.getTime())) { + return date; // 如果无法解析,返回原始值 + } + + // 格式化为 YYYY-MM-DD HH:mm:ss + const year = d.getFullYear(); + const month = String(d.getMonth() + 1).padStart(2, '0'); + const day = String(d.getDate()).padStart(2, '0'); + const hours = String(d.getHours()).padStart(2, '0'); + const minutes = String(d.getMinutes()).padStart(2, '0'); + const seconds = String(d.getSeconds()).padStart(2, '0'); + + return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`; + } catch (error) { + console.warn('日期格式化错误:', error, '原始值:', date); + return date; // 如果格式化失败,返回原始值 + } + }, + editColor(row) { + this.editForm = { + id: row.id, + red: row.red, + green: row.green, + blue: row.blue, + additionNote: row.additionNote || '' + }; + this.editFormDialogVisible = true; + }, + deleteColor(row) { + this.$confirm('此操作将永久删除该颜色, 是否继续?', '提示', { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: 'warning' + }).then(async () => { + console.log('📤 发送删除请求:', { id: row.id }); + + await service.post('/Admin/Template_XncfName/DatabaseSampleIndex?handler=DeleteColor', { + id: row.id + }, { + headers: { + 'Content-Type': 'application/json' + } + }) + .then(res => { + console.log('📥 删除响应:', res); + // 兼容NCF框架的嵌套响应格式 + const responseData = res.data.data || res.data; + this.$message({ + type: responseData.success ? 'success' : 'error', + message: responseData.message || '操作完成' + }); + if (responseData.success) { + this.getDataList(); + } + }) + .catch(error => { + console.error('删除失败:', error); + this.$message.error('删除失败'); + }); + }).catch(() => { + this.$message({ + type: 'info', + message: '已取消删除' + }); + }); + }, + async randomizeColor(row) { + console.log('📤 发送随机化请求:', { id: row.id }); + + await service.post('/Admin/Template_XncfName/DatabaseSampleIndex?handler=RandomizeColor', { + id: row.id + }, { + headers: { + 'Content-Type': 'application/json' + } + }) + .then(res => { + console.log('📥 随机化响应:', res); + // 兼容NCF框架的嵌套响应格式 + const responseData = res.data.data || res.data; + this.$message({ + type: responseData.success ? 'success' : 'error', + message: responseData.message || '操作完成' + }); + if (responseData.success) { + this.getDataList(); + } + }) + .catch(error => { + console.error('随机化失败:', error); + this.$message.error('随机化失败'); + }); + }, + randomizeForm() { + this.addForm.red = Math.floor(Math.random() * 256); + this.addForm.green = Math.floor(Math.random() * 256); + this.addForm.blue = Math.floor(Math.random() * 256); + }, + randomizeEditForm() { + this.editForm.red = Math.floor(Math.random() * 256); + this.editForm.green = Math.floor(Math.random() * 256); + this.editForm.blue = Math.floor(Math.random() * 256); + }, + debugInfo() { + this.showDebug = !this.showDebug; + console.log('=== Vue Component Debug Info ==='); + console.log('Current tableData:', this.tableData); + console.log('tableData length:', this.tableData ? this.tableData.length : 'null/undefined'); + console.log('Total:', this.total); + console.log('Page:', this.page); + console.log('Table Loading:', this.tableLoading); + console.log('Show Debug:', this.showDebug); + console.log('Vue instance $el:', this.$el); + console.log('================================'); + + // 测试Vue响应性 + if (this.tableData && this.tableData.length === 0) { + console.log('测试:添加假数据'); + this.tableData = [ + {id: 999, red: 255, green: 0, blue: 0, addTime: new Date().toISOString(), lastUpdateTime: new Date().toISOString(), remark: 'test'} + ]; + this.total = 1; + setTimeout(() => { + console.log('2秒后清除假数据'); + this.tableData = []; + this.total = 0; + }, 2000); + } + } + } }); "; #endregion @@ -1232,224 +1232,224 @@ await service.post('/Admin/Template_XncfName/DatabaseSampleIndex?handler=Randomi /// 数据库示例索引页面CSS模板 /// 类型: frontend_style /// - public const string DatabaseSampleIndexCssTemplate = @"/* 通用样式 */ -.d-flex{ - display: flex; -} -.justify-content-between{ - justify-content: space-between; -} -.align-items-center{ - align-items: center; -} - -/* 过滤器容器样式 */ -.filter-container { - margin-bottom: 20px; - padding: 10px 0; -} - -.filter-container .el-button { - margin-right: 10px; -} - -/* 颜色预览样式 */ -.color-preview { - width: 100%; - height: 40px; - border-radius: 4px; - border: 1px solid #dcdfe6; - display: flex; - align-items: center; - justify-content: center; - color: white; - font-size: 12px; - font-weight: bold; - text-shadow: 1px 1px 2px rgba(0,0,0,0.5); -} - -.color-preview-large { - width: 100%; - height: 80px; - border-radius: 8px; - border: 2px solid #dcdfe6; - display: flex; - align-items: center; - justify-content: center; - color: white; - font-size: 16px; - font-weight: bold; - text-shadow: 2px 2px 4px rgba(0,0,0,0.7); - margin: 10px 0; - transition: all 0.3s ease; -} - -.color-preview-large:hover { - transform: scale(1.02); - box-shadow: 0 4px 12px rgba(0,0,0,0.15); -} - -/* 分页容器样式 */ -.pagination-container { - margin-top: 20px; - text-align: center; -} - -/* 表格样式增强 */ -.el-table { - border-radius: 8px; - overflow: hidden; - box-shadow: 0 2px 12px 0 rgba(0,0,0,0.1); -} - -.el-table th { - background-color: #fafafa; - color: #333; - font-weight: 600; -} - -/* 颜色标签样式 */ -.el-tag { - min-width: 50px; - text-align: center; - font-weight: bold; - border: none !important; - text-shadow: 1px 1px 2px rgba(0,0,0,0.5); -} - -/* 对话框样式 */ -.el-dialog { - border-radius: 12px; - overflow: hidden; -} - -.el-dialog__header { - background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); - color: white; - padding: 20px 20px 0 20px; -} - -.el-dialog__title { - color: white; - font-weight: 600; -} - -.el-dialog__body { - padding: 30px 20px; -} - -/* 滑块样式 */ -.el-slider { - margin: 20px 0; -} - -.el-slider__runway { - height: 6px; - background-color: #e4e7ed; - border-radius: 3px; -} - -.el-slider__button { - width: 20px; - height: 20px; - border: 2px solid #409eff; -} - -/* 按钮样式增强 */ -.el-button--mini { - padding: 5px 10px; - font-size: 12px; - border-radius: 4px; -} - -.el-button--primary { - background: linear-gradient(135deg, #409eff 0%, #3a8ee6 100%); - border: none; -} - -.el-button--success { - background: linear-gradient(135deg, #67c23a 0%, #5daf34 100%); - border: none; -} - -.el-button--warning { - background: linear-gradient(135deg, #e6a23c 0%, #cf9236 100%); - border: none; -} - -.el-button--danger { - background: linear-gradient(135deg, #f56c6c 0%, #f25c5c 100%); - border: none; -} - -.el-button--info { - background: linear-gradient(135deg, #909399 0%, #82848a 100%); - border: none; -} - -/* 表单项样式 */ -.el-form-item { - margin-bottom: 22px; -} - -.el-form-item__label { - font-weight: 600; - color: #333; -} - -/* 加载动画样式 */ -.el-loading-mask { - background-color: rgba(255, 255, 255, 0.9); -} - -/* 响应式设计 */ -@media (max-width: 768px) { - .filter-container { - text-align: center; - } - - .filter-container .el-button { - margin: 5px; - width: auto; - } - - .color-preview { - height: 30px; - font-size: 10px; - } - - .color-preview-large { - height: 60px; - font-size: 14px; - } -} - -/* 动画效果 */ -@keyframes fadeIn { - from { - opacity: 0; - transform: translateY(20px); - } - to { - opacity: 1; - transform: translateY(0); - } -} - -.el-table tbody tr { - animation: fadeIn 0.3s ease-out; -} - -/* 鼠标悬停效果 */ -.el-table tbody tr:hover { - background-color: #f5f7fa !important; - transition: background-color 0.3s ease; -} - -.el-button:hover { - transform: translateY(-1px); - box-shadow: 0 4px 8px rgba(0,0,0,0.15); - transition: all 0.3s ease; + public const string DatabaseSampleIndexCssTemplate = @"/* 通用样式 */ +.d-flex{ + display: flex; +} +.justify-content-between{ + justify-content: space-between; +} +.align-items-center{ + align-items: center; +} + +/* 过滤器容器样式 */ +.filter-container { + margin-bottom: 20px; + padding: 10px 0; +} + +.filter-container .el-button { + margin-right: 10px; +} + +/* 颜色预览样式 */ +.color-preview { + width: 100%; + height: 40px; + border-radius: 4px; + border: 1px solid #dcdfe6; + display: flex; + align-items: center; + justify-content: center; + color: white; + font-size: 12px; + font-weight: bold; + text-shadow: 1px 1px 2px rgba(0,0,0,0.5); +} + +.color-preview-large { + width: 100%; + height: 80px; + border-radius: 8px; + border: 2px solid #dcdfe6; + display: flex; + align-items: center; + justify-content: center; + color: white; + font-size: 16px; + font-weight: bold; + text-shadow: 2px 2px 4px rgba(0,0,0,0.7); + margin: 10px 0; + transition: all 0.3s ease; +} + +.color-preview-large:hover { + transform: scale(1.02); + box-shadow: 0 4px 12px rgba(0,0,0,0.15); +} + +/* 分页容器样式 */ +.pagination-container { + margin-top: 20px; + text-align: center; +} + +/* 表格样式增强 */ +.el-table { + border-radius: 8px; + overflow: hidden; + box-shadow: 0 2px 12px 0 rgba(0,0,0,0.1); +} + +.el-table th { + background-color: #fafafa; + color: #333; + font-weight: 600; +} + +/* 颜色标签样式 */ +.el-tag { + min-width: 50px; + text-align: center; + font-weight: bold; + border: none !important; + text-shadow: 1px 1px 2px rgba(0,0,0,0.5); +} + +/* 对话框样式 */ +.el-dialog { + border-radius: 12px; + overflow: hidden; +} + +.el-dialog__header { + background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); + color: white; + padding: 20px 20px 0 20px; +} + +.el-dialog__title { + color: white; + font-weight: 600; +} + +.el-dialog__body { + padding: 30px 20px; +} + +/* 滑块样式 */ +.el-slider { + margin: 20px 0; +} + +.el-slider__runway { + height: 6px; + background-color: #e4e7ed; + border-radius: 3px; +} + +.el-slider__button { + width: 20px; + height: 20px; + border: 2px solid #409eff; +} + +/* 按钮样式增强 */ +.el-button--mini { + padding: 5px 10px; + font-size: 12px; + border-radius: 4px; +} + +.el-button--primary { + background: linear-gradient(135deg, #409eff 0%, #3a8ee6 100%); + border: none; +} + +.el-button--success { + background: linear-gradient(135deg, #67c23a 0%, #5daf34 100%); + border: none; +} + +.el-button--warning { + background: linear-gradient(135deg, #e6a23c 0%, #cf9236 100%); + border: none; +} + +.el-button--danger { + background: linear-gradient(135deg, #f56c6c 0%, #f25c5c 100%); + border: none; +} + +.el-button--info { + background: linear-gradient(135deg, #909399 0%, #82848a 100%); + border: none; +} + +/* 表单项样式 */ +.el-form-item { + margin-bottom: 22px; +} + +.el-form-item__label { + font-weight: 600; + color: #333; +} + +/* 加载动画样式 */ +.el-loading-mask { + background-color: rgba(255, 255, 255, 0.9); +} + +/* 响应式设计 */ +@media (max-width: 768px) { + .filter-container { + text-align: center; + } + + .filter-container .el-button { + margin: 5px; + width: auto; + } + + .color-preview { + height: 30px; + font-size: 10px; + } + + .color-preview-large { + height: 60px; + font-size: 14px; + } +} + +/* 动画效果 */ +@keyframes fadeIn { + from { + opacity: 0; + transform: translateY(20px); + } + to { + opacity: 1; + transform: translateY(0); + } +} + +.el-table tbody tr { + animation: fadeIn 0.3s ease-out; +} + +/* 鼠标悬停效果 */ +.el-table tbody tr:hover { + background-color: #f5f7fa !important; + transition: background-color 0.3s ease; +} + +.el-button:hover { + transform: translateY(-1px); + box-shadow: 0 4px 8px rgba(0,0,0,0.15); + transition: all 0.3s ease; } "; #endregion From 895133520d474fc66da3c0d521c4cbc71f63d6ab Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 4 Apr 2026 10:56:00 +0000 Subject: [PATCH 3/5] revert: undo accidental auto-generated file changes Agent-Logs-Url: https://github.com/NeuCharFramework/NcfPackageSources/sessions/2b0ded12-8dc2-4c02-8ed9-a726706e8edb Co-authored-by: JeffreySu <2281927+JeffreySu@users.noreply.github.com> --- .../BuildXncfAppService.Generated.cs | 2728 ++++++++--------- 1 file changed, 1364 insertions(+), 1364 deletions(-) diff --git a/src/Extensions/Senparc.Xncf.XncfBuilder/Senparc.Xncf.XncfBuilder/Generated/Senparc.Xncf.XncfBuilder.DynamicContentGenerator/MultiFileCodeGenerator/BuildXncfAppService.Generated.cs b/src/Extensions/Senparc.Xncf.XncfBuilder/Senparc.Xncf.XncfBuilder/Generated/Senparc.Xncf.XncfBuilder.DynamicContentGenerator/MultiFileCodeGenerator/BuildXncfAppService.Generated.cs index f09d62519..fbd7b9527 100644 --- a/src/Extensions/Senparc.Xncf.XncfBuilder/Senparc.Xncf.XncfBuilder/Generated/Senparc.Xncf.XncfBuilder.DynamicContentGenerator/MultiFileCodeGenerator/BuildXncfAppService.Generated.cs +++ b/src/Extensions/Senparc.Xncf.XncfBuilder/Senparc.Xncf.XncfBuilder/Generated/Senparc.Xncf.XncfBuilder.DynamicContentGenerator/MultiFileCodeGenerator/BuildXncfAppService.Generated.cs @@ -14,73 +14,73 @@ namespace Senparc.Xncf.XncfBuilder.OHS.Local /// public partial class BuildXncfAppService { -public const string BackendTemplate = @$" -## Database EntityFramework DbContext class sample -File Name: Template_XncfNameSenparcEntities.cs -File Path: /Domain/Models/DatabaseModel -Code: -```csharp -{SenparcEntitiesTemplate} -``` - -## Database Entity class sample -File Name: Color.cs -File Path: /Domain/Models/DatabaseModel -Code: -```csharp -{ColorModelTemplate} -``` - -## Database Entity DTO class sample -File Name: ColorDto.cs -File Path: /Domain/Models/DatabaseModel/Dto -Code: -```csharp -{ColorDtoTemplate} -``` - -## Service class sample -File Name: Template_XncfNameService.cs -File Path: /Domain/Services -Code: -```csharp -{ColorServiceTemplate} -``` -"; - -public const string FrontendTemplate = @$" -## Page UI sample (front-end) -File Name: DatabaseSampleIndex.cshtml -File Path: < ModuleRootPath >/ Areas / Admin / Pages / Template_XncfName -Code: -```razorpage -{DatabaseSampleIndexViewTemplate} -``` - -## Page UI sample (back-end) -File Name: DatabaseSampleIndex.cshtml.cs -File Path: < ModuleRootPath >/ Areas / Admin / Pages / Template_XncfName -Code: -```csharp -{DatabaseSampleIndexCodeBehindTemplate} -``` - -## Page JavaScript file sample -File Name: databaseSampleIndex.js -File Path: < ModuleRootPath >/ wwwroot / js / Admin / Template_XncfName -Code: -```javascript -{DatabaseSampleIndexJsTemplate} -``` - -## Page CSS file sample -File Name: databaseSampleIndex.css -File Path: < ModuleRootPath >/ wwwroot / css / Admin / Template_XncfName -Code: -```css -{DatabaseSampleIndexCssTemplate} -``` -"; +public const string BackendTemplate = @$" +## Database EntityFramework DbContext class sample +File Name: Template_XncfNameSenparcEntities.cs +File Path: /Domain/Models/DatabaseModel +Code: +```csharp +{SenparcEntitiesTemplate} +``` + +## Database Entity class sample +File Name: Color.cs +File Path: /Domain/Models/DatabaseModel +Code: +```csharp +{ColorModelTemplate} +``` + +## Database Entity DTO class sample +File Name: ColorDto.cs +File Path: /Domain/Models/DatabaseModel/Dto +Code: +```csharp +{ColorDtoTemplate} +``` + +## Service class sample +File Name: Template_XncfNameService.cs +File Path: /Domain/Services +Code: +```csharp +{ColorServiceTemplate} +``` +"; + +public const string FrontendTemplate = @$" +## Page UI sample (front-end) +File Name: DatabaseSampleIndex.cshtml +File Path: < ModuleRootPath >/ Areas / Admin / Pages / Template_XncfName +Code: +```razorpage +{DatabaseSampleIndexViewTemplate} +``` + +## Page UI sample (back-end) +File Name: DatabaseSampleIndex.cshtml.cs +File Path: < ModuleRootPath >/ Areas / Admin / Pages / Template_XncfName +Code: +```csharp +{DatabaseSampleIndexCodeBehindTemplate} +``` + +## Page JavaScript file sample +File Name: databaseSampleIndex.js +File Path: < ModuleRootPath >/ wwwroot / js / Admin / Template_XncfName +Code: +```javascript +{DatabaseSampleIndexJsTemplate} +``` + +## Page CSS file sample +File Name: databaseSampleIndex.css +File Path: < ModuleRootPath >/ wwwroot / css / Admin / Template_XncfName +Code: +```css +{DatabaseSampleIndexCssTemplate} +``` +"; #region CODE Templates @@ -89,26 +89,26 @@ public partial class BuildXncfAppService /// 请求类代码 /// 类型: code /// - public const string RequestCode = @"using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Senparc.Xncf.XncfBuilder -{ - public class Request - { - public string? Method { get; set; } - public string? Path { get; set; } - public string? Body { get; set; } - - // 新增字段测试动态更新 - public Dictionary? Headers { get; set; } - public DateTime Timestamp { get; set; } = DateTime.Now; - } - -} + public const string RequestCode = @"using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Senparc.Xncf.XncfBuilder +{ + public class Request + { + public string? Method { get; set; } + public string? Path { get; set; } + public string? Body { get; set; } + + // 新增字段测试动态更新 + public Dictionary? Headers { get; set; } + public DateTime Timestamp { get; set; } = DateTime.Now; + } + +} "; #endregion @@ -119,237 +119,237 @@ public class Request /// Senparc实体类模板 /// 类型: backend_template /// - public const string SenparcEntitiesTemplate = @"using Microsoft.EntityFrameworkCore; -using Senparc.Ncf.Database; -using Senparc.Ncf.Core.Models; -using Senparc.Ncf.XncfBase.Database; - -namespace Template_OrgName.Xncf.Template_XncfName.Models -{ - public class Template_XncfNameSenparcEntities : XncfDatabaseDbContext - { - public Template_XncfNameSenparcEntities(DbContextOptions dbContextOptions) : base(dbContextOptions) - { - } - - public DbSet Colors { get; set; } - - //DOT REMOVE OR MODIFY THIS LINE 请勿移除或修改本行 - Entities Point - //ex. public DbSet Colors { get; set; } - - //如无特殊需需要,OnModelCreating 方法可以不用写,已经在 Register 中要求注册 - //protected override void OnModelCreating(ModelBuilder modelBuilder) - //{ - //} - } -} + public const string SenparcEntitiesTemplate = @"using Microsoft.EntityFrameworkCore; +using Senparc.Ncf.Database; +using Senparc.Ncf.Core.Models; +using Senparc.Ncf.XncfBase.Database; + +namespace Template_OrgName.Xncf.Template_XncfName.Models +{ + public class Template_XncfNameSenparcEntities : XncfDatabaseDbContext + { + public Template_XncfNameSenparcEntities(DbContextOptions dbContextOptions) : base(dbContextOptions) + { + } + + public DbSet Colors { get; set; } + + //DOT REMOVE OR MODIFY THIS LINE 请勿移除或修改本行 - Entities Point + //ex. public DbSet Colors { get; set; } + + //如无特殊需需要,OnModelCreating 方法可以不用写,已经在 Register 中要求注册 + //protected override void OnModelCreating(ModelBuilder modelBuilder) + //{ + //} + } +} "; /// /// 颜色模型模板 /// 类型: backend_template /// - public const string ColorModelTemplate = @"using Senparc.Ncf.Core.Models; -using Template_OrgName.Xncf.Template_XncfName.Domain.Models.DatabaseModel.Dto; -using System; -using System.ComponentModel.DataAnnotations.Schema; -using Template_OrgName.Xncf.Template_XncfName.Domain.Models.DatabaseModel.Dto; - -namespace Template_OrgName.Xncf.Template_XncfName -{ - /// - /// Color 实体类 - /// - [Table(Register.DATABASE_PREFIX + nameof(Color))]//必须添加前缀,防止全系统中发生冲突 - [Serializable] - public class Color : EntityBase - { - /// - /// 颜色码,0-255 - /// - public int Red { get; private set; } - /// - /// 颜色码,0-255 - /// - public int Green { get; private set; } - - /// - /// 颜色码,0-255 - /// - public int Blue { get; private set; } - - /// - /// 附加列,测试多次数据库 Migrate - /// - public string AdditionNote { get; private set; } - - private Color() { } - - public Color(int red, int green, int blue) - { - if (red < 0 || green < 0 || blue < 0) - { - Random();//随机 - } - else - { - Red = red; - Green = green; - Blue = blue; - } - } - - public Color(int red, int green, int blue, string additionNote) : this(red, green, blue) - { - AdditionNote = additionNote; - } - - public Color(ColorDto colorDto) - { - Red = colorDto.Red; - Green = colorDto.Green; - Blue = colorDto.Blue; - } - - public void Random() - { - //随机产生颜色代码 - var radom = new Random(); - Func getRadomColorCode = () => radom.Next(0, 255); - Red = getRadomColorCode(); - Green = getRadomColorCode(); - Blue = getRadomColorCode(); - } - - public void Brighten() - { - Red = Math.Min(255, Red + 10); - Green = Math.Min(255, Green + 10); - Blue = Math.Min(255, Blue + 10); - } - - public void Darken() - { - Red = Math.Max(0, Red - 10); - Green = Math.Max(0, Green - 10); - Blue = Math.Max(0, Blue - 10); - } - - public void Update(UpdateColorRequestDto dto) - { - Red = dto.Red; - Green = dto.Green; - Blue = dto.Blue; - AdditionNote = dto.AdditionNote; - } - } -} + public const string ColorModelTemplate = @"using Senparc.Ncf.Core.Models; +using Template_OrgName.Xncf.Template_XncfName.Domain.Models.DatabaseModel.Dto; +using System; +using System.ComponentModel.DataAnnotations.Schema; +using Template_OrgName.Xncf.Template_XncfName.Domain.Models.DatabaseModel.Dto; + +namespace Template_OrgName.Xncf.Template_XncfName +{ + /// + /// Color 实体类 + /// + [Table(Register.DATABASE_PREFIX + nameof(Color))]//必须添加前缀,防止全系统中发生冲突 + [Serializable] + public class Color : EntityBase + { + /// + /// 颜色码,0-255 + /// + public int Red { get; private set; } + /// + /// 颜色码,0-255 + /// + public int Green { get; private set; } + + /// + /// 颜色码,0-255 + /// + public int Blue { get; private set; } + + /// + /// 附加列,测试多次数据库 Migrate + /// + public string AdditionNote { get; private set; } + + private Color() { } + + public Color(int red, int green, int blue) + { + if (red < 0 || green < 0 || blue < 0) + { + Random();//随机 + } + else + { + Red = red; + Green = green; + Blue = blue; + } + } + + public Color(int red, int green, int blue, string additionNote) : this(red, green, blue) + { + AdditionNote = additionNote; + } + + public Color(ColorDto colorDto) + { + Red = colorDto.Red; + Green = colorDto.Green; + Blue = colorDto.Blue; + } + + public void Random() + { + //随机产生颜色代码 + var radom = new Random(); + Func getRadomColorCode = () => radom.Next(0, 255); + Red = getRadomColorCode(); + Green = getRadomColorCode(); + Blue = getRadomColorCode(); + } + + public void Brighten() + { + Red = Math.Min(255, Red + 10); + Green = Math.Min(255, Green + 10); + Blue = Math.Min(255, Blue + 10); + } + + public void Darken() + { + Red = Math.Max(0, Red - 10); + Green = Math.Max(0, Green - 10); + Blue = Math.Max(0, Blue - 10); + } + + public void Update(UpdateColorRequestDto dto) + { + Red = dto.Red; + Green = dto.Green; + Blue = dto.Blue; + AdditionNote = dto.AdditionNote; + } + } +} "; /// /// 颜色DTO模板 /// 类型: backend_template /// - public const string ColorDtoTemplate = @"using Senparc.Ncf.Core.Models; - -namespace Template_OrgName.Xncf.Template_XncfName.Domain.Models.DatabaseModel.Dto -{ - public class ColorDto : DtoBase - { - /// - /// 颜色码,0-255 - /// - public int Red { get; set; } - /// - /// 颜色码,0-255 - /// - public int Green { get; set; } - /// - /// 颜色码,0-255 - /// - public int Blue { get; set; } - - /// - /// 附加列,测试多次数据库 Migrate - /// - public string AdditionNote { get; set; } - - public ColorDto() { } - } -} + public const string ColorDtoTemplate = @"using Senparc.Ncf.Core.Models; + +namespace Template_OrgName.Xncf.Template_XncfName.Domain.Models.DatabaseModel.Dto +{ + public class ColorDto : DtoBase + { + /// + /// 颜色码,0-255 + /// + public int Red { get; set; } + /// + /// 颜色码,0-255 + /// + public int Green { get; set; } + /// + /// 颜色码,0-255 + /// + public int Blue { get; set; } + + /// + /// 附加列,测试多次数据库 Migrate + /// + public string AdditionNote { get; set; } + + public ColorDto() { } + } +} "; /// /// 颜色服务模板 /// 类型: backend_template /// - public const string ColorServiceTemplate = @"using Senparc.Ncf.Core.Enums; -using Senparc.Ncf.Repository; -using Senparc.Ncf.Service; -using Template_OrgName.Xncf.Template_XncfName.Domain.Models.DatabaseModel.Dto; -using System; -using System.Threading.Tasks; - -namespace Template_OrgName.Xncf.Template_XncfName.Domain.Services -{ - public class ColorService : ServiceBase - { - public ColorService(IRepositoryBase repo, IServiceProvider serviceProvider) - : base(repo, serviceProvider) - { - } - - public async Task CreateNewColor() - { - Color color = new Color(-1, -1, -1); - await base.SaveObjectAsync(color).ConfigureAwait(false); - ColorDto colorDto = base.Mapper.Map(color); - return colorDto; - } - - public async Task GetOrInitColor() - { - var color = await base.GetObjectAsync(z => true); - if (color == null)//如果是纯第一次安装,理论上不会有残留数据 - { - //创建默认颜色 - ColorDto colorDto = await this.CreateNewColor().ConfigureAwait(false); - return colorDto; - } - - return base.Mapper.Map(color); - } - - public async Task Brighten() - { - //TODO:异步方法需要添加排序功能 - var obj = await this.GetObjectAsync(z => true, z => z.Id, OrderingType.Descending); - obj.Brighten(); - await base.SaveObjectAsync(obj).ConfigureAwait(false); - return base.Mapper.Map(obj); - } - - public async Task Darken() - { - //TODO:异步方法需要添加排序功能 - var obj = await this.GetObjectAsync(z => true, z => z.Id, OrderingType.Descending); - obj.Darken(); - await base.SaveObjectAsync(obj).ConfigureAwait(false); - return base.Mapper.Map(obj); - } - - public async Task Random() - { - //TODO:异步方法需要添加排序功能 - var obj = await this.GetObjectAsync(z => true, z => z.Id, OrderingType.Descending); - obj.Random(); - await base.SaveObjectAsync(obj).ConfigureAwait(false); - return base.Mapper.Map(obj); - } - - //TODO: 更多业务方法可以写到这里 - } -} + public const string ColorServiceTemplate = @"using Senparc.Ncf.Core.Enums; +using Senparc.Ncf.Repository; +using Senparc.Ncf.Service; +using Template_OrgName.Xncf.Template_XncfName.Domain.Models.DatabaseModel.Dto; +using System; +using System.Threading.Tasks; + +namespace Template_OrgName.Xncf.Template_XncfName.Domain.Services +{ + public class ColorService : ServiceBase + { + public ColorService(IRepositoryBase repo, IServiceProvider serviceProvider) + : base(repo, serviceProvider) + { + } + + public async Task CreateNewColor() + { + Color color = new Color(-1, -1, -1); + await base.SaveObjectAsync(color).ConfigureAwait(false); + ColorDto colorDto = base.Mapper.Map(color); + return colorDto; + } + + public async Task GetOrInitColor() + { + var color = await base.GetObjectAsync(z => true); + if (color == null)//如果是纯第一次安装,理论上不会有残留数据 + { + //创建默认颜色 + ColorDto colorDto = await this.CreateNewColor().ConfigureAwait(false); + return colorDto; + } + + return base.Mapper.Map(color); + } + + public async Task Brighten() + { + //TODO:异步方法需要添加排序功能 + var obj = await this.GetObjectAsync(z => true, z => z.Id, OrderingType.Descending); + obj.Brighten(); + await base.SaveObjectAsync(obj).ConfigureAwait(false); + return base.Mapper.Map(obj); + } + + public async Task Darken() + { + //TODO:异步方法需要添加排序功能 + var obj = await this.GetObjectAsync(z => true, z => z.Id, OrderingType.Descending); + obj.Darken(); + await base.SaveObjectAsync(obj).ConfigureAwait(false); + return base.Mapper.Map(obj); + } + + public async Task Random() + { + //TODO:异步方法需要添加排序功能 + var obj = await this.GetObjectAsync(z => true, z => z.Id, OrderingType.Descending); + obj.Random(); + await base.SaveObjectAsync(obj).ConfigureAwait(false); + return base.Mapper.Map(obj); + } + + //TODO: 更多业务方法可以写到这里 + } +} "; #endregion @@ -360,431 +360,431 @@ public async Task Random() /// 数据库示例索引页面视图模板 /// 类型: frontend_template /// - public const string DatabaseSampleIndexViewTemplate = @"@page -@model Template_OrgName.Xncf.Template_XncfName.Areas.Template_XncfName.Pages.DatabaseSampleIndex -@{ - ViewData[""Title""] = ""Color 数据库管理""; - Layout = ""_Layout_Vue""; -} - -@section Style { - -} - -@section breadcrumbs { - 扩展模块 - Template_MenuName - Color 数据库管理 -} - -
-
- 添加颜色 - 刷新 - 调试信息 -
- - -
-

调试信息:

-

tableData长度: {{ tableData ? tableData.length : 'null/undefined' }}

-

total: {{ total }}

-

tableLoading: {{ tableLoading }}

-

Vue实例是否正常: {{ $el ? '是' : '否' }}

-
0""> - 第一条数据: -
{{ JSON.stringify(tableData[0], null, 2) }}
-
- - -
-
简化数据显示测试:
-
- ID: {{item.id}} | - RGB: {{item.red}},{{item.green}},{{item.blue}} | - 时间: {{item.addTime}} -
-

- 没有数据显示! -

-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - -
- - -
- - @* dialog for 添加颜色 *@ - - - - - - - - - - - - -
- RGB({{addForm.red}}, {{addForm.green}}, {{addForm.blue}}) -
-
- - - - - 随机颜色 - -
- - 取 消 - 确 定 - -
- - @* dialog for 编辑颜色 *@ - - - - - - - - - - - - -
- RGB({{editForm.red}}, {{editForm.green}}, {{editForm.blue}}) -
-
- - - - - 随机颜色 - -
- - 取 消 - 确 定 - -
-
- -@section scripts{ - + public const string DatabaseSampleIndexViewTemplate = @"@page +@model Template_OrgName.Xncf.Template_XncfName.Areas.Template_XncfName.Pages.DatabaseSampleIndex +@{ + ViewData[""Title""] = ""Color 数据库管理""; + Layout = ""_Layout_Vue""; +} + +@section Style { + +} + +@section breadcrumbs { + 扩展模块 + Template_MenuName + Color 数据库管理 +} + +
+
+ 添加颜色 + 刷新 + 调试信息 +
+ + +
+

调试信息:

+

tableData长度: {{ tableData ? tableData.length : 'null/undefined' }}

+

total: {{ total }}

+

tableLoading: {{ tableLoading }}

+

Vue实例是否正常: {{ $el ? '是' : '否' }}

+
0""> + 第一条数据: +
{{ JSON.stringify(tableData[0], null, 2) }}
+
+ + +
+
简化数据显示测试:
+
+ ID: {{item.id}} | + RGB: {{item.red}},{{item.green}},{{item.blue}} | + 时间: {{item.addTime}} +
+

+ 没有数据显示! +

+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ + @* dialog for 添加颜色 *@ + + + + + + + + + + + + +
+ RGB({{addForm.red}}, {{addForm.green}}, {{addForm.blue}}) +
+
+ + + + + 随机颜色 + +
+ + 取 消 + 确 定 + +
+ + @* dialog for 编辑颜色 *@ + + + + + + + + + + + + +
+ RGB({{editForm.red}}, {{editForm.green}}, {{editForm.blue}}) +
+
+ + + + + 随机颜色 + +
+ + 取 消 + 确 定 + +
+
+ +@section scripts{ + } "; /// /// 数据库示例索引页面代码后置模板 /// 类型: frontend_template /// - public const string DatabaseSampleIndexCodeBehindTemplate = @"using Microsoft.AspNetCore.Mvc; -using Senparc.Ncf.Service; -using Senparc.Ncf.Utility; -using Template_OrgName.Xncf.Template_XncfName.Domain.Services; -using System; -using System.Linq; -using System.Threading.Tasks; -using Template_OrgName.Xncf.Template_XncfName.Domain.Models.DatabaseModel.Dto; - -namespace Template_OrgName.Xncf.Template_XncfName.Areas.Template_XncfName.Pages -{ - public class DatabaseSampleIndex : Senparc.Ncf.AreaBase.Admin.AdminXncfModulePageModelBase - { - private readonly ColorService _colorService; - - public DatabaseSampleIndex(Lazy xncfModuleService, ColorService colorService) : base(xncfModuleService) - { - _colorService = colorService; - } - - public void OnGet() - { - } - - /// - /// 获取颜色列表(分页) - /// - /// 关键词 - /// 排序字段 - /// 页码 - /// 页大小 - /// - public async Task OnGetColorListAsync(string keyword, string orderField, int pageIndex, int pageSize) - { - try - { - // 调试信息 - System.Diagnostics.Debug.WriteLine($""ColorList API Called - PageIndex: {pageIndex}, PageSize: {pageSize}, OrderField: {orderField}""); - - var seh = new SenparcExpressionHelper(); - // 可以根据需要添加搜索条件 - // seh.ValueCompare.AndAlso(!string.IsNullOrEmpty(keyword), _ => _.Remark.Contains(keyword)); - var where = seh.BuildWhereExpression(); - var response = await _colorService.GetObjectListAsync(pageIndex, pageSize, where, orderField ?? ""Id desc""); - - // 调试信息 - System.Diagnostics.Debug.WriteLine($""Database Query Result - TotalCount: {response.TotalCount}, ItemCount: {response.Count()}""); - - var result = new - { - success = true, - message = ""数据获取成功"", - data = new { - totalCount = response.TotalCount, - pageIndex = response.PageIndex, - list = response.Select(_ => new - { - id = _.Id, - red = _.Red, - green = _.Green, - blue = _.Blue, - additionNote = _.AdditionNote, - addTime = _.AddTime, - lastUpdateTime = _.LastUpdateTime, - remark = _.Remark - }).ToList() - } - }; - - // 调试信息 - System.Diagnostics.Debug.WriteLine($""API Response - ListCount: {result.data.list.Count}""); - - return Ok(result); - } - catch (Exception ex) - { - System.Diagnostics.Debug.WriteLine($""ColorList API Error: {ex.Message}""); - return Ok(new { - success = false, - message = ""获取数据失败: "" + ex.Message, - totalCount = 0, - pageIndex = pageIndex, - list = new object[0] - }); - } - } - - /// - /// 创建新颜色 - /// - /// 创建颜色请求 - /// - public async Task OnPostCreateColorAsync([FromBody] CreateColorRequestDto request) - { - try - { - // 调试信息 - System.Diagnostics.Debug.WriteLine($""CreateColor API Called - Red: {request.Red}, Green: {request.Green}, Blue: {request.Blue}, AdditionNote: {request.AdditionNote}""); - - if (request == null) - { - return Ok(new { success = false, message = ""请求参数不能为空"" }); - } - - var color = new Color(request.Red, request.Green, request.Blue, request.AdditionNote); - await _colorService.SaveObjectAsync(color); - - return Ok(new { success = true, message = ""颜色创建成功"", data = new { color.Id, color.Red, color.Green, color.Blue, color.AdditionNote, color.AddTime, color.LastUpdateTime } }); - } - catch (Exception ex) - { - System.Diagnostics.Debug.WriteLine($""CreateColor API Error: {ex.Message}""); - return Ok(new { success = false, message = ""创建失败:"" + ex.Message }); - } - } - - /// - /// 更新颜色 - /// - /// 更新颜色请求 - /// - public async Task OnPostUpdateColorAsync([FromBody] UpdateColorRequestDto request) - { - try - { - // 调试信息 - System.Diagnostics.Debug.WriteLine($""UpdateColor API Called - Id: {request.Id}, Red: {request.Red}, Green: {request.Green}, Blue: {request.Blue}, AdditionNote: {request.AdditionNote}""); - - if (request == null) - { - return Ok(new { success = false, message = ""请求参数不能为空"" }); - } - - var color = await _colorService.GetObjectAsync(c => c.Id == request.Id); - if (color == null) - { - return Ok(new { success = false, message = ""颜色不存在"" }); - } - - // 更新 - color.Update(request); - - await _colorService.SaveObjectAsync(color); - - return Ok(new { success = true, message = ""颜色更新成功"", data = new { color.Id, color.Red, color.Green, color.Blue, color.AdditionNote, color.LastUpdateTime } }); - } - catch (Exception ex) - { - System.Diagnostics.Debug.WriteLine($""UpdateColor API Error: {ex.Message}""); - return Ok(new { success = false, message = ""更新失败:"" + ex.Message }); - } - } - - /// - /// 删除颜色 - /// - /// 删除颜色请求 - /// - public async Task OnPostDeleteColorAsync([FromBody] DeleteColorRequestDto request) - { - try - { - // 调试信息 - System.Diagnostics.Debug.WriteLine($""DeleteColor API Called - Id: {request.Id}""); - - if (request == null) - { - return Ok(new { success = false, message = ""请求参数不能为空"" }); - } - - var color = await _colorService.GetObjectAsync(c => c.Id == request.Id); - if (color == null) - { - return Ok(new { success = false, message = ""颜色不存在"" }); - } - - await _colorService.DeleteObjectAsync(color); - return Ok(new { success = true, message = ""颜色删除成功"" }); - } - catch (Exception ex) - { - System.Diagnostics.Debug.WriteLine($""DeleteColor API Error: {ex.Message}""); - return Ok(new { success = false, message = ""删除失败:"" + ex.Message }); - } - } - - /// - /// 随机化指定颜色 - /// - /// 随机化颜色请求 - /// - public async Task OnPostRandomizeColorAsync([FromBody] RandomizeColorRequestDto request) - { - try - { - // 调试信息 - System.Diagnostics.Debug.WriteLine($""RandomizeColor API Called - Id: {request.Id}""); - - if (request == null) - { - return Ok(new { success = false, message = ""请求参数不能为空"" }); - } - - var color = await _colorService.GetObjectAsync(c => c.Id == request.Id); - if (color == null) - { - return Ok(new { success = false, message = ""颜色不存在"" }); - } - - color.Random(); - await _colorService.SaveObjectAsync(color); - - return Ok(new { success = true, message = ""颜色随机化成功"", data = new { color.Id, color.Red, color.Green, color.Blue, color.AdditionNote, color.LastUpdateTime } }); - } - catch (Exception ex) - { - System.Diagnostics.Debug.WriteLine($""RandomizeColor API Error: {ex.Message}""); - return Ok(new { success = false, message = ""随机化失败:"" + ex.Message }); - } - } - - /// - /// 获取颜色详情 - /// - /// 颜色ID - /// - public async Task OnGetColorDetailAsync(int id) - { - try - { - var color = await _colorService.GetObjectAsync(c => c.Id == id); - if (color == null) - { - return Ok(new { success = false, message = ""颜色不存在"" }); - } - - return Ok(new { success = true, data = new { color.Id, color.Red, color.Green, color.Blue, color.AdditionNote, color.AddTime, color.LastUpdateTime, color.Remark } }); - } - catch (Exception ex) - { - return Ok(new { success = false, message = ""获取失败:"" + ex.Message }); - } - } - } + public const string DatabaseSampleIndexCodeBehindTemplate = @"using Microsoft.AspNetCore.Mvc; +using Senparc.Ncf.Service; +using Senparc.Ncf.Utility; +using Template_OrgName.Xncf.Template_XncfName.Domain.Services; +using System; +using System.Linq; +using System.Threading.Tasks; +using Template_OrgName.Xncf.Template_XncfName.Domain.Models.DatabaseModel.Dto; + +namespace Template_OrgName.Xncf.Template_XncfName.Areas.Template_XncfName.Pages +{ + public class DatabaseSampleIndex : Senparc.Ncf.AreaBase.Admin.AdminXncfModulePageModelBase + { + private readonly ColorService _colorService; + + public DatabaseSampleIndex(Lazy xncfModuleService, ColorService colorService) : base(xncfModuleService) + { + _colorService = colorService; + } + + public void OnGet() + { + } + + /// + /// 获取颜色列表(分页) + /// + /// 关键词 + /// 排序字段 + /// 页码 + /// 页大小 + /// + public async Task OnGetColorListAsync(string keyword, string orderField, int pageIndex, int pageSize) + { + try + { + // 调试信息 + System.Diagnostics.Debug.WriteLine($""ColorList API Called - PageIndex: {pageIndex}, PageSize: {pageSize}, OrderField: {orderField}""); + + var seh = new SenparcExpressionHelper(); + // 可以根据需要添加搜索条件 + // seh.ValueCompare.AndAlso(!string.IsNullOrEmpty(keyword), _ => _.Remark.Contains(keyword)); + var where = seh.BuildWhereExpression(); + var response = await _colorService.GetObjectListAsync(pageIndex, pageSize, where, orderField ?? ""Id desc""); + + // 调试信息 + System.Diagnostics.Debug.WriteLine($""Database Query Result - TotalCount: {response.TotalCount}, ItemCount: {response.Count()}""); + + var result = new + { + success = true, + message = ""数据获取成功"", + data = new { + totalCount = response.TotalCount, + pageIndex = response.PageIndex, + list = response.Select(_ => new + { + id = _.Id, + red = _.Red, + green = _.Green, + blue = _.Blue, + additionNote = _.AdditionNote, + addTime = _.AddTime, + lastUpdateTime = _.LastUpdateTime, + remark = _.Remark + }).ToList() + } + }; + + // 调试信息 + System.Diagnostics.Debug.WriteLine($""API Response - ListCount: {result.data.list.Count}""); + + return Ok(result); + } + catch (Exception ex) + { + System.Diagnostics.Debug.WriteLine($""ColorList API Error: {ex.Message}""); + return Ok(new { + success = false, + message = ""获取数据失败: "" + ex.Message, + totalCount = 0, + pageIndex = pageIndex, + list = new object[0] + }); + } + } + + /// + /// 创建新颜色 + /// + /// 创建颜色请求 + /// + public async Task OnPostCreateColorAsync([FromBody] CreateColorRequestDto request) + { + try + { + // 调试信息 + System.Diagnostics.Debug.WriteLine($""CreateColor API Called - Red: {request.Red}, Green: {request.Green}, Blue: {request.Blue}, AdditionNote: {request.AdditionNote}""); + + if (request == null) + { + return Ok(new { success = false, message = ""请求参数不能为空"" }); + } + + var color = new Color(request.Red, request.Green, request.Blue, request.AdditionNote); + await _colorService.SaveObjectAsync(color); + + return Ok(new { success = true, message = ""颜色创建成功"", data = new { color.Id, color.Red, color.Green, color.Blue, color.AdditionNote, color.AddTime, color.LastUpdateTime } }); + } + catch (Exception ex) + { + System.Diagnostics.Debug.WriteLine($""CreateColor API Error: {ex.Message}""); + return Ok(new { success = false, message = ""创建失败:"" + ex.Message }); + } + } + + /// + /// 更新颜色 + /// + /// 更新颜色请求 + /// + public async Task OnPostUpdateColorAsync([FromBody] UpdateColorRequestDto request) + { + try + { + // 调试信息 + System.Diagnostics.Debug.WriteLine($""UpdateColor API Called - Id: {request.Id}, Red: {request.Red}, Green: {request.Green}, Blue: {request.Blue}, AdditionNote: {request.AdditionNote}""); + + if (request == null) + { + return Ok(new { success = false, message = ""请求参数不能为空"" }); + } + + var color = await _colorService.GetObjectAsync(c => c.Id == request.Id); + if (color == null) + { + return Ok(new { success = false, message = ""颜色不存在"" }); + } + + // 更新 + color.Update(request); + + await _colorService.SaveObjectAsync(color); + + return Ok(new { success = true, message = ""颜色更新成功"", data = new { color.Id, color.Red, color.Green, color.Blue, color.AdditionNote, color.LastUpdateTime } }); + } + catch (Exception ex) + { + System.Diagnostics.Debug.WriteLine($""UpdateColor API Error: {ex.Message}""); + return Ok(new { success = false, message = ""更新失败:"" + ex.Message }); + } + } + + /// + /// 删除颜色 + /// + /// 删除颜色请求 + /// + public async Task OnPostDeleteColorAsync([FromBody] DeleteColorRequestDto request) + { + try + { + // 调试信息 + System.Diagnostics.Debug.WriteLine($""DeleteColor API Called - Id: {request.Id}""); + + if (request == null) + { + return Ok(new { success = false, message = ""请求参数不能为空"" }); + } + + var color = await _colorService.GetObjectAsync(c => c.Id == request.Id); + if (color == null) + { + return Ok(new { success = false, message = ""颜色不存在"" }); + } + + await _colorService.DeleteObjectAsync(color); + return Ok(new { success = true, message = ""颜色删除成功"" }); + } + catch (Exception ex) + { + System.Diagnostics.Debug.WriteLine($""DeleteColor API Error: {ex.Message}""); + return Ok(new { success = false, message = ""删除失败:"" + ex.Message }); + } + } + + /// + /// 随机化指定颜色 + /// + /// 随机化颜色请求 + /// + public async Task OnPostRandomizeColorAsync([FromBody] RandomizeColorRequestDto request) + { + try + { + // 调试信息 + System.Diagnostics.Debug.WriteLine($""RandomizeColor API Called - Id: {request.Id}""); + + if (request == null) + { + return Ok(new { success = false, message = ""请求参数不能为空"" }); + } + + var color = await _colorService.GetObjectAsync(c => c.Id == request.Id); + if (color == null) + { + return Ok(new { success = false, message = ""颜色不存在"" }); + } + + color.Random(); + await _colorService.SaveObjectAsync(color); + + return Ok(new { success = true, message = ""颜色随机化成功"", data = new { color.Id, color.Red, color.Green, color.Blue, color.AdditionNote, color.LastUpdateTime } }); + } + catch (Exception ex) + { + System.Diagnostics.Debug.WriteLine($""RandomizeColor API Error: {ex.Message}""); + return Ok(new { success = false, message = ""随机化失败:"" + ex.Message }); + } + } + + /// + /// 获取颜色详情 + /// + /// 颜色ID + /// + public async Task OnGetColorDetailAsync(int id) + { + try + { + var color = await _colorService.GetObjectAsync(c => c.Id == id); + if (color == null) + { + return Ok(new { success = false, message = ""颜色不存在"" }); + } + + return Ok(new { success = true, data = new { color.Id, color.Red, color.Green, color.Blue, color.AdditionNote, color.AddTime, color.LastUpdateTime, color.Remark } }); + } + catch (Exception ex) + { + return Ok(new { success = false, message = ""获取失败:"" + ex.Message }); + } + } + } } "; #endregion @@ -795,433 +795,433 @@ public async Task OnGetColorDetailAsync(int id) /// 数据库示例索引页面JavaScript模板 /// 类型: frontend_script /// - public const string DatabaseSampleIndexJsTemplate = @"var app = new Vue({ - el: ""#app"", - data() { - return { - page: { - page: 1, - size: 10 - }, - tableLoading: true, - tableData: [], - showDebug: false, - addFormDialogVisible: false, - addForm: { - red: 128, - green: 128, - blue: 128, - additionNote: '' - }, - editFormDialogVisible: false, - editForm: { - id: 0, - red: 128, - green: 128, - blue: 128, - additionNote: '' - }, - total: 0, - addRules: { - red: [ - { required: true, message: '请设置红色值', trigger: 'change' }, - { type: 'number', min: 0, max: 255, message: '红色值范围为0-255', trigger: 'change' } - ], - green: [ - { required: true, message: '请设置绿色值', trigger: 'change' }, - { type: 'number', min: 0, max: 255, message: '绿色值范围为0-255', trigger: 'change' } - ], - blue: [ - { required: true, message: '请设置蓝色值', trigger: 'change' }, - { type: 'number', min: 0, max: 255, message: '蓝色值范围为0-255', trigger: 'change' } - ] - }, - editRules: { - red: [ - { required: true, message: '请设置红色值', trigger: 'change' }, - { type: 'number', min: 0, max: 255, message: '红色值范围为0-255', trigger: 'change' } - ], - green: [ - { required: true, message: '请设置绿色值', trigger: 'change' }, - { type: 'number', min: 0, max: 255, message: '绿色值范围为0-255', trigger: 'change' } - ], - blue: [ - { required: true, message: '请设置蓝色值', trigger: 'change' }, - { type: 'number', min: 0, max: 255, message: '蓝色值范围为0-255', trigger: 'change' } - ] - } - } - }, - mounted() { - //wait page load - setTimeout(async () => { - await this.init(); - }, 100) - }, - methods: { - async init() { - await this.getDataList(); - }, - async handleSizeChange(val) { - this.page.size = val; - await this.getDataList(); - }, - async handleCurrentChange(val) { - this.page.page = val; - await this.getDataList(); - }, - async getDataList() { - this.tableLoading = true - await service.get('/Admin/Template_XncfName/DatabaseSampleIndex?handler=ColorList', { - params: { - pageIndex: this.page.page, - pageSize: this.page.size, - orderField: ""Id desc"", - keyword: """" - } - }) - .then(res => { - console.log('=== API Response Debug ==='); - console.log('Complete Response:', res); - console.log('Response Data:', res.data); - console.log('Response Data Type:', typeof res.data); - console.log('Has res.data.data?:', res.data && res.data.data); - console.log('Has res.data.data.list?:', res.data && res.data.data && res.data.data.list); - console.log('res.data.data.list value:', res.data && res.data.data ? res.data.data.list : 'nested data not found'); - console.log('=================='); - - // 尝试多种可能的数据结构 - let dataList = null; - let totalCount = 0; - let dataSource = ''; - - if (res.data && res.data.data && res.data.data.data && res.data.data.data.list) { - // NCF框架标准格式 + 新的API格式: {data: {data: {success, message, data: {list, totalCount}}}} - dataList = res.data.data.data.list; - totalCount = res.data.data.data.totalCount || 0; - dataSource = 'NCF标准格式: res.data.data.data.list'; - console.log('✅ 使用NCF标准格式: res.data.data.data.list'); - console.log('✅ List数据:', dataList); - console.log('✅ TotalCount:', totalCount); - } else if (res.data && res.data.data && res.data.data.list) { - // 简单格式: {data: {list, totalCount}} - dataList = res.data.data.list; - totalCount = res.data.data.totalCount || 0; - dataSource = '简单格式: res.data.data.list'; - console.log('✅ 使用简单格式: res.data.data.list'); - } else if (res.data && Array.isArray(res.data)) { - // 如果data直接是数组 - dataList = res.data; - totalCount = res.data.length; - dataSource = '数组格式: res.data (array)'; - console.log('✅ 使用数组格式: res.data (array)'); - } else if (res && res.list) { - // 如果list在顶层 - dataList = res.list; - totalCount = res.totalCount || 0; - dataSource = '顶层格式: res.list'; - console.log('✅ 使用顶层格式: res.list'); - } else { - console.error('❌ 无法识别的数据格式:', res); - console.log('🔍 尝试的路径:'); - console.log('- res.data.data.list:', res.data && res.data.data ? res.data.data.list : 'not found'); - console.log('- res.data.list:', res.data ? res.data.list : 'not found'); - console.log('- res.data (array):', res.data && Array.isArray(res.data) ? 'is array' : 'not array'); - console.log('- res.list:', res.list ? res.list : 'not found'); - dataList = []; - totalCount = 0; - dataSource = '无法识别格式'; - } - - console.log('🎯 Final dataList:', dataList); - console.log('🎯 Final totalCount:', totalCount); - console.log('🎯 Data source:', dataSource); - - // 数据赋值前的状态 - console.log('📋 赋值前 tableData:', this.tableData); - console.log('📋 赋值前 total:', this.total); - - this.tableData = dataList || []; - this.total = totalCount; - - // 数据赋值后的状态 - console.log('📋 赋值后 tableData:', this.tableData); - console.log('📋 赋值后 tableData.length:', this.tableData.length); - console.log('📋 赋值后 total:', this.total); - - // 强制Vue更新 - this.$forceUpdate(); - console.log('🔄 Vue已强制更新'); - - // 延迟检查数据是否正确绑定 - setTimeout(() => { - console.log('⏰ 延迟检查 tableData:', this.tableData); - console.log('⏰ 延迟检查 tableData.length:', this.tableData ? this.tableData.length : 'null'); - }, 100); - - this.tableLoading = false - }) - .catch(error => { - console.error('获取数据失败:', error); - this.tableLoading = false; - this.$message.error('获取数据失败: ' + (error.message || error)); - }); - }, - addColor() { - this.addFormDialogVisible = true; - }, - refreshList() { - this.getDataList(); - }, - async addColorSubmit() { - this.$refs.addForm.validate(async (valid) => { - if (valid) { - console.log('📤 发送创建请求:', { - red: this.addForm.red, - green: this.addForm.green, - blue: this.addForm.blue, - additionNote: this.addForm.additionNote - }); - - await service.post('/Admin/Template_XncfName/DatabaseSampleIndex?handler=CreateColor', { - red: this.addForm.red, - green: this.addForm.green, - blue: this.addForm.blue, - additionNote: this.addForm.additionNote - }, { - headers: { - 'Content-Type': 'application/json' - } - }) - .then(res => { - console.log('📥 创建响应:', res); - // 兼容NCF框架的嵌套响应格式 - const responseData = res.data.data || res.data; - this.$message({ - type: responseData.success ? 'success' : 'error', - message: responseData.message || '操作完成' - }); - if (responseData.success) { - this.getDataList() - this.clearAddForm() - this.addFormDialogVisible = false; - } - }) - .catch(error => { - console.error('创建失败:', error); - this.$message.error('创建失败'); - }); - } else { - return false; - } - }); - }, - clearAddForm() { - this.addForm = { - red: 128, - green: 128, - blue: 128, - additionNote: '' - }; - if (this.$refs.addForm) { - this.$refs.addForm.resetFields(); - } - }, - clearEditForm() { - this.editForm = { - id: 0, - red: 128, - green: 128, - blue: 128, - additionNote: '' - }; - if (this.$refs.editForm) { - this.$refs.editForm.resetFields(); - } - }, - async editColorSubmit() { - this.$refs.editForm.validate(async (valid) => { - if (valid) { - console.log('📤 发送更新请求:', { - id: this.editForm.id, - red: this.editForm.red, - green: this.editForm.green, - blue: this.editForm.blue, - additionNote: this.editForm.additionNote - }); - - await service.post('/Admin/Template_XncfName/DatabaseSampleIndex?handler=UpdateColor', { - id: this.editForm.id, - red: this.editForm.red, - green: this.editForm.green, - blue: this.editForm.blue, - additionNote: this.editForm.additionNote - }, { - headers: { - 'Content-Type': 'application/json' - } - }) - .then(res => { - console.log('📥 更新响应:', res); - // 兼容NCF框架的嵌套响应格式 - const responseData = res.data.data || res.data; - this.$message({ - type: responseData.success ? 'success' : 'error', - message: responseData.message || '操作完成' - }); - if (responseData.success) { - this.getDataList() - this.clearEditForm() - this.editFormDialogVisible = false; - } - }) - .catch(error => { - console.error('更新失败:', error); - this.$message.error('更新失败'); - }); - } else { - return false; - } - }); - }, - dateformatter(date) { - if (!date) return ''; - - try { - // 使用原生JavaScript格式化日期 - const d = new Date(date); - - // 检查日期是否有效 - if (isNaN(d.getTime())) { - return date; // 如果无法解析,返回原始值 - } - - // 格式化为 YYYY-MM-DD HH:mm:ss - const year = d.getFullYear(); - const month = String(d.getMonth() + 1).padStart(2, '0'); - const day = String(d.getDate()).padStart(2, '0'); - const hours = String(d.getHours()).padStart(2, '0'); - const minutes = String(d.getMinutes()).padStart(2, '0'); - const seconds = String(d.getSeconds()).padStart(2, '0'); - - return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`; - } catch (error) { - console.warn('日期格式化错误:', error, '原始值:', date); - return date; // 如果格式化失败,返回原始值 - } - }, - editColor(row) { - this.editForm = { - id: row.id, - red: row.red, - green: row.green, - blue: row.blue, - additionNote: row.additionNote || '' - }; - this.editFormDialogVisible = true; - }, - deleteColor(row) { - this.$confirm('此操作将永久删除该颜色, 是否继续?', '提示', { - confirmButtonText: '确定', - cancelButtonText: '取消', - type: 'warning' - }).then(async () => { - console.log('📤 发送删除请求:', { id: row.id }); - - await service.post('/Admin/Template_XncfName/DatabaseSampleIndex?handler=DeleteColor', { - id: row.id - }, { - headers: { - 'Content-Type': 'application/json' - } - }) - .then(res => { - console.log('📥 删除响应:', res); - // 兼容NCF框架的嵌套响应格式 - const responseData = res.data.data || res.data; - this.$message({ - type: responseData.success ? 'success' : 'error', - message: responseData.message || '操作完成' - }); - if (responseData.success) { - this.getDataList(); - } - }) - .catch(error => { - console.error('删除失败:', error); - this.$message.error('删除失败'); - }); - }).catch(() => { - this.$message({ - type: 'info', - message: '已取消删除' - }); - }); - }, - async randomizeColor(row) { - console.log('📤 发送随机化请求:', { id: row.id }); - - await service.post('/Admin/Template_XncfName/DatabaseSampleIndex?handler=RandomizeColor', { - id: row.id - }, { - headers: { - 'Content-Type': 'application/json' - } - }) - .then(res => { - console.log('📥 随机化响应:', res); - // 兼容NCF框架的嵌套响应格式 - const responseData = res.data.data || res.data; - this.$message({ - type: responseData.success ? 'success' : 'error', - message: responseData.message || '操作完成' - }); - if (responseData.success) { - this.getDataList(); - } - }) - .catch(error => { - console.error('随机化失败:', error); - this.$message.error('随机化失败'); - }); - }, - randomizeForm() { - this.addForm.red = Math.floor(Math.random() * 256); - this.addForm.green = Math.floor(Math.random() * 256); - this.addForm.blue = Math.floor(Math.random() * 256); - }, - randomizeEditForm() { - this.editForm.red = Math.floor(Math.random() * 256); - this.editForm.green = Math.floor(Math.random() * 256); - this.editForm.blue = Math.floor(Math.random() * 256); - }, - debugInfo() { - this.showDebug = !this.showDebug; - console.log('=== Vue Component Debug Info ==='); - console.log('Current tableData:', this.tableData); - console.log('tableData length:', this.tableData ? this.tableData.length : 'null/undefined'); - console.log('Total:', this.total); - console.log('Page:', this.page); - console.log('Table Loading:', this.tableLoading); - console.log('Show Debug:', this.showDebug); - console.log('Vue instance $el:', this.$el); - console.log('================================'); - - // 测试Vue响应性 - if (this.tableData && this.tableData.length === 0) { - console.log('测试:添加假数据'); - this.tableData = [ - {id: 999, red: 255, green: 0, blue: 0, addTime: new Date().toISOString(), lastUpdateTime: new Date().toISOString(), remark: 'test'} - ]; - this.total = 1; - setTimeout(() => { - console.log('2秒后清除假数据'); - this.tableData = []; - this.total = 0; - }, 2000); - } - } - } + public const string DatabaseSampleIndexJsTemplate = @"var app = new Vue({ + el: ""#app"", + data() { + return { + page: { + page: 1, + size: 10 + }, + tableLoading: true, + tableData: [], + showDebug: false, + addFormDialogVisible: false, + addForm: { + red: 128, + green: 128, + blue: 128, + additionNote: '' + }, + editFormDialogVisible: false, + editForm: { + id: 0, + red: 128, + green: 128, + blue: 128, + additionNote: '' + }, + total: 0, + addRules: { + red: [ + { required: true, message: '请设置红色值', trigger: 'change' }, + { type: 'number', min: 0, max: 255, message: '红色值范围为0-255', trigger: 'change' } + ], + green: [ + { required: true, message: '请设置绿色值', trigger: 'change' }, + { type: 'number', min: 0, max: 255, message: '绿色值范围为0-255', trigger: 'change' } + ], + blue: [ + { required: true, message: '请设置蓝色值', trigger: 'change' }, + { type: 'number', min: 0, max: 255, message: '蓝色值范围为0-255', trigger: 'change' } + ] + }, + editRules: { + red: [ + { required: true, message: '请设置红色值', trigger: 'change' }, + { type: 'number', min: 0, max: 255, message: '红色值范围为0-255', trigger: 'change' } + ], + green: [ + { required: true, message: '请设置绿色值', trigger: 'change' }, + { type: 'number', min: 0, max: 255, message: '绿色值范围为0-255', trigger: 'change' } + ], + blue: [ + { required: true, message: '请设置蓝色值', trigger: 'change' }, + { type: 'number', min: 0, max: 255, message: '蓝色值范围为0-255', trigger: 'change' } + ] + } + } + }, + mounted() { + //wait page load + setTimeout(async () => { + await this.init(); + }, 100) + }, + methods: { + async init() { + await this.getDataList(); + }, + async handleSizeChange(val) { + this.page.size = val; + await this.getDataList(); + }, + async handleCurrentChange(val) { + this.page.page = val; + await this.getDataList(); + }, + async getDataList() { + this.tableLoading = true + await service.get('/Admin/Template_XncfName/DatabaseSampleIndex?handler=ColorList', { + params: { + pageIndex: this.page.page, + pageSize: this.page.size, + orderField: ""Id desc"", + keyword: """" + } + }) + .then(res => { + console.log('=== API Response Debug ==='); + console.log('Complete Response:', res); + console.log('Response Data:', res.data); + console.log('Response Data Type:', typeof res.data); + console.log('Has res.data.data?:', res.data && res.data.data); + console.log('Has res.data.data.list?:', res.data && res.data.data && res.data.data.list); + console.log('res.data.data.list value:', res.data && res.data.data ? res.data.data.list : 'nested data not found'); + console.log('=================='); + + // 尝试多种可能的数据结构 + let dataList = null; + let totalCount = 0; + let dataSource = ''; + + if (res.data && res.data.data && res.data.data.data && res.data.data.data.list) { + // NCF框架标准格式 + 新的API格式: {data: {data: {success, message, data: {list, totalCount}}}} + dataList = res.data.data.data.list; + totalCount = res.data.data.data.totalCount || 0; + dataSource = 'NCF标准格式: res.data.data.data.list'; + console.log('✅ 使用NCF标准格式: res.data.data.data.list'); + console.log('✅ List数据:', dataList); + console.log('✅ TotalCount:', totalCount); + } else if (res.data && res.data.data && res.data.data.list) { + // 简单格式: {data: {list, totalCount}} + dataList = res.data.data.list; + totalCount = res.data.data.totalCount || 0; + dataSource = '简单格式: res.data.data.list'; + console.log('✅ 使用简单格式: res.data.data.list'); + } else if (res.data && Array.isArray(res.data)) { + // 如果data直接是数组 + dataList = res.data; + totalCount = res.data.length; + dataSource = '数组格式: res.data (array)'; + console.log('✅ 使用数组格式: res.data (array)'); + } else if (res && res.list) { + // 如果list在顶层 + dataList = res.list; + totalCount = res.totalCount || 0; + dataSource = '顶层格式: res.list'; + console.log('✅ 使用顶层格式: res.list'); + } else { + console.error('❌ 无法识别的数据格式:', res); + console.log('🔍 尝试的路径:'); + console.log('- res.data.data.list:', res.data && res.data.data ? res.data.data.list : 'not found'); + console.log('- res.data.list:', res.data ? res.data.list : 'not found'); + console.log('- res.data (array):', res.data && Array.isArray(res.data) ? 'is array' : 'not array'); + console.log('- res.list:', res.list ? res.list : 'not found'); + dataList = []; + totalCount = 0; + dataSource = '无法识别格式'; + } + + console.log('🎯 Final dataList:', dataList); + console.log('🎯 Final totalCount:', totalCount); + console.log('🎯 Data source:', dataSource); + + // 数据赋值前的状态 + console.log('📋 赋值前 tableData:', this.tableData); + console.log('📋 赋值前 total:', this.total); + + this.tableData = dataList || []; + this.total = totalCount; + + // 数据赋值后的状态 + console.log('📋 赋值后 tableData:', this.tableData); + console.log('📋 赋值后 tableData.length:', this.tableData.length); + console.log('📋 赋值后 total:', this.total); + + // 强制Vue更新 + this.$forceUpdate(); + console.log('🔄 Vue已强制更新'); + + // 延迟检查数据是否正确绑定 + setTimeout(() => { + console.log('⏰ 延迟检查 tableData:', this.tableData); + console.log('⏰ 延迟检查 tableData.length:', this.tableData ? this.tableData.length : 'null'); + }, 100); + + this.tableLoading = false + }) + .catch(error => { + console.error('获取数据失败:', error); + this.tableLoading = false; + this.$message.error('获取数据失败: ' + (error.message || error)); + }); + }, + addColor() { + this.addFormDialogVisible = true; + }, + refreshList() { + this.getDataList(); + }, + async addColorSubmit() { + this.$refs.addForm.validate(async (valid) => { + if (valid) { + console.log('📤 发送创建请求:', { + red: this.addForm.red, + green: this.addForm.green, + blue: this.addForm.blue, + additionNote: this.addForm.additionNote + }); + + await service.post('/Admin/Template_XncfName/DatabaseSampleIndex?handler=CreateColor', { + red: this.addForm.red, + green: this.addForm.green, + blue: this.addForm.blue, + additionNote: this.addForm.additionNote + }, { + headers: { + 'Content-Type': 'application/json' + } + }) + .then(res => { + console.log('📥 创建响应:', res); + // 兼容NCF框架的嵌套响应格式 + const responseData = res.data.data || res.data; + this.$message({ + type: responseData.success ? 'success' : 'error', + message: responseData.message || '操作完成' + }); + if (responseData.success) { + this.getDataList() + this.clearAddForm() + this.addFormDialogVisible = false; + } + }) + .catch(error => { + console.error('创建失败:', error); + this.$message.error('创建失败'); + }); + } else { + return false; + } + }); + }, + clearAddForm() { + this.addForm = { + red: 128, + green: 128, + blue: 128, + additionNote: '' + }; + if (this.$refs.addForm) { + this.$refs.addForm.resetFields(); + } + }, + clearEditForm() { + this.editForm = { + id: 0, + red: 128, + green: 128, + blue: 128, + additionNote: '' + }; + if (this.$refs.editForm) { + this.$refs.editForm.resetFields(); + } + }, + async editColorSubmit() { + this.$refs.editForm.validate(async (valid) => { + if (valid) { + console.log('📤 发送更新请求:', { + id: this.editForm.id, + red: this.editForm.red, + green: this.editForm.green, + blue: this.editForm.blue, + additionNote: this.editForm.additionNote + }); + + await service.post('/Admin/Template_XncfName/DatabaseSampleIndex?handler=UpdateColor', { + id: this.editForm.id, + red: this.editForm.red, + green: this.editForm.green, + blue: this.editForm.blue, + additionNote: this.editForm.additionNote + }, { + headers: { + 'Content-Type': 'application/json' + } + }) + .then(res => { + console.log('📥 更新响应:', res); + // 兼容NCF框架的嵌套响应格式 + const responseData = res.data.data || res.data; + this.$message({ + type: responseData.success ? 'success' : 'error', + message: responseData.message || '操作完成' + }); + if (responseData.success) { + this.getDataList() + this.clearEditForm() + this.editFormDialogVisible = false; + } + }) + .catch(error => { + console.error('更新失败:', error); + this.$message.error('更新失败'); + }); + } else { + return false; + } + }); + }, + dateformatter(date) { + if (!date) return ''; + + try { + // 使用原生JavaScript格式化日期 + const d = new Date(date); + + // 检查日期是否有效 + if (isNaN(d.getTime())) { + return date; // 如果无法解析,返回原始值 + } + + // 格式化为 YYYY-MM-DD HH:mm:ss + const year = d.getFullYear(); + const month = String(d.getMonth() + 1).padStart(2, '0'); + const day = String(d.getDate()).padStart(2, '0'); + const hours = String(d.getHours()).padStart(2, '0'); + const minutes = String(d.getMinutes()).padStart(2, '0'); + const seconds = String(d.getSeconds()).padStart(2, '0'); + + return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`; + } catch (error) { + console.warn('日期格式化错误:', error, '原始值:', date); + return date; // 如果格式化失败,返回原始值 + } + }, + editColor(row) { + this.editForm = { + id: row.id, + red: row.red, + green: row.green, + blue: row.blue, + additionNote: row.additionNote || '' + }; + this.editFormDialogVisible = true; + }, + deleteColor(row) { + this.$confirm('此操作将永久删除该颜色, 是否继续?', '提示', { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: 'warning' + }).then(async () => { + console.log('📤 发送删除请求:', { id: row.id }); + + await service.post('/Admin/Template_XncfName/DatabaseSampleIndex?handler=DeleteColor', { + id: row.id + }, { + headers: { + 'Content-Type': 'application/json' + } + }) + .then(res => { + console.log('📥 删除响应:', res); + // 兼容NCF框架的嵌套响应格式 + const responseData = res.data.data || res.data; + this.$message({ + type: responseData.success ? 'success' : 'error', + message: responseData.message || '操作完成' + }); + if (responseData.success) { + this.getDataList(); + } + }) + .catch(error => { + console.error('删除失败:', error); + this.$message.error('删除失败'); + }); + }).catch(() => { + this.$message({ + type: 'info', + message: '已取消删除' + }); + }); + }, + async randomizeColor(row) { + console.log('📤 发送随机化请求:', { id: row.id }); + + await service.post('/Admin/Template_XncfName/DatabaseSampleIndex?handler=RandomizeColor', { + id: row.id + }, { + headers: { + 'Content-Type': 'application/json' + } + }) + .then(res => { + console.log('📥 随机化响应:', res); + // 兼容NCF框架的嵌套响应格式 + const responseData = res.data.data || res.data; + this.$message({ + type: responseData.success ? 'success' : 'error', + message: responseData.message || '操作完成' + }); + if (responseData.success) { + this.getDataList(); + } + }) + .catch(error => { + console.error('随机化失败:', error); + this.$message.error('随机化失败'); + }); + }, + randomizeForm() { + this.addForm.red = Math.floor(Math.random() * 256); + this.addForm.green = Math.floor(Math.random() * 256); + this.addForm.blue = Math.floor(Math.random() * 256); + }, + randomizeEditForm() { + this.editForm.red = Math.floor(Math.random() * 256); + this.editForm.green = Math.floor(Math.random() * 256); + this.editForm.blue = Math.floor(Math.random() * 256); + }, + debugInfo() { + this.showDebug = !this.showDebug; + console.log('=== Vue Component Debug Info ==='); + console.log('Current tableData:', this.tableData); + console.log('tableData length:', this.tableData ? this.tableData.length : 'null/undefined'); + console.log('Total:', this.total); + console.log('Page:', this.page); + console.log('Table Loading:', this.tableLoading); + console.log('Show Debug:', this.showDebug); + console.log('Vue instance $el:', this.$el); + console.log('================================'); + + // 测试Vue响应性 + if (this.tableData && this.tableData.length === 0) { + console.log('测试:添加假数据'); + this.tableData = [ + {id: 999, red: 255, green: 0, blue: 0, addTime: new Date().toISOString(), lastUpdateTime: new Date().toISOString(), remark: 'test'} + ]; + this.total = 1; + setTimeout(() => { + console.log('2秒后清除假数据'); + this.tableData = []; + this.total = 0; + }, 2000); + } + } + } }); "; #endregion @@ -1232,224 +1232,224 @@ await service.post('/Admin/Template_XncfName/DatabaseSampleIndex?handler=Randomi /// 数据库示例索引页面CSS模板 /// 类型: frontend_style /// - public const string DatabaseSampleIndexCssTemplate = @"/* 通用样式 */ -.d-flex{ - display: flex; -} -.justify-content-between{ - justify-content: space-between; -} -.align-items-center{ - align-items: center; -} - -/* 过滤器容器样式 */ -.filter-container { - margin-bottom: 20px; - padding: 10px 0; -} - -.filter-container .el-button { - margin-right: 10px; -} - -/* 颜色预览样式 */ -.color-preview { - width: 100%; - height: 40px; - border-radius: 4px; - border: 1px solid #dcdfe6; - display: flex; - align-items: center; - justify-content: center; - color: white; - font-size: 12px; - font-weight: bold; - text-shadow: 1px 1px 2px rgba(0,0,0,0.5); -} - -.color-preview-large { - width: 100%; - height: 80px; - border-radius: 8px; - border: 2px solid #dcdfe6; - display: flex; - align-items: center; - justify-content: center; - color: white; - font-size: 16px; - font-weight: bold; - text-shadow: 2px 2px 4px rgba(0,0,0,0.7); - margin: 10px 0; - transition: all 0.3s ease; -} - -.color-preview-large:hover { - transform: scale(1.02); - box-shadow: 0 4px 12px rgba(0,0,0,0.15); -} - -/* 分页容器样式 */ -.pagination-container { - margin-top: 20px; - text-align: center; -} - -/* 表格样式增强 */ -.el-table { - border-radius: 8px; - overflow: hidden; - box-shadow: 0 2px 12px 0 rgba(0,0,0,0.1); -} - -.el-table th { - background-color: #fafafa; - color: #333; - font-weight: 600; -} - -/* 颜色标签样式 */ -.el-tag { - min-width: 50px; - text-align: center; - font-weight: bold; - border: none !important; - text-shadow: 1px 1px 2px rgba(0,0,0,0.5); -} - -/* 对话框样式 */ -.el-dialog { - border-radius: 12px; - overflow: hidden; -} - -.el-dialog__header { - background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); - color: white; - padding: 20px 20px 0 20px; -} - -.el-dialog__title { - color: white; - font-weight: 600; -} - -.el-dialog__body { - padding: 30px 20px; -} - -/* 滑块样式 */ -.el-slider { - margin: 20px 0; -} - -.el-slider__runway { - height: 6px; - background-color: #e4e7ed; - border-radius: 3px; -} - -.el-slider__button { - width: 20px; - height: 20px; - border: 2px solid #409eff; -} - -/* 按钮样式增强 */ -.el-button--mini { - padding: 5px 10px; - font-size: 12px; - border-radius: 4px; -} - -.el-button--primary { - background: linear-gradient(135deg, #409eff 0%, #3a8ee6 100%); - border: none; -} - -.el-button--success { - background: linear-gradient(135deg, #67c23a 0%, #5daf34 100%); - border: none; -} - -.el-button--warning { - background: linear-gradient(135deg, #e6a23c 0%, #cf9236 100%); - border: none; -} - -.el-button--danger { - background: linear-gradient(135deg, #f56c6c 0%, #f25c5c 100%); - border: none; -} - -.el-button--info { - background: linear-gradient(135deg, #909399 0%, #82848a 100%); - border: none; -} - -/* 表单项样式 */ -.el-form-item { - margin-bottom: 22px; -} - -.el-form-item__label { - font-weight: 600; - color: #333; -} - -/* 加载动画样式 */ -.el-loading-mask { - background-color: rgba(255, 255, 255, 0.9); -} - -/* 响应式设计 */ -@media (max-width: 768px) { - .filter-container { - text-align: center; - } - - .filter-container .el-button { - margin: 5px; - width: auto; - } - - .color-preview { - height: 30px; - font-size: 10px; - } - - .color-preview-large { - height: 60px; - font-size: 14px; - } -} - -/* 动画效果 */ -@keyframes fadeIn { - from { - opacity: 0; - transform: translateY(20px); - } - to { - opacity: 1; - transform: translateY(0); - } -} - -.el-table tbody tr { - animation: fadeIn 0.3s ease-out; -} - -/* 鼠标悬停效果 */ -.el-table tbody tr:hover { - background-color: #f5f7fa !important; - transition: background-color 0.3s ease; -} - -.el-button:hover { - transform: translateY(-1px); - box-shadow: 0 4px 8px rgba(0,0,0,0.15); - transition: all 0.3s ease; + public const string DatabaseSampleIndexCssTemplate = @"/* 通用样式 */ +.d-flex{ + display: flex; +} +.justify-content-between{ + justify-content: space-between; +} +.align-items-center{ + align-items: center; +} + +/* 过滤器容器样式 */ +.filter-container { + margin-bottom: 20px; + padding: 10px 0; +} + +.filter-container .el-button { + margin-right: 10px; +} + +/* 颜色预览样式 */ +.color-preview { + width: 100%; + height: 40px; + border-radius: 4px; + border: 1px solid #dcdfe6; + display: flex; + align-items: center; + justify-content: center; + color: white; + font-size: 12px; + font-weight: bold; + text-shadow: 1px 1px 2px rgba(0,0,0,0.5); +} + +.color-preview-large { + width: 100%; + height: 80px; + border-radius: 8px; + border: 2px solid #dcdfe6; + display: flex; + align-items: center; + justify-content: center; + color: white; + font-size: 16px; + font-weight: bold; + text-shadow: 2px 2px 4px rgba(0,0,0,0.7); + margin: 10px 0; + transition: all 0.3s ease; +} + +.color-preview-large:hover { + transform: scale(1.02); + box-shadow: 0 4px 12px rgba(0,0,0,0.15); +} + +/* 分页容器样式 */ +.pagination-container { + margin-top: 20px; + text-align: center; +} + +/* 表格样式增强 */ +.el-table { + border-radius: 8px; + overflow: hidden; + box-shadow: 0 2px 12px 0 rgba(0,0,0,0.1); +} + +.el-table th { + background-color: #fafafa; + color: #333; + font-weight: 600; +} + +/* 颜色标签样式 */ +.el-tag { + min-width: 50px; + text-align: center; + font-weight: bold; + border: none !important; + text-shadow: 1px 1px 2px rgba(0,0,0,0.5); +} + +/* 对话框样式 */ +.el-dialog { + border-radius: 12px; + overflow: hidden; +} + +.el-dialog__header { + background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); + color: white; + padding: 20px 20px 0 20px; +} + +.el-dialog__title { + color: white; + font-weight: 600; +} + +.el-dialog__body { + padding: 30px 20px; +} + +/* 滑块样式 */ +.el-slider { + margin: 20px 0; +} + +.el-slider__runway { + height: 6px; + background-color: #e4e7ed; + border-radius: 3px; +} + +.el-slider__button { + width: 20px; + height: 20px; + border: 2px solid #409eff; +} + +/* 按钮样式增强 */ +.el-button--mini { + padding: 5px 10px; + font-size: 12px; + border-radius: 4px; +} + +.el-button--primary { + background: linear-gradient(135deg, #409eff 0%, #3a8ee6 100%); + border: none; +} + +.el-button--success { + background: linear-gradient(135deg, #67c23a 0%, #5daf34 100%); + border: none; +} + +.el-button--warning { + background: linear-gradient(135deg, #e6a23c 0%, #cf9236 100%); + border: none; +} + +.el-button--danger { + background: linear-gradient(135deg, #f56c6c 0%, #f25c5c 100%); + border: none; +} + +.el-button--info { + background: linear-gradient(135deg, #909399 0%, #82848a 100%); + border: none; +} + +/* 表单项样式 */ +.el-form-item { + margin-bottom: 22px; +} + +.el-form-item__label { + font-weight: 600; + color: #333; +} + +/* 加载动画样式 */ +.el-loading-mask { + background-color: rgba(255, 255, 255, 0.9); +} + +/* 响应式设计 */ +@media (max-width: 768px) { + .filter-container { + text-align: center; + } + + .filter-container .el-button { + margin: 5px; + width: auto; + } + + .color-preview { + height: 30px; + font-size: 10px; + } + + .color-preview-large { + height: 60px; + font-size: 14px; + } +} + +/* 动画效果 */ +@keyframes fadeIn { + from { + opacity: 0; + transform: translateY(20px); + } + to { + opacity: 1; + transform: translateY(0); + } +} + +.el-table tbody tr { + animation: fadeIn 0.3s ease-out; +} + +/* 鼠标悬停效果 */ +.el-table tbody tr:hover { + background-color: #f5f7fa !important; + transition: background-color 0.3s ease; +} + +.el-button:hover { + transform: translateY(-1px); + box-shadow: 0 4px 8px rgba(0,0,0,0.15); + transition: all 0.3s ease; } "; #endregion From b9e52e76d0e8fc2ae6553c0adf87d22f5ef9b667 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 4 Apr 2026 11:03:25 +0000 Subject: [PATCH 4/5] fix: Address code review comments - add error handling, fix whitespace, fix chat history filter Agent-Logs-Url: https://github.com/NeuCharFramework/NcfPackageSources/sessions/2b0ded12-8dc2-4c02-8ed9-a726706e8edb Co-authored-by: JeffreySu <2281927+JeffreySu@users.noreply.github.com> --- .../OHS/Local/AppService/AiChatAppService.cs | 23 +- .../OHS/Local/PL/AiChatRequest.cs | 3 +- .../wwwroot/js/AgentsManager/index.js | 5 +- .../BuildXncfAppService.Generated.cs | 2728 ++++++++--------- 4 files changed, 1388 insertions(+), 1371 deletions(-) diff --git a/src/Extensions/Senparc.Xncf.AgentsManager/OHS/Local/AppService/AiChatAppService.cs b/src/Extensions/Senparc.Xncf.AgentsManager/OHS/Local/AppService/AiChatAppService.cs index cc1a7f298..c2a2a7879 100644 --- a/src/Extensions/Senparc.Xncf.AgentsManager/OHS/Local/AppService/AiChatAppService.cs +++ b/src/Extensions/Senparc.Xncf.AgentsManager/OHS/Local/AppService/AiChatAppService.cs @@ -211,7 +211,14 @@ public async Task> ConfirmCreateAndR // 使用 EventBus 模式,在独立线程中运行任务(不阻塞) var _ = Task.Run(async () => { - await _chatGroupService.RunChatGroupInThread(runRequest); + try + { + await _chatGroupService.RunChatGroupInThread(runRequest); + } + catch (Exception ex) + { + Senparc.CO2NET.Trace.SenparcTrace.BaseExceptionLog(ex); + } }); var taskName = runRequest.Name; @@ -253,7 +260,14 @@ public async Task> RunExistingGroup( // 使用 EventBus 模式,在独立线程中运行任务(不阻塞) var _ = Task.Run(async () => { - await _chatGroupService.RunChatGroupInThread(runRequest); + try + { + await _chatGroupService.RunChatGroupInThread(runRequest); + } + catch (Exception ex) + { + Senparc.CO2NET.Trace.SenparcTrace.BaseExceptionLog(ex); + } }); return new AiChat_SendMessageResponse @@ -409,9 +423,10 @@ private AiChat_SendMessageResponse ParseAiResponse( }; } } - catch + catch (Exception ex) { - // 解析失败时,将原始文本作为普通消息返回 + // 解析失败时,将原始文本作为普通消息返回(AI 可能返回非 JSON 格式的内容) + Senparc.CO2NET.Trace.SenparcTrace.Log($"AiChatAppService ParseAiResponse 解析异常: {ex.Message},原始响应: {aiResponseText?.Substring(0, Math.Min(200, aiResponseText?.Length ?? 0))}"); return new AiChat_SendMessageResponse { AiMessage = aiResponseText, diff --git a/src/Extensions/Senparc.Xncf.AgentsManager/OHS/Local/PL/AiChatRequest.cs b/src/Extensions/Senparc.Xncf.AgentsManager/OHS/Local/PL/AiChatRequest.cs index 653692d23..ac97fe9e2 100644 --- a/src/Extensions/Senparc.Xncf.AgentsManager/OHS/Local/PL/AiChatRequest.cs +++ b/src/Extensions/Senparc.Xncf.AgentsManager/OHS/Local/PL/AiChatRequest.cs @@ -47,7 +47,8 @@ public class AiChat_SendMessageRequest /// /// AI 建议创建的 ChatGroup 信息 /// - public class AiChat_SuggestedGroupDto { + public class AiChat_SuggestedGroupDto + { /// /// 建议的组名称 /// diff --git a/src/Extensions/Senparc.Xncf.AgentsManager/wwwroot/js/AgentsManager/index.js b/src/Extensions/Senparc.Xncf.AgentsManager/wwwroot/js/AgentsManager/index.js index 88fcc9385..b68b928ce 100644 --- a/src/Extensions/Senparc.Xncf.AgentsManager/wwwroot/js/AgentsManager/index.js +++ b/src/Extensions/Senparc.Xncf.AgentsManager/wwwroot/js/AgentsManager/index.js @@ -3420,10 +3420,11 @@ Vue.component('load-more-select', { this.aiChatLoading = true try { - // 构建历史记录(只发送 user/assistant 角色) + // 构建历史记录(只发送 user/assistant 角色,不包含最新的用户消息) + // 先截取除最后一条外的所有消息,再过滤角色 const chatHistory = this.aiChatMessages + .slice(0, -1) .filter(m => m.role === 'user' || m.role === 'assistant') - .slice(0, -1) // 不包含最新的用户消息 .map(m => ({ role: m.role, content: m.content })) const payload = { diff --git a/src/Extensions/Senparc.Xncf.XncfBuilder/Senparc.Xncf.XncfBuilder/Generated/Senparc.Xncf.XncfBuilder.DynamicContentGenerator/MultiFileCodeGenerator/BuildXncfAppService.Generated.cs b/src/Extensions/Senparc.Xncf.XncfBuilder/Senparc.Xncf.XncfBuilder/Generated/Senparc.Xncf.XncfBuilder.DynamicContentGenerator/MultiFileCodeGenerator/BuildXncfAppService.Generated.cs index fbd7b9527..f09d62519 100644 --- a/src/Extensions/Senparc.Xncf.XncfBuilder/Senparc.Xncf.XncfBuilder/Generated/Senparc.Xncf.XncfBuilder.DynamicContentGenerator/MultiFileCodeGenerator/BuildXncfAppService.Generated.cs +++ b/src/Extensions/Senparc.Xncf.XncfBuilder/Senparc.Xncf.XncfBuilder/Generated/Senparc.Xncf.XncfBuilder.DynamicContentGenerator/MultiFileCodeGenerator/BuildXncfAppService.Generated.cs @@ -14,73 +14,73 @@ namespace Senparc.Xncf.XncfBuilder.OHS.Local /// public partial class BuildXncfAppService { -public const string BackendTemplate = @$" -## Database EntityFramework DbContext class sample -File Name: Template_XncfNameSenparcEntities.cs -File Path: /Domain/Models/DatabaseModel -Code: -```csharp -{SenparcEntitiesTemplate} -``` - -## Database Entity class sample -File Name: Color.cs -File Path: /Domain/Models/DatabaseModel -Code: -```csharp -{ColorModelTemplate} -``` - -## Database Entity DTO class sample -File Name: ColorDto.cs -File Path: /Domain/Models/DatabaseModel/Dto -Code: -```csharp -{ColorDtoTemplate} -``` - -## Service class sample -File Name: Template_XncfNameService.cs -File Path: /Domain/Services -Code: -```csharp -{ColorServiceTemplate} -``` -"; - -public const string FrontendTemplate = @$" -## Page UI sample (front-end) -File Name: DatabaseSampleIndex.cshtml -File Path: < ModuleRootPath >/ Areas / Admin / Pages / Template_XncfName -Code: -```razorpage -{DatabaseSampleIndexViewTemplate} -``` - -## Page UI sample (back-end) -File Name: DatabaseSampleIndex.cshtml.cs -File Path: < ModuleRootPath >/ Areas / Admin / Pages / Template_XncfName -Code: -```csharp -{DatabaseSampleIndexCodeBehindTemplate} -``` - -## Page JavaScript file sample -File Name: databaseSampleIndex.js -File Path: < ModuleRootPath >/ wwwroot / js / Admin / Template_XncfName -Code: -```javascript -{DatabaseSampleIndexJsTemplate} -``` - -## Page CSS file sample -File Name: databaseSampleIndex.css -File Path: < ModuleRootPath >/ wwwroot / css / Admin / Template_XncfName -Code: -```css -{DatabaseSampleIndexCssTemplate} -``` -"; +public const string BackendTemplate = @$" +## Database EntityFramework DbContext class sample +File Name: Template_XncfNameSenparcEntities.cs +File Path: /Domain/Models/DatabaseModel +Code: +```csharp +{SenparcEntitiesTemplate} +``` + +## Database Entity class sample +File Name: Color.cs +File Path: /Domain/Models/DatabaseModel +Code: +```csharp +{ColorModelTemplate} +``` + +## Database Entity DTO class sample +File Name: ColorDto.cs +File Path: /Domain/Models/DatabaseModel/Dto +Code: +```csharp +{ColorDtoTemplate} +``` + +## Service class sample +File Name: Template_XncfNameService.cs +File Path: /Domain/Services +Code: +```csharp +{ColorServiceTemplate} +``` +"; + +public const string FrontendTemplate = @$" +## Page UI sample (front-end) +File Name: DatabaseSampleIndex.cshtml +File Path: < ModuleRootPath >/ Areas / Admin / Pages / Template_XncfName +Code: +```razorpage +{DatabaseSampleIndexViewTemplate} +``` + +## Page UI sample (back-end) +File Name: DatabaseSampleIndex.cshtml.cs +File Path: < ModuleRootPath >/ Areas / Admin / Pages / Template_XncfName +Code: +```csharp +{DatabaseSampleIndexCodeBehindTemplate} +``` + +## Page JavaScript file sample +File Name: databaseSampleIndex.js +File Path: < ModuleRootPath >/ wwwroot / js / Admin / Template_XncfName +Code: +```javascript +{DatabaseSampleIndexJsTemplate} +``` + +## Page CSS file sample +File Name: databaseSampleIndex.css +File Path: < ModuleRootPath >/ wwwroot / css / Admin / Template_XncfName +Code: +```css +{DatabaseSampleIndexCssTemplate} +``` +"; #region CODE Templates @@ -89,26 +89,26 @@ public partial class BuildXncfAppService /// 请求类代码 /// 类型: code /// - public const string RequestCode = @"using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Senparc.Xncf.XncfBuilder -{ - public class Request - { - public string? Method { get; set; } - public string? Path { get; set; } - public string? Body { get; set; } - - // 新增字段测试动态更新 - public Dictionary? Headers { get; set; } - public DateTime Timestamp { get; set; } = DateTime.Now; - } - -} + public const string RequestCode = @"using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Senparc.Xncf.XncfBuilder +{ + public class Request + { + public string? Method { get; set; } + public string? Path { get; set; } + public string? Body { get; set; } + + // 新增字段测试动态更新 + public Dictionary? Headers { get; set; } + public DateTime Timestamp { get; set; } = DateTime.Now; + } + +} "; #endregion @@ -119,237 +119,237 @@ public class Request /// Senparc实体类模板 /// 类型: backend_template /// - public const string SenparcEntitiesTemplate = @"using Microsoft.EntityFrameworkCore; -using Senparc.Ncf.Database; -using Senparc.Ncf.Core.Models; -using Senparc.Ncf.XncfBase.Database; - -namespace Template_OrgName.Xncf.Template_XncfName.Models -{ - public class Template_XncfNameSenparcEntities : XncfDatabaseDbContext - { - public Template_XncfNameSenparcEntities(DbContextOptions dbContextOptions) : base(dbContextOptions) - { - } - - public DbSet Colors { get; set; } - - //DOT REMOVE OR MODIFY THIS LINE 请勿移除或修改本行 - Entities Point - //ex. public DbSet Colors { get; set; } - - //如无特殊需需要,OnModelCreating 方法可以不用写,已经在 Register 中要求注册 - //protected override void OnModelCreating(ModelBuilder modelBuilder) - //{ - //} - } -} + public const string SenparcEntitiesTemplate = @"using Microsoft.EntityFrameworkCore; +using Senparc.Ncf.Database; +using Senparc.Ncf.Core.Models; +using Senparc.Ncf.XncfBase.Database; + +namespace Template_OrgName.Xncf.Template_XncfName.Models +{ + public class Template_XncfNameSenparcEntities : XncfDatabaseDbContext + { + public Template_XncfNameSenparcEntities(DbContextOptions dbContextOptions) : base(dbContextOptions) + { + } + + public DbSet Colors { get; set; } + + //DOT REMOVE OR MODIFY THIS LINE 请勿移除或修改本行 - Entities Point + //ex. public DbSet Colors { get; set; } + + //如无特殊需需要,OnModelCreating 方法可以不用写,已经在 Register 中要求注册 + //protected override void OnModelCreating(ModelBuilder modelBuilder) + //{ + //} + } +} "; /// /// 颜色模型模板 /// 类型: backend_template /// - public const string ColorModelTemplate = @"using Senparc.Ncf.Core.Models; -using Template_OrgName.Xncf.Template_XncfName.Domain.Models.DatabaseModel.Dto; -using System; -using System.ComponentModel.DataAnnotations.Schema; -using Template_OrgName.Xncf.Template_XncfName.Domain.Models.DatabaseModel.Dto; - -namespace Template_OrgName.Xncf.Template_XncfName -{ - /// - /// Color 实体类 - /// - [Table(Register.DATABASE_PREFIX + nameof(Color))]//必须添加前缀,防止全系统中发生冲突 - [Serializable] - public class Color : EntityBase - { - /// - /// 颜色码,0-255 - /// - public int Red { get; private set; } - /// - /// 颜色码,0-255 - /// - public int Green { get; private set; } - - /// - /// 颜色码,0-255 - /// - public int Blue { get; private set; } - - /// - /// 附加列,测试多次数据库 Migrate - /// - public string AdditionNote { get; private set; } - - private Color() { } - - public Color(int red, int green, int blue) - { - if (red < 0 || green < 0 || blue < 0) - { - Random();//随机 - } - else - { - Red = red; - Green = green; - Blue = blue; - } - } - - public Color(int red, int green, int blue, string additionNote) : this(red, green, blue) - { - AdditionNote = additionNote; - } - - public Color(ColorDto colorDto) - { - Red = colorDto.Red; - Green = colorDto.Green; - Blue = colorDto.Blue; - } - - public void Random() - { - //随机产生颜色代码 - var radom = new Random(); - Func getRadomColorCode = () => radom.Next(0, 255); - Red = getRadomColorCode(); - Green = getRadomColorCode(); - Blue = getRadomColorCode(); - } - - public void Brighten() - { - Red = Math.Min(255, Red + 10); - Green = Math.Min(255, Green + 10); - Blue = Math.Min(255, Blue + 10); - } - - public void Darken() - { - Red = Math.Max(0, Red - 10); - Green = Math.Max(0, Green - 10); - Blue = Math.Max(0, Blue - 10); - } - - public void Update(UpdateColorRequestDto dto) - { - Red = dto.Red; - Green = dto.Green; - Blue = dto.Blue; - AdditionNote = dto.AdditionNote; - } - } -} + public const string ColorModelTemplate = @"using Senparc.Ncf.Core.Models; +using Template_OrgName.Xncf.Template_XncfName.Domain.Models.DatabaseModel.Dto; +using System; +using System.ComponentModel.DataAnnotations.Schema; +using Template_OrgName.Xncf.Template_XncfName.Domain.Models.DatabaseModel.Dto; + +namespace Template_OrgName.Xncf.Template_XncfName +{ + /// + /// Color 实体类 + /// + [Table(Register.DATABASE_PREFIX + nameof(Color))]//必须添加前缀,防止全系统中发生冲突 + [Serializable] + public class Color : EntityBase + { + /// + /// 颜色码,0-255 + /// + public int Red { get; private set; } + /// + /// 颜色码,0-255 + /// + public int Green { get; private set; } + + /// + /// 颜色码,0-255 + /// + public int Blue { get; private set; } + + /// + /// 附加列,测试多次数据库 Migrate + /// + public string AdditionNote { get; private set; } + + private Color() { } + + public Color(int red, int green, int blue) + { + if (red < 0 || green < 0 || blue < 0) + { + Random();//随机 + } + else + { + Red = red; + Green = green; + Blue = blue; + } + } + + public Color(int red, int green, int blue, string additionNote) : this(red, green, blue) + { + AdditionNote = additionNote; + } + + public Color(ColorDto colorDto) + { + Red = colorDto.Red; + Green = colorDto.Green; + Blue = colorDto.Blue; + } + + public void Random() + { + //随机产生颜色代码 + var radom = new Random(); + Func getRadomColorCode = () => radom.Next(0, 255); + Red = getRadomColorCode(); + Green = getRadomColorCode(); + Blue = getRadomColorCode(); + } + + public void Brighten() + { + Red = Math.Min(255, Red + 10); + Green = Math.Min(255, Green + 10); + Blue = Math.Min(255, Blue + 10); + } + + public void Darken() + { + Red = Math.Max(0, Red - 10); + Green = Math.Max(0, Green - 10); + Blue = Math.Max(0, Blue - 10); + } + + public void Update(UpdateColorRequestDto dto) + { + Red = dto.Red; + Green = dto.Green; + Blue = dto.Blue; + AdditionNote = dto.AdditionNote; + } + } +} "; /// /// 颜色DTO模板 /// 类型: backend_template /// - public const string ColorDtoTemplate = @"using Senparc.Ncf.Core.Models; - -namespace Template_OrgName.Xncf.Template_XncfName.Domain.Models.DatabaseModel.Dto -{ - public class ColorDto : DtoBase - { - /// - /// 颜色码,0-255 - /// - public int Red { get; set; } - /// - /// 颜色码,0-255 - /// - public int Green { get; set; } - /// - /// 颜色码,0-255 - /// - public int Blue { get; set; } - - /// - /// 附加列,测试多次数据库 Migrate - /// - public string AdditionNote { get; set; } - - public ColorDto() { } - } -} + public const string ColorDtoTemplate = @"using Senparc.Ncf.Core.Models; + +namespace Template_OrgName.Xncf.Template_XncfName.Domain.Models.DatabaseModel.Dto +{ + public class ColorDto : DtoBase + { + /// + /// 颜色码,0-255 + /// + public int Red { get; set; } + /// + /// 颜色码,0-255 + /// + public int Green { get; set; } + /// + /// 颜色码,0-255 + /// + public int Blue { get; set; } + + /// + /// 附加列,测试多次数据库 Migrate + /// + public string AdditionNote { get; set; } + + public ColorDto() { } + } +} "; /// /// 颜色服务模板 /// 类型: backend_template /// - public const string ColorServiceTemplate = @"using Senparc.Ncf.Core.Enums; -using Senparc.Ncf.Repository; -using Senparc.Ncf.Service; -using Template_OrgName.Xncf.Template_XncfName.Domain.Models.DatabaseModel.Dto; -using System; -using System.Threading.Tasks; - -namespace Template_OrgName.Xncf.Template_XncfName.Domain.Services -{ - public class ColorService : ServiceBase - { - public ColorService(IRepositoryBase repo, IServiceProvider serviceProvider) - : base(repo, serviceProvider) - { - } - - public async Task CreateNewColor() - { - Color color = new Color(-1, -1, -1); - await base.SaveObjectAsync(color).ConfigureAwait(false); - ColorDto colorDto = base.Mapper.Map(color); - return colorDto; - } - - public async Task GetOrInitColor() - { - var color = await base.GetObjectAsync(z => true); - if (color == null)//如果是纯第一次安装,理论上不会有残留数据 - { - //创建默认颜色 - ColorDto colorDto = await this.CreateNewColor().ConfigureAwait(false); - return colorDto; - } - - return base.Mapper.Map(color); - } - - public async Task Brighten() - { - //TODO:异步方法需要添加排序功能 - var obj = await this.GetObjectAsync(z => true, z => z.Id, OrderingType.Descending); - obj.Brighten(); - await base.SaveObjectAsync(obj).ConfigureAwait(false); - return base.Mapper.Map(obj); - } - - public async Task Darken() - { - //TODO:异步方法需要添加排序功能 - var obj = await this.GetObjectAsync(z => true, z => z.Id, OrderingType.Descending); - obj.Darken(); - await base.SaveObjectAsync(obj).ConfigureAwait(false); - return base.Mapper.Map(obj); - } - - public async Task Random() - { - //TODO:异步方法需要添加排序功能 - var obj = await this.GetObjectAsync(z => true, z => z.Id, OrderingType.Descending); - obj.Random(); - await base.SaveObjectAsync(obj).ConfigureAwait(false); - return base.Mapper.Map(obj); - } - - //TODO: 更多业务方法可以写到这里 - } -} + public const string ColorServiceTemplate = @"using Senparc.Ncf.Core.Enums; +using Senparc.Ncf.Repository; +using Senparc.Ncf.Service; +using Template_OrgName.Xncf.Template_XncfName.Domain.Models.DatabaseModel.Dto; +using System; +using System.Threading.Tasks; + +namespace Template_OrgName.Xncf.Template_XncfName.Domain.Services +{ + public class ColorService : ServiceBase + { + public ColorService(IRepositoryBase repo, IServiceProvider serviceProvider) + : base(repo, serviceProvider) + { + } + + public async Task CreateNewColor() + { + Color color = new Color(-1, -1, -1); + await base.SaveObjectAsync(color).ConfigureAwait(false); + ColorDto colorDto = base.Mapper.Map(color); + return colorDto; + } + + public async Task GetOrInitColor() + { + var color = await base.GetObjectAsync(z => true); + if (color == null)//如果是纯第一次安装,理论上不会有残留数据 + { + //创建默认颜色 + ColorDto colorDto = await this.CreateNewColor().ConfigureAwait(false); + return colorDto; + } + + return base.Mapper.Map(color); + } + + public async Task Brighten() + { + //TODO:异步方法需要添加排序功能 + var obj = await this.GetObjectAsync(z => true, z => z.Id, OrderingType.Descending); + obj.Brighten(); + await base.SaveObjectAsync(obj).ConfigureAwait(false); + return base.Mapper.Map(obj); + } + + public async Task Darken() + { + //TODO:异步方法需要添加排序功能 + var obj = await this.GetObjectAsync(z => true, z => z.Id, OrderingType.Descending); + obj.Darken(); + await base.SaveObjectAsync(obj).ConfigureAwait(false); + return base.Mapper.Map(obj); + } + + public async Task Random() + { + //TODO:异步方法需要添加排序功能 + var obj = await this.GetObjectAsync(z => true, z => z.Id, OrderingType.Descending); + obj.Random(); + await base.SaveObjectAsync(obj).ConfigureAwait(false); + return base.Mapper.Map(obj); + } + + //TODO: 更多业务方法可以写到这里 + } +} "; #endregion @@ -360,431 +360,431 @@ public async Task Random() /// 数据库示例索引页面视图模板 /// 类型: frontend_template /// - public const string DatabaseSampleIndexViewTemplate = @"@page -@model Template_OrgName.Xncf.Template_XncfName.Areas.Template_XncfName.Pages.DatabaseSampleIndex -@{ - ViewData[""Title""] = ""Color 数据库管理""; - Layout = ""_Layout_Vue""; -} - -@section Style { - -} - -@section breadcrumbs { - 扩展模块 - Template_MenuName - Color 数据库管理 -} - -
-
- 添加颜色 - 刷新 - 调试信息 -
- - -
-

调试信息:

-

tableData长度: {{ tableData ? tableData.length : 'null/undefined' }}

-

total: {{ total }}

-

tableLoading: {{ tableLoading }}

-

Vue实例是否正常: {{ $el ? '是' : '否' }}

-
0""> - 第一条数据: -
{{ JSON.stringify(tableData[0], null, 2) }}
-
- - -
-
简化数据显示测试:
-
- ID: {{item.id}} | - RGB: {{item.red}},{{item.green}},{{item.blue}} | - 时间: {{item.addTime}} -
-

- 没有数据显示! -

-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - -
- - -
- - @* dialog for 添加颜色 *@ - - - - - - - - - - - - -
- RGB({{addForm.red}}, {{addForm.green}}, {{addForm.blue}}) -
-
- - - - - 随机颜色 - -
- - 取 消 - 确 定 - -
- - @* dialog for 编辑颜色 *@ - - - - - - - - - - - - -
- RGB({{editForm.red}}, {{editForm.green}}, {{editForm.blue}}) -
-
- - - - - 随机颜色 - -
- - 取 消 - 确 定 - -
-
- -@section scripts{ - + public const string DatabaseSampleIndexViewTemplate = @"@page +@model Template_OrgName.Xncf.Template_XncfName.Areas.Template_XncfName.Pages.DatabaseSampleIndex +@{ + ViewData[""Title""] = ""Color 数据库管理""; + Layout = ""_Layout_Vue""; +} + +@section Style { + +} + +@section breadcrumbs { + 扩展模块 + Template_MenuName + Color 数据库管理 +} + +
+
+ 添加颜色 + 刷新 + 调试信息 +
+ + +
+

调试信息:

+

tableData长度: {{ tableData ? tableData.length : 'null/undefined' }}

+

total: {{ total }}

+

tableLoading: {{ tableLoading }}

+

Vue实例是否正常: {{ $el ? '是' : '否' }}

+
0""> + 第一条数据: +
{{ JSON.stringify(tableData[0], null, 2) }}
+
+ + +
+
简化数据显示测试:
+
+ ID: {{item.id}} | + RGB: {{item.red}},{{item.green}},{{item.blue}} | + 时间: {{item.addTime}} +
+

+ 没有数据显示! +

+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ + @* dialog for 添加颜色 *@ + + + + + + + + + + + + +
+ RGB({{addForm.red}}, {{addForm.green}}, {{addForm.blue}}) +
+
+ + + + + 随机颜色 + +
+ + 取 消 + 确 定 + +
+ + @* dialog for 编辑颜色 *@ + + + + + + + + + + + + +
+ RGB({{editForm.red}}, {{editForm.green}}, {{editForm.blue}}) +
+
+ + + + + 随机颜色 + +
+ + 取 消 + 确 定 + +
+
+ +@section scripts{ + } "; /// /// 数据库示例索引页面代码后置模板 /// 类型: frontend_template /// - public const string DatabaseSampleIndexCodeBehindTemplate = @"using Microsoft.AspNetCore.Mvc; -using Senparc.Ncf.Service; -using Senparc.Ncf.Utility; -using Template_OrgName.Xncf.Template_XncfName.Domain.Services; -using System; -using System.Linq; -using System.Threading.Tasks; -using Template_OrgName.Xncf.Template_XncfName.Domain.Models.DatabaseModel.Dto; - -namespace Template_OrgName.Xncf.Template_XncfName.Areas.Template_XncfName.Pages -{ - public class DatabaseSampleIndex : Senparc.Ncf.AreaBase.Admin.AdminXncfModulePageModelBase - { - private readonly ColorService _colorService; - - public DatabaseSampleIndex(Lazy xncfModuleService, ColorService colorService) : base(xncfModuleService) - { - _colorService = colorService; - } - - public void OnGet() - { - } - - /// - /// 获取颜色列表(分页) - /// - /// 关键词 - /// 排序字段 - /// 页码 - /// 页大小 - /// - public async Task OnGetColorListAsync(string keyword, string orderField, int pageIndex, int pageSize) - { - try - { - // 调试信息 - System.Diagnostics.Debug.WriteLine($""ColorList API Called - PageIndex: {pageIndex}, PageSize: {pageSize}, OrderField: {orderField}""); - - var seh = new SenparcExpressionHelper(); - // 可以根据需要添加搜索条件 - // seh.ValueCompare.AndAlso(!string.IsNullOrEmpty(keyword), _ => _.Remark.Contains(keyword)); - var where = seh.BuildWhereExpression(); - var response = await _colorService.GetObjectListAsync(pageIndex, pageSize, where, orderField ?? ""Id desc""); - - // 调试信息 - System.Diagnostics.Debug.WriteLine($""Database Query Result - TotalCount: {response.TotalCount}, ItemCount: {response.Count()}""); - - var result = new - { - success = true, - message = ""数据获取成功"", - data = new { - totalCount = response.TotalCount, - pageIndex = response.PageIndex, - list = response.Select(_ => new - { - id = _.Id, - red = _.Red, - green = _.Green, - blue = _.Blue, - additionNote = _.AdditionNote, - addTime = _.AddTime, - lastUpdateTime = _.LastUpdateTime, - remark = _.Remark - }).ToList() - } - }; - - // 调试信息 - System.Diagnostics.Debug.WriteLine($""API Response - ListCount: {result.data.list.Count}""); - - return Ok(result); - } - catch (Exception ex) - { - System.Diagnostics.Debug.WriteLine($""ColorList API Error: {ex.Message}""); - return Ok(new { - success = false, - message = ""获取数据失败: "" + ex.Message, - totalCount = 0, - pageIndex = pageIndex, - list = new object[0] - }); - } - } - - /// - /// 创建新颜色 - /// - /// 创建颜色请求 - /// - public async Task OnPostCreateColorAsync([FromBody] CreateColorRequestDto request) - { - try - { - // 调试信息 - System.Diagnostics.Debug.WriteLine($""CreateColor API Called - Red: {request.Red}, Green: {request.Green}, Blue: {request.Blue}, AdditionNote: {request.AdditionNote}""); - - if (request == null) - { - return Ok(new { success = false, message = ""请求参数不能为空"" }); - } - - var color = new Color(request.Red, request.Green, request.Blue, request.AdditionNote); - await _colorService.SaveObjectAsync(color); - - return Ok(new { success = true, message = ""颜色创建成功"", data = new { color.Id, color.Red, color.Green, color.Blue, color.AdditionNote, color.AddTime, color.LastUpdateTime } }); - } - catch (Exception ex) - { - System.Diagnostics.Debug.WriteLine($""CreateColor API Error: {ex.Message}""); - return Ok(new { success = false, message = ""创建失败:"" + ex.Message }); - } - } - - /// - /// 更新颜色 - /// - /// 更新颜色请求 - /// - public async Task OnPostUpdateColorAsync([FromBody] UpdateColorRequestDto request) - { - try - { - // 调试信息 - System.Diagnostics.Debug.WriteLine($""UpdateColor API Called - Id: {request.Id}, Red: {request.Red}, Green: {request.Green}, Blue: {request.Blue}, AdditionNote: {request.AdditionNote}""); - - if (request == null) - { - return Ok(new { success = false, message = ""请求参数不能为空"" }); - } - - var color = await _colorService.GetObjectAsync(c => c.Id == request.Id); - if (color == null) - { - return Ok(new { success = false, message = ""颜色不存在"" }); - } - - // 更新 - color.Update(request); - - await _colorService.SaveObjectAsync(color); - - return Ok(new { success = true, message = ""颜色更新成功"", data = new { color.Id, color.Red, color.Green, color.Blue, color.AdditionNote, color.LastUpdateTime } }); - } - catch (Exception ex) - { - System.Diagnostics.Debug.WriteLine($""UpdateColor API Error: {ex.Message}""); - return Ok(new { success = false, message = ""更新失败:"" + ex.Message }); - } - } - - /// - /// 删除颜色 - /// - /// 删除颜色请求 - /// - public async Task OnPostDeleteColorAsync([FromBody] DeleteColorRequestDto request) - { - try - { - // 调试信息 - System.Diagnostics.Debug.WriteLine($""DeleteColor API Called - Id: {request.Id}""); - - if (request == null) - { - return Ok(new { success = false, message = ""请求参数不能为空"" }); - } - - var color = await _colorService.GetObjectAsync(c => c.Id == request.Id); - if (color == null) - { - return Ok(new { success = false, message = ""颜色不存在"" }); - } - - await _colorService.DeleteObjectAsync(color); - return Ok(new { success = true, message = ""颜色删除成功"" }); - } - catch (Exception ex) - { - System.Diagnostics.Debug.WriteLine($""DeleteColor API Error: {ex.Message}""); - return Ok(new { success = false, message = ""删除失败:"" + ex.Message }); - } - } - - /// - /// 随机化指定颜色 - /// - /// 随机化颜色请求 - /// - public async Task OnPostRandomizeColorAsync([FromBody] RandomizeColorRequestDto request) - { - try - { - // 调试信息 - System.Diagnostics.Debug.WriteLine($""RandomizeColor API Called - Id: {request.Id}""); - - if (request == null) - { - return Ok(new { success = false, message = ""请求参数不能为空"" }); - } - - var color = await _colorService.GetObjectAsync(c => c.Id == request.Id); - if (color == null) - { - return Ok(new { success = false, message = ""颜色不存在"" }); - } - - color.Random(); - await _colorService.SaveObjectAsync(color); - - return Ok(new { success = true, message = ""颜色随机化成功"", data = new { color.Id, color.Red, color.Green, color.Blue, color.AdditionNote, color.LastUpdateTime } }); - } - catch (Exception ex) - { - System.Diagnostics.Debug.WriteLine($""RandomizeColor API Error: {ex.Message}""); - return Ok(new { success = false, message = ""随机化失败:"" + ex.Message }); - } - } - - /// - /// 获取颜色详情 - /// - /// 颜色ID - /// - public async Task OnGetColorDetailAsync(int id) - { - try - { - var color = await _colorService.GetObjectAsync(c => c.Id == id); - if (color == null) - { - return Ok(new { success = false, message = ""颜色不存在"" }); - } - - return Ok(new { success = true, data = new { color.Id, color.Red, color.Green, color.Blue, color.AdditionNote, color.AddTime, color.LastUpdateTime, color.Remark } }); - } - catch (Exception ex) - { - return Ok(new { success = false, message = ""获取失败:"" + ex.Message }); - } - } - } + public const string DatabaseSampleIndexCodeBehindTemplate = @"using Microsoft.AspNetCore.Mvc; +using Senparc.Ncf.Service; +using Senparc.Ncf.Utility; +using Template_OrgName.Xncf.Template_XncfName.Domain.Services; +using System; +using System.Linq; +using System.Threading.Tasks; +using Template_OrgName.Xncf.Template_XncfName.Domain.Models.DatabaseModel.Dto; + +namespace Template_OrgName.Xncf.Template_XncfName.Areas.Template_XncfName.Pages +{ + public class DatabaseSampleIndex : Senparc.Ncf.AreaBase.Admin.AdminXncfModulePageModelBase + { + private readonly ColorService _colorService; + + public DatabaseSampleIndex(Lazy xncfModuleService, ColorService colorService) : base(xncfModuleService) + { + _colorService = colorService; + } + + public void OnGet() + { + } + + /// + /// 获取颜色列表(分页) + /// + /// 关键词 + /// 排序字段 + /// 页码 + /// 页大小 + /// + public async Task OnGetColorListAsync(string keyword, string orderField, int pageIndex, int pageSize) + { + try + { + // 调试信息 + System.Diagnostics.Debug.WriteLine($""ColorList API Called - PageIndex: {pageIndex}, PageSize: {pageSize}, OrderField: {orderField}""); + + var seh = new SenparcExpressionHelper(); + // 可以根据需要添加搜索条件 + // seh.ValueCompare.AndAlso(!string.IsNullOrEmpty(keyword), _ => _.Remark.Contains(keyword)); + var where = seh.BuildWhereExpression(); + var response = await _colorService.GetObjectListAsync(pageIndex, pageSize, where, orderField ?? ""Id desc""); + + // 调试信息 + System.Diagnostics.Debug.WriteLine($""Database Query Result - TotalCount: {response.TotalCount}, ItemCount: {response.Count()}""); + + var result = new + { + success = true, + message = ""数据获取成功"", + data = new { + totalCount = response.TotalCount, + pageIndex = response.PageIndex, + list = response.Select(_ => new + { + id = _.Id, + red = _.Red, + green = _.Green, + blue = _.Blue, + additionNote = _.AdditionNote, + addTime = _.AddTime, + lastUpdateTime = _.LastUpdateTime, + remark = _.Remark + }).ToList() + } + }; + + // 调试信息 + System.Diagnostics.Debug.WriteLine($""API Response - ListCount: {result.data.list.Count}""); + + return Ok(result); + } + catch (Exception ex) + { + System.Diagnostics.Debug.WriteLine($""ColorList API Error: {ex.Message}""); + return Ok(new { + success = false, + message = ""获取数据失败: "" + ex.Message, + totalCount = 0, + pageIndex = pageIndex, + list = new object[0] + }); + } + } + + /// + /// 创建新颜色 + /// + /// 创建颜色请求 + /// + public async Task OnPostCreateColorAsync([FromBody] CreateColorRequestDto request) + { + try + { + // 调试信息 + System.Diagnostics.Debug.WriteLine($""CreateColor API Called - Red: {request.Red}, Green: {request.Green}, Blue: {request.Blue}, AdditionNote: {request.AdditionNote}""); + + if (request == null) + { + return Ok(new { success = false, message = ""请求参数不能为空"" }); + } + + var color = new Color(request.Red, request.Green, request.Blue, request.AdditionNote); + await _colorService.SaveObjectAsync(color); + + return Ok(new { success = true, message = ""颜色创建成功"", data = new { color.Id, color.Red, color.Green, color.Blue, color.AdditionNote, color.AddTime, color.LastUpdateTime } }); + } + catch (Exception ex) + { + System.Diagnostics.Debug.WriteLine($""CreateColor API Error: {ex.Message}""); + return Ok(new { success = false, message = ""创建失败:"" + ex.Message }); + } + } + + /// + /// 更新颜色 + /// + /// 更新颜色请求 + /// + public async Task OnPostUpdateColorAsync([FromBody] UpdateColorRequestDto request) + { + try + { + // 调试信息 + System.Diagnostics.Debug.WriteLine($""UpdateColor API Called - Id: {request.Id}, Red: {request.Red}, Green: {request.Green}, Blue: {request.Blue}, AdditionNote: {request.AdditionNote}""); + + if (request == null) + { + return Ok(new { success = false, message = ""请求参数不能为空"" }); + } + + var color = await _colorService.GetObjectAsync(c => c.Id == request.Id); + if (color == null) + { + return Ok(new { success = false, message = ""颜色不存在"" }); + } + + // 更新 + color.Update(request); + + await _colorService.SaveObjectAsync(color); + + return Ok(new { success = true, message = ""颜色更新成功"", data = new { color.Id, color.Red, color.Green, color.Blue, color.AdditionNote, color.LastUpdateTime } }); + } + catch (Exception ex) + { + System.Diagnostics.Debug.WriteLine($""UpdateColor API Error: {ex.Message}""); + return Ok(new { success = false, message = ""更新失败:"" + ex.Message }); + } + } + + /// + /// 删除颜色 + /// + /// 删除颜色请求 + /// + public async Task OnPostDeleteColorAsync([FromBody] DeleteColorRequestDto request) + { + try + { + // 调试信息 + System.Diagnostics.Debug.WriteLine($""DeleteColor API Called - Id: {request.Id}""); + + if (request == null) + { + return Ok(new { success = false, message = ""请求参数不能为空"" }); + } + + var color = await _colorService.GetObjectAsync(c => c.Id == request.Id); + if (color == null) + { + return Ok(new { success = false, message = ""颜色不存在"" }); + } + + await _colorService.DeleteObjectAsync(color); + return Ok(new { success = true, message = ""颜色删除成功"" }); + } + catch (Exception ex) + { + System.Diagnostics.Debug.WriteLine($""DeleteColor API Error: {ex.Message}""); + return Ok(new { success = false, message = ""删除失败:"" + ex.Message }); + } + } + + /// + /// 随机化指定颜色 + /// + /// 随机化颜色请求 + /// + public async Task OnPostRandomizeColorAsync([FromBody] RandomizeColorRequestDto request) + { + try + { + // 调试信息 + System.Diagnostics.Debug.WriteLine($""RandomizeColor API Called - Id: {request.Id}""); + + if (request == null) + { + return Ok(new { success = false, message = ""请求参数不能为空"" }); + } + + var color = await _colorService.GetObjectAsync(c => c.Id == request.Id); + if (color == null) + { + return Ok(new { success = false, message = ""颜色不存在"" }); + } + + color.Random(); + await _colorService.SaveObjectAsync(color); + + return Ok(new { success = true, message = ""颜色随机化成功"", data = new { color.Id, color.Red, color.Green, color.Blue, color.AdditionNote, color.LastUpdateTime } }); + } + catch (Exception ex) + { + System.Diagnostics.Debug.WriteLine($""RandomizeColor API Error: {ex.Message}""); + return Ok(new { success = false, message = ""随机化失败:"" + ex.Message }); + } + } + + /// + /// 获取颜色详情 + /// + /// 颜色ID + /// + public async Task OnGetColorDetailAsync(int id) + { + try + { + var color = await _colorService.GetObjectAsync(c => c.Id == id); + if (color == null) + { + return Ok(new { success = false, message = ""颜色不存在"" }); + } + + return Ok(new { success = true, data = new { color.Id, color.Red, color.Green, color.Blue, color.AdditionNote, color.AddTime, color.LastUpdateTime, color.Remark } }); + } + catch (Exception ex) + { + return Ok(new { success = false, message = ""获取失败:"" + ex.Message }); + } + } + } } "; #endregion @@ -795,433 +795,433 @@ public async Task OnGetColorDetailAsync(int id) /// 数据库示例索引页面JavaScript模板 /// 类型: frontend_script /// - public const string DatabaseSampleIndexJsTemplate = @"var app = new Vue({ - el: ""#app"", - data() { - return { - page: { - page: 1, - size: 10 - }, - tableLoading: true, - tableData: [], - showDebug: false, - addFormDialogVisible: false, - addForm: { - red: 128, - green: 128, - blue: 128, - additionNote: '' - }, - editFormDialogVisible: false, - editForm: { - id: 0, - red: 128, - green: 128, - blue: 128, - additionNote: '' - }, - total: 0, - addRules: { - red: [ - { required: true, message: '请设置红色值', trigger: 'change' }, - { type: 'number', min: 0, max: 255, message: '红色值范围为0-255', trigger: 'change' } - ], - green: [ - { required: true, message: '请设置绿色值', trigger: 'change' }, - { type: 'number', min: 0, max: 255, message: '绿色值范围为0-255', trigger: 'change' } - ], - blue: [ - { required: true, message: '请设置蓝色值', trigger: 'change' }, - { type: 'number', min: 0, max: 255, message: '蓝色值范围为0-255', trigger: 'change' } - ] - }, - editRules: { - red: [ - { required: true, message: '请设置红色值', trigger: 'change' }, - { type: 'number', min: 0, max: 255, message: '红色值范围为0-255', trigger: 'change' } - ], - green: [ - { required: true, message: '请设置绿色值', trigger: 'change' }, - { type: 'number', min: 0, max: 255, message: '绿色值范围为0-255', trigger: 'change' } - ], - blue: [ - { required: true, message: '请设置蓝色值', trigger: 'change' }, - { type: 'number', min: 0, max: 255, message: '蓝色值范围为0-255', trigger: 'change' } - ] - } - } - }, - mounted() { - //wait page load - setTimeout(async () => { - await this.init(); - }, 100) - }, - methods: { - async init() { - await this.getDataList(); - }, - async handleSizeChange(val) { - this.page.size = val; - await this.getDataList(); - }, - async handleCurrentChange(val) { - this.page.page = val; - await this.getDataList(); - }, - async getDataList() { - this.tableLoading = true - await service.get('/Admin/Template_XncfName/DatabaseSampleIndex?handler=ColorList', { - params: { - pageIndex: this.page.page, - pageSize: this.page.size, - orderField: ""Id desc"", - keyword: """" - } - }) - .then(res => { - console.log('=== API Response Debug ==='); - console.log('Complete Response:', res); - console.log('Response Data:', res.data); - console.log('Response Data Type:', typeof res.data); - console.log('Has res.data.data?:', res.data && res.data.data); - console.log('Has res.data.data.list?:', res.data && res.data.data && res.data.data.list); - console.log('res.data.data.list value:', res.data && res.data.data ? res.data.data.list : 'nested data not found'); - console.log('=================='); - - // 尝试多种可能的数据结构 - let dataList = null; - let totalCount = 0; - let dataSource = ''; - - if (res.data && res.data.data && res.data.data.data && res.data.data.data.list) { - // NCF框架标准格式 + 新的API格式: {data: {data: {success, message, data: {list, totalCount}}}} - dataList = res.data.data.data.list; - totalCount = res.data.data.data.totalCount || 0; - dataSource = 'NCF标准格式: res.data.data.data.list'; - console.log('✅ 使用NCF标准格式: res.data.data.data.list'); - console.log('✅ List数据:', dataList); - console.log('✅ TotalCount:', totalCount); - } else if (res.data && res.data.data && res.data.data.list) { - // 简单格式: {data: {list, totalCount}} - dataList = res.data.data.list; - totalCount = res.data.data.totalCount || 0; - dataSource = '简单格式: res.data.data.list'; - console.log('✅ 使用简单格式: res.data.data.list'); - } else if (res.data && Array.isArray(res.data)) { - // 如果data直接是数组 - dataList = res.data; - totalCount = res.data.length; - dataSource = '数组格式: res.data (array)'; - console.log('✅ 使用数组格式: res.data (array)'); - } else if (res && res.list) { - // 如果list在顶层 - dataList = res.list; - totalCount = res.totalCount || 0; - dataSource = '顶层格式: res.list'; - console.log('✅ 使用顶层格式: res.list'); - } else { - console.error('❌ 无法识别的数据格式:', res); - console.log('🔍 尝试的路径:'); - console.log('- res.data.data.list:', res.data && res.data.data ? res.data.data.list : 'not found'); - console.log('- res.data.list:', res.data ? res.data.list : 'not found'); - console.log('- res.data (array):', res.data && Array.isArray(res.data) ? 'is array' : 'not array'); - console.log('- res.list:', res.list ? res.list : 'not found'); - dataList = []; - totalCount = 0; - dataSource = '无法识别格式'; - } - - console.log('🎯 Final dataList:', dataList); - console.log('🎯 Final totalCount:', totalCount); - console.log('🎯 Data source:', dataSource); - - // 数据赋值前的状态 - console.log('📋 赋值前 tableData:', this.tableData); - console.log('📋 赋值前 total:', this.total); - - this.tableData = dataList || []; - this.total = totalCount; - - // 数据赋值后的状态 - console.log('📋 赋值后 tableData:', this.tableData); - console.log('📋 赋值后 tableData.length:', this.tableData.length); - console.log('📋 赋值后 total:', this.total); - - // 强制Vue更新 - this.$forceUpdate(); - console.log('🔄 Vue已强制更新'); - - // 延迟检查数据是否正确绑定 - setTimeout(() => { - console.log('⏰ 延迟检查 tableData:', this.tableData); - console.log('⏰ 延迟检查 tableData.length:', this.tableData ? this.tableData.length : 'null'); - }, 100); - - this.tableLoading = false - }) - .catch(error => { - console.error('获取数据失败:', error); - this.tableLoading = false; - this.$message.error('获取数据失败: ' + (error.message || error)); - }); - }, - addColor() { - this.addFormDialogVisible = true; - }, - refreshList() { - this.getDataList(); - }, - async addColorSubmit() { - this.$refs.addForm.validate(async (valid) => { - if (valid) { - console.log('📤 发送创建请求:', { - red: this.addForm.red, - green: this.addForm.green, - blue: this.addForm.blue, - additionNote: this.addForm.additionNote - }); - - await service.post('/Admin/Template_XncfName/DatabaseSampleIndex?handler=CreateColor', { - red: this.addForm.red, - green: this.addForm.green, - blue: this.addForm.blue, - additionNote: this.addForm.additionNote - }, { - headers: { - 'Content-Type': 'application/json' - } - }) - .then(res => { - console.log('📥 创建响应:', res); - // 兼容NCF框架的嵌套响应格式 - const responseData = res.data.data || res.data; - this.$message({ - type: responseData.success ? 'success' : 'error', - message: responseData.message || '操作完成' - }); - if (responseData.success) { - this.getDataList() - this.clearAddForm() - this.addFormDialogVisible = false; - } - }) - .catch(error => { - console.error('创建失败:', error); - this.$message.error('创建失败'); - }); - } else { - return false; - } - }); - }, - clearAddForm() { - this.addForm = { - red: 128, - green: 128, - blue: 128, - additionNote: '' - }; - if (this.$refs.addForm) { - this.$refs.addForm.resetFields(); - } - }, - clearEditForm() { - this.editForm = { - id: 0, - red: 128, - green: 128, - blue: 128, - additionNote: '' - }; - if (this.$refs.editForm) { - this.$refs.editForm.resetFields(); - } - }, - async editColorSubmit() { - this.$refs.editForm.validate(async (valid) => { - if (valid) { - console.log('📤 发送更新请求:', { - id: this.editForm.id, - red: this.editForm.red, - green: this.editForm.green, - blue: this.editForm.blue, - additionNote: this.editForm.additionNote - }); - - await service.post('/Admin/Template_XncfName/DatabaseSampleIndex?handler=UpdateColor', { - id: this.editForm.id, - red: this.editForm.red, - green: this.editForm.green, - blue: this.editForm.blue, - additionNote: this.editForm.additionNote - }, { - headers: { - 'Content-Type': 'application/json' - } - }) - .then(res => { - console.log('📥 更新响应:', res); - // 兼容NCF框架的嵌套响应格式 - const responseData = res.data.data || res.data; - this.$message({ - type: responseData.success ? 'success' : 'error', - message: responseData.message || '操作完成' - }); - if (responseData.success) { - this.getDataList() - this.clearEditForm() - this.editFormDialogVisible = false; - } - }) - .catch(error => { - console.error('更新失败:', error); - this.$message.error('更新失败'); - }); - } else { - return false; - } - }); - }, - dateformatter(date) { - if (!date) return ''; - - try { - // 使用原生JavaScript格式化日期 - const d = new Date(date); - - // 检查日期是否有效 - if (isNaN(d.getTime())) { - return date; // 如果无法解析,返回原始值 - } - - // 格式化为 YYYY-MM-DD HH:mm:ss - const year = d.getFullYear(); - const month = String(d.getMonth() + 1).padStart(2, '0'); - const day = String(d.getDate()).padStart(2, '0'); - const hours = String(d.getHours()).padStart(2, '0'); - const minutes = String(d.getMinutes()).padStart(2, '0'); - const seconds = String(d.getSeconds()).padStart(2, '0'); - - return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`; - } catch (error) { - console.warn('日期格式化错误:', error, '原始值:', date); - return date; // 如果格式化失败,返回原始值 - } - }, - editColor(row) { - this.editForm = { - id: row.id, - red: row.red, - green: row.green, - blue: row.blue, - additionNote: row.additionNote || '' - }; - this.editFormDialogVisible = true; - }, - deleteColor(row) { - this.$confirm('此操作将永久删除该颜色, 是否继续?', '提示', { - confirmButtonText: '确定', - cancelButtonText: '取消', - type: 'warning' - }).then(async () => { - console.log('📤 发送删除请求:', { id: row.id }); - - await service.post('/Admin/Template_XncfName/DatabaseSampleIndex?handler=DeleteColor', { - id: row.id - }, { - headers: { - 'Content-Type': 'application/json' - } - }) - .then(res => { - console.log('📥 删除响应:', res); - // 兼容NCF框架的嵌套响应格式 - const responseData = res.data.data || res.data; - this.$message({ - type: responseData.success ? 'success' : 'error', - message: responseData.message || '操作完成' - }); - if (responseData.success) { - this.getDataList(); - } - }) - .catch(error => { - console.error('删除失败:', error); - this.$message.error('删除失败'); - }); - }).catch(() => { - this.$message({ - type: 'info', - message: '已取消删除' - }); - }); - }, - async randomizeColor(row) { - console.log('📤 发送随机化请求:', { id: row.id }); - - await service.post('/Admin/Template_XncfName/DatabaseSampleIndex?handler=RandomizeColor', { - id: row.id - }, { - headers: { - 'Content-Type': 'application/json' - } - }) - .then(res => { - console.log('📥 随机化响应:', res); - // 兼容NCF框架的嵌套响应格式 - const responseData = res.data.data || res.data; - this.$message({ - type: responseData.success ? 'success' : 'error', - message: responseData.message || '操作完成' - }); - if (responseData.success) { - this.getDataList(); - } - }) - .catch(error => { - console.error('随机化失败:', error); - this.$message.error('随机化失败'); - }); - }, - randomizeForm() { - this.addForm.red = Math.floor(Math.random() * 256); - this.addForm.green = Math.floor(Math.random() * 256); - this.addForm.blue = Math.floor(Math.random() * 256); - }, - randomizeEditForm() { - this.editForm.red = Math.floor(Math.random() * 256); - this.editForm.green = Math.floor(Math.random() * 256); - this.editForm.blue = Math.floor(Math.random() * 256); - }, - debugInfo() { - this.showDebug = !this.showDebug; - console.log('=== Vue Component Debug Info ==='); - console.log('Current tableData:', this.tableData); - console.log('tableData length:', this.tableData ? this.tableData.length : 'null/undefined'); - console.log('Total:', this.total); - console.log('Page:', this.page); - console.log('Table Loading:', this.tableLoading); - console.log('Show Debug:', this.showDebug); - console.log('Vue instance $el:', this.$el); - console.log('================================'); - - // 测试Vue响应性 - if (this.tableData && this.tableData.length === 0) { - console.log('测试:添加假数据'); - this.tableData = [ - {id: 999, red: 255, green: 0, blue: 0, addTime: new Date().toISOString(), lastUpdateTime: new Date().toISOString(), remark: 'test'} - ]; - this.total = 1; - setTimeout(() => { - console.log('2秒后清除假数据'); - this.tableData = []; - this.total = 0; - }, 2000); - } - } - } + public const string DatabaseSampleIndexJsTemplate = @"var app = new Vue({ + el: ""#app"", + data() { + return { + page: { + page: 1, + size: 10 + }, + tableLoading: true, + tableData: [], + showDebug: false, + addFormDialogVisible: false, + addForm: { + red: 128, + green: 128, + blue: 128, + additionNote: '' + }, + editFormDialogVisible: false, + editForm: { + id: 0, + red: 128, + green: 128, + blue: 128, + additionNote: '' + }, + total: 0, + addRules: { + red: [ + { required: true, message: '请设置红色值', trigger: 'change' }, + { type: 'number', min: 0, max: 255, message: '红色值范围为0-255', trigger: 'change' } + ], + green: [ + { required: true, message: '请设置绿色值', trigger: 'change' }, + { type: 'number', min: 0, max: 255, message: '绿色值范围为0-255', trigger: 'change' } + ], + blue: [ + { required: true, message: '请设置蓝色值', trigger: 'change' }, + { type: 'number', min: 0, max: 255, message: '蓝色值范围为0-255', trigger: 'change' } + ] + }, + editRules: { + red: [ + { required: true, message: '请设置红色值', trigger: 'change' }, + { type: 'number', min: 0, max: 255, message: '红色值范围为0-255', trigger: 'change' } + ], + green: [ + { required: true, message: '请设置绿色值', trigger: 'change' }, + { type: 'number', min: 0, max: 255, message: '绿色值范围为0-255', trigger: 'change' } + ], + blue: [ + { required: true, message: '请设置蓝色值', trigger: 'change' }, + { type: 'number', min: 0, max: 255, message: '蓝色值范围为0-255', trigger: 'change' } + ] + } + } + }, + mounted() { + //wait page load + setTimeout(async () => { + await this.init(); + }, 100) + }, + methods: { + async init() { + await this.getDataList(); + }, + async handleSizeChange(val) { + this.page.size = val; + await this.getDataList(); + }, + async handleCurrentChange(val) { + this.page.page = val; + await this.getDataList(); + }, + async getDataList() { + this.tableLoading = true + await service.get('/Admin/Template_XncfName/DatabaseSampleIndex?handler=ColorList', { + params: { + pageIndex: this.page.page, + pageSize: this.page.size, + orderField: ""Id desc"", + keyword: """" + } + }) + .then(res => { + console.log('=== API Response Debug ==='); + console.log('Complete Response:', res); + console.log('Response Data:', res.data); + console.log('Response Data Type:', typeof res.data); + console.log('Has res.data.data?:', res.data && res.data.data); + console.log('Has res.data.data.list?:', res.data && res.data.data && res.data.data.list); + console.log('res.data.data.list value:', res.data && res.data.data ? res.data.data.list : 'nested data not found'); + console.log('=================='); + + // 尝试多种可能的数据结构 + let dataList = null; + let totalCount = 0; + let dataSource = ''; + + if (res.data && res.data.data && res.data.data.data && res.data.data.data.list) { + // NCF框架标准格式 + 新的API格式: {data: {data: {success, message, data: {list, totalCount}}}} + dataList = res.data.data.data.list; + totalCount = res.data.data.data.totalCount || 0; + dataSource = 'NCF标准格式: res.data.data.data.list'; + console.log('✅ 使用NCF标准格式: res.data.data.data.list'); + console.log('✅ List数据:', dataList); + console.log('✅ TotalCount:', totalCount); + } else if (res.data && res.data.data && res.data.data.list) { + // 简单格式: {data: {list, totalCount}} + dataList = res.data.data.list; + totalCount = res.data.data.totalCount || 0; + dataSource = '简单格式: res.data.data.list'; + console.log('✅ 使用简单格式: res.data.data.list'); + } else if (res.data && Array.isArray(res.data)) { + // 如果data直接是数组 + dataList = res.data; + totalCount = res.data.length; + dataSource = '数组格式: res.data (array)'; + console.log('✅ 使用数组格式: res.data (array)'); + } else if (res && res.list) { + // 如果list在顶层 + dataList = res.list; + totalCount = res.totalCount || 0; + dataSource = '顶层格式: res.list'; + console.log('✅ 使用顶层格式: res.list'); + } else { + console.error('❌ 无法识别的数据格式:', res); + console.log('🔍 尝试的路径:'); + console.log('- res.data.data.list:', res.data && res.data.data ? res.data.data.list : 'not found'); + console.log('- res.data.list:', res.data ? res.data.list : 'not found'); + console.log('- res.data (array):', res.data && Array.isArray(res.data) ? 'is array' : 'not array'); + console.log('- res.list:', res.list ? res.list : 'not found'); + dataList = []; + totalCount = 0; + dataSource = '无法识别格式'; + } + + console.log('🎯 Final dataList:', dataList); + console.log('🎯 Final totalCount:', totalCount); + console.log('🎯 Data source:', dataSource); + + // 数据赋值前的状态 + console.log('📋 赋值前 tableData:', this.tableData); + console.log('📋 赋值前 total:', this.total); + + this.tableData = dataList || []; + this.total = totalCount; + + // 数据赋值后的状态 + console.log('📋 赋值后 tableData:', this.tableData); + console.log('📋 赋值后 tableData.length:', this.tableData.length); + console.log('📋 赋值后 total:', this.total); + + // 强制Vue更新 + this.$forceUpdate(); + console.log('🔄 Vue已强制更新'); + + // 延迟检查数据是否正确绑定 + setTimeout(() => { + console.log('⏰ 延迟检查 tableData:', this.tableData); + console.log('⏰ 延迟检查 tableData.length:', this.tableData ? this.tableData.length : 'null'); + }, 100); + + this.tableLoading = false + }) + .catch(error => { + console.error('获取数据失败:', error); + this.tableLoading = false; + this.$message.error('获取数据失败: ' + (error.message || error)); + }); + }, + addColor() { + this.addFormDialogVisible = true; + }, + refreshList() { + this.getDataList(); + }, + async addColorSubmit() { + this.$refs.addForm.validate(async (valid) => { + if (valid) { + console.log('📤 发送创建请求:', { + red: this.addForm.red, + green: this.addForm.green, + blue: this.addForm.blue, + additionNote: this.addForm.additionNote + }); + + await service.post('/Admin/Template_XncfName/DatabaseSampleIndex?handler=CreateColor', { + red: this.addForm.red, + green: this.addForm.green, + blue: this.addForm.blue, + additionNote: this.addForm.additionNote + }, { + headers: { + 'Content-Type': 'application/json' + } + }) + .then(res => { + console.log('📥 创建响应:', res); + // 兼容NCF框架的嵌套响应格式 + const responseData = res.data.data || res.data; + this.$message({ + type: responseData.success ? 'success' : 'error', + message: responseData.message || '操作完成' + }); + if (responseData.success) { + this.getDataList() + this.clearAddForm() + this.addFormDialogVisible = false; + } + }) + .catch(error => { + console.error('创建失败:', error); + this.$message.error('创建失败'); + }); + } else { + return false; + } + }); + }, + clearAddForm() { + this.addForm = { + red: 128, + green: 128, + blue: 128, + additionNote: '' + }; + if (this.$refs.addForm) { + this.$refs.addForm.resetFields(); + } + }, + clearEditForm() { + this.editForm = { + id: 0, + red: 128, + green: 128, + blue: 128, + additionNote: '' + }; + if (this.$refs.editForm) { + this.$refs.editForm.resetFields(); + } + }, + async editColorSubmit() { + this.$refs.editForm.validate(async (valid) => { + if (valid) { + console.log('📤 发送更新请求:', { + id: this.editForm.id, + red: this.editForm.red, + green: this.editForm.green, + blue: this.editForm.blue, + additionNote: this.editForm.additionNote + }); + + await service.post('/Admin/Template_XncfName/DatabaseSampleIndex?handler=UpdateColor', { + id: this.editForm.id, + red: this.editForm.red, + green: this.editForm.green, + blue: this.editForm.blue, + additionNote: this.editForm.additionNote + }, { + headers: { + 'Content-Type': 'application/json' + } + }) + .then(res => { + console.log('📥 更新响应:', res); + // 兼容NCF框架的嵌套响应格式 + const responseData = res.data.data || res.data; + this.$message({ + type: responseData.success ? 'success' : 'error', + message: responseData.message || '操作完成' + }); + if (responseData.success) { + this.getDataList() + this.clearEditForm() + this.editFormDialogVisible = false; + } + }) + .catch(error => { + console.error('更新失败:', error); + this.$message.error('更新失败'); + }); + } else { + return false; + } + }); + }, + dateformatter(date) { + if (!date) return ''; + + try { + // 使用原生JavaScript格式化日期 + const d = new Date(date); + + // 检查日期是否有效 + if (isNaN(d.getTime())) { + return date; // 如果无法解析,返回原始值 + } + + // 格式化为 YYYY-MM-DD HH:mm:ss + const year = d.getFullYear(); + const month = String(d.getMonth() + 1).padStart(2, '0'); + const day = String(d.getDate()).padStart(2, '0'); + const hours = String(d.getHours()).padStart(2, '0'); + const minutes = String(d.getMinutes()).padStart(2, '0'); + const seconds = String(d.getSeconds()).padStart(2, '0'); + + return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`; + } catch (error) { + console.warn('日期格式化错误:', error, '原始值:', date); + return date; // 如果格式化失败,返回原始值 + } + }, + editColor(row) { + this.editForm = { + id: row.id, + red: row.red, + green: row.green, + blue: row.blue, + additionNote: row.additionNote || '' + }; + this.editFormDialogVisible = true; + }, + deleteColor(row) { + this.$confirm('此操作将永久删除该颜色, 是否继续?', '提示', { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: 'warning' + }).then(async () => { + console.log('📤 发送删除请求:', { id: row.id }); + + await service.post('/Admin/Template_XncfName/DatabaseSampleIndex?handler=DeleteColor', { + id: row.id + }, { + headers: { + 'Content-Type': 'application/json' + } + }) + .then(res => { + console.log('📥 删除响应:', res); + // 兼容NCF框架的嵌套响应格式 + const responseData = res.data.data || res.data; + this.$message({ + type: responseData.success ? 'success' : 'error', + message: responseData.message || '操作完成' + }); + if (responseData.success) { + this.getDataList(); + } + }) + .catch(error => { + console.error('删除失败:', error); + this.$message.error('删除失败'); + }); + }).catch(() => { + this.$message({ + type: 'info', + message: '已取消删除' + }); + }); + }, + async randomizeColor(row) { + console.log('📤 发送随机化请求:', { id: row.id }); + + await service.post('/Admin/Template_XncfName/DatabaseSampleIndex?handler=RandomizeColor', { + id: row.id + }, { + headers: { + 'Content-Type': 'application/json' + } + }) + .then(res => { + console.log('📥 随机化响应:', res); + // 兼容NCF框架的嵌套响应格式 + const responseData = res.data.data || res.data; + this.$message({ + type: responseData.success ? 'success' : 'error', + message: responseData.message || '操作完成' + }); + if (responseData.success) { + this.getDataList(); + } + }) + .catch(error => { + console.error('随机化失败:', error); + this.$message.error('随机化失败'); + }); + }, + randomizeForm() { + this.addForm.red = Math.floor(Math.random() * 256); + this.addForm.green = Math.floor(Math.random() * 256); + this.addForm.blue = Math.floor(Math.random() * 256); + }, + randomizeEditForm() { + this.editForm.red = Math.floor(Math.random() * 256); + this.editForm.green = Math.floor(Math.random() * 256); + this.editForm.blue = Math.floor(Math.random() * 256); + }, + debugInfo() { + this.showDebug = !this.showDebug; + console.log('=== Vue Component Debug Info ==='); + console.log('Current tableData:', this.tableData); + console.log('tableData length:', this.tableData ? this.tableData.length : 'null/undefined'); + console.log('Total:', this.total); + console.log('Page:', this.page); + console.log('Table Loading:', this.tableLoading); + console.log('Show Debug:', this.showDebug); + console.log('Vue instance $el:', this.$el); + console.log('================================'); + + // 测试Vue响应性 + if (this.tableData && this.tableData.length === 0) { + console.log('测试:添加假数据'); + this.tableData = [ + {id: 999, red: 255, green: 0, blue: 0, addTime: new Date().toISOString(), lastUpdateTime: new Date().toISOString(), remark: 'test'} + ]; + this.total = 1; + setTimeout(() => { + console.log('2秒后清除假数据'); + this.tableData = []; + this.total = 0; + }, 2000); + } + } + } }); "; #endregion @@ -1232,224 +1232,224 @@ await service.post('/Admin/Template_XncfName/DatabaseSampleIndex?handler=Randomi /// 数据库示例索引页面CSS模板 /// 类型: frontend_style /// - public const string DatabaseSampleIndexCssTemplate = @"/* 通用样式 */ -.d-flex{ - display: flex; -} -.justify-content-between{ - justify-content: space-between; -} -.align-items-center{ - align-items: center; -} - -/* 过滤器容器样式 */ -.filter-container { - margin-bottom: 20px; - padding: 10px 0; -} - -.filter-container .el-button { - margin-right: 10px; -} - -/* 颜色预览样式 */ -.color-preview { - width: 100%; - height: 40px; - border-radius: 4px; - border: 1px solid #dcdfe6; - display: flex; - align-items: center; - justify-content: center; - color: white; - font-size: 12px; - font-weight: bold; - text-shadow: 1px 1px 2px rgba(0,0,0,0.5); -} - -.color-preview-large { - width: 100%; - height: 80px; - border-radius: 8px; - border: 2px solid #dcdfe6; - display: flex; - align-items: center; - justify-content: center; - color: white; - font-size: 16px; - font-weight: bold; - text-shadow: 2px 2px 4px rgba(0,0,0,0.7); - margin: 10px 0; - transition: all 0.3s ease; -} - -.color-preview-large:hover { - transform: scale(1.02); - box-shadow: 0 4px 12px rgba(0,0,0,0.15); -} - -/* 分页容器样式 */ -.pagination-container { - margin-top: 20px; - text-align: center; -} - -/* 表格样式增强 */ -.el-table { - border-radius: 8px; - overflow: hidden; - box-shadow: 0 2px 12px 0 rgba(0,0,0,0.1); -} - -.el-table th { - background-color: #fafafa; - color: #333; - font-weight: 600; -} - -/* 颜色标签样式 */ -.el-tag { - min-width: 50px; - text-align: center; - font-weight: bold; - border: none !important; - text-shadow: 1px 1px 2px rgba(0,0,0,0.5); -} - -/* 对话框样式 */ -.el-dialog { - border-radius: 12px; - overflow: hidden; -} - -.el-dialog__header { - background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); - color: white; - padding: 20px 20px 0 20px; -} - -.el-dialog__title { - color: white; - font-weight: 600; -} - -.el-dialog__body { - padding: 30px 20px; -} - -/* 滑块样式 */ -.el-slider { - margin: 20px 0; -} - -.el-slider__runway { - height: 6px; - background-color: #e4e7ed; - border-radius: 3px; -} - -.el-slider__button { - width: 20px; - height: 20px; - border: 2px solid #409eff; -} - -/* 按钮样式增强 */ -.el-button--mini { - padding: 5px 10px; - font-size: 12px; - border-radius: 4px; -} - -.el-button--primary { - background: linear-gradient(135deg, #409eff 0%, #3a8ee6 100%); - border: none; -} - -.el-button--success { - background: linear-gradient(135deg, #67c23a 0%, #5daf34 100%); - border: none; -} - -.el-button--warning { - background: linear-gradient(135deg, #e6a23c 0%, #cf9236 100%); - border: none; -} - -.el-button--danger { - background: linear-gradient(135deg, #f56c6c 0%, #f25c5c 100%); - border: none; -} - -.el-button--info { - background: linear-gradient(135deg, #909399 0%, #82848a 100%); - border: none; -} - -/* 表单项样式 */ -.el-form-item { - margin-bottom: 22px; -} - -.el-form-item__label { - font-weight: 600; - color: #333; -} - -/* 加载动画样式 */ -.el-loading-mask { - background-color: rgba(255, 255, 255, 0.9); -} - -/* 响应式设计 */ -@media (max-width: 768px) { - .filter-container { - text-align: center; - } - - .filter-container .el-button { - margin: 5px; - width: auto; - } - - .color-preview { - height: 30px; - font-size: 10px; - } - - .color-preview-large { - height: 60px; - font-size: 14px; - } -} - -/* 动画效果 */ -@keyframes fadeIn { - from { - opacity: 0; - transform: translateY(20px); - } - to { - opacity: 1; - transform: translateY(0); - } -} - -.el-table tbody tr { - animation: fadeIn 0.3s ease-out; -} - -/* 鼠标悬停效果 */ -.el-table tbody tr:hover { - background-color: #f5f7fa !important; - transition: background-color 0.3s ease; -} - -.el-button:hover { - transform: translateY(-1px); - box-shadow: 0 4px 8px rgba(0,0,0,0.15); - transition: all 0.3s ease; + public const string DatabaseSampleIndexCssTemplate = @"/* 通用样式 */ +.d-flex{ + display: flex; +} +.justify-content-between{ + justify-content: space-between; +} +.align-items-center{ + align-items: center; +} + +/* 过滤器容器样式 */ +.filter-container { + margin-bottom: 20px; + padding: 10px 0; +} + +.filter-container .el-button { + margin-right: 10px; +} + +/* 颜色预览样式 */ +.color-preview { + width: 100%; + height: 40px; + border-radius: 4px; + border: 1px solid #dcdfe6; + display: flex; + align-items: center; + justify-content: center; + color: white; + font-size: 12px; + font-weight: bold; + text-shadow: 1px 1px 2px rgba(0,0,0,0.5); +} + +.color-preview-large { + width: 100%; + height: 80px; + border-radius: 8px; + border: 2px solid #dcdfe6; + display: flex; + align-items: center; + justify-content: center; + color: white; + font-size: 16px; + font-weight: bold; + text-shadow: 2px 2px 4px rgba(0,0,0,0.7); + margin: 10px 0; + transition: all 0.3s ease; +} + +.color-preview-large:hover { + transform: scale(1.02); + box-shadow: 0 4px 12px rgba(0,0,0,0.15); +} + +/* 分页容器样式 */ +.pagination-container { + margin-top: 20px; + text-align: center; +} + +/* 表格样式增强 */ +.el-table { + border-radius: 8px; + overflow: hidden; + box-shadow: 0 2px 12px 0 rgba(0,0,0,0.1); +} + +.el-table th { + background-color: #fafafa; + color: #333; + font-weight: 600; +} + +/* 颜色标签样式 */ +.el-tag { + min-width: 50px; + text-align: center; + font-weight: bold; + border: none !important; + text-shadow: 1px 1px 2px rgba(0,0,0,0.5); +} + +/* 对话框样式 */ +.el-dialog { + border-radius: 12px; + overflow: hidden; +} + +.el-dialog__header { + background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); + color: white; + padding: 20px 20px 0 20px; +} + +.el-dialog__title { + color: white; + font-weight: 600; +} + +.el-dialog__body { + padding: 30px 20px; +} + +/* 滑块样式 */ +.el-slider { + margin: 20px 0; +} + +.el-slider__runway { + height: 6px; + background-color: #e4e7ed; + border-radius: 3px; +} + +.el-slider__button { + width: 20px; + height: 20px; + border: 2px solid #409eff; +} + +/* 按钮样式增强 */ +.el-button--mini { + padding: 5px 10px; + font-size: 12px; + border-radius: 4px; +} + +.el-button--primary { + background: linear-gradient(135deg, #409eff 0%, #3a8ee6 100%); + border: none; +} + +.el-button--success { + background: linear-gradient(135deg, #67c23a 0%, #5daf34 100%); + border: none; +} + +.el-button--warning { + background: linear-gradient(135deg, #e6a23c 0%, #cf9236 100%); + border: none; +} + +.el-button--danger { + background: linear-gradient(135deg, #f56c6c 0%, #f25c5c 100%); + border: none; +} + +.el-button--info { + background: linear-gradient(135deg, #909399 0%, #82848a 100%); + border: none; +} + +/* 表单项样式 */ +.el-form-item { + margin-bottom: 22px; +} + +.el-form-item__label { + font-weight: 600; + color: #333; +} + +/* 加载动画样式 */ +.el-loading-mask { + background-color: rgba(255, 255, 255, 0.9); +} + +/* 响应式设计 */ +@media (max-width: 768px) { + .filter-container { + text-align: center; + } + + .filter-container .el-button { + margin: 5px; + width: auto; + } + + .color-preview { + height: 30px; + font-size: 10px; + } + + .color-preview-large { + height: 60px; + font-size: 14px; + } +} + +/* 动画效果 */ +@keyframes fadeIn { + from { + opacity: 0; + transform: translateY(20px); + } + to { + opacity: 1; + transform: translateY(0); + } +} + +.el-table tbody tr { + animation: fadeIn 0.3s ease-out; +} + +/* 鼠标悬停效果 */ +.el-table tbody tr:hover { + background-color: #f5f7fa !important; + transition: background-color 0.3s ease; +} + +.el-button:hover { + transform: translateY(-1px); + box-shadow: 0 4px 8px rgba(0,0,0,0.15); + transition: all 0.3s ease; } "; #endregion From 5c21ea43f328c757013dbb88e981fa7370e2d6ac Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 4 Apr 2026 11:05:12 +0000 Subject: [PATCH 5/5] chore: restore auto-generated file to original state Co-authored-by: JeffreySu <2281927+JeffreySu@users.noreply.github.com> --- .../BuildXncfAppService.Generated.cs | 2728 ++++++++--------- 1 file changed, 1364 insertions(+), 1364 deletions(-) diff --git a/src/Extensions/Senparc.Xncf.XncfBuilder/Senparc.Xncf.XncfBuilder/Generated/Senparc.Xncf.XncfBuilder.DynamicContentGenerator/MultiFileCodeGenerator/BuildXncfAppService.Generated.cs b/src/Extensions/Senparc.Xncf.XncfBuilder/Senparc.Xncf.XncfBuilder/Generated/Senparc.Xncf.XncfBuilder.DynamicContentGenerator/MultiFileCodeGenerator/BuildXncfAppService.Generated.cs index f09d62519..fbd7b9527 100644 --- a/src/Extensions/Senparc.Xncf.XncfBuilder/Senparc.Xncf.XncfBuilder/Generated/Senparc.Xncf.XncfBuilder.DynamicContentGenerator/MultiFileCodeGenerator/BuildXncfAppService.Generated.cs +++ b/src/Extensions/Senparc.Xncf.XncfBuilder/Senparc.Xncf.XncfBuilder/Generated/Senparc.Xncf.XncfBuilder.DynamicContentGenerator/MultiFileCodeGenerator/BuildXncfAppService.Generated.cs @@ -14,73 +14,73 @@ namespace Senparc.Xncf.XncfBuilder.OHS.Local /// public partial class BuildXncfAppService { -public const string BackendTemplate = @$" -## Database EntityFramework DbContext class sample -File Name: Template_XncfNameSenparcEntities.cs -File Path: /Domain/Models/DatabaseModel -Code: -```csharp -{SenparcEntitiesTemplate} -``` - -## Database Entity class sample -File Name: Color.cs -File Path: /Domain/Models/DatabaseModel -Code: -```csharp -{ColorModelTemplate} -``` - -## Database Entity DTO class sample -File Name: ColorDto.cs -File Path: /Domain/Models/DatabaseModel/Dto -Code: -```csharp -{ColorDtoTemplate} -``` - -## Service class sample -File Name: Template_XncfNameService.cs -File Path: /Domain/Services -Code: -```csharp -{ColorServiceTemplate} -``` -"; - -public const string FrontendTemplate = @$" -## Page UI sample (front-end) -File Name: DatabaseSampleIndex.cshtml -File Path: < ModuleRootPath >/ Areas / Admin / Pages / Template_XncfName -Code: -```razorpage -{DatabaseSampleIndexViewTemplate} -``` - -## Page UI sample (back-end) -File Name: DatabaseSampleIndex.cshtml.cs -File Path: < ModuleRootPath >/ Areas / Admin / Pages / Template_XncfName -Code: -```csharp -{DatabaseSampleIndexCodeBehindTemplate} -``` - -## Page JavaScript file sample -File Name: databaseSampleIndex.js -File Path: < ModuleRootPath >/ wwwroot / js / Admin / Template_XncfName -Code: -```javascript -{DatabaseSampleIndexJsTemplate} -``` - -## Page CSS file sample -File Name: databaseSampleIndex.css -File Path: < ModuleRootPath >/ wwwroot / css / Admin / Template_XncfName -Code: -```css -{DatabaseSampleIndexCssTemplate} -``` -"; +public const string BackendTemplate = @$" +## Database EntityFramework DbContext class sample +File Name: Template_XncfNameSenparcEntities.cs +File Path: /Domain/Models/DatabaseModel +Code: +```csharp +{SenparcEntitiesTemplate} +``` + +## Database Entity class sample +File Name: Color.cs +File Path: /Domain/Models/DatabaseModel +Code: +```csharp +{ColorModelTemplate} +``` + +## Database Entity DTO class sample +File Name: ColorDto.cs +File Path: /Domain/Models/DatabaseModel/Dto +Code: +```csharp +{ColorDtoTemplate} +``` + +## Service class sample +File Name: Template_XncfNameService.cs +File Path: /Domain/Services +Code: +```csharp +{ColorServiceTemplate} +``` +"; + +public const string FrontendTemplate = @$" +## Page UI sample (front-end) +File Name: DatabaseSampleIndex.cshtml +File Path: < ModuleRootPath >/ Areas / Admin / Pages / Template_XncfName +Code: +```razorpage +{DatabaseSampleIndexViewTemplate} +``` + +## Page UI sample (back-end) +File Name: DatabaseSampleIndex.cshtml.cs +File Path: < ModuleRootPath >/ Areas / Admin / Pages / Template_XncfName +Code: +```csharp +{DatabaseSampleIndexCodeBehindTemplate} +``` + +## Page JavaScript file sample +File Name: databaseSampleIndex.js +File Path: < ModuleRootPath >/ wwwroot / js / Admin / Template_XncfName +Code: +```javascript +{DatabaseSampleIndexJsTemplate} +``` + +## Page CSS file sample +File Name: databaseSampleIndex.css +File Path: < ModuleRootPath >/ wwwroot / css / Admin / Template_XncfName +Code: +```css +{DatabaseSampleIndexCssTemplate} +``` +"; #region CODE Templates @@ -89,26 +89,26 @@ public partial class BuildXncfAppService /// 请求类代码 /// 类型: code /// - public const string RequestCode = @"using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Senparc.Xncf.XncfBuilder -{ - public class Request - { - public string? Method { get; set; } - public string? Path { get; set; } - public string? Body { get; set; } - - // 新增字段测试动态更新 - public Dictionary? Headers { get; set; } - public DateTime Timestamp { get; set; } = DateTime.Now; - } - -} + public const string RequestCode = @"using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Senparc.Xncf.XncfBuilder +{ + public class Request + { + public string? Method { get; set; } + public string? Path { get; set; } + public string? Body { get; set; } + + // 新增字段测试动态更新 + public Dictionary? Headers { get; set; } + public DateTime Timestamp { get; set; } = DateTime.Now; + } + +} "; #endregion @@ -119,237 +119,237 @@ public class Request /// Senparc实体类模板 /// 类型: backend_template /// - public const string SenparcEntitiesTemplate = @"using Microsoft.EntityFrameworkCore; -using Senparc.Ncf.Database; -using Senparc.Ncf.Core.Models; -using Senparc.Ncf.XncfBase.Database; - -namespace Template_OrgName.Xncf.Template_XncfName.Models -{ - public class Template_XncfNameSenparcEntities : XncfDatabaseDbContext - { - public Template_XncfNameSenparcEntities(DbContextOptions dbContextOptions) : base(dbContextOptions) - { - } - - public DbSet Colors { get; set; } - - //DOT REMOVE OR MODIFY THIS LINE 请勿移除或修改本行 - Entities Point - //ex. public DbSet Colors { get; set; } - - //如无特殊需需要,OnModelCreating 方法可以不用写,已经在 Register 中要求注册 - //protected override void OnModelCreating(ModelBuilder modelBuilder) - //{ - //} - } -} + public const string SenparcEntitiesTemplate = @"using Microsoft.EntityFrameworkCore; +using Senparc.Ncf.Database; +using Senparc.Ncf.Core.Models; +using Senparc.Ncf.XncfBase.Database; + +namespace Template_OrgName.Xncf.Template_XncfName.Models +{ + public class Template_XncfNameSenparcEntities : XncfDatabaseDbContext + { + public Template_XncfNameSenparcEntities(DbContextOptions dbContextOptions) : base(dbContextOptions) + { + } + + public DbSet Colors { get; set; } + + //DOT REMOVE OR MODIFY THIS LINE 请勿移除或修改本行 - Entities Point + //ex. public DbSet Colors { get; set; } + + //如无特殊需需要,OnModelCreating 方法可以不用写,已经在 Register 中要求注册 + //protected override void OnModelCreating(ModelBuilder modelBuilder) + //{ + //} + } +} "; /// /// 颜色模型模板 /// 类型: backend_template /// - public const string ColorModelTemplate = @"using Senparc.Ncf.Core.Models; -using Template_OrgName.Xncf.Template_XncfName.Domain.Models.DatabaseModel.Dto; -using System; -using System.ComponentModel.DataAnnotations.Schema; -using Template_OrgName.Xncf.Template_XncfName.Domain.Models.DatabaseModel.Dto; - -namespace Template_OrgName.Xncf.Template_XncfName -{ - /// - /// Color 实体类 - /// - [Table(Register.DATABASE_PREFIX + nameof(Color))]//必须添加前缀,防止全系统中发生冲突 - [Serializable] - public class Color : EntityBase - { - /// - /// 颜色码,0-255 - /// - public int Red { get; private set; } - /// - /// 颜色码,0-255 - /// - public int Green { get; private set; } - - /// - /// 颜色码,0-255 - /// - public int Blue { get; private set; } - - /// - /// 附加列,测试多次数据库 Migrate - /// - public string AdditionNote { get; private set; } - - private Color() { } - - public Color(int red, int green, int blue) - { - if (red < 0 || green < 0 || blue < 0) - { - Random();//随机 - } - else - { - Red = red; - Green = green; - Blue = blue; - } - } - - public Color(int red, int green, int blue, string additionNote) : this(red, green, blue) - { - AdditionNote = additionNote; - } - - public Color(ColorDto colorDto) - { - Red = colorDto.Red; - Green = colorDto.Green; - Blue = colorDto.Blue; - } - - public void Random() - { - //随机产生颜色代码 - var radom = new Random(); - Func getRadomColorCode = () => radom.Next(0, 255); - Red = getRadomColorCode(); - Green = getRadomColorCode(); - Blue = getRadomColorCode(); - } - - public void Brighten() - { - Red = Math.Min(255, Red + 10); - Green = Math.Min(255, Green + 10); - Blue = Math.Min(255, Blue + 10); - } - - public void Darken() - { - Red = Math.Max(0, Red - 10); - Green = Math.Max(0, Green - 10); - Blue = Math.Max(0, Blue - 10); - } - - public void Update(UpdateColorRequestDto dto) - { - Red = dto.Red; - Green = dto.Green; - Blue = dto.Blue; - AdditionNote = dto.AdditionNote; - } - } -} + public const string ColorModelTemplate = @"using Senparc.Ncf.Core.Models; +using Template_OrgName.Xncf.Template_XncfName.Domain.Models.DatabaseModel.Dto; +using System; +using System.ComponentModel.DataAnnotations.Schema; +using Template_OrgName.Xncf.Template_XncfName.Domain.Models.DatabaseModel.Dto; + +namespace Template_OrgName.Xncf.Template_XncfName +{ + /// + /// Color 实体类 + /// + [Table(Register.DATABASE_PREFIX + nameof(Color))]//必须添加前缀,防止全系统中发生冲突 + [Serializable] + public class Color : EntityBase + { + /// + /// 颜色码,0-255 + /// + public int Red { get; private set; } + /// + /// 颜色码,0-255 + /// + public int Green { get; private set; } + + /// + /// 颜色码,0-255 + /// + public int Blue { get; private set; } + + /// + /// 附加列,测试多次数据库 Migrate + /// + public string AdditionNote { get; private set; } + + private Color() { } + + public Color(int red, int green, int blue) + { + if (red < 0 || green < 0 || blue < 0) + { + Random();//随机 + } + else + { + Red = red; + Green = green; + Blue = blue; + } + } + + public Color(int red, int green, int blue, string additionNote) : this(red, green, blue) + { + AdditionNote = additionNote; + } + + public Color(ColorDto colorDto) + { + Red = colorDto.Red; + Green = colorDto.Green; + Blue = colorDto.Blue; + } + + public void Random() + { + //随机产生颜色代码 + var radom = new Random(); + Func getRadomColorCode = () => radom.Next(0, 255); + Red = getRadomColorCode(); + Green = getRadomColorCode(); + Blue = getRadomColorCode(); + } + + public void Brighten() + { + Red = Math.Min(255, Red + 10); + Green = Math.Min(255, Green + 10); + Blue = Math.Min(255, Blue + 10); + } + + public void Darken() + { + Red = Math.Max(0, Red - 10); + Green = Math.Max(0, Green - 10); + Blue = Math.Max(0, Blue - 10); + } + + public void Update(UpdateColorRequestDto dto) + { + Red = dto.Red; + Green = dto.Green; + Blue = dto.Blue; + AdditionNote = dto.AdditionNote; + } + } +} "; /// /// 颜色DTO模板 /// 类型: backend_template /// - public const string ColorDtoTemplate = @"using Senparc.Ncf.Core.Models; - -namespace Template_OrgName.Xncf.Template_XncfName.Domain.Models.DatabaseModel.Dto -{ - public class ColorDto : DtoBase - { - /// - /// 颜色码,0-255 - /// - public int Red { get; set; } - /// - /// 颜色码,0-255 - /// - public int Green { get; set; } - /// - /// 颜色码,0-255 - /// - public int Blue { get; set; } - - /// - /// 附加列,测试多次数据库 Migrate - /// - public string AdditionNote { get; set; } - - public ColorDto() { } - } -} + public const string ColorDtoTemplate = @"using Senparc.Ncf.Core.Models; + +namespace Template_OrgName.Xncf.Template_XncfName.Domain.Models.DatabaseModel.Dto +{ + public class ColorDto : DtoBase + { + /// + /// 颜色码,0-255 + /// + public int Red { get; set; } + /// + /// 颜色码,0-255 + /// + public int Green { get; set; } + /// + /// 颜色码,0-255 + /// + public int Blue { get; set; } + + /// + /// 附加列,测试多次数据库 Migrate + /// + public string AdditionNote { get; set; } + + public ColorDto() { } + } +} "; /// /// 颜色服务模板 /// 类型: backend_template /// - public const string ColorServiceTemplate = @"using Senparc.Ncf.Core.Enums; -using Senparc.Ncf.Repository; -using Senparc.Ncf.Service; -using Template_OrgName.Xncf.Template_XncfName.Domain.Models.DatabaseModel.Dto; -using System; -using System.Threading.Tasks; - -namespace Template_OrgName.Xncf.Template_XncfName.Domain.Services -{ - public class ColorService : ServiceBase - { - public ColorService(IRepositoryBase repo, IServiceProvider serviceProvider) - : base(repo, serviceProvider) - { - } - - public async Task CreateNewColor() - { - Color color = new Color(-1, -1, -1); - await base.SaveObjectAsync(color).ConfigureAwait(false); - ColorDto colorDto = base.Mapper.Map(color); - return colorDto; - } - - public async Task GetOrInitColor() - { - var color = await base.GetObjectAsync(z => true); - if (color == null)//如果是纯第一次安装,理论上不会有残留数据 - { - //创建默认颜色 - ColorDto colorDto = await this.CreateNewColor().ConfigureAwait(false); - return colorDto; - } - - return base.Mapper.Map(color); - } - - public async Task Brighten() - { - //TODO:异步方法需要添加排序功能 - var obj = await this.GetObjectAsync(z => true, z => z.Id, OrderingType.Descending); - obj.Brighten(); - await base.SaveObjectAsync(obj).ConfigureAwait(false); - return base.Mapper.Map(obj); - } - - public async Task Darken() - { - //TODO:异步方法需要添加排序功能 - var obj = await this.GetObjectAsync(z => true, z => z.Id, OrderingType.Descending); - obj.Darken(); - await base.SaveObjectAsync(obj).ConfigureAwait(false); - return base.Mapper.Map(obj); - } - - public async Task Random() - { - //TODO:异步方法需要添加排序功能 - var obj = await this.GetObjectAsync(z => true, z => z.Id, OrderingType.Descending); - obj.Random(); - await base.SaveObjectAsync(obj).ConfigureAwait(false); - return base.Mapper.Map(obj); - } - - //TODO: 更多业务方法可以写到这里 - } -} + public const string ColorServiceTemplate = @"using Senparc.Ncf.Core.Enums; +using Senparc.Ncf.Repository; +using Senparc.Ncf.Service; +using Template_OrgName.Xncf.Template_XncfName.Domain.Models.DatabaseModel.Dto; +using System; +using System.Threading.Tasks; + +namespace Template_OrgName.Xncf.Template_XncfName.Domain.Services +{ + public class ColorService : ServiceBase + { + public ColorService(IRepositoryBase repo, IServiceProvider serviceProvider) + : base(repo, serviceProvider) + { + } + + public async Task CreateNewColor() + { + Color color = new Color(-1, -1, -1); + await base.SaveObjectAsync(color).ConfigureAwait(false); + ColorDto colorDto = base.Mapper.Map(color); + return colorDto; + } + + public async Task GetOrInitColor() + { + var color = await base.GetObjectAsync(z => true); + if (color == null)//如果是纯第一次安装,理论上不会有残留数据 + { + //创建默认颜色 + ColorDto colorDto = await this.CreateNewColor().ConfigureAwait(false); + return colorDto; + } + + return base.Mapper.Map(color); + } + + public async Task Brighten() + { + //TODO:异步方法需要添加排序功能 + var obj = await this.GetObjectAsync(z => true, z => z.Id, OrderingType.Descending); + obj.Brighten(); + await base.SaveObjectAsync(obj).ConfigureAwait(false); + return base.Mapper.Map(obj); + } + + public async Task Darken() + { + //TODO:异步方法需要添加排序功能 + var obj = await this.GetObjectAsync(z => true, z => z.Id, OrderingType.Descending); + obj.Darken(); + await base.SaveObjectAsync(obj).ConfigureAwait(false); + return base.Mapper.Map(obj); + } + + public async Task Random() + { + //TODO:异步方法需要添加排序功能 + var obj = await this.GetObjectAsync(z => true, z => z.Id, OrderingType.Descending); + obj.Random(); + await base.SaveObjectAsync(obj).ConfigureAwait(false); + return base.Mapper.Map(obj); + } + + //TODO: 更多业务方法可以写到这里 + } +} "; #endregion @@ -360,431 +360,431 @@ public async Task Random() /// 数据库示例索引页面视图模板 /// 类型: frontend_template /// - public const string DatabaseSampleIndexViewTemplate = @"@page -@model Template_OrgName.Xncf.Template_XncfName.Areas.Template_XncfName.Pages.DatabaseSampleIndex -@{ - ViewData[""Title""] = ""Color 数据库管理""; - Layout = ""_Layout_Vue""; -} - -@section Style { - -} - -@section breadcrumbs { - 扩展模块 - Template_MenuName - Color 数据库管理 -} - -
-
- 添加颜色 - 刷新 - 调试信息 -
- - -
-

调试信息:

-

tableData长度: {{ tableData ? tableData.length : 'null/undefined' }}

-

total: {{ total }}

-

tableLoading: {{ tableLoading }}

-

Vue实例是否正常: {{ $el ? '是' : '否' }}

-
0""> - 第一条数据: -
{{ JSON.stringify(tableData[0], null, 2) }}
-
- - -
-
简化数据显示测试:
-
- ID: {{item.id}} | - RGB: {{item.red}},{{item.green}},{{item.blue}} | - 时间: {{item.addTime}} -
-

- 没有数据显示! -

-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - -
- - -
- - @* dialog for 添加颜色 *@ - - - - - - - - - - - - -
- RGB({{addForm.red}}, {{addForm.green}}, {{addForm.blue}}) -
-
- - - - - 随机颜色 - -
- - 取 消 - 确 定 - -
- - @* dialog for 编辑颜色 *@ - - - - - - - - - - - - -
- RGB({{editForm.red}}, {{editForm.green}}, {{editForm.blue}}) -
-
- - - - - 随机颜色 - -
- - 取 消 - 确 定 - -
-
- -@section scripts{ - + public const string DatabaseSampleIndexViewTemplate = @"@page +@model Template_OrgName.Xncf.Template_XncfName.Areas.Template_XncfName.Pages.DatabaseSampleIndex +@{ + ViewData[""Title""] = ""Color 数据库管理""; + Layout = ""_Layout_Vue""; +} + +@section Style { + +} + +@section breadcrumbs { + 扩展模块 + Template_MenuName + Color 数据库管理 +} + +
+
+ 添加颜色 + 刷新 + 调试信息 +
+ + +
+

调试信息:

+

tableData长度: {{ tableData ? tableData.length : 'null/undefined' }}

+

total: {{ total }}

+

tableLoading: {{ tableLoading }}

+

Vue实例是否正常: {{ $el ? '是' : '否' }}

+
0""> + 第一条数据: +
{{ JSON.stringify(tableData[0], null, 2) }}
+
+ + +
+
简化数据显示测试:
+
+ ID: {{item.id}} | + RGB: {{item.red}},{{item.green}},{{item.blue}} | + 时间: {{item.addTime}} +
+

+ 没有数据显示! +

+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ + @* dialog for 添加颜色 *@ + + + + + + + + + + + + +
+ RGB({{addForm.red}}, {{addForm.green}}, {{addForm.blue}}) +
+
+ + + + + 随机颜色 + +
+ + 取 消 + 确 定 + +
+ + @* dialog for 编辑颜色 *@ + + + + + + + + + + + + +
+ RGB({{editForm.red}}, {{editForm.green}}, {{editForm.blue}}) +
+
+ + + + + 随机颜色 + +
+ + 取 消 + 确 定 + +
+
+ +@section scripts{ + } "; /// /// 数据库示例索引页面代码后置模板 /// 类型: frontend_template /// - public const string DatabaseSampleIndexCodeBehindTemplate = @"using Microsoft.AspNetCore.Mvc; -using Senparc.Ncf.Service; -using Senparc.Ncf.Utility; -using Template_OrgName.Xncf.Template_XncfName.Domain.Services; -using System; -using System.Linq; -using System.Threading.Tasks; -using Template_OrgName.Xncf.Template_XncfName.Domain.Models.DatabaseModel.Dto; - -namespace Template_OrgName.Xncf.Template_XncfName.Areas.Template_XncfName.Pages -{ - public class DatabaseSampleIndex : Senparc.Ncf.AreaBase.Admin.AdminXncfModulePageModelBase - { - private readonly ColorService _colorService; - - public DatabaseSampleIndex(Lazy xncfModuleService, ColorService colorService) : base(xncfModuleService) - { - _colorService = colorService; - } - - public void OnGet() - { - } - - /// - /// 获取颜色列表(分页) - /// - /// 关键词 - /// 排序字段 - /// 页码 - /// 页大小 - /// - public async Task OnGetColorListAsync(string keyword, string orderField, int pageIndex, int pageSize) - { - try - { - // 调试信息 - System.Diagnostics.Debug.WriteLine($""ColorList API Called - PageIndex: {pageIndex}, PageSize: {pageSize}, OrderField: {orderField}""); - - var seh = new SenparcExpressionHelper(); - // 可以根据需要添加搜索条件 - // seh.ValueCompare.AndAlso(!string.IsNullOrEmpty(keyword), _ => _.Remark.Contains(keyword)); - var where = seh.BuildWhereExpression(); - var response = await _colorService.GetObjectListAsync(pageIndex, pageSize, where, orderField ?? ""Id desc""); - - // 调试信息 - System.Diagnostics.Debug.WriteLine($""Database Query Result - TotalCount: {response.TotalCount}, ItemCount: {response.Count()}""); - - var result = new - { - success = true, - message = ""数据获取成功"", - data = new { - totalCount = response.TotalCount, - pageIndex = response.PageIndex, - list = response.Select(_ => new - { - id = _.Id, - red = _.Red, - green = _.Green, - blue = _.Blue, - additionNote = _.AdditionNote, - addTime = _.AddTime, - lastUpdateTime = _.LastUpdateTime, - remark = _.Remark - }).ToList() - } - }; - - // 调试信息 - System.Diagnostics.Debug.WriteLine($""API Response - ListCount: {result.data.list.Count}""); - - return Ok(result); - } - catch (Exception ex) - { - System.Diagnostics.Debug.WriteLine($""ColorList API Error: {ex.Message}""); - return Ok(new { - success = false, - message = ""获取数据失败: "" + ex.Message, - totalCount = 0, - pageIndex = pageIndex, - list = new object[0] - }); - } - } - - /// - /// 创建新颜色 - /// - /// 创建颜色请求 - /// - public async Task OnPostCreateColorAsync([FromBody] CreateColorRequestDto request) - { - try - { - // 调试信息 - System.Diagnostics.Debug.WriteLine($""CreateColor API Called - Red: {request.Red}, Green: {request.Green}, Blue: {request.Blue}, AdditionNote: {request.AdditionNote}""); - - if (request == null) - { - return Ok(new { success = false, message = ""请求参数不能为空"" }); - } - - var color = new Color(request.Red, request.Green, request.Blue, request.AdditionNote); - await _colorService.SaveObjectAsync(color); - - return Ok(new { success = true, message = ""颜色创建成功"", data = new { color.Id, color.Red, color.Green, color.Blue, color.AdditionNote, color.AddTime, color.LastUpdateTime } }); - } - catch (Exception ex) - { - System.Diagnostics.Debug.WriteLine($""CreateColor API Error: {ex.Message}""); - return Ok(new { success = false, message = ""创建失败:"" + ex.Message }); - } - } - - /// - /// 更新颜色 - /// - /// 更新颜色请求 - /// - public async Task OnPostUpdateColorAsync([FromBody] UpdateColorRequestDto request) - { - try - { - // 调试信息 - System.Diagnostics.Debug.WriteLine($""UpdateColor API Called - Id: {request.Id}, Red: {request.Red}, Green: {request.Green}, Blue: {request.Blue}, AdditionNote: {request.AdditionNote}""); - - if (request == null) - { - return Ok(new { success = false, message = ""请求参数不能为空"" }); - } - - var color = await _colorService.GetObjectAsync(c => c.Id == request.Id); - if (color == null) - { - return Ok(new { success = false, message = ""颜色不存在"" }); - } - - // 更新 - color.Update(request); - - await _colorService.SaveObjectAsync(color); - - return Ok(new { success = true, message = ""颜色更新成功"", data = new { color.Id, color.Red, color.Green, color.Blue, color.AdditionNote, color.LastUpdateTime } }); - } - catch (Exception ex) - { - System.Diagnostics.Debug.WriteLine($""UpdateColor API Error: {ex.Message}""); - return Ok(new { success = false, message = ""更新失败:"" + ex.Message }); - } - } - - /// - /// 删除颜色 - /// - /// 删除颜色请求 - /// - public async Task OnPostDeleteColorAsync([FromBody] DeleteColorRequestDto request) - { - try - { - // 调试信息 - System.Diagnostics.Debug.WriteLine($""DeleteColor API Called - Id: {request.Id}""); - - if (request == null) - { - return Ok(new { success = false, message = ""请求参数不能为空"" }); - } - - var color = await _colorService.GetObjectAsync(c => c.Id == request.Id); - if (color == null) - { - return Ok(new { success = false, message = ""颜色不存在"" }); - } - - await _colorService.DeleteObjectAsync(color); - return Ok(new { success = true, message = ""颜色删除成功"" }); - } - catch (Exception ex) - { - System.Diagnostics.Debug.WriteLine($""DeleteColor API Error: {ex.Message}""); - return Ok(new { success = false, message = ""删除失败:"" + ex.Message }); - } - } - - /// - /// 随机化指定颜色 - /// - /// 随机化颜色请求 - /// - public async Task OnPostRandomizeColorAsync([FromBody] RandomizeColorRequestDto request) - { - try - { - // 调试信息 - System.Diagnostics.Debug.WriteLine($""RandomizeColor API Called - Id: {request.Id}""); - - if (request == null) - { - return Ok(new { success = false, message = ""请求参数不能为空"" }); - } - - var color = await _colorService.GetObjectAsync(c => c.Id == request.Id); - if (color == null) - { - return Ok(new { success = false, message = ""颜色不存在"" }); - } - - color.Random(); - await _colorService.SaveObjectAsync(color); - - return Ok(new { success = true, message = ""颜色随机化成功"", data = new { color.Id, color.Red, color.Green, color.Blue, color.AdditionNote, color.LastUpdateTime } }); - } - catch (Exception ex) - { - System.Diagnostics.Debug.WriteLine($""RandomizeColor API Error: {ex.Message}""); - return Ok(new { success = false, message = ""随机化失败:"" + ex.Message }); - } - } - - /// - /// 获取颜色详情 - /// - /// 颜色ID - /// - public async Task OnGetColorDetailAsync(int id) - { - try - { - var color = await _colorService.GetObjectAsync(c => c.Id == id); - if (color == null) - { - return Ok(new { success = false, message = ""颜色不存在"" }); - } - - return Ok(new { success = true, data = new { color.Id, color.Red, color.Green, color.Blue, color.AdditionNote, color.AddTime, color.LastUpdateTime, color.Remark } }); - } - catch (Exception ex) - { - return Ok(new { success = false, message = ""获取失败:"" + ex.Message }); - } - } - } + public const string DatabaseSampleIndexCodeBehindTemplate = @"using Microsoft.AspNetCore.Mvc; +using Senparc.Ncf.Service; +using Senparc.Ncf.Utility; +using Template_OrgName.Xncf.Template_XncfName.Domain.Services; +using System; +using System.Linq; +using System.Threading.Tasks; +using Template_OrgName.Xncf.Template_XncfName.Domain.Models.DatabaseModel.Dto; + +namespace Template_OrgName.Xncf.Template_XncfName.Areas.Template_XncfName.Pages +{ + public class DatabaseSampleIndex : Senparc.Ncf.AreaBase.Admin.AdminXncfModulePageModelBase + { + private readonly ColorService _colorService; + + public DatabaseSampleIndex(Lazy xncfModuleService, ColorService colorService) : base(xncfModuleService) + { + _colorService = colorService; + } + + public void OnGet() + { + } + + /// + /// 获取颜色列表(分页) + /// + /// 关键词 + /// 排序字段 + /// 页码 + /// 页大小 + /// + public async Task OnGetColorListAsync(string keyword, string orderField, int pageIndex, int pageSize) + { + try + { + // 调试信息 + System.Diagnostics.Debug.WriteLine($""ColorList API Called - PageIndex: {pageIndex}, PageSize: {pageSize}, OrderField: {orderField}""); + + var seh = new SenparcExpressionHelper(); + // 可以根据需要添加搜索条件 + // seh.ValueCompare.AndAlso(!string.IsNullOrEmpty(keyword), _ => _.Remark.Contains(keyword)); + var where = seh.BuildWhereExpression(); + var response = await _colorService.GetObjectListAsync(pageIndex, pageSize, where, orderField ?? ""Id desc""); + + // 调试信息 + System.Diagnostics.Debug.WriteLine($""Database Query Result - TotalCount: {response.TotalCount}, ItemCount: {response.Count()}""); + + var result = new + { + success = true, + message = ""数据获取成功"", + data = new { + totalCount = response.TotalCount, + pageIndex = response.PageIndex, + list = response.Select(_ => new + { + id = _.Id, + red = _.Red, + green = _.Green, + blue = _.Blue, + additionNote = _.AdditionNote, + addTime = _.AddTime, + lastUpdateTime = _.LastUpdateTime, + remark = _.Remark + }).ToList() + } + }; + + // 调试信息 + System.Diagnostics.Debug.WriteLine($""API Response - ListCount: {result.data.list.Count}""); + + return Ok(result); + } + catch (Exception ex) + { + System.Diagnostics.Debug.WriteLine($""ColorList API Error: {ex.Message}""); + return Ok(new { + success = false, + message = ""获取数据失败: "" + ex.Message, + totalCount = 0, + pageIndex = pageIndex, + list = new object[0] + }); + } + } + + /// + /// 创建新颜色 + /// + /// 创建颜色请求 + /// + public async Task OnPostCreateColorAsync([FromBody] CreateColorRequestDto request) + { + try + { + // 调试信息 + System.Diagnostics.Debug.WriteLine($""CreateColor API Called - Red: {request.Red}, Green: {request.Green}, Blue: {request.Blue}, AdditionNote: {request.AdditionNote}""); + + if (request == null) + { + return Ok(new { success = false, message = ""请求参数不能为空"" }); + } + + var color = new Color(request.Red, request.Green, request.Blue, request.AdditionNote); + await _colorService.SaveObjectAsync(color); + + return Ok(new { success = true, message = ""颜色创建成功"", data = new { color.Id, color.Red, color.Green, color.Blue, color.AdditionNote, color.AddTime, color.LastUpdateTime } }); + } + catch (Exception ex) + { + System.Diagnostics.Debug.WriteLine($""CreateColor API Error: {ex.Message}""); + return Ok(new { success = false, message = ""创建失败:"" + ex.Message }); + } + } + + /// + /// 更新颜色 + /// + /// 更新颜色请求 + /// + public async Task OnPostUpdateColorAsync([FromBody] UpdateColorRequestDto request) + { + try + { + // 调试信息 + System.Diagnostics.Debug.WriteLine($""UpdateColor API Called - Id: {request.Id}, Red: {request.Red}, Green: {request.Green}, Blue: {request.Blue}, AdditionNote: {request.AdditionNote}""); + + if (request == null) + { + return Ok(new { success = false, message = ""请求参数不能为空"" }); + } + + var color = await _colorService.GetObjectAsync(c => c.Id == request.Id); + if (color == null) + { + return Ok(new { success = false, message = ""颜色不存在"" }); + } + + // 更新 + color.Update(request); + + await _colorService.SaveObjectAsync(color); + + return Ok(new { success = true, message = ""颜色更新成功"", data = new { color.Id, color.Red, color.Green, color.Blue, color.AdditionNote, color.LastUpdateTime } }); + } + catch (Exception ex) + { + System.Diagnostics.Debug.WriteLine($""UpdateColor API Error: {ex.Message}""); + return Ok(new { success = false, message = ""更新失败:"" + ex.Message }); + } + } + + /// + /// 删除颜色 + /// + /// 删除颜色请求 + /// + public async Task OnPostDeleteColorAsync([FromBody] DeleteColorRequestDto request) + { + try + { + // 调试信息 + System.Diagnostics.Debug.WriteLine($""DeleteColor API Called - Id: {request.Id}""); + + if (request == null) + { + return Ok(new { success = false, message = ""请求参数不能为空"" }); + } + + var color = await _colorService.GetObjectAsync(c => c.Id == request.Id); + if (color == null) + { + return Ok(new { success = false, message = ""颜色不存在"" }); + } + + await _colorService.DeleteObjectAsync(color); + return Ok(new { success = true, message = ""颜色删除成功"" }); + } + catch (Exception ex) + { + System.Diagnostics.Debug.WriteLine($""DeleteColor API Error: {ex.Message}""); + return Ok(new { success = false, message = ""删除失败:"" + ex.Message }); + } + } + + /// + /// 随机化指定颜色 + /// + /// 随机化颜色请求 + /// + public async Task OnPostRandomizeColorAsync([FromBody] RandomizeColorRequestDto request) + { + try + { + // 调试信息 + System.Diagnostics.Debug.WriteLine($""RandomizeColor API Called - Id: {request.Id}""); + + if (request == null) + { + return Ok(new { success = false, message = ""请求参数不能为空"" }); + } + + var color = await _colorService.GetObjectAsync(c => c.Id == request.Id); + if (color == null) + { + return Ok(new { success = false, message = ""颜色不存在"" }); + } + + color.Random(); + await _colorService.SaveObjectAsync(color); + + return Ok(new { success = true, message = ""颜色随机化成功"", data = new { color.Id, color.Red, color.Green, color.Blue, color.AdditionNote, color.LastUpdateTime } }); + } + catch (Exception ex) + { + System.Diagnostics.Debug.WriteLine($""RandomizeColor API Error: {ex.Message}""); + return Ok(new { success = false, message = ""随机化失败:"" + ex.Message }); + } + } + + /// + /// 获取颜色详情 + /// + /// 颜色ID + /// + public async Task OnGetColorDetailAsync(int id) + { + try + { + var color = await _colorService.GetObjectAsync(c => c.Id == id); + if (color == null) + { + return Ok(new { success = false, message = ""颜色不存在"" }); + } + + return Ok(new { success = true, data = new { color.Id, color.Red, color.Green, color.Blue, color.AdditionNote, color.AddTime, color.LastUpdateTime, color.Remark } }); + } + catch (Exception ex) + { + return Ok(new { success = false, message = ""获取失败:"" + ex.Message }); + } + } + } } "; #endregion @@ -795,433 +795,433 @@ public async Task OnGetColorDetailAsync(int id) /// 数据库示例索引页面JavaScript模板 /// 类型: frontend_script /// - public const string DatabaseSampleIndexJsTemplate = @"var app = new Vue({ - el: ""#app"", - data() { - return { - page: { - page: 1, - size: 10 - }, - tableLoading: true, - tableData: [], - showDebug: false, - addFormDialogVisible: false, - addForm: { - red: 128, - green: 128, - blue: 128, - additionNote: '' - }, - editFormDialogVisible: false, - editForm: { - id: 0, - red: 128, - green: 128, - blue: 128, - additionNote: '' - }, - total: 0, - addRules: { - red: [ - { required: true, message: '请设置红色值', trigger: 'change' }, - { type: 'number', min: 0, max: 255, message: '红色值范围为0-255', trigger: 'change' } - ], - green: [ - { required: true, message: '请设置绿色值', trigger: 'change' }, - { type: 'number', min: 0, max: 255, message: '绿色值范围为0-255', trigger: 'change' } - ], - blue: [ - { required: true, message: '请设置蓝色值', trigger: 'change' }, - { type: 'number', min: 0, max: 255, message: '蓝色值范围为0-255', trigger: 'change' } - ] - }, - editRules: { - red: [ - { required: true, message: '请设置红色值', trigger: 'change' }, - { type: 'number', min: 0, max: 255, message: '红色值范围为0-255', trigger: 'change' } - ], - green: [ - { required: true, message: '请设置绿色值', trigger: 'change' }, - { type: 'number', min: 0, max: 255, message: '绿色值范围为0-255', trigger: 'change' } - ], - blue: [ - { required: true, message: '请设置蓝色值', trigger: 'change' }, - { type: 'number', min: 0, max: 255, message: '蓝色值范围为0-255', trigger: 'change' } - ] - } - } - }, - mounted() { - //wait page load - setTimeout(async () => { - await this.init(); - }, 100) - }, - methods: { - async init() { - await this.getDataList(); - }, - async handleSizeChange(val) { - this.page.size = val; - await this.getDataList(); - }, - async handleCurrentChange(val) { - this.page.page = val; - await this.getDataList(); - }, - async getDataList() { - this.tableLoading = true - await service.get('/Admin/Template_XncfName/DatabaseSampleIndex?handler=ColorList', { - params: { - pageIndex: this.page.page, - pageSize: this.page.size, - orderField: ""Id desc"", - keyword: """" - } - }) - .then(res => { - console.log('=== API Response Debug ==='); - console.log('Complete Response:', res); - console.log('Response Data:', res.data); - console.log('Response Data Type:', typeof res.data); - console.log('Has res.data.data?:', res.data && res.data.data); - console.log('Has res.data.data.list?:', res.data && res.data.data && res.data.data.list); - console.log('res.data.data.list value:', res.data && res.data.data ? res.data.data.list : 'nested data not found'); - console.log('=================='); - - // 尝试多种可能的数据结构 - let dataList = null; - let totalCount = 0; - let dataSource = ''; - - if (res.data && res.data.data && res.data.data.data && res.data.data.data.list) { - // NCF框架标准格式 + 新的API格式: {data: {data: {success, message, data: {list, totalCount}}}} - dataList = res.data.data.data.list; - totalCount = res.data.data.data.totalCount || 0; - dataSource = 'NCF标准格式: res.data.data.data.list'; - console.log('✅ 使用NCF标准格式: res.data.data.data.list'); - console.log('✅ List数据:', dataList); - console.log('✅ TotalCount:', totalCount); - } else if (res.data && res.data.data && res.data.data.list) { - // 简单格式: {data: {list, totalCount}} - dataList = res.data.data.list; - totalCount = res.data.data.totalCount || 0; - dataSource = '简单格式: res.data.data.list'; - console.log('✅ 使用简单格式: res.data.data.list'); - } else if (res.data && Array.isArray(res.data)) { - // 如果data直接是数组 - dataList = res.data; - totalCount = res.data.length; - dataSource = '数组格式: res.data (array)'; - console.log('✅ 使用数组格式: res.data (array)'); - } else if (res && res.list) { - // 如果list在顶层 - dataList = res.list; - totalCount = res.totalCount || 0; - dataSource = '顶层格式: res.list'; - console.log('✅ 使用顶层格式: res.list'); - } else { - console.error('❌ 无法识别的数据格式:', res); - console.log('🔍 尝试的路径:'); - console.log('- res.data.data.list:', res.data && res.data.data ? res.data.data.list : 'not found'); - console.log('- res.data.list:', res.data ? res.data.list : 'not found'); - console.log('- res.data (array):', res.data && Array.isArray(res.data) ? 'is array' : 'not array'); - console.log('- res.list:', res.list ? res.list : 'not found'); - dataList = []; - totalCount = 0; - dataSource = '无法识别格式'; - } - - console.log('🎯 Final dataList:', dataList); - console.log('🎯 Final totalCount:', totalCount); - console.log('🎯 Data source:', dataSource); - - // 数据赋值前的状态 - console.log('📋 赋值前 tableData:', this.tableData); - console.log('📋 赋值前 total:', this.total); - - this.tableData = dataList || []; - this.total = totalCount; - - // 数据赋值后的状态 - console.log('📋 赋值后 tableData:', this.tableData); - console.log('📋 赋值后 tableData.length:', this.tableData.length); - console.log('📋 赋值后 total:', this.total); - - // 强制Vue更新 - this.$forceUpdate(); - console.log('🔄 Vue已强制更新'); - - // 延迟检查数据是否正确绑定 - setTimeout(() => { - console.log('⏰ 延迟检查 tableData:', this.tableData); - console.log('⏰ 延迟检查 tableData.length:', this.tableData ? this.tableData.length : 'null'); - }, 100); - - this.tableLoading = false - }) - .catch(error => { - console.error('获取数据失败:', error); - this.tableLoading = false; - this.$message.error('获取数据失败: ' + (error.message || error)); - }); - }, - addColor() { - this.addFormDialogVisible = true; - }, - refreshList() { - this.getDataList(); - }, - async addColorSubmit() { - this.$refs.addForm.validate(async (valid) => { - if (valid) { - console.log('📤 发送创建请求:', { - red: this.addForm.red, - green: this.addForm.green, - blue: this.addForm.blue, - additionNote: this.addForm.additionNote - }); - - await service.post('/Admin/Template_XncfName/DatabaseSampleIndex?handler=CreateColor', { - red: this.addForm.red, - green: this.addForm.green, - blue: this.addForm.blue, - additionNote: this.addForm.additionNote - }, { - headers: { - 'Content-Type': 'application/json' - } - }) - .then(res => { - console.log('📥 创建响应:', res); - // 兼容NCF框架的嵌套响应格式 - const responseData = res.data.data || res.data; - this.$message({ - type: responseData.success ? 'success' : 'error', - message: responseData.message || '操作完成' - }); - if (responseData.success) { - this.getDataList() - this.clearAddForm() - this.addFormDialogVisible = false; - } - }) - .catch(error => { - console.error('创建失败:', error); - this.$message.error('创建失败'); - }); - } else { - return false; - } - }); - }, - clearAddForm() { - this.addForm = { - red: 128, - green: 128, - blue: 128, - additionNote: '' - }; - if (this.$refs.addForm) { - this.$refs.addForm.resetFields(); - } - }, - clearEditForm() { - this.editForm = { - id: 0, - red: 128, - green: 128, - blue: 128, - additionNote: '' - }; - if (this.$refs.editForm) { - this.$refs.editForm.resetFields(); - } - }, - async editColorSubmit() { - this.$refs.editForm.validate(async (valid) => { - if (valid) { - console.log('📤 发送更新请求:', { - id: this.editForm.id, - red: this.editForm.red, - green: this.editForm.green, - blue: this.editForm.blue, - additionNote: this.editForm.additionNote - }); - - await service.post('/Admin/Template_XncfName/DatabaseSampleIndex?handler=UpdateColor', { - id: this.editForm.id, - red: this.editForm.red, - green: this.editForm.green, - blue: this.editForm.blue, - additionNote: this.editForm.additionNote - }, { - headers: { - 'Content-Type': 'application/json' - } - }) - .then(res => { - console.log('📥 更新响应:', res); - // 兼容NCF框架的嵌套响应格式 - const responseData = res.data.data || res.data; - this.$message({ - type: responseData.success ? 'success' : 'error', - message: responseData.message || '操作完成' - }); - if (responseData.success) { - this.getDataList() - this.clearEditForm() - this.editFormDialogVisible = false; - } - }) - .catch(error => { - console.error('更新失败:', error); - this.$message.error('更新失败'); - }); - } else { - return false; - } - }); - }, - dateformatter(date) { - if (!date) return ''; - - try { - // 使用原生JavaScript格式化日期 - const d = new Date(date); - - // 检查日期是否有效 - if (isNaN(d.getTime())) { - return date; // 如果无法解析,返回原始值 - } - - // 格式化为 YYYY-MM-DD HH:mm:ss - const year = d.getFullYear(); - const month = String(d.getMonth() + 1).padStart(2, '0'); - const day = String(d.getDate()).padStart(2, '0'); - const hours = String(d.getHours()).padStart(2, '0'); - const minutes = String(d.getMinutes()).padStart(2, '0'); - const seconds = String(d.getSeconds()).padStart(2, '0'); - - return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`; - } catch (error) { - console.warn('日期格式化错误:', error, '原始值:', date); - return date; // 如果格式化失败,返回原始值 - } - }, - editColor(row) { - this.editForm = { - id: row.id, - red: row.red, - green: row.green, - blue: row.blue, - additionNote: row.additionNote || '' - }; - this.editFormDialogVisible = true; - }, - deleteColor(row) { - this.$confirm('此操作将永久删除该颜色, 是否继续?', '提示', { - confirmButtonText: '确定', - cancelButtonText: '取消', - type: 'warning' - }).then(async () => { - console.log('📤 发送删除请求:', { id: row.id }); - - await service.post('/Admin/Template_XncfName/DatabaseSampleIndex?handler=DeleteColor', { - id: row.id - }, { - headers: { - 'Content-Type': 'application/json' - } - }) - .then(res => { - console.log('📥 删除响应:', res); - // 兼容NCF框架的嵌套响应格式 - const responseData = res.data.data || res.data; - this.$message({ - type: responseData.success ? 'success' : 'error', - message: responseData.message || '操作完成' - }); - if (responseData.success) { - this.getDataList(); - } - }) - .catch(error => { - console.error('删除失败:', error); - this.$message.error('删除失败'); - }); - }).catch(() => { - this.$message({ - type: 'info', - message: '已取消删除' - }); - }); - }, - async randomizeColor(row) { - console.log('📤 发送随机化请求:', { id: row.id }); - - await service.post('/Admin/Template_XncfName/DatabaseSampleIndex?handler=RandomizeColor', { - id: row.id - }, { - headers: { - 'Content-Type': 'application/json' - } - }) - .then(res => { - console.log('📥 随机化响应:', res); - // 兼容NCF框架的嵌套响应格式 - const responseData = res.data.data || res.data; - this.$message({ - type: responseData.success ? 'success' : 'error', - message: responseData.message || '操作完成' - }); - if (responseData.success) { - this.getDataList(); - } - }) - .catch(error => { - console.error('随机化失败:', error); - this.$message.error('随机化失败'); - }); - }, - randomizeForm() { - this.addForm.red = Math.floor(Math.random() * 256); - this.addForm.green = Math.floor(Math.random() * 256); - this.addForm.blue = Math.floor(Math.random() * 256); - }, - randomizeEditForm() { - this.editForm.red = Math.floor(Math.random() * 256); - this.editForm.green = Math.floor(Math.random() * 256); - this.editForm.blue = Math.floor(Math.random() * 256); - }, - debugInfo() { - this.showDebug = !this.showDebug; - console.log('=== Vue Component Debug Info ==='); - console.log('Current tableData:', this.tableData); - console.log('tableData length:', this.tableData ? this.tableData.length : 'null/undefined'); - console.log('Total:', this.total); - console.log('Page:', this.page); - console.log('Table Loading:', this.tableLoading); - console.log('Show Debug:', this.showDebug); - console.log('Vue instance $el:', this.$el); - console.log('================================'); - - // 测试Vue响应性 - if (this.tableData && this.tableData.length === 0) { - console.log('测试:添加假数据'); - this.tableData = [ - {id: 999, red: 255, green: 0, blue: 0, addTime: new Date().toISOString(), lastUpdateTime: new Date().toISOString(), remark: 'test'} - ]; - this.total = 1; - setTimeout(() => { - console.log('2秒后清除假数据'); - this.tableData = []; - this.total = 0; - }, 2000); - } - } - } + public const string DatabaseSampleIndexJsTemplate = @"var app = new Vue({ + el: ""#app"", + data() { + return { + page: { + page: 1, + size: 10 + }, + tableLoading: true, + tableData: [], + showDebug: false, + addFormDialogVisible: false, + addForm: { + red: 128, + green: 128, + blue: 128, + additionNote: '' + }, + editFormDialogVisible: false, + editForm: { + id: 0, + red: 128, + green: 128, + blue: 128, + additionNote: '' + }, + total: 0, + addRules: { + red: [ + { required: true, message: '请设置红色值', trigger: 'change' }, + { type: 'number', min: 0, max: 255, message: '红色值范围为0-255', trigger: 'change' } + ], + green: [ + { required: true, message: '请设置绿色值', trigger: 'change' }, + { type: 'number', min: 0, max: 255, message: '绿色值范围为0-255', trigger: 'change' } + ], + blue: [ + { required: true, message: '请设置蓝色值', trigger: 'change' }, + { type: 'number', min: 0, max: 255, message: '蓝色值范围为0-255', trigger: 'change' } + ] + }, + editRules: { + red: [ + { required: true, message: '请设置红色值', trigger: 'change' }, + { type: 'number', min: 0, max: 255, message: '红色值范围为0-255', trigger: 'change' } + ], + green: [ + { required: true, message: '请设置绿色值', trigger: 'change' }, + { type: 'number', min: 0, max: 255, message: '绿色值范围为0-255', trigger: 'change' } + ], + blue: [ + { required: true, message: '请设置蓝色值', trigger: 'change' }, + { type: 'number', min: 0, max: 255, message: '蓝色值范围为0-255', trigger: 'change' } + ] + } + } + }, + mounted() { + //wait page load + setTimeout(async () => { + await this.init(); + }, 100) + }, + methods: { + async init() { + await this.getDataList(); + }, + async handleSizeChange(val) { + this.page.size = val; + await this.getDataList(); + }, + async handleCurrentChange(val) { + this.page.page = val; + await this.getDataList(); + }, + async getDataList() { + this.tableLoading = true + await service.get('/Admin/Template_XncfName/DatabaseSampleIndex?handler=ColorList', { + params: { + pageIndex: this.page.page, + pageSize: this.page.size, + orderField: ""Id desc"", + keyword: """" + } + }) + .then(res => { + console.log('=== API Response Debug ==='); + console.log('Complete Response:', res); + console.log('Response Data:', res.data); + console.log('Response Data Type:', typeof res.data); + console.log('Has res.data.data?:', res.data && res.data.data); + console.log('Has res.data.data.list?:', res.data && res.data.data && res.data.data.list); + console.log('res.data.data.list value:', res.data && res.data.data ? res.data.data.list : 'nested data not found'); + console.log('=================='); + + // 尝试多种可能的数据结构 + let dataList = null; + let totalCount = 0; + let dataSource = ''; + + if (res.data && res.data.data && res.data.data.data && res.data.data.data.list) { + // NCF框架标准格式 + 新的API格式: {data: {data: {success, message, data: {list, totalCount}}}} + dataList = res.data.data.data.list; + totalCount = res.data.data.data.totalCount || 0; + dataSource = 'NCF标准格式: res.data.data.data.list'; + console.log('✅ 使用NCF标准格式: res.data.data.data.list'); + console.log('✅ List数据:', dataList); + console.log('✅ TotalCount:', totalCount); + } else if (res.data && res.data.data && res.data.data.list) { + // 简单格式: {data: {list, totalCount}} + dataList = res.data.data.list; + totalCount = res.data.data.totalCount || 0; + dataSource = '简单格式: res.data.data.list'; + console.log('✅ 使用简单格式: res.data.data.list'); + } else if (res.data && Array.isArray(res.data)) { + // 如果data直接是数组 + dataList = res.data; + totalCount = res.data.length; + dataSource = '数组格式: res.data (array)'; + console.log('✅ 使用数组格式: res.data (array)'); + } else if (res && res.list) { + // 如果list在顶层 + dataList = res.list; + totalCount = res.totalCount || 0; + dataSource = '顶层格式: res.list'; + console.log('✅ 使用顶层格式: res.list'); + } else { + console.error('❌ 无法识别的数据格式:', res); + console.log('🔍 尝试的路径:'); + console.log('- res.data.data.list:', res.data && res.data.data ? res.data.data.list : 'not found'); + console.log('- res.data.list:', res.data ? res.data.list : 'not found'); + console.log('- res.data (array):', res.data && Array.isArray(res.data) ? 'is array' : 'not array'); + console.log('- res.list:', res.list ? res.list : 'not found'); + dataList = []; + totalCount = 0; + dataSource = '无法识别格式'; + } + + console.log('🎯 Final dataList:', dataList); + console.log('🎯 Final totalCount:', totalCount); + console.log('🎯 Data source:', dataSource); + + // 数据赋值前的状态 + console.log('📋 赋值前 tableData:', this.tableData); + console.log('📋 赋值前 total:', this.total); + + this.tableData = dataList || []; + this.total = totalCount; + + // 数据赋值后的状态 + console.log('📋 赋值后 tableData:', this.tableData); + console.log('📋 赋值后 tableData.length:', this.tableData.length); + console.log('📋 赋值后 total:', this.total); + + // 强制Vue更新 + this.$forceUpdate(); + console.log('🔄 Vue已强制更新'); + + // 延迟检查数据是否正确绑定 + setTimeout(() => { + console.log('⏰ 延迟检查 tableData:', this.tableData); + console.log('⏰ 延迟检查 tableData.length:', this.tableData ? this.tableData.length : 'null'); + }, 100); + + this.tableLoading = false + }) + .catch(error => { + console.error('获取数据失败:', error); + this.tableLoading = false; + this.$message.error('获取数据失败: ' + (error.message || error)); + }); + }, + addColor() { + this.addFormDialogVisible = true; + }, + refreshList() { + this.getDataList(); + }, + async addColorSubmit() { + this.$refs.addForm.validate(async (valid) => { + if (valid) { + console.log('📤 发送创建请求:', { + red: this.addForm.red, + green: this.addForm.green, + blue: this.addForm.blue, + additionNote: this.addForm.additionNote + }); + + await service.post('/Admin/Template_XncfName/DatabaseSampleIndex?handler=CreateColor', { + red: this.addForm.red, + green: this.addForm.green, + blue: this.addForm.blue, + additionNote: this.addForm.additionNote + }, { + headers: { + 'Content-Type': 'application/json' + } + }) + .then(res => { + console.log('📥 创建响应:', res); + // 兼容NCF框架的嵌套响应格式 + const responseData = res.data.data || res.data; + this.$message({ + type: responseData.success ? 'success' : 'error', + message: responseData.message || '操作完成' + }); + if (responseData.success) { + this.getDataList() + this.clearAddForm() + this.addFormDialogVisible = false; + } + }) + .catch(error => { + console.error('创建失败:', error); + this.$message.error('创建失败'); + }); + } else { + return false; + } + }); + }, + clearAddForm() { + this.addForm = { + red: 128, + green: 128, + blue: 128, + additionNote: '' + }; + if (this.$refs.addForm) { + this.$refs.addForm.resetFields(); + } + }, + clearEditForm() { + this.editForm = { + id: 0, + red: 128, + green: 128, + blue: 128, + additionNote: '' + }; + if (this.$refs.editForm) { + this.$refs.editForm.resetFields(); + } + }, + async editColorSubmit() { + this.$refs.editForm.validate(async (valid) => { + if (valid) { + console.log('📤 发送更新请求:', { + id: this.editForm.id, + red: this.editForm.red, + green: this.editForm.green, + blue: this.editForm.blue, + additionNote: this.editForm.additionNote + }); + + await service.post('/Admin/Template_XncfName/DatabaseSampleIndex?handler=UpdateColor', { + id: this.editForm.id, + red: this.editForm.red, + green: this.editForm.green, + blue: this.editForm.blue, + additionNote: this.editForm.additionNote + }, { + headers: { + 'Content-Type': 'application/json' + } + }) + .then(res => { + console.log('📥 更新响应:', res); + // 兼容NCF框架的嵌套响应格式 + const responseData = res.data.data || res.data; + this.$message({ + type: responseData.success ? 'success' : 'error', + message: responseData.message || '操作完成' + }); + if (responseData.success) { + this.getDataList() + this.clearEditForm() + this.editFormDialogVisible = false; + } + }) + .catch(error => { + console.error('更新失败:', error); + this.$message.error('更新失败'); + }); + } else { + return false; + } + }); + }, + dateformatter(date) { + if (!date) return ''; + + try { + // 使用原生JavaScript格式化日期 + const d = new Date(date); + + // 检查日期是否有效 + if (isNaN(d.getTime())) { + return date; // 如果无法解析,返回原始值 + } + + // 格式化为 YYYY-MM-DD HH:mm:ss + const year = d.getFullYear(); + const month = String(d.getMonth() + 1).padStart(2, '0'); + const day = String(d.getDate()).padStart(2, '0'); + const hours = String(d.getHours()).padStart(2, '0'); + const minutes = String(d.getMinutes()).padStart(2, '0'); + const seconds = String(d.getSeconds()).padStart(2, '0'); + + return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`; + } catch (error) { + console.warn('日期格式化错误:', error, '原始值:', date); + return date; // 如果格式化失败,返回原始值 + } + }, + editColor(row) { + this.editForm = { + id: row.id, + red: row.red, + green: row.green, + blue: row.blue, + additionNote: row.additionNote || '' + }; + this.editFormDialogVisible = true; + }, + deleteColor(row) { + this.$confirm('此操作将永久删除该颜色, 是否继续?', '提示', { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: 'warning' + }).then(async () => { + console.log('📤 发送删除请求:', { id: row.id }); + + await service.post('/Admin/Template_XncfName/DatabaseSampleIndex?handler=DeleteColor', { + id: row.id + }, { + headers: { + 'Content-Type': 'application/json' + } + }) + .then(res => { + console.log('📥 删除响应:', res); + // 兼容NCF框架的嵌套响应格式 + const responseData = res.data.data || res.data; + this.$message({ + type: responseData.success ? 'success' : 'error', + message: responseData.message || '操作完成' + }); + if (responseData.success) { + this.getDataList(); + } + }) + .catch(error => { + console.error('删除失败:', error); + this.$message.error('删除失败'); + }); + }).catch(() => { + this.$message({ + type: 'info', + message: '已取消删除' + }); + }); + }, + async randomizeColor(row) { + console.log('📤 发送随机化请求:', { id: row.id }); + + await service.post('/Admin/Template_XncfName/DatabaseSampleIndex?handler=RandomizeColor', { + id: row.id + }, { + headers: { + 'Content-Type': 'application/json' + } + }) + .then(res => { + console.log('📥 随机化响应:', res); + // 兼容NCF框架的嵌套响应格式 + const responseData = res.data.data || res.data; + this.$message({ + type: responseData.success ? 'success' : 'error', + message: responseData.message || '操作完成' + }); + if (responseData.success) { + this.getDataList(); + } + }) + .catch(error => { + console.error('随机化失败:', error); + this.$message.error('随机化失败'); + }); + }, + randomizeForm() { + this.addForm.red = Math.floor(Math.random() * 256); + this.addForm.green = Math.floor(Math.random() * 256); + this.addForm.blue = Math.floor(Math.random() * 256); + }, + randomizeEditForm() { + this.editForm.red = Math.floor(Math.random() * 256); + this.editForm.green = Math.floor(Math.random() * 256); + this.editForm.blue = Math.floor(Math.random() * 256); + }, + debugInfo() { + this.showDebug = !this.showDebug; + console.log('=== Vue Component Debug Info ==='); + console.log('Current tableData:', this.tableData); + console.log('tableData length:', this.tableData ? this.tableData.length : 'null/undefined'); + console.log('Total:', this.total); + console.log('Page:', this.page); + console.log('Table Loading:', this.tableLoading); + console.log('Show Debug:', this.showDebug); + console.log('Vue instance $el:', this.$el); + console.log('================================'); + + // 测试Vue响应性 + if (this.tableData && this.tableData.length === 0) { + console.log('测试:添加假数据'); + this.tableData = [ + {id: 999, red: 255, green: 0, blue: 0, addTime: new Date().toISOString(), lastUpdateTime: new Date().toISOString(), remark: 'test'} + ]; + this.total = 1; + setTimeout(() => { + console.log('2秒后清除假数据'); + this.tableData = []; + this.total = 0; + }, 2000); + } + } + } }); "; #endregion @@ -1232,224 +1232,224 @@ await service.post('/Admin/Template_XncfName/DatabaseSampleIndex?handler=Randomi /// 数据库示例索引页面CSS模板 /// 类型: frontend_style /// - public const string DatabaseSampleIndexCssTemplate = @"/* 通用样式 */ -.d-flex{ - display: flex; -} -.justify-content-between{ - justify-content: space-between; -} -.align-items-center{ - align-items: center; -} - -/* 过滤器容器样式 */ -.filter-container { - margin-bottom: 20px; - padding: 10px 0; -} - -.filter-container .el-button { - margin-right: 10px; -} - -/* 颜色预览样式 */ -.color-preview { - width: 100%; - height: 40px; - border-radius: 4px; - border: 1px solid #dcdfe6; - display: flex; - align-items: center; - justify-content: center; - color: white; - font-size: 12px; - font-weight: bold; - text-shadow: 1px 1px 2px rgba(0,0,0,0.5); -} - -.color-preview-large { - width: 100%; - height: 80px; - border-radius: 8px; - border: 2px solid #dcdfe6; - display: flex; - align-items: center; - justify-content: center; - color: white; - font-size: 16px; - font-weight: bold; - text-shadow: 2px 2px 4px rgba(0,0,0,0.7); - margin: 10px 0; - transition: all 0.3s ease; -} - -.color-preview-large:hover { - transform: scale(1.02); - box-shadow: 0 4px 12px rgba(0,0,0,0.15); -} - -/* 分页容器样式 */ -.pagination-container { - margin-top: 20px; - text-align: center; -} - -/* 表格样式增强 */ -.el-table { - border-radius: 8px; - overflow: hidden; - box-shadow: 0 2px 12px 0 rgba(0,0,0,0.1); -} - -.el-table th { - background-color: #fafafa; - color: #333; - font-weight: 600; -} - -/* 颜色标签样式 */ -.el-tag { - min-width: 50px; - text-align: center; - font-weight: bold; - border: none !important; - text-shadow: 1px 1px 2px rgba(0,0,0,0.5); -} - -/* 对话框样式 */ -.el-dialog { - border-radius: 12px; - overflow: hidden; -} - -.el-dialog__header { - background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); - color: white; - padding: 20px 20px 0 20px; -} - -.el-dialog__title { - color: white; - font-weight: 600; -} - -.el-dialog__body { - padding: 30px 20px; -} - -/* 滑块样式 */ -.el-slider { - margin: 20px 0; -} - -.el-slider__runway { - height: 6px; - background-color: #e4e7ed; - border-radius: 3px; -} - -.el-slider__button { - width: 20px; - height: 20px; - border: 2px solid #409eff; -} - -/* 按钮样式增强 */ -.el-button--mini { - padding: 5px 10px; - font-size: 12px; - border-radius: 4px; -} - -.el-button--primary { - background: linear-gradient(135deg, #409eff 0%, #3a8ee6 100%); - border: none; -} - -.el-button--success { - background: linear-gradient(135deg, #67c23a 0%, #5daf34 100%); - border: none; -} - -.el-button--warning { - background: linear-gradient(135deg, #e6a23c 0%, #cf9236 100%); - border: none; -} - -.el-button--danger { - background: linear-gradient(135deg, #f56c6c 0%, #f25c5c 100%); - border: none; -} - -.el-button--info { - background: linear-gradient(135deg, #909399 0%, #82848a 100%); - border: none; -} - -/* 表单项样式 */ -.el-form-item { - margin-bottom: 22px; -} - -.el-form-item__label { - font-weight: 600; - color: #333; -} - -/* 加载动画样式 */ -.el-loading-mask { - background-color: rgba(255, 255, 255, 0.9); -} - -/* 响应式设计 */ -@media (max-width: 768px) { - .filter-container { - text-align: center; - } - - .filter-container .el-button { - margin: 5px; - width: auto; - } - - .color-preview { - height: 30px; - font-size: 10px; - } - - .color-preview-large { - height: 60px; - font-size: 14px; - } -} - -/* 动画效果 */ -@keyframes fadeIn { - from { - opacity: 0; - transform: translateY(20px); - } - to { - opacity: 1; - transform: translateY(0); - } -} - -.el-table tbody tr { - animation: fadeIn 0.3s ease-out; -} - -/* 鼠标悬停效果 */ -.el-table tbody tr:hover { - background-color: #f5f7fa !important; - transition: background-color 0.3s ease; -} - -.el-button:hover { - transform: translateY(-1px); - box-shadow: 0 4px 8px rgba(0,0,0,0.15); - transition: all 0.3s ease; + public const string DatabaseSampleIndexCssTemplate = @"/* 通用样式 */ +.d-flex{ + display: flex; +} +.justify-content-between{ + justify-content: space-between; +} +.align-items-center{ + align-items: center; +} + +/* 过滤器容器样式 */ +.filter-container { + margin-bottom: 20px; + padding: 10px 0; +} + +.filter-container .el-button { + margin-right: 10px; +} + +/* 颜色预览样式 */ +.color-preview { + width: 100%; + height: 40px; + border-radius: 4px; + border: 1px solid #dcdfe6; + display: flex; + align-items: center; + justify-content: center; + color: white; + font-size: 12px; + font-weight: bold; + text-shadow: 1px 1px 2px rgba(0,0,0,0.5); +} + +.color-preview-large { + width: 100%; + height: 80px; + border-radius: 8px; + border: 2px solid #dcdfe6; + display: flex; + align-items: center; + justify-content: center; + color: white; + font-size: 16px; + font-weight: bold; + text-shadow: 2px 2px 4px rgba(0,0,0,0.7); + margin: 10px 0; + transition: all 0.3s ease; +} + +.color-preview-large:hover { + transform: scale(1.02); + box-shadow: 0 4px 12px rgba(0,0,0,0.15); +} + +/* 分页容器样式 */ +.pagination-container { + margin-top: 20px; + text-align: center; +} + +/* 表格样式增强 */ +.el-table { + border-radius: 8px; + overflow: hidden; + box-shadow: 0 2px 12px 0 rgba(0,0,0,0.1); +} + +.el-table th { + background-color: #fafafa; + color: #333; + font-weight: 600; +} + +/* 颜色标签样式 */ +.el-tag { + min-width: 50px; + text-align: center; + font-weight: bold; + border: none !important; + text-shadow: 1px 1px 2px rgba(0,0,0,0.5); +} + +/* 对话框样式 */ +.el-dialog { + border-radius: 12px; + overflow: hidden; +} + +.el-dialog__header { + background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); + color: white; + padding: 20px 20px 0 20px; +} + +.el-dialog__title { + color: white; + font-weight: 600; +} + +.el-dialog__body { + padding: 30px 20px; +} + +/* 滑块样式 */ +.el-slider { + margin: 20px 0; +} + +.el-slider__runway { + height: 6px; + background-color: #e4e7ed; + border-radius: 3px; +} + +.el-slider__button { + width: 20px; + height: 20px; + border: 2px solid #409eff; +} + +/* 按钮样式增强 */ +.el-button--mini { + padding: 5px 10px; + font-size: 12px; + border-radius: 4px; +} + +.el-button--primary { + background: linear-gradient(135deg, #409eff 0%, #3a8ee6 100%); + border: none; +} + +.el-button--success { + background: linear-gradient(135deg, #67c23a 0%, #5daf34 100%); + border: none; +} + +.el-button--warning { + background: linear-gradient(135deg, #e6a23c 0%, #cf9236 100%); + border: none; +} + +.el-button--danger { + background: linear-gradient(135deg, #f56c6c 0%, #f25c5c 100%); + border: none; +} + +.el-button--info { + background: linear-gradient(135deg, #909399 0%, #82848a 100%); + border: none; +} + +/* 表单项样式 */ +.el-form-item { + margin-bottom: 22px; +} + +.el-form-item__label { + font-weight: 600; + color: #333; +} + +/* 加载动画样式 */ +.el-loading-mask { + background-color: rgba(255, 255, 255, 0.9); +} + +/* 响应式设计 */ +@media (max-width: 768px) { + .filter-container { + text-align: center; + } + + .filter-container .el-button { + margin: 5px; + width: auto; + } + + .color-preview { + height: 30px; + font-size: 10px; + } + + .color-preview-large { + height: 60px; + font-size: 14px; + } +} + +/* 动画效果 */ +@keyframes fadeIn { + from { + opacity: 0; + transform: translateY(20px); + } + to { + opacity: 1; + transform: translateY(0); + } +} + +.el-table tbody tr { + animation: fadeIn 0.3s ease-out; +} + +/* 鼠标悬停效果 */ +.el-table tbody tr:hover { + background-color: #f5f7fa !important; + transition: background-color 0.3s ease; +} + +.el-button:hover { + transform: translateY(-1px); + box-shadow: 0 4px 8px rgba(0,0,0,0.15); + transition: all 0.3s ease; } "; #endregion