添加主界面

This commit is contained in:
hsc
2026-01-14 15:19:16 +08:00
parent 72f3b855d8
commit 73e2cd8383
16 changed files with 868 additions and 38 deletions

View File

@@ -1,19 +1,21 @@
using LAEPS.ViewModels;
using Castle.DynamicProxy;
using Common;
using LAEPS.ViewModels;
using LAEPS.ViewModels.Dialogs;
using LAEPS.Views;
using LAEPS.Views.Dialogs;
using Castle.DynamicProxy;
using LAEPS.Views;
using LAEPS.Views.Dialogs;
using Logger;
using Notifications.Wpf.Core;
using ORM;
using Service.Implement;
using Service.Interface;
using System.Configuration;
using System.Data;
using System.Reflection;
using System.Windows;
using static System.Runtime.InteropServices.JavaScript.JSType;
using UIShare.PubEvent;
using Notifications.Wpf.Core;
using Logger;
using Common;
using ORM;
using static System.Runtime.InteropServices.JavaScript.JSType;
namespace LAEPS
{
@@ -69,6 +71,8 @@ namespace LAEPS
// 注册通知管理器
INotificationManager NotificationManager = new NotificationManager();
containerRegistry.RegisterInstance<INotificationManager>(NotificationManager);
// 注册服务
containerRegistry.RegisterSingleton<IPostService, PostService>();
}
//指定模块加载方式(需要手动将模块生成的dll放入Modules文件夹中)
protected override IModuleCatalog CreateModuleCatalog()
@@ -77,17 +81,16 @@ namespace LAEPS
return new DirectoryModuleCatalog() { ModulePath = @".\Modules" };
}
//手动模块加载方式
//protected override void ConfigureModuleCatalog(IModuleCatalog moduleCatalog)
//{
// Type moduleAType = typeof(LoginModule.LoginModule);
// moduleCatalog.AddModule(new ModuleInfo()
// {
// ModuleName = moduleAType.Name,
// ModuleType = moduleAType.AssemblyQualifiedName,
// InitializationMode = InitializationMode.OnDemand
// });
// base.ConfigureModuleCatalog(moduleCatalog);
//}
}
protected override void ConfigureModuleCatalog(IModuleCatalog moduleCatalog)
{
Type moduleAType = typeof(MainModule.MainModule);
moduleCatalog.AddModule(new ModuleInfo()
{
ModuleName = moduleAType.Name,
ModuleType = moduleAType.AssemblyQualifiedName,
InitializationMode = InitializationMode.OnDemand
});
base.ConfigureModuleCatalog(moduleCatalog);
}
}
}

View File

@@ -41,12 +41,14 @@ namespace LAEPS.ViewModels
private IRegionManager _regionManager;
private IContainerProvider _containerProvider;
private INotificationManager _notificationManager;
private IModuleManager _moduleManager;
public ShellViewModel( IContainerProvider containerProvider)
{
_containerProvider= containerProvider;
_eventAggregator = containerProvider.Resolve<IEventAggregator>();
_regionManager = containerProvider.Resolve<IRegionManager>();
_notificationManager = containerProvider.Resolve<INotificationManager>();
_moduleManager = containerProvider.Resolve<IModuleManager>();
LeftDrawerOpenCommand = new DelegateCommand(LeftDrawerOpen);
MinimizeCommand = new DelegateCommand<Window>(MinimizeWindow);
MaximizeCommand = new DelegateCommand<Window>(MaximizeWindow);
@@ -65,6 +67,9 @@ namespace LAEPS.ViewModels
private void Load()
{
_notificationManager.ShowAsync(new NotificationContent { Title = "登录成功", Message = "", Type = NotificationType.Success });
//默认导航到主界面
Type moduleAType = typeof(MainModule.MainModule);
_moduleManager.LoadModule(moduleAType.Name);
}
private void Navigate(string content)
{

View File

@@ -14,6 +14,7 @@ namespace MainModule
public void RegisterTypes(IContainerRegistry containerRegistry)
{
containerRegistry.RegisterForNavigation<MainView>("MainView");
containerRegistry.RegisterForNavigation<PostDetailView>("PostDetailView");
}
}
}

View File

@@ -8,6 +8,8 @@
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Model\Model.csproj" />
<ProjectReference Include="..\Service\Service.csproj" />
<ProjectReference Include="..\UIShare\UIShare.csproj" />
</ItemGroup>

