using Dpz.Core.EnumLibrary;
using Dpz.Core.Service.ObjectStorage.Services;

namespace Dpz.Core.Web.Controllers;

public class TimelineController(
    ITimelineService timelineService,
    IObjectStorageOperation objectStorageService
) : Controller
{
    [Route("timeline")]
    [HttpGet]
    public async Task<IActionResult> Index(
        int pageIndex = 1,
        int pageSize = 10,
        CancellationToken cancellationToken = default
    )
    {
        ViewBag.Menu = MenuItem.Timeline;
        this.SetTitle("时间轴");
        ViewBag.Account = "pengqian";
        var pagedList = await timelineService.GetPageAsync(
            pageIndex,
            pageSize,
            account: "pengqian",
            cancellationToken: cancellationToken
        );
        return View(pagedList);
    }

    [HttpGet]
    public async Task<IActionResult> LoadMore(
        string account,
        int pageIndex = 1,
        int pageSize = 10,
        CancellationToken cancellationToken = default
    )
    {
        var pagedList = await timelineService.GetPageAsync(
            pageIndex,
            pageSize,
            account: account,
            cancellationToken: cancellationToken
        );
        return PartialView("_TimelineItemsPartial", pagedList);
    }

    [Route("timeline/{account}.html")]
    public async Task<IActionResult> Timeline2(
        string account,
        int pageIndex = 1,
        int pageSize = 10,
        CancellationToken cancellationToken = default
    )
    {
        ViewBag.Menu = MenuItem.Timeline;
        this.SetTitle($"{account} - 时间轴");
        ViewBag.Account = account;
        var pagedList = await timelineService.GetPageAsync(
            pageIndex,
            pageSize,
            account: account,
            cancellationToken: cancellationToken
        );
        return View("Index", pagedList);
    }

    [CheckAuthorize, HttpPost]
    public async Task<IActionResult> Publish(
        VmTimeline viewModel,
        CancellationToken cancellationToken = default
    )
    {
        if (!string.IsNullOrEmpty(viewModel.Id))
        {
            var timeline = await timelineService.FindAsync(viewModel.Id, cancellationToken);
            if (User.RequiredUserId != timeline?.Author?.Id)
            {
                return Json(new ResultInfo("没有权限修改其他用户的时间轴!"));
            }
        }

        if (string.IsNullOrEmpty(viewModel.Title))
        {
            return Json(new ResultInfo("标题不能为空!"));
        }

        if (viewModel.Date == DateTime.MinValue)
        {
            return Json(new ResultInfo("时间不能为空!"));
        }

        viewModel.CreateTime = DateTime.Now;
        viewModel.LastUpdateTime = DateTime.Now;
        viewModel.Author = User.RequiredUserInfo;
        await timelineService.SaveAsync(viewModel, cancellationToken);
        return Json(new ResultInfo(true));
    }

    [CheckAuthorize, HttpPost]
    public async Task<IActionResult> Delete(string id, CancellationToken cancellationToken)
    {
        var timeline = await timelineService.FindAsync(id, cancellationToken);
        if (User.RequiredUserId != timeline?.Author?.Id)
        {
            return Json(new ResultInfo("不能删除别人的时间轴!"));
        }

        await timelineService.DeleteAsync([id], cancellationToken);
        return Json(new ResultInfo(true));
    }

    [CheckAuthorize]
    [HttpPost]
    public async Task<IActionResult> Upload(CancellationToken cancellationToken)
    {
        var file = Request.Form.Files.FirstOrDefault();
        if (file is { Length: > 0 } && file.ContentType.Contains("image"))
        {
            //var userInfo = User.GetIdentity();
            var path = new[] { "images", "timeline", DateTime.Now.ToString("yyyy-MM-dd") };
            var fileName =
                ObjectId.GenerateNewId() + file.FileName[file.FileName.LastIndexOf('.')..];
            var result = await objectStorageService.UploadAsync(
                file.OpenReadStream(),
                path,
                fileName,
                cancellationToken
            );
            return Json(
                new
                {
                    success = 1,
                    message = "",
                    url = result.AccessUrl,
                }
            );
        }

        return Json(
            new
            {
                success = 0,
                message = "请选择一张图片!",
                url = "",
            }
        );
    }

    #region memble mobile

    [HttpGet, CheckAuthorize]
    public async Task<IActionResult> MyTimeline(
        int pageIndex = 1,
        int pageSize = 10,
        string content = ""
    )
    {
        var source = await timelineService.GetPageAsync(
            pageIndex,
            pageSize,
            content,
            User.RequiredUserId
        );
        var data = Pagination<VmTimeline>.Create(source);
        return Json(new ResultInfo(data));
    }

    public async Task<IActionResult> Detail(string id = "")
    {
        if (string.IsNullOrEmpty(id))
        {
            return Json(new ResultInfo("缺失参数"));
        }

        var timeline = await timelineService.FindAsync(id);
        if (timeline == null)
        {
            return Json(new ResultInfo("时间轴不存在"));
        }
        return Json(new ResultInfo(timeline));
    }

    #endregion
}
⚠⚠    以下内容为AI分析的结果,请根据实际情况进行判断。

这是一个ASP.NET Core MVC控制器类,用于处理时间轴(Timeline)相关的功能。让我详细解释一下这个代码:

控制器概述

TimelineController 是一个时间轴管理控制器,使用了依赖注入来获取两个核心服务:

  • ITimelineService:时间轴业务逻辑服务
  • IObjectStorageOperation:对象存储服务(用于文件上传)

主要功能模块

1. 页面展示功能

Index 方法

  • 路由:/timeline
  • 功能:显示时间轴主页,支持分页
  • 硬编码了账户名为 "pengqian"

Timeline2 方法

  • 路由:/timeline/{account}.html
  • 功能:显示指定账户的时间轴页面
  • 使用与Index相同的视图模板

LoadMore 方法

  • 功能:Ajax加载更多时间轴项目
  • 返回部分视图用于异步加载

2. 内容管理功能

Publish 方法

  • 需要授权验证([CheckAuthorize]
  • 功能:发布或编辑时间轴内容
  • 包含权限验证:只能编辑自己的内容
  • 验证必填字段(标题、时间)

Delete 方法

  • 需要授权验证
  • 功能:删除时间轴项目
  • 权限控制:只能删除自己的内容

3. 文件上传功能

Upload 方法

  • 需要授权验证
  • 功能:上传图片文件
  • 文件类型验证:只允许图片
  • 自动生成文件名和存储路径
  • 返回JSON格式的上传结果

4. 移动端API

MyTimeline 方法

  • 获取当前用户的时间轴数据
  • 支持内容搜索和分页
  • 返回JSON格式数据

Detail 方法

  • 获取指定时间轴项目的详细信息
  • 返回JSON格式数据

技术特点

  1. 现代C#语法:使用了主构造函数(Primary Constructor)
  2. 异步编程:所有数据库操作都是异步的,支持取消令牌
  3. 权限控制:使用[CheckAuthorize]特性进行授权验证
  4. RESTful设计:合理使用HTTP动词(GET、POST)
  5. 分页支持:内置分页功能
  6. 文件上传:集成对象存储服务
  7. 移动端兼容:提供专门的移动端API接口

安全考虑

  • 权限验证:确保用户只能操作自己的数据
  • 文件类型验证:上传时检查文件类型
  • 参数验证:检查必填字段和数据有效性

这个控制器实现了一个完整的时间轴功能,包括查看、发布、编辑、删除和文件上传等核心功能,同时考虑了安全性和用户体验。

评论加载中...