This commit is contained in:
2026-03-25 14:55:34 +08:00
commit 2c44b3a4b2
131 changed files with 7453 additions and 0 deletions

View File

@@ -0,0 +1,6 @@
namespace StopShopping.Services.Models.Req;
public record CategoryIdParams
{
public int CategoryId { get; set; }
}

View File

@@ -0,0 +1,24 @@
using System.ComponentModel.DataAnnotations;
namespace StopShopping.Services.Models.Req;
/// <summary>
/// 修改密码
/// </summary>
/// <value></value>
public record ChangePasswordParams
{
/// <summary>
/// 原密码
/// </summary>
/// <value></value>
[Required]
public string? OldPassword { get; set; }
/// <summary>
/// 新密码
/// </summary>
/// <value></value>
[Required]
[MinLength(6)]
public string? NewPassword { get; set; }
}

View File

@@ -0,0 +1,36 @@
using System.ComponentModel.DataAnnotations;
namespace StopShopping.Services.Models.Req;
/// <summary>
/// 创建需求请求
/// </summary>
/// <value></value>
public record CreateRequestParams
{
/// <summary>
/// 商品名
/// </summary>
/// <value></value>
[Required]
[MaxLength(100)]
public string Name { get; set; } = string.Empty;
/// <summary>
/// 描述
/// </summary>
/// <value></value>
[MaxLength(1000)]
public string? Description { get; set; }
/// <summary>
/// 分类id
/// </summary>
/// <value></value>
public int CategoryId { get; set; }
/// <summary>
/// 截止日期
/// </summary>
/// <value></value>
[Required]
[RegularExpression(@"^\d{4}\D\d{1,2}\D\d{1,2}$")]
public string Deadline { get; set; } = string.Empty;
}

View File

@@ -0,0 +1,6 @@
namespace StopShopping.Services.Models.Req;
public record DistrictParentIdParams
{
public int ParentId { get; set; }
}

View File

@@ -0,0 +1,67 @@
using System.ComponentModel.DataAnnotations;
namespace StopShopping.Services.Models.Req;
/// <summary>
/// 新增/修改收货地址
/// </summary>
/// <value></value>
public record EditAddressParams
{
/// <summary>
/// 大于0时为修改
/// </summary>
/// <value></value>
public int? Id { get; set; }
/// <summary>
/// 姓名
/// </summary>
/// <value></value>
[Required]
[MaxLength(20)]
public string Name { get; set; } = string.Empty;
/// <summary>
/// 联系电话
/// </summary>
/// <value></value>
[Required]
[Phone]
public string Telephone { get; set; } = string.Empty;
/// <summary>
/// 自定义标签
/// </summary>
/// <value></value>
[MaxLength(20)]
public string? Tag { get; set; }
/// <summary>
/// 是否默认地址
/// </summary>
/// <value></value>
public bool Default { get; set; }
/// <summary>
/// 区域id表示省/直辖市
/// </summary>
/// <value></value>
public int DistrictLevel1Id { get; set; }
/// <summary>
/// 区域id表示市/直辖市时为空
/// </summary>
/// <value></value>
public int? DistrictLevel2Id { get; set; }
/// <summary>
/// 区域id表示区
/// </summary>
/// <value></value>
public int DistrictLevel3Id { get; set; }
/// <summary>
/// 区域id表示街道/镇
/// </summary>
/// <value></value>
public int DistrictLevel4Id { get; set; }
/// <summary>
/// 详细地址
/// </summary>
/// <value></value>
[MaxLength(200)]
public string? Detail { get; set; }
}

View File

@@ -0,0 +1,34 @@
using System.ComponentModel.DataAnnotations;
namespace StopShopping.Services.Models.Req;
/// <summary>
/// 新增/修改分类
/// </summary>
/// <value></value>
public record EditCategoryParams
{
/// <summary>
/// 大于0时修改
/// </summary>
/// <value></value>
public int? Id { get; set; }
/// <summary>
/// 顶级为0
/// </summary>
/// <value></value>
public int ParentId { get; set; }
/// <summary>
/// 名称j
/// </summary>
/// <value></value>
[Required]
[MaxLength(50)]
public string Name { get; set; } = string.Empty;
/// <summary>
/// 空时保持不变
/// </summary>
/// <value></value>
[MaxLength(50)]
public string? Logo { get; set; }
}