View File

@@ -1,32 +1,155 @@
using UIShare.ViewModelBase;
using Model.Entity;
using Prism.Commands;
using Prism.Ioc;
using Service.Interface;
using System.Collections.ObjectModel;
using System.Windows.Input;
using UIShare.ViewModelBase;
namespace MainModule.ViewModels
{
public class MainViewModel : NavigateViewModelBase
{
#region
#endregion
#region
#endregion
public MainViewModel(IContainerProvider containerProvider) : base(containerProvider)
private ObservableCollection<PostEntity> _posts;
public ObservableCollection<PostEntity> Posts
{
get => _posts;
set => SetProperty(ref _posts, value);
}
private string _searchKeyword;
public string SearchKeyword
{
get => _searchKeyword;
set => SetProperty(ref _searchKeyword, value);
}
#endregion
#region
public ICommand CreatePostCommand { get; set; }
public ICommand SearchCommand { get; set; }
public ICommand CategorySelectCommand { get; set; }
#endregion
#region
private IContainerProvider _containerProvider;
private IPostService _postService;
private IDialogService _dialogService;
#endregion
public MainViewModel(IContainerProvider containerProvider ) : base(containerProvider)
{
_containerProvider=containerProvider;
_postService = containerProvider.Resolve<IPostService>();
_dialogService = containerProvider.Resolve<IDialogService>();
InitializeCommands();
LoadPosts();
}
private void InitializeCommands()
{
CreatePostCommand = new DelegateCommand(OnCreatePost);
SearchCommand = new AsyncDelegateCommand(OnSearch);
CategorySelectCommand = new AsyncDelegateCommand<string>(OnCategorySelect);
}
#region
private async void OnCreatePost()
{
// 这里可以导航到发帖页面
ShowInfoMessageBox("跳转到发帖页面",null);
}
private async Task OnSearch()
{
// 执行搜索逻辑
if (!string.IsNullOrWhiteSpace(SearchKeyword))
{
await SearchPostsAsync(SearchKeyword);
}
}
private async Task OnCategorySelect(string category)
{
// 按分类筛选帖子
await FilterPostsByCategoryAsync(category);
}
#endregion
#region
private async Task LoadPosts()
{
try
{
var result = await _postService.GetRecommendedPostsAsync(20);
if (result.IsSuccess)
{
Posts = new ObservableCollection<PostEntity>(result.Data);
}
else
{
ShowErrorMessageBox("帖子加载错误",null);
}
}
catch (Exception ex)
{
ShowErrorMessageBox($"加载帖子异常: {ex.Message}", null);
}
}
private async Task SearchPostsAsync(string keyword)
{
try
{
var result = await _postService.SearchPostsAsync(keyword);
if (result.IsSuccess)
{
Posts = new ObservableCollection<PostEntity>(result.Data);
}
else
{
ShowErrorMessageBox("查询帖子失败", null);
}
}
catch (Exception ex)
{
// 处理异常
ShowErrorMessageBox($"查询帖子异常: {ex.Message}", null);
}
}
private async Task FilterPostsByCategoryAsync(string category)
{
if (category == "全部")
{
await LoadPosts(); // 重新加载所有帖子
return;
}
try
{
var result = await _postService.GetPostsByCategoryAsync(category, 20);
if (result.IsSuccess)
{
Posts = new ObservableCollection<PostEntity>(result.Data);
}
else
{
ShowErrorMessageBox("加载分类子失败", null);
}
}
catch (Exception ex)
{
ShowErrorMessageBox($"获取分类帖子异常: {ex.Message}", null);
}
}
#endregion
}
}

View File

