框架优化
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -343,7 +343,7 @@ ASALocalRun/
|
||||
|
||||
# NVidia Nsight GPU debugger configuration file
|
||||
*.nvuser
|
||||
|
||||
![Dd]ebug/[Mm]odules/
|
||||
# MFractors (Xamarin productivity tool) working folder
|
||||
.mfractor/
|
||||
|
||||
|
||||
@@ -53,10 +53,10 @@ namespace LAEPS
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
//初始化数据库
|
||||
DatabaseConfig.SetTenant(10001);
|
||||
DatabaseConfig.InitMySql("127.0.0.1",3306,"LAEPS","root","123456");
|
||||
DatabaseConfig.CreateDatabaseAndCheckConnection(createDatabase: true, checkConnection: true);
|
||||
SqlSugarContext.InitDatabase();
|
||||
//DatabaseConfig.SetTenant(10001);
|
||||
//DatabaseConfig.InitMySql("127.0.0.1",3306,"LAEPS","root","123456");
|
||||
//DatabaseConfig.CreateDatabaseAndCheckConnection(createDatabase: true, checkConnection: true);
|
||||
//SqlSugarContext.InitDatabase();
|
||||
//显示登录窗口
|
||||
var login=Container.Resolve<LoginModuleView>();
|
||||
var re=Container.Resolve<IRegionManager>();
|
||||
@@ -71,8 +71,6 @@ namespace LAEPS
|
||||
// 注册通知管理器
|
||||
INotificationManager NotificationManager = new NotificationManager();
|
||||
containerRegistry.RegisterInstance<INotificationManager>(NotificationManager);
|
||||
// 注册服务
|
||||
containerRegistry.RegisterSingleton<IPostService, PostService>();
|
||||
}
|
||||
//指定模块加载方式(需要手动将模块生成的dll放入Modules文件夹中)
|
||||
protected override IModuleCatalog CreateModuleCatalog()
|
||||
|
||||
@@ -15,7 +15,6 @@ namespace MainModule
|
||||
public void RegisterTypes(IContainerRegistry containerRegistry)
|
||||
{
|
||||
containerRegistry.RegisterForNavigation<MainView>("MainView");
|
||||
containerRegistry.RegisterForNavigation<PostDetailView>("PostDetailView");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,146 +10,16 @@ namespace MainModule.ViewModels
|
||||
{
|
||||
public class MainViewModel : NavigateViewModelBase
|
||||
{
|
||||
#region 属性
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,138 +0,0 @@
|
||||
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
|
||||
}
|
||||
}
|
||||
@@ -15,208 +15,5 @@
|
||||
<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>
|
||||
|
||||
@@ -25,16 +25,6 @@ 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,108 +0,0 @@
|
||||
<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>
|
||||
@@ -1,28 +0,0 @@
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
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; }
|
||||
}
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Model.Entity
|
||||
{
|
||||
public class UserEntity:BaseEntity
|
||||
{
|
||||
public string UserName { get; set; }
|
||||
public string Password { get; set; }
|
||||
public string Role { get; set; }
|
||||
public string Status { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,129 +0,0 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,91 +0,0 @@
|
||||
using Model;
|
||||
using Model.Entity;
|
||||
using ORM;
|
||||
using Service.Implement;
|
||||
using Service.Interface;
|
||||
|
||||
public class UserService: BaseService<UserEntity>, IUserService
|
||||
{
|
||||
public UserService(SqlSugarRepository<UserEntity> repository) : base(repository)
|
||||
{
|
||||
}
|
||||
|
||||
public async Task<Result<UserEntity>> GetUserByUserNameAsync(string username)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(username))
|
||||
return Result<UserEntity>.Error("用户名不能为空");
|
||||
|
||||
try
|
||||
{
|
||||
var user = await _repository.Entities
|
||||
.Where(x => x.UserName == username)
|
||||
.FirstAsync();
|
||||
|
||||
if (user == null)
|
||||
return Result<UserEntity>.Error("用户不存在");
|
||||
|
||||
return Result<UserEntity>.Success(user);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return Result<UserEntity>.Error("获取用户失败", ex);
|
||||
}
|
||||
}
|
||||
|
||||
public override async Task<Result<bool>> InsertAsync(UserEntity entity)
|
||||
{
|
||||
if (entity == null)
|
||||
return Result<bool>.Error("用户数据不能为空");
|
||||
|
||||
try
|
||||
{
|
||||
// 唯一性校验
|
||||
bool exists = await _repository.Entities
|
||||
.AnyAsync(x => x.UserName == entity.UserName);
|
||||
|
||||
if (exists)
|
||||
return Result<bool>.Error("用户名已存在");
|
||||
|
||||
var result = await _repository.InsertAsync(entity);
|
||||
|
||||
return Result<bool>.Success(result);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return Result<bool>.Error("插入数据失败", ex);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 更新单条用户记录
|
||||
/// </summary>
|
||||
/// <param name="entity">要更新的用户实体,Id 必须有值</param>
|
||||
public async Task<Result<bool>> UpdateAsync(UserEntity entity)
|
||||
{
|
||||
if (entity == null)
|
||||
return Result<bool>.Error("用户数据不能为空");
|
||||
|
||||
if (entity.Id <= 0)
|
||||
return Result<bool>.Error("主键 Id 无效,无法更新");
|
||||
|
||||
try
|
||||
{
|
||||
// 唯一性校验(可选,如果允许改用户名就检查)
|
||||
bool exists = await _repository.Entities
|
||||
.Where(x => x.UserName == entity.UserName && x.Id != entity.Id)
|
||||
.AnyAsync();
|
||||
|
||||
if (exists)
|
||||
return Result<bool>.Error("用户名已存在");
|
||||
|
||||
// 更新整个实体
|
||||
var result = await _repository.UpdateAsync(entity);
|
||||
|
||||
return Result<bool>.Success(result);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return Result<bool>.Error("更新用户失败", ex);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
using Model;
|
||||
using Model.Entity;
|
||||
|
||||
namespace Service.Interface
|
||||
{
|
||||
public interface IUserService : IBaseService<UserEntity>
|
||||
{
|
||||
public Task<Result<UserEntity>> GetUserByUserNameAsync(string username);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -9,7 +9,7 @@
|
||||
prism:ViewModelLocator.AutoWireViewModel="True"
|
||||
d:DesignHeight="1080"
|
||||
d:DesignWidth="1920">
|
||||
<Grid>
|
||||
<Grid Background="Green">
|
||||
|
||||
</Grid>
|
||||
</UserControl>
|
||||
|
||||
Reference in New Issue
Block a user