View File

@@ -0,0 +1,56 @@
using System.ComponentModel.DataAnnotations;
namespace StopShopping.Services.Models.Req;
/// <summary>
/// 新增/修改商品
/// </summary>
public record EditProductParams
{
/// <summary>
/// 大于0时修改
/// </summary>
/// <value></value>
public int? Id { get; set; }
/// <summary>
/// 商品名称
/// </summary>
/// <value></value>
[Required]
[MaxLength(100)]
public string? Name { get; set; }
/// <summary>
/// 简介
/// </summary>
/// <value></value>
[MaxLength(200)]
public string? Description { get; set; }
/// <summary>
/// 图片名,修改时传空保持不变
/// </summary>
/// <value></value>
[MaxLength(50)]
public string? LogoName { get; set; }
/// <summary>
/// 分类id
/// </summary>
/// <value></value>
public int CategoryId { get; set; }
/// <summary>
/// 最小销售单元
/// </summary>
/// <value></value>
[Required]
[MaxLength(20)]
public string? MinimumUnit { get; set; }
/// <summary>
/// 单价
/// </summary>
/// <value></value>
public decimal UnitPrice { get; set; }
/// <summary>
/// 详情
/// </summary>
/// <value></value>
public string? Detail { get; set; }
}

View File

@@ -0,0 +1,34 @@
using System.ComponentModel.DataAnnotations;
namespace StopShopping.Services.Models.Req;
/// <summary>
/// 修改用户资料
/// </summary>
/// <value></value>
public record EditUserParams
{
/// <summary>
/// 昵称
/// </summary>
/// <value></value>
[Length(2, 50)]
[Required]
public string NickName { get; set; } = string.Empty;
/// <summary>
/// 头像文件名
/// </summary>
/// <value></value>
public string? AvatarFileName { get; set; }
/// <summary>
/// 默认角色
/// </summary>
/// <value></value>
public UserRoles DefaultRole { get; set; }
/// <summary>
/// 联系电话
/// </summary>
/// <value></value>
[Phone]
public string? Telephone { get; set; }
}

View File

@@ -0,0 +1,18 @@
namespace StopShopping.Services.Models.Req;
/// <summary>
/// 分页搜索
/// </summary>
public record PagedSearch
{
/// <summary>
/// 页码
/// </summary>
/// <value></value>
public int PageIndex { get; set; }
/// <summary>
/// 页大小
/// </summary>
/// <value></value>
public int PageSize { get; set; }
}

View File

@@ -0,0 +1,6 @@
namespace StopShopping.Services.Models.Req;
public record ProductIdParams
{
public int ProductId { get; set; }
}

View File

@@ -0,0 +1,32 @@
namespace StopShopping.Services.Models.Req;
/// <summary>
/// 商品搜索排序
/// </summary>
public enum ProductOrderBys
{
/// <summary>
/// 添加时间
/// </summary>
CreateTime,
/// <summary>
/// 添加时间倒序
/// </summary>
CreateTimeDesc,
/// <summary>
/// 分类
/// </summary>
Category,
/// <summary>
/// 分类倒序
/// </summary>
CategoryDesc,
/// <summary>
/// 已售数量
/// </summary>
SoldAmount,
/// <summary>
/// 已售数量倒序
/// </summary>
SoldAmountDesc,
}

View File

@@ -0,0 +1,29 @@
using System.ComponentModel.DataAnnotations;
namespace StopShopping.Services.Models.Req;
/// <summary>
/// 分页搜索商品
/// </summary>
public record ProductSearchParms : PagedSearch
{
/// <summary>
/// 搜索此分类及下级所有商品
/// </summary>
/// <value></value>
public int? CategoryId { get; set; }
/// <summary>
/// 商品名、描述关键字
/// </summary>
/// <value></value>
public string? Keyword { get; set; }
/// <summary>
/// 排序条件
/// </summary>
/// <value></value>
[MinLength(1)]
public ProductOrderBys[] OrderBys { get; set; } = [
ProductOrderBys.CreateTimeDesc,
ProductOrderBys.Category
];
}