@@ -0,0 +1,138 @@
using Model.Entity;
using Prism.Commands;
using Prism.Ioc;
using Service.Interface;
using System.Windows.Input;
using UIShare.ViewModelBase;
namespace MainModule.ViewModels
{
public class PostDetailViewModel : NavigateViewModelBase
{
#region
private PostEntity _selectedPost;
public PostEntity SelectedPost
{
get => _selectedPost;
set => SetProperty(ref _selectedPost, value);
}
#endregion
#region
public ICommand LikePostCommand { get; set; }
public ICommand FavoritePostCommand { get; set; }
public ICommand SharePostCommand { get; set; }
#endregion
#region
private IContainerProvider _containerProvider;
private IPostService _postService;
private IDialogService _dialogService;
#endregion
public PostDetailViewModel(IContainerProvider containerProvider) : base(containerProvider)
{
_containerProvider = containerProvider;
_postService = containerProvider.Resolve<IPostService>();
_dialogService = containerProvider.Resolve<IDialogService>();
InitializeCommands();
}
private void InitializeCommands()
{
LikePostCommand = new DelegateCommand(OnLikePost);
FavoritePostCommand = new DelegateCommand(OnFavoritePost);
SharePostCommand = new DelegateCommand(OnSharePost);
}
#region
private async void OnLikePost()
{
if (SelectedPost != null)
{
SelectedPost.LikeCount++;
// 在实际应用中,这里应该调用服务更新数据库
var result = await _postService.UpdatePostAsync(SelectedPost);
if (!result.IsSuccess)
{
var dialogParams = new DialogParameters();
dialogParams.Add("Title", "错误");
dialogParams.Add("Message", "点赞失败" + result.Msg);
dialogParams.Add("Icon", "error");
dialogParams.Add("ShowOk", true);
_dialogService.ShowDialog("MessageBox", dialogParams);
}
}
}
private async void OnFavoritePost()
{
if (SelectedPost != null)
{
var dialogParams = new DialogParameters();
dialogParams.Add("Title", "提示");
dialogParams.Add("Message", "帖子已收藏");
dialogParams.Add("Icon", "info");
dialogParams.Add("ShowOk", true);
_dialogService.ShowDialog("MessageBox", dialogParams, result =>
{
if (result.Result == ButtonResult.OK)
{
// 用户点击了确定
}
});
}
}
private async void OnSharePost()
{
if (SelectedPost != null)
{
var dialogParams = new DialogParameters();
dialogParams.Add("Title", "提示");
dialogParams.Add("Message", "分享功能待实现");
dialogParams.Add("Icon", "info");
dialogParams.Add("ShowOk", true);
_dialogService.ShowDialog("MessageBox", dialogParams, result =>
{
if (result.Result == ButtonResult.OK)
{
// 用户点击了确定
}
});
}
}
#endregion
#region
public async void LoadPostDetails(PostEntity post)
{
if (post != null)
{
SelectedPost = post;
// 增加浏览量
SelectedPost.ViewCount++;
// 在实际应用中,这里应该调用服务更新数据库
var result = await _postService.UpdatePostAsync(SelectedPost);
if (!result.IsSuccess)
{
var dialogParams = new DialogParameters();
dialogParams.Add("Title", "错误");
dialogParams.Add("Message", "加载帖子详情失败" + result.Msg);
dialogParams.Add("Icon", "error");
dialogParams.Add("ShowOk", true);
_dialogService.ShowDialog("MessageBox", dialogParams);
}
}
}
#endregion
}
}

View File