View File

@@ -0,0 +1,34 @@
namespace StopShopping.Services.Models.Req;
/// <summary>
/// 竞标参数
/// </summary>
/// <value></value>
public record ReplyParams
{
/// <summary>
/// 需求id
/// </summary>
/// <value></value>
public int RequestId { get; set; }
/// <summary>
/// 商品id
/// </summary>
/// <value></value>
public int ProductId { get; set; }
/// <summary>
/// 数量
/// </summary>
/// <value></value>
public int Amount { get; set; }
/// <summary>
/// 价格
/// </summary>
/// <value></value>
public decimal Price { get; set; }
/// <summary>
/// 留言
/// </summary>
/// <value></value>
public string? Memo { get; set; }
}

View File

@@ -0,0 +1,6 @@
namespace StopShopping.Services.Models.Req;
public record RequestIdParams
{
public int RequestId { get; set; }
}

View File

@@ -0,0 +1,32 @@
namespace StopShopping.Services.Models.Req;
/// <summary>
/// 需求排序
/// </summary>
public enum RequestOrderBys
{
/// <summary>
/// 发布时间
/// </summary>
PublishTime,
/// <summary>
/// 发布时间倒序j
/// </summary>
PublishTimeDesc,
/// <summary>
/// 分类id
/// </summary>
CategoryId,
/// <summary>
/// 分类id倒序
/// </summary>
CategoryIdDesc,
/// <summary>
/// 竞标数量
/// </summary>
ReplyAmount,
/// <summary>
/// 竞标数量倒序
/// </summary>
ReplyAmountDesc,
}

View File

@@ -0,0 +1,43 @@
using System.ComponentModel.DataAnnotations;
namespace StopShopping.Services.Models.Req;
/// <summary>
/// 需求分页检索
/// </summary>
/// <value></value>
public record RequestSearchParams : PagedSearch
{
/// <summary>
/// 分类id
/// </summary>
/// <value></value>
public int? CategoryId { get; set; }
/// <summary>
/// 关键词,序号、名称、描述
/// </summary>
/// <value></value>
public string? Keyword { get; set; }
/// <summary>
/// 排序,不要同时传同一个字段的升序和降序
/// </summary>
/// <value></value>
[MinLength(1)]
[Required]
public RequestOrderBys[] OrderBys { get; set; } = [
RequestOrderBys.PublishTimeDesc,
];
}
/// <summary>
/// 订单搜索
/// </summary>
/// <value></value>
public record RequestSearchWithStatusParams : RequestSearchParams
{
/// <summary>
/// 订单状态
/// </summary>
/// <value></value>
public RequestStatus Status { get; set; }
}

View File

@@ -0,0 +1,15 @@
namespace StopShopping.Services.Models.Req;
/// <summary>
/// 调整层级内排序
/// </summary>
/// <value></value>
public record ResortCategoryParams
{
public int Id { get; set; }
/// <summary>
/// 当前层级中排序从1开始
/// </summary>
/// <value></value>
public short TargetOrder { get; set; }
}

View File

@@ -0,0 +1,24 @@
using System.ComponentModel.DataAnnotations;
namespace StopShopping.Services.Models.Req;
/// <summary>
/// 登录参数
/// </summary>
/// <value></value>
public record SignInParams
{
/// <summary>
/// 登录账号
/// </summary>
/// <value></value>
[Required]
public string Account { get; set; } = string.Empty;
/// <summary>
/// 登录密码
/// </summary>
/// <value></value>
[Required]
public string Password { get; set; } = string.Empty;
}

View File