@@ -4,12 +4,219 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
xmlns:converters="clr-namespace:UIShare.Converters;assembly=UIShare"
mc:Ignorable="d"
xmlns:prism="http://prismlibrary.com/"
prism:ViewModelLocator.AutoWireViewModel="True"
d:DesignHeight="1080"
d:DesignWidth="1920">
<Grid Background="Red">
<UserControl.Resources>
<converters:BooleanToVisibilityConverter x:Key="BoolToVis" />
</UserControl.Resources>
<Grid>
<Grid.RowDefinitions>
<!-- 搜索栏区域 -->
<RowDefinition Height="Auto"/>
<!-- 标签分类区域 -->
<RowDefinition Height="Auto"/>
<!-- 内容区域 -->
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!-- 顶部搜索栏 -->
<Border Grid.Row="0" Background="#F5F5F5" Padding="20,15">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<!-- 搜索框 -->
<TextBox Grid.Column="0"
Margin="0,0,10,0"
Style="{StaticResource MaterialDesignOutlinedTextBox}"
VerticalAlignment="Center"
FontSize="16"
Height="40"
materialDesign:HintAssist.Hint="搜索帖子..."
Text="{Binding SearchKeyword, UpdateSourceTrigger=PropertyChanged}"
KeyDown="SearchBox_KeyDown"/>
<!-- 消息通知按钮 -->
<Button Grid.Column="1"
Margin="0,0,10,0"
Style="{StaticResource MaterialDesignFloatingActionMiniDarkButton}"
ToolTip="消息通知">
<materialDesign:PackIcon Kind="BellOutline" Height="24" Width="24" />
</Button>
<!-- 发帖按钮 -->
<Button Grid.Column="2"
Content="发布帖子"
Style="{StaticResource MaterialDesignRaisedLightButton}"
Background="#FF2196F3"
Foreground="White"
FontSize="14"
FontWeight="Medium"
Height="40"
Width="100"
Command="{Binding CreatePostCommand}"/>
</Grid>
</Border>
<!-- 标签分类区域 -->
<Border Grid.Row="1" Background="White" Padding="20,10" BorderBrush="#E0E0E0" BorderThickness="0,0,0,1">
<ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Disabled">
<StackPanel Orientation="Horizontal" >
<Button Content="全部"
Style="{StaticResource MaterialDesignFlatButton}"
Background="#FF2196F3"
Foreground="White"
Command="{Binding CategorySelectCommand}"
CommandParameter="全部"/>
<Button Content="热门"
Style="{StaticResource MaterialDesignFlatButton}"
Background="#FF9800"
Foreground="White"
Command="{Binding CategorySelectCommand}"
CommandParameter="热门"/>
<Button Content="科技"
Style="{StaticResource MaterialDesignFlatButton}"
Background="#4CAF50"
Foreground="White"
Command="{Binding CategorySelectCommand}"
CommandParameter="科技"/>
<Button Content="生活"
Style="{StaticResource MaterialDesignFlatButton}"
Background="#9C27B0"
Foreground="White"
Command="{Binding CategorySelectCommand}"
CommandParameter="生活"/>
<Button Content="娱乐"
Style="{StaticResource MaterialDesignFlatButton}"
Background="#E91E63"
Foreground="White"
Command="{Binding CategorySelectCommand}"
CommandParameter="娱乐"/>
<Button Content="游戏"
Style="{StaticResource MaterialDesignFlatButton}"
Background="#795548"
Foreground="White"
Command="{Binding CategorySelectCommand}"
CommandParameter="游戏"/>
<Button Content="学习"
Style="{StaticResource MaterialDesignFlatButton}"
Background="#009688"
Foreground="White"
Command="{Binding CategorySelectCommand}"
CommandParameter="学习"/>
<Button Content="美食"
Style="{StaticResource MaterialDesignFlatButton}"
Background="#FF5722"
Foreground="White"
Command="{Binding CategorySelectCommand}"
CommandParameter="美食"/>
</StackPanel>
</ScrollViewer>
</Border>
<!-- 推荐帖子列表 -->
<ScrollViewer Grid.Row="2" VerticalScrollBarVisibility="Auto">
<ItemsControl ItemsSource="{Binding Posts}" Margin="20,15,20,20">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border Background="White"
Margin="0,0,0,15"
CornerRadius="8"
BorderBrush="#E0E0E0"
BorderThickness="1"
Effect="{DynamicResource MaterialDesignShadowDepth1}">
<Grid Margin="15">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<!-- 帖子头部信息 -->
<Grid Grid.Row="0" Margin="0,0,0,10">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<!-- 用户头像占位 -->
<Ellipse Grid.Column="0"
Width="40"
Height="40"
Fill="#BDBDBD"
VerticalAlignment="Center"/>
<StackPanel Grid.Column="1" Margin="10,0,0,0" VerticalAlignment="Center">
<TextBlock Text="{Binding AuthorName}"
FontSize="14"
FontWeight="Medium"
Foreground="#212121"/>
<TextBlock Text="{Binding PublishTime, StringFormat=\{0:MM-dd HH:mm\}}"
FontSize="12"
Foreground="#757575"
Margin="0,2,0,0"/>
</StackPanel>
<!-- 置顶或精华标识 -->
<StackPanel Grid.Column="2" Orientation="Horizontal" HorizontalAlignment="Right" >
<Border Background="#FF9800" Padding="6,2" CornerRadius="3" Visibility="{Binding IsEssence, Converter={StaticResource BoolToVis}}">
<TextBlock Text="精" FontSize="12" Foreground="White" FontWeight="Bold"/>
</Border>
<Border Background="#2196F3" Padding="6,2" CornerRadius="3" Visibility="{Binding IsTop, Converter={StaticResource BoolToVis}}">
<TextBlock Text="顶" FontSize="12" Foreground="White" FontWeight="Bold"/>
</Border>
</StackPanel>
</Grid>
<!-- 帖子标题和内容 -->
<StackPanel Grid.Row="1" Margin="0,0,0,10">
<TextBlock Text="{Binding Title}"
FontSize="16"
FontWeight="SemiBold"
Foreground="#212121"
TextWrapping="Wrap"
Margin="0,0,0,5"/>
<TextBlock Text="{Binding Content}"
FontSize="14"
Foreground="#424242"
TextWrapping="Wrap"
MaxHeight="60"
TextTrimming="CharacterEllipsis"/>
</StackPanel>
<!-- 帖子底部统计信息 -->
<Grid Grid.Row="2">
<StackPanel Orientation="Horizontal" >
<StackPanel Orientation="Horizontal" >
<materialDesign:PackIcon Kind="Eye" Height="16" Width="16" Foreground="#757575"/>
<TextBlock Text="{Binding ViewCount}" Foreground="#757575" FontSize="12"/>
</StackPanel>
<StackPanel Orientation="Horizontal">
<materialDesign:PackIcon Kind="ThumbUpOutline" Height="16" Width="16" Foreground="#757575"/>
<TextBlock Text="{Binding LikeCount}" Foreground="#757575" FontSize="12"/>
</StackPanel>
<StackPanel Orientation="Horizontal">
<materialDesign:PackIcon Kind="CommentOutline" Height="16" Width="16" Foreground="#757575"/>
<TextBlock Text="{Binding CommentCount}" Foreground="#757575" FontSize="12"/>
</StackPanel>
<TextBlock Text="{Binding Category}" Foreground="#2196F3" FontSize="12" VerticalAlignment="Center"/>
</StackPanel>
</Grid>
</Grid>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
</Grid>
</UserControl>