@@ -0,0 +1,40 @@
using System.ComponentModel.DataAnnotations;
namespace StopShopping.Services.Models.Req;
/// <summary>
/// 注册参数
/// </summary>
/// <value></value>
public record SignUpParams
{
/// <summary>
/// 登录账号
/// </summary>
/// <value></value>
[Required]
[Length(2, 20)]
public string Account { get; set; } = string.Empty;
/// <summary>
/// 昵称
/// </summary>
/// <value></value>
[Required]
[Length(2, 50)]
public string NickName { get; set; } = string.Empty;
/// <summary>
/// 默认角色
/// </summary>
/// <value></value>
public UserRoles DefaultRole { get; set; }
/// <summary>
/// 登录密码
/// </summary>
/// <value></value>
[Required]
[MinLength(6)]
public string Password { get; set; } = string.Empty;
}

View File

@@ -0,0 +1,24 @@
using System.ComponentModel.DataAnnotations;
using Microsoft.AspNetCore.Http;
namespace StopShopping.Services.Models.Req;
/// <summary>
/// 上传
/// </summary>
/// <value></value>
public record UploadParams
{
/// <summary>
/// 场景
/// </summary>
/// <value></value>
public UploadScences Scences { get; set; }
/// <summary>
/// 文件
/// </summary>
/// <value></value>
[Required]
[ImageFileValidation(2 * 1024 * 1024)]
public IFormFile? File { get; set; }
}

View File

@@ -0,0 +1,42 @@
using System.ComponentModel;
namespace StopShopping.Services.Models;
/// <summary>
/// 需求状态
/// </summary>
public enum RequestStatus
{
[Description("全部")]
All = -1,
/// <summary>
/// 发布
/// </summary>
[Description("发布")]
Publish = 0,
/// <summary>
/// 有竞标
/// </summary>
[Description("有竞标")]
Replied = 1,
/// <summary>
/// 待发货
/// </summary>
[Description("待发货")]
Accepted = 2,
/// <summary>
/// 待收货
/// </summary>
[Description("待收货")]
Sent = 3,
/// <summary>
/// 已完成
/// </summary>
[Description("已完成")]
Completed = 4,
/// <summary>
/// 已评价
/// </summary>
[Description("已评价")]
Commented = 5,
}

View File

@@ -0,0 +1,15 @@
namespace StopShopping.Services.Models.Resp;
public class AccessToken
{
/// <summary>
/// token
/// </summary>
/// <value></value>
public string? Token { get; set; }
/// <summary>
/// 有效秒
/// </summary>
/// <value></value>
public int ExpiresIn { get; set; }
}

View File

@@ -0,0 +1,54 @@
namespace StopShopping.Services.Models.Resp;
/// <summary>
/// 收货地址
/// </summary>
public class Address
{
public int Id { get; set; }
/// <summary>
/// 姓名
/// </summary>
/// <value></value>
public string Name { get; set; } = string.Empty;
/// <summary>
/// 联系电话
/// </summary>
/// <value></value>
public string Telephone { get; set; } = string.Empty;
/// <summary>
/// 自定义标签
/// </summary>
/// <value></value>
public string? Tag { get; set; }
/// <summary>
/// 是否默认地址
/// </summary>
/// <value></value>
public bool Default { get; set; }
/// <summary>
/// 区域id表示省/直辖市
/// </summary>
/// <value></value>
public int DistrictLevel1Id { get; set; }
/// <summary>
/// 区域id表示市/直辖市时为空
/// </summary>
/// <value></value>
public int? DistrictLevel2Id { get; set; }
/// <summary>
/// 区域id表示区
/// </summary>
/// <value></value>
public int DistrictLevel3Id { get; set; }
/// <summary>
/// 区域id表示街道/镇
/// </summary>
/// <value></value>
public int DistrictLevel4Id { get; set; }
/// <summary>
/// 详细地址
/// </summary>
/// <value></value>
public string? Detail { get; set; }
}

View File

@@ -0,0 +1,18 @@
namespace StopShopping.Services.Models.Resp;
/// <summary>
/// csrf token
/// </summary>
public class AntiForgeryToken
{
/// <summary>
/// csrf请求头
/// </summary>
/// <value></value>
public string? HeaderName { get; set; }
/// <summary>
/// csrf token
/// </summary>
/// <value></value>
public string? Token { get; set; }
}

View File

@@ -0,0 +1,64 @@
namespace StopShopping.Services.Models.Resp;
/// <summary>
/// 强类型返回值
/// </summary>
/// <typeparam name="T"></typeparam>
public class ApiResponse<T>
{
public ApiResponse()
{ }
public ApiResponse(T data)
{
Data = data;
}
/// <summary>
/// 是否成功
/// </summary>
/// <value></value>
public bool IsSucced { get; set; } = true;
/// <summary>
/// 错误消息
/// </summary>
/// <value></value>
public string? Message { get; set; }
/// <summary>
/// 关联数据
/// </summary>
/// <value></value>
public T? Data { get; set; }
public ApiResponse<T> Failed(string message)
{
IsSucced = false;
Message = message;
return this;
}
}
/// <summary>
/// 强类型返回值,只返回成功与否和消息
/// </summary>
public class ApiResponse : ApiResponse<object?>
{
public ApiResponse(bool isSucced = true, string message = "")
{
IsSucced = isSucced;
Message = message;
}
public static ApiResponse Succed(string message = "")
{
return new ApiResponse(message: message);
}
public static new ApiResponse Failed(string message)
{
return new ApiResponse(false, message);
}
}

View File

@@ -0,0 +1,23 @@
namespace StopShopping.Services.Models.Resp;
public record Category
{
public int Id { get; set; }
public int ParentId { get; set; }
public string Name { get; set; } = string.Empty;
/// <summary>
/// logo地址
/// </summary>
/// <value></value>
public string LogoUrl { get; set; } = string.Empty;
/// <summary>
/// 层级中序号
/// </summary>
/// <value></value>
public int Order { get; set; }
/// <summary>
/// 下级分类列表
/// </summary>
/// <value></value>
public List<Category> Children { get; set; } = [];
}

View File

@@ -0,0 +1,29 @@
namespace StopShopping.Services.Models.Resp;
/// <summary>
/// 行政区划
/// </summary>
public class District
{
public int Id { get; set; }
/// <summary>
/// 父级id
/// </summary>
/// <value></value>
public int ParentId { get; set; }
/// <summary>
/// 层级1[2]34
/// </summary>
/// <value></value>
public int Level { get; set; }
/// <summary>
/// 名称
/// </summary>
/// <value></value>
public string FullName { get; set; } = string.Empty;
/// <summary>
/// 下级,街道无下级
/// </summary>
/// <value></value>
public List<District> Children { get; set; } = [];
}

View File

@@ -0,0 +1,18 @@
namespace StopShopping.Services.Models.Resp;
/// <summary>
/// 文件上传结果
/// </summary>
public class FileUpload
{
/// <summary>
/// 新名,上传后重命名
/// </summary>
/// <value></value>
public string NewName { get; set; } = string.Empty;
/// <summary>
/// Url
/// </summary>
/// <value></value>
public string Url { get; set; } = string.Empty;
}

View File

@@ -0,0 +1,32 @@
namespace StopShopping.Services.Models.Resp;
public class PagedResult<T>
{
public int PageCount { get; set; }
public int PageSize { get; set; }
public int PageIndex { get; set; }
public List<T> Data { get; set; } = [];
}
public static class PagedQueryExtensions
{
public static async Task<PagedResult<T>> ToPagedAsync<T>(this IAsyncEnumerable<T> query
, int pageIndex = 1
, int pageSize = 20)
{
PagedResult<T> result = new()
{
PageSize = pageSize,
PageIndex = pageIndex
};
var total = await query.CountAsync();
result.PageCount = (int)Math.Ceiling(total / (decimal)result.PageSize);
result.Data = await query
.Skip((result.PageIndex - 1) * result.PageSize)
.Take(result.PageSize)
.ToListAsync();
return result;
}
}

View File