View File

@@ -25,6 +25,16 @@ namespace MainModule.Views
InitializeComponent();
}
private void SearchBox_KeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Enter)
{
// 触发搜索命令
if (DataContext is ViewModels.MainViewModel viewModel)
{
viewModel.SearchCommand?.Execute(null);
}
}
}
}
}
}

View File

@@ -0,0 +1,108 @@
<UserControl x:Class="MainModule.Views.PostDetailView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
xmlns:converters="clr-namespace:UIShare.Converters;assembly=UIShare"
mc:Ignorable="d"
xmlns:prism="http://prismlibrary.com/"
prism:ViewModelLocator.AutoWireViewModel="True"
d:DesignHeight="800"
d:DesignWidth="1000">
<UserControl.Resources>
<converters:BooleanToVisibilityConverter x:Key="BoolToVis" />
</UserControl.Resources>
<Grid Margin="20">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<!-- 帖子头部信息 -->
<Border Grid.Row="0" Background="White" CornerRadius="8" BorderBrush="#E0E0E0" BorderThickness="1" Padding="20">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Ellipse Grid.Column="0" Width="50" Height="50" Fill="#BDBDBD" VerticalAlignment="Center"/>
<StackPanel Grid.Column="1" Margin="15,0,0,0" VerticalAlignment="Center">
<TextBlock Text="{Binding SelectedPost.AuthorName}" FontSize="16" FontWeight="Medium" Foreground="#212121"/>
<TextBlock Text="{Binding SelectedPost.PublishTime, StringFormat=\\{0:yyyy-MM-dd HH:mm:ss\\}}" FontSize="12" Foreground="#757575" Margin="0,2,0,0"/>
</StackPanel>
<StackPanel Grid.Column="2" Orientation="Horizontal" HorizontalAlignment="Right" >
<Border Background="#FF9800" Padding="8,4" CornerRadius="4" Visibility="{Binding SelectedPost.IsEssence, Converter={StaticResource BoolToVis}}">
<TextBlock Text="精" FontSize="12" Foreground="White" FontWeight="Bold"/>
</Border>
<Border Background="#2196F3" Padding="8,4" CornerRadius="4" Visibility="{Binding SelectedPost.IsTop, Converter={StaticResource BoolToVis}}">
<TextBlock Text="顶" FontSize="12" Foreground="White" FontWeight="Bold"/>
</Border>
</StackPanel>
</Grid>
</Border>
<!-- 帖子内容区域 -->
<Border Grid.Row="1" Background="White" CornerRadius="8" BorderBrush="#E0E0E0" BorderThickness="1" Margin="0,10,0,10" Padding="20">
<ScrollViewer VerticalScrollBarVisibility="Auto">
<StackPanel>
<TextBlock Text="{Binding SelectedPost.Title}" FontSize="24" FontWeight="Bold" Foreground="#212121" Margin="0,0,0,20"/>
<TextBlock Text="{Binding SelectedPost.Content}" FontSize="16" Foreground="#424242" TextWrapping="Wrap" LineHeight="28"/>
</StackPanel>
</ScrollViewer>
</Border>
<!-- 统计信息和操作区域 -->
<Border Grid.Row="2" Background="White" CornerRadius="8" BorderBrush="#E0E0E0" BorderThickness="1" Padding="20">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0" Orientation="Horizontal" >
<StackPanel Orientation="Horizontal" >
<materialDesign:PackIcon Kind="Eye" Height="20" Width="20" Foreground="#757575"/>
<TextBlock Text="{Binding SelectedPost.ViewCount}" Foreground="#757575" FontSize="14"/>
</StackPanel>
<StackPanel Orientation="Horizontal" >
<materialDesign:PackIcon Kind="ThumbUpOutline" Height="20" Width="20" Foreground="#757575"/>
<TextBlock Text="{Binding SelectedPost.LikeCount}" Foreground="#757575" FontSize="14"/>
</StackPanel>
<StackPanel Orientation="Horizontal" >
<materialDesign:PackIcon Kind="CommentOutline" Height="20" Width="20" Foreground="#757575"/>
<TextBlock Text="{Binding SelectedPost.CommentCount}" Foreground="#757575" FontSize="14"/>
</StackPanel>
<TextBlock Text="{Binding SelectedPost.Category}" Foreground="#2196F3" FontSize="14" FontWeight="Medium" VerticalAlignment="Center"/>
</StackPanel>
<StackPanel Grid.Column="1" Orientation="Horizontal">
<Button Content="点赞"
Style="{StaticResource MaterialDesignRaisedLightButton}"
Background="#4CAF50"
Foreground="White"
Command="{Binding LikePostCommand}"/>
<Button Content="收藏"
Style="{StaticResource MaterialDesignRaisedLightButton}"
Background="#FF9800"
Foreground="White"
Command="{Binding FavoritePostCommand}"/>
<Button Content="分享"
Style="{StaticResource MaterialDesignRaisedLightButton}"
Background="#2196F3"
Foreground="White"
Command="{Binding SharePostCommand}"/>
</StackPanel>
</Grid>
</Border>
</Grid>
</UserControl>