@@ -0,0 +1,62 @@
namespace StopShopping.Services.Models.Resp;
/// <summary>
/// 列表商品
/// </summary>
public class Product
{
public int Id { get; set; }
public string Name { get; set; } = "";
/// <summary>
/// 简介
/// </summary>
/// <value></value>
public string? Description { get; set; }
/// <summary>
/// 图片地址
/// </summary>
/// <value></value>
public string? LogoUrl { get; set; }
/// <summary>
/// 分类名称
/// </summary>
/// <value></value>
public string CategoryName { get; set; } = "";
/// <summary>
/// 最小销售单元
/// </summary>
/// <value></value>
public string MinimumUnit { get; set; } = "";
/// <summary>
/// 单价
/// </summary>
/// <value></value>
public decimal UnitPrice { get; set; }
/// <summary>
/// 已售数量
/// </summary>
/// <value></value>
public int SoldAmount { get; set; }
/// <summary>
/// 添加时间
/// </summary>
/// <value></value>
public string CreateTime { get; set; } = "";
}
/// <summary>
/// 详情商品
/// </summary>
public class ProductInfo : Product
{
/// <summary>
/// 分类id
/// </summary>
/// <value></value>
public int CategoryId { get; set; }
/// <summary>
/// 详情
/// </summary>
/// <value></value>
public string? Detail { get; set; }
}

View File

@@ -0,0 +1,41 @@
namespace StopShopping.Services.Models.Resp;
/// <summary>
/// 竞标
/// </summary>
public class Reply
{
public int Id { get; set; }
public int ProductId { get; set; }
public string ProductName { get; set; } = string.Empty;
/// <summary>
/// 单价
/// </summary>
/// <value></value>
public decimal UnitPrice { get; set; }
/// <summary>
/// 最小销售单元
/// </summary>
/// <value></value>
public string MinimumUnit { get; set; } = string.Empty;
/// <summary>
/// 数量
/// </summary>
/// <value></value>
public int Amount { get; set; }
/// <summary>
/// 竞标时间
/// </summary>
/// <value></value>
public string ReplyTime { get; set; } = string.Empty;
/// <summary>
/// 竞标者
/// </summary>
/// <value></value>
public string Replier { get; set; } = string.Empty;
/// <summary>
/// 留言
/// </summary>
/// <value></value>
public string? Memo { get; set; }
}

View File

@@ -0,0 +1,59 @@
namespace StopShopping.Services.Models.Resp;
/// <summary>
/// 列表需求
/// </summary>
public class Request
{
public int Id { get; set; }
/// <summary>
/// 序列号
/// </summary>
/// <value></value>
public string SerialNo { get; set; } = string.Empty;
/// <summary>
/// 状态
/// </summary>
/// <value></value>
public RequestStatus Status { get; set; }
/// <summary>
/// 名称
/// </summary>
/// <value></value>
public string Name { get; set; } = string.Empty;
/// <summary>
/// 描述
/// </summary>
/// <value></value>
public string? Description { get; set; }
/// <summary>
/// 分类id
/// </summary>
/// <value></value>
public int CategoryId { get; set; }
/// <summary>
/// 分类名称
/// </summary>
/// <value></value>
public string CategoryName { get; set; } = string.Empty;
/// <summary>
/// 发布者
/// </summary>
/// <value></value>
public string Publisher { get; set; } = string.Empty;
/// <summary>
/// 发布时间
/// </summary>
/// <value></value>
public string PublishTime { get; set; } = string.Empty;
/// <summary>
/// 截止日期
/// </summary>
/// <value></value>
public string Deadline { get; set; } = string.Empty;
/// <summary>
/// 竞标者数量
/// </summary>
/// <value></value>
public int ReplyAmount { get; set; }
}

View File

@@ -0,0 +1,47 @@
namespace StopShopping.Services.Models.Resp;
/// <summary>
/// 登录返回
/// </summary>
public abstract class SignIn
{
/// <summary>
/// 访问令牌
/// </summary>
/// <returns></returns>
public AccessToken AccessToken { get; set; } = new();
}
/// <summary>
/// 登录用户
/// </summary>
public class SignInUser : SignIn
{
/// <summary>
/// 昵称
/// </summary>
/// <value></value>
public string NickName { get; set; } = string.Empty;
/// <summary>
/// 头像地址
/// </summary>
/// <value></value>
public string? AvatarUrl { get; set; }
/// <summary>
/// 默认角色
/// </summary>
/// <value></value>
public UserRoles DefaultRole { get; set; }
}
/// <summary>
/// 登录管理员
/// </summary>
public class SignInAdmin : SignIn
{
/// <summary>
/// 昵称
/// </summary>
/// <value></value>
public string NickName { get; set; } = string.Empty;
}

View File

@@ -0,0 +1,38 @@
namespace StopShopping.Services.Models.Resp;
/// <summary>
///
/// </summary>
public class User
{
/// <summary>
/// 登录账号
/// </summary>
/// <value></value>
public string Account { get; set; } = string.Empty;
/// <summary>
/// 昵称
/// </summary>
/// <value></value>
public string NickName { get; set; } = string.Empty;
/// <summary>
/// 电话
/// </summary>
/// <value></value>
public string? Telephone { get; set; }
/// <summary>
/// 默认角色
/// </summary>
/// <value></value>
public UserRoles DefaultRole { get; set; }
/// <summary>
/// 头像地址
/// </summary>
/// <value></value>
public string? AvatarUrl { get; set; }
/// <summary>
/// 上次登录时间
/// </summary>
/// <value></value>
public string? LastLoginTime { get; set; }
}

View File

@@ -0,0 +1,12 @@
using StopShopping.Services.Models.Resp;
namespace StopShopping.Services.Models;
public class SignInResult<TUser>
where TUser : SignIn
{
public bool IsSucced { get; set; } = true;
public string? Message { get; set; }
public TUser? User { get; set; }
public AccessToken? RefreshToken { get; set; }
}

View File

@@ -0,0 +1,16 @@
namespace StopShopping.Services.Models;
/// <summary>
/// 系统角色
/// </summary>
public enum SystemRoles
{
/// <summary>
/// 管理员
/// </summary>
Admin = 'a',
/// <summary>
/// 用户
/// </summary>
User = 'u',
}

View File

@@ -0,0 +1,20 @@
namespace StopShopping.Services.Models;
/// <summary>
/// 文件上传场景
/// </summary>
public enum UploadScences
{
/// <summary>
/// 头像
/// </summary>
Avatar,
/// <summary>
/// 商品
/// </summary>
Product,
/// <summary>
/// 商品分类
/// </summary>
Category,
}

View File

@@ -0,0 +1,16 @@
namespace StopShopping.Services.Models;
/// <summary>
/// 用户角色
/// </summary>
public enum UserRoles
{
/// <summary>
/// 卖家
/// </summary>
Seller,
/// <summary>
/// 买家
/// </summary>
Buyer
}

View File

@@ -0,0 +1,51 @@
using FileSignatures;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
namespace System.ComponentModel.DataAnnotations;
public class ImageFileValidationAttribute : ValidationAttribute
{
public ImageFileValidationAttribute(long length)
{
Length = length;
}
public long Length { get; set; }
protected override ValidationResult? IsValid(object? value, ValidationContext validationContext)
{
var fileInspector = validationContext.GetRequiredService<IFileFormatInspector>();
if (null == fileInspector)
{
return new ValidationResult("未配置文件验证器");
}
if (value is IFormFile file)
{
var result = Validate(fileInspector, file);
if (null != result)
return result;
}
else if (value is IFormFileCollection files)
{
foreach (var f in files)
{
var result = Validate(fileInspector, f);
if (null != result)
return result;
}
}
return ValidationResult.Success;
}
private ValidationResult? Validate(IFileFormatInspector fileInspector, IFormFile file)
{
if (file.Length > Length)
return new ValidationResult("文件太大");
var format = fileInspector.DetermineFileFormat(file.OpenReadStream());
if (null == format)
return new ValidationResult("文件格式不支持");
return null;
}
}