View File

@@ -0,0 +1,28 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace MainModule.Views
{
/// <summary>
/// PostDetailView.xaml 的交互逻辑
/// </summary>
public partial class PostDetailView : UserControl
{
public PostDetailView()
{
InitializeComponent();
}
}
}

View File

@@ -0,0 +1,24 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Model.Entity
{
public class PostEntity : BaseEntity
{
public string Title { get; set; }
public string Content { get; set; }
public string AuthorId { get; set; }
public string AuthorName { get; set; }
public string Category { get; set; }
public DateTime PublishTime { get; set; }
public int ViewCount { get; set; }
public int LikeCount { get; set; }
public int CommentCount { get; set; }
public bool IsTop { get; set; }
public bool IsEssence { get; set; }
public string ThumbnailUrl { get; set; }
}
}

View File

@@ -0,0 +1,129 @@
using Model;
using Model.Entity;
using ORM;
using Service.Implement;
using Service.Interface;
using SqlSugar;
namespace Service.Implement
{
public class PostService : BaseService<PostEntity>, IPostService
{
public PostService(SqlSugarRepository<PostEntity> repository) : base(repository)
{
}
public async Task<Result<List<PostEntity>>> GetRecommendedPostsAsync(int count = 10)
{
try
{
var posts = await _repository.Entities
.Where(x => x.IsDel == 0) // 使用正确的字段名
.OrderBy(x => x.IsTop, OrderByType.Desc)
.OrderBy(x => x.PublishTime, OrderByType.Desc)
.Take(count)
.ToListAsync();
return Result<List<PostEntity>>.Success(posts);
}
catch (Exception ex)
{
return Result<List<PostEntity>>.Error("获取推荐帖子失败", ex);
}
}
public async Task<Result<List<PostEntity>>> SearchPostsAsync(string keyword)
{
try
{
if (string.IsNullOrWhiteSpace(keyword))
{
return Result<List<PostEntity>>.Success(new List<PostEntity>());
}
var posts = await _repository.Entities
.Where(x => (x.Title.Contains(keyword) || x.Content.Contains(keyword))
&& x.IsDel == 0) // 使用正确的字段名
.OrderBy(x => x.IsTop, OrderByType.Desc)
.OrderBy(x => x.PublishTime, OrderByType.Desc)
.ToListAsync();
return Result<List<PostEntity>>.Success(posts);
}
catch (Exception ex)
{
return Result<List<PostEntity>>.Error("搜索帖子失败", ex);
}
}
public async Task<Result<List<PostEntity>>> GetPostsByCategoryAsync(string category, int count = 10)
{
try
{
if (string.IsNullOrWhiteSpace(category))
{
return Result<List<PostEntity>>.Success(new List<PostEntity>());
}
var posts = await _repository.Entities
.Where(x => x.Category == category && x.IsDel == 0) // 使用正确的字段名
.OrderBy(x => x.IsTop, OrderByType.Desc)
.OrderBy(x => x.PublishTime, OrderByType.Desc)
.Take(count)
.ToListAsync();
return Result<List<PostEntity>>.Success(posts);
}
catch (Exception ex)
{
return Result<List<PostEntity>>.Error("获取分类帖子失败", ex);
}
}
public async Task<Result<bool>> CreatePostAsync(PostEntity post)
{
try
{
post.PublishTime = DateTime.Now;
var result = await _repository.InsertAsync(post);
return Result<bool>.Success(result);
}
catch (Exception ex)
{
return Result<bool>.Error("创建帖子失败", ex);
}
}
public async Task<Result<bool>> UpdatePostAsync(PostEntity post)
{
try
{
var result = await _repository.UpdateAsync(post);
return Result<bool>.Success(result);
}
catch (Exception ex)
{
return Result<bool>.Error("更新帖子失败", ex);
}
}
public async Task<Result<bool>> DeletePostAsync(long postId)
{
try
{
// 软删除将IsDel设为1
var post = await _repository.Entities.FirstAsync(x => x.Id == postId);
if (post == null)
return Result<bool>.Error("帖子不存在");
post.IsDel = 1;
var result = await _repository.UpdateAsync(post);
return Result<bool>.Success(result);
}
catch (Exception ex)
{
return Result<bool>.Error("删除帖子失败", ex);
}
}
}
}

View File

@@ -2,8 +2,9 @@
using Model.Entity;
using ORM;
using Service.Implement;
using Service.Interface;
public class UserService: BaseService<UserEntity>
public class UserService: BaseService<UserEntity>, IUserService
{
public UserService(SqlSugarRepository<UserEntity> repository) : base(repository)
{

View File

@@ -0,0 +1,16 @@
using Model;
using Model.Entity;
using Service.Interface;
namespace Service.Interface
{
public interface IPostService : IBaseService<PostEntity>
{
Task<Result<List<PostEntity>>> GetRecommendedPostsAsync(int count = 10);
Task<Result<List<PostEntity>>> SearchPostsAsync(string keyword);
Task<Result<List<PostEntity>>> GetPostsByCategoryAsync(string category, int count = 10);
Task<Result<bool>> CreatePostAsync(PostEntity post);
Task<Result<bool>> UpdatePostAsync(PostEntity post);
Task<Result<bool>> DeletePostAsync(long postId);
}
}

View File

@@ -0,0 +1,11 @@
using Model;
using Model.Entity;
namespace Service.Interface
{
public interface IUserService : IBaseService<UserEntity>
{
public Task<Result<UserEntity>> GetUserByUserNameAsync(string username);
}
}

View File

@@ -22,6 +22,30 @@ namespace UIShare.ViewModelBase
_notificationManager = containerProvider.Resolve<INotificationManager>();
}
protected void ShowInfoMessageBox(string Message,Action callback)
{
var dialogParams = new DialogParameters();
dialogParams.Add("Title", "提示");
dialogParams.Add("Message", Message);
dialogParams.Add("Icon", "info");
dialogParams.Add("ShowOk", true);
_dialogService.ShowDialog("MessageBoxView", dialogParams, result =>
{
callback();
});
}
protected void ShowErrorMessageBox(string Message,Action callback)
{
var dialogParams = new DialogParameters();
dialogParams.Add("Title", "错误");
dialogParams.Add("Message", Message);
dialogParams.Add("Icon", "info");
dialogParams.Add("ShowOk", true);
_dialogService.ShowDialog("MessageBoxView", dialogParams, result =>
{
callback();
});
}
#region Navigation
public virtual void OnNavigatedTo(NavigationContext navigationContext) { }