diff --git a/.drone.yml b/.drone.yml
new file mode 100644
index 0000000..76cf5b7
--- /dev/null
+++ b/.drone.yml
@@ -0,0 +1,69 @@
+kind: pipeline
+type: docker
+name: deployment
+
+steps:
+ - name: check
+ image: alpine
+ commands:
+ - ls -la
+ - ls -la Dockerfile # 查看当前文件夹是否包含了Dockerfile
+ - name: publish
+ image: plugins/docker
+ settings:
+ username:
+ from_secret: nexus_username
+ password:
+ from_secret: nexus_password
+ pull: if-not-exists # 如果镜像不存在则拉取,免去每次都要重新下载
+ dockerfile: Dockerfile
+ tags: latest
+ # you need insecure: true since we don't have a TLS certificate
+ insecure: true
+ registry: 192.168.31.104:8082
+ repo: 192.168.31.104:8082/tiamo/user-point-management
+ volumes: # 将容器内目录挂载到宿主机,仓库需要开启Trusted设置
+ - name: dockersock
+ path: /var/run/docker.sock
+ - name: deploy
+ pull: if-not-exists
+ image: appleboy/drone-ssh
+ environment:
+ Connection:
+ from_secret: connection
+ NEXUS_USER:
+ from_secret: nexus_username
+ NEXUS_PASSWORD:
+ from_secret: nexus_password
+ settings:
+ host: 192.168.31.225
+ port: 22
+ username: drone
+ password: dronepw
+ command_timeout: 2m
+ envs: [ NEXUS_USER, NEXUS_PASSWORD ]
+ script:
+ - echo $NEXUS_PASSWORD | docker login -u $NEXUS_USER --password-stdin 192.168.31.104:8082
+ - docker pull 192.168.31.104:8082/tiamo/user-point-management
+ - echo 开始停止容器
+ - docker stop user-point-management
+ - echo 开始强制清除停止容器
+ - docker container prune -f
+ - echo 开始清除镜像
+ - docker image prune -f
+ - echo 开始标签镜像
+ - docker tag 192.168.31.104:8082/tiamo/user-point-management tiamo/user-point-management:latest
+ - echo 开始运行容器
+ - docker run --name user-point-management -d -p 29029:5000
+ -e Connection__UserPointManagement="Server=192.168.31.225;Port=5432;UserId=postgres;Password=postgres;Database=tiamo;"
+ tiamo/user-point-management
+ - echo 执行完成
+
+volumes:
+ - name: dockersock
+ host:
+ path: /var/run/docker.sock
+
+trigger:
+ branch:
+ - master
\ No newline at end of file
diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 0000000..a822e00
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,26 @@
+FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base
+
+WORKDIR /docker
+EXPOSE 5000
+
+FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
+WORKDIR /build
+COPY . .
+RUN dotnet restore src/UserPointManagement.Web/UserPointManagement.Web.csproj --configfile ./NuGet.Config
+WORKDIR src/UserPointManagement.Web
+RUN dotnet build UserPointManagement.Web.csproj -c Release
+
+FROM build AS publish
+RUN dotnet publish UserPointManagement.Web.csproj -c Release -o /app
+
+FROM base AS final
+WORKDIR /app
+COPY --from=publish /app .
+
+ENV ASPNETCORE_URLS http://*:5000
+ENV TZ Asia/Shanghai
+ENV Connection__UserPointManagement=""
+
+ENTRYPOINT ["dotnet", "UserPointManagement.Web.dll"]
+
+
diff --git a/NuGet.Config b/NuGet.Config
new file mode 100644
index 0000000..a728892
--- /dev/null
+++ b/NuGet.Config
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..793a0ac
--- /dev/null
+++ b/README.md
@@ -0,0 +1 @@
+## 会员积分管理系统
\ No newline at end of file
diff --git a/UserPointManagement.sln b/UserPointManagement.sln
index 217ae76..ed58511 100644
--- a/UserPointManagement.sln
+++ b/UserPointManagement.sln
@@ -18,6 +18,15 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UserPointManagement.Persist
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UserPointManagement.Application.Tests", "test\UserPointManagement.Application.Tests\UserPointManagement.Application.Tests.csproj", "{5770D3E5-9B3E-40FC-8209-62F0B4B45BD4}"
EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{08F901D9-600A-4B4D-A942-AD2F61EDFE49}"
+ ProjectSection(SolutionItems) = preProject
+ Dockerfile = Dockerfile
+ README.md = README.md
+ NuGet.Config = NuGet.Config
+ .drone.yml = .drone.yml
+ .gitignore = .gitignore
+ EndProjectSection
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
diff --git a/src/UserPointManagement.Application/Services/UserPointService.cs b/src/UserPointManagement.Application/Services/UserPointService.cs
index 21489c5..7e23d9f 100644
--- a/src/UserPointManagement.Application/Services/UserPointService.cs
+++ b/src/UserPointManagement.Application/Services/UserPointService.cs
@@ -8,7 +8,7 @@ namespace UserPointManagement.Application.Services;
public interface IUserPointService
{
- Task> GetUserPoints(GetUserPointDto req);
+ Task> GetUserPoints(GetUserPointDto req);
Task CreateUserPoint(CreateUserPointDto input);
@@ -24,26 +24,39 @@ public class UserPointService : IUserPointService
_dbContextFactory = dbContextFactory;
}
- public async Task> GetUserPoints(GetUserPointDto req)
+ public async Task> GetUserPoints(GetUserPointDto req)
{
await using var _userPointManagementDbContext = await _dbContextFactory.CreateDbContextAsync();
- var queryable = from userPoint in _userPointManagementDbContext.UserPoints
- join user in _userPointManagementDbContext.Users on userPoint.UserId equals user.Id
+
+ var queryable = _userPointManagementDbContext.Users
+ .Where(x => x.Id == req.UserId, req.UserId.HasValue);
+
+ // 分页筛选只能针对用户
+ var users = await queryable.OrderByDescending(x => x.Id).Paging(req).ToListAsync();
+
+ // 查出用户底下积分明细
+ var userPoints = await (from userPoint in _userPointManagementDbContext.UserPoints
+ where users.Select(x => x.Id).Contains(userPoint.UserId)
select new UserPointDto()
{
UserPointId = userPoint.Id,
- UserId = user.Id,
- Name = user.Name,
+ UserId = userPoint.UserId,
Point = userPoint.Point,
CreateTime = userPoint.CreateTime
- };
+ }).ToListAsync();
- queryable = queryable.Where(x => x.UserId == req.UserId, req.UserId.HasValue);
+ var data = userPoints.GroupBy(x => x.UserId)
+ .Select(x => new UserPointInfoDto()
+ {
+ UserId = x.Key,
+ Name = users.First(p => p.Id == x.Key).Name,
+ TotalPoint = x.Sum(p => p.Point),
+ Items = x.ToList()
+ }).ToList();
var count = queryable.Count();
- var data = await queryable.OrderByDescending(x => x.CreateTime).Paging(req).ToListAsync().ConfigureAwait(false);
- return new PageResultDto()
+ return new PageResultDto()
{
Items = data,
TotalCount = count
diff --git a/src/UserPointManagement.Application/Services/UserService.cs b/src/UserPointManagement.Application/Services/UserService.cs
index b7978ba..46b4921 100644
--- a/src/UserPointManagement.Application/Services/UserService.cs
+++ b/src/UserPointManagement.Application/Services/UserService.cs
@@ -37,7 +37,7 @@ public class UserService : IUserService
queryable = queryable.Where(x => x.Mobile.Contains(req.Keyword) || x.Name.Contains(req.Keyword),
!string.IsNullOrEmpty(req.Keyword));
-
+
var count = queryable.Count();
var data = await queryable.OrderByDescending(x => x.Id).Paging(req).ToListAsync().ConfigureAwait(false);
@@ -63,7 +63,8 @@ public class UserService : IUserService
public async Task CreateUser(User input)
{
await using var _userPointManagementDbContext = await _dbContextFactory.CreateDbContextAsync();
- if (_userPointManagementDbContext.Users.Any(x => x.Mobile == input.Mobile))
+ if (!string.IsNullOrWhiteSpace(input.Mobile) &&
+ _userPointManagementDbContext.Users.Any(x => x.Mobile == input.Mobile))
{
throw new ArgumentException("手机号不可重复!");
}
@@ -72,6 +73,7 @@ public class UserService : IUserService
{
throw new ArgumentException("名称不可重复!");
}
+
_userPointManagementDbContext.Users.Add(input);
await _userPointManagementDbContext.SaveChangesAsync().ConfigureAwait(false);
}
diff --git a/src/UserPointManagement.Model/Dtos/User/GetUserDto.cs b/src/UserPointManagement.Model/Dtos/User/GetUserDto.cs
index f263408..b0c866c 100644
--- a/src/UserPointManagement.Model/Dtos/User/GetUserDto.cs
+++ b/src/UserPointManagement.Model/Dtos/User/GetUserDto.cs
@@ -2,5 +2,5 @@
public class GetUserDto : PageBase
{
- public string Keyword { get; set; }
+ public string? Keyword { get; set; }
}
\ No newline at end of file
diff --git a/src/UserPointManagement.Model/Dtos/UserPoint/UserPointDto.cs b/src/UserPointManagement.Model/Dtos/UserPoint/UserPointDto.cs
index b1479b6..282260a 100644
--- a/src/UserPointManagement.Model/Dtos/UserPoint/UserPointDto.cs
+++ b/src/UserPointManagement.Model/Dtos/UserPoint/UserPointDto.cs
@@ -6,8 +6,6 @@ public class UserPointDto
public int UserId { get; set; }
- public string Name { get; set; }
-
public int Point { get; set; }
public DateTime CreateTime { get; set; }
diff --git a/src/UserPointManagement.Model/Dtos/UserPoint/UserPointInfoDto.cs b/src/UserPointManagement.Model/Dtos/UserPoint/UserPointInfoDto.cs
new file mode 100644
index 0000000..d35c4a0
--- /dev/null
+++ b/src/UserPointManagement.Model/Dtos/UserPoint/UserPointInfoDto.cs
@@ -0,0 +1,12 @@
+namespace UserPointManagement.Model.Dtos.UserPoint;
+
+public class UserPointInfoDto
+{
+ public int UserId { get; set; }
+
+ public string Name { get; set; }
+
+ public int TotalPoint { get; set; }
+
+ public List Items { get; set; }
+}
\ No newline at end of file
diff --git a/src/UserPointManagement.Model/Entities/User.cs b/src/UserPointManagement.Model/Entities/User.cs
index ca12ba6..6336605 100644
--- a/src/UserPointManagement.Model/Entities/User.cs
+++ b/src/UserPointManagement.Model/Entities/User.cs
@@ -6,5 +6,5 @@ public class User
public string Name { get; set; }
- public string Mobile { get; set; }
+ public string? Mobile { get; set; }
}
\ No newline at end of file
diff --git a/src/UserPointManagement.Persistence/EntityTypeConfigurations/UserConfiguration.cs b/src/UserPointManagement.Persistence/EntityTypeConfigurations/UserConfiguration.cs
index 473ad28..31329a3 100644
--- a/src/UserPointManagement.Persistence/EntityTypeConfigurations/UserConfiguration.cs
+++ b/src/UserPointManagement.Persistence/EntityTypeConfigurations/UserConfiguration.cs
@@ -9,10 +9,10 @@ public class UserConfiguration : IEntityTypeConfiguration
public void Configure(EntityTypeBuilder builder)
{
builder.HasKey(e => e.Id);
-
+
builder.Property(e => e.Id)
.HasComment("主键");
-
+
builder.Property(e => e.Name)
.HasComment("姓名")
.HasMaxLength(50);
diff --git a/src/UserPointManagement.Persistence/Migrations/20230730134035_ModifyUser.Designer.cs b/src/UserPointManagement.Persistence/Migrations/20230730134035_ModifyUser.Designer.cs
new file mode 100644
index 0000000..2721dee
--- /dev/null
+++ b/src/UserPointManagement.Persistence/Migrations/20230730134035_ModifyUser.Designer.cs
@@ -0,0 +1,89 @@
+//
+using System;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
+using UserPointManagement.Persistence;
+
+#nullable disable
+
+namespace UserPointManagement.Persistence.Migrations
+{
+ [DbContext(typeof(UserPointManagementDbContext))]
+ [Migration("20230730134035_ModifyUser")]
+ partial class ModifyUser
+ {
+ protected override void BuildTargetModel(ModelBuilder modelBuilder)
+ {
+#pragma warning disable 612, 618
+ modelBuilder
+ .HasAnnotation("ProductVersion", "6.0.0")
+ .HasAnnotation("Relational:MaxIdentifierLength", 63);
+
+ NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
+
+ modelBuilder.Entity("UserPointManagement.Model.Entities.User", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer")
+ .HasColumnName("id")
+ .HasComment("主键");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id"));
+
+ b.Property("Mobile")
+ .HasMaxLength(30)
+ .HasColumnType("character varying(30)")
+ .HasColumnName("mobile")
+ .HasComment("手机号");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasMaxLength(50)
+ .HasColumnType("character varying(50)")
+ .HasColumnName("name")
+ .HasComment("姓名");
+
+ b.HasKey("Id")
+ .HasName("pk_user");
+
+ b.ToTable("user", (string)null);
+ });
+
+ modelBuilder.Entity("UserPointManagement.Model.Entities.UserPoint", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bigint")
+ .HasColumnName("id")
+ .HasComment("主键");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id"));
+
+ b.Property("CreateTime")
+ .HasColumnType("timestamp without time zone")
+ .HasColumnName("create_time")
+ .HasComment("新增时间");
+
+ b.Property("Point")
+ .HasColumnType("integer")
+ .HasColumnName("point")
+ .HasComment("积分");
+
+ b.Property("UserId")
+ .HasColumnType("integer")
+ .HasColumnName("user_id")
+ .HasComment("用户Id");
+
+ b.HasKey("Id")
+ .HasName("pk_user_point");
+
+ b.ToTable("user_point", (string)null);
+ });
+#pragma warning restore 612, 618
+ }
+ }
+}
diff --git a/src/UserPointManagement.Persistence/Migrations/20230730134035_ModifyUser.cs b/src/UserPointManagement.Persistence/Migrations/20230730134035_ModifyUser.cs
new file mode 100644
index 0000000..89f6326
--- /dev/null
+++ b/src/UserPointManagement.Persistence/Migrations/20230730134035_ModifyUser.cs
@@ -0,0 +1,41 @@
+using Microsoft.EntityFrameworkCore.Migrations;
+
+#nullable disable
+
+namespace UserPointManagement.Persistence.Migrations
+{
+ public partial class ModifyUser : Migration
+ {
+ protected override void Up(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.AlterColumn(
+ name: "mobile",
+ table: "user",
+ type: "character varying(30)",
+ maxLength: 30,
+ nullable: true,
+ comment: "手机号",
+ oldClrType: typeof(string),
+ oldType: "character varying(30)",
+ oldMaxLength: 30,
+ oldComment: "手机号");
+ }
+
+ protected override void Down(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.AlterColumn(
+ name: "mobile",
+ table: "user",
+ type: "character varying(30)",
+ maxLength: 30,
+ nullable: false,
+ defaultValue: "",
+ comment: "手机号",
+ oldClrType: typeof(string),
+ oldType: "character varying(30)",
+ oldMaxLength: 30,
+ oldNullable: true,
+ oldComment: "手机号");
+ }
+ }
+}
diff --git a/src/UserPointManagement.Persistence/Migrations/UserPointManagementDbContextModelSnapshot.cs b/src/UserPointManagement.Persistence/Migrations/UserPointManagementDbContextModelSnapshot.cs
index ff15431..d3f4674 100644
--- a/src/UserPointManagement.Persistence/Migrations/UserPointManagementDbContextModelSnapshot.cs
+++ b/src/UserPointManagement.Persistence/Migrations/UserPointManagementDbContextModelSnapshot.cs
@@ -33,7 +33,6 @@ namespace UserPointManagement.Persistence.Migrations
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id"));
b.Property("Mobile")
- .IsRequired()
.HasMaxLength(30)
.HasColumnType("character varying(30)")
.HasColumnName("mobile")
diff --git a/src/UserPointManagement.Persistence/UserPointManagementDbContext.cs b/src/UserPointManagement.Persistence/UserPointManagementDbContext.cs
index 7b7d34b..1ea298f 100644
--- a/src/UserPointManagement.Persistence/UserPointManagementDbContext.cs
+++ b/src/UserPointManagement.Persistence/UserPointManagementDbContext.cs
@@ -9,9 +9,9 @@ public class UserPointManagementDbContext : Microsoft.EntityFrameworkCore.DbCont
public UserPointManagementDbContext(DbContextOptions options) : base(options)
{
}
-
+
public virtual DbSet Users { get; set; }
-
+
public virtual DbSet UserPoints { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
diff --git a/src/UserPointManagement.Persistence/UserPointManagementDbContextFactory.cs b/src/UserPointManagement.Persistence/UserPointManagementDbContextFactory.cs
index 6edfa7e..9853b76 100644
--- a/src/UserPointManagement.Persistence/UserPointManagementDbContextFactory.cs
+++ b/src/UserPointManagement.Persistence/UserPointManagementDbContextFactory.cs
@@ -10,7 +10,7 @@ public class UserPointManagementDbContextFactory : IDesignTimeDbContextFactory();
optionsBuilder
- .UseNpgsql("Server=67.230.184.225;Port=58007;UserId=postgres;Password=postgres;Database=tiamo;")
+ .UseNpgsql("Server=67.230.184.225;Port=58007;UserId=postgres;Password=postgres;Database=tiamo_dev;")
.UseSnakeCaseNamingConvention();
AppContext.SetSwitch("Npgsql.EnableLegacyTimestampBehavior", true);
diff --git a/src/UserPointManagement.Web/Controllers/UserController.cs b/src/UserPointManagement.Web/Controllers/UserController.cs
new file mode 100644
index 0000000..e6296f6
--- /dev/null
+++ b/src/UserPointManagement.Web/Controllers/UserController.cs
@@ -0,0 +1,31 @@
+using System.Threading.Tasks;
+using Microsoft.AspNetCore.Mvc;
+using UserPointManagement.Application.Services;
+using UserPointManagement.Model;
+using UserPointManagement.Model.Dtos.User;
+using UserPointManagement.Model.Entities;
+
+namespace UserPointManagement.Web.Controllers;
+
+[ApiController]
+[Route("[controller]")]
+public class UserController : ControllerBase
+{
+ private readonly IUserService _userService;
+
+ public UserController(IUserService userService)
+ {
+ _userService = userService;
+ }
+
+ ///
+ /// 获取用户
+ ///
+ ///
+ ///
+ [HttpGet]
+ public async Task> GetUsers([FromQuery]GetUserDto req)
+ {
+ return await _userService.GetUsers(req).ConfigureAwait(false);
+ }
+}
\ No newline at end of file
diff --git a/src/UserPointManagement.Web/MvcOptionsExtensions.cs b/src/UserPointManagement.Web/MvcOptionsExtensions.cs
new file mode 100644
index 0000000..72e4d8e
--- /dev/null
+++ b/src/UserPointManagement.Web/MvcOptionsExtensions.cs
@@ -0,0 +1,45 @@
+using System.Linq;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.AspNetCore.Mvc.ApplicationModels;
+using Microsoft.AspNetCore.Mvc.Routing;
+
+namespace UserPointManagement.Web;
+
+public static class MvcOptionsExtensions
+{
+ private static void UseGeneralRoutePrefix(this MvcOptions opts, IRouteTemplateProvider routeAttribute)
+ {
+ opts.Conventions.Add(new RoutePrefixConvention(routeAttribute));
+ }
+
+ public static void UseGeneralRoutePrefix(this MvcOptions opts, string
+ prefix)
+ {
+ opts.UseGeneralRoutePrefix(new RouteAttribute(prefix));
+ }
+}
+
+public class RoutePrefixConvention : IApplicationModelConvention
+{
+ private readonly AttributeRouteModel _routePrefix;
+
+ public RoutePrefixConvention(IRouteTemplateProvider route)
+ {
+ _routePrefix = new AttributeRouteModel(route);
+ }
+
+ public void Apply(ApplicationModel application)
+ {
+ foreach (var selector in application.Controllers.SelectMany(c => c.Selectors))
+ {
+ if (selector.AttributeRouteModel != null)
+ {
+ selector.AttributeRouteModel = AttributeRouteModel.CombineAttributeRouteModel(_routePrefix, selector.AttributeRouteModel);
+ }
+ else
+ {
+ selector.AttributeRouteModel = _routePrefix;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/UserPointManagement.Web/Pages/UserManagement/UserManagement.razor b/src/UserPointManagement.Web/Pages/UserManagement/UserManagement.razor
index 6ffe8c1..cb41f0f 100644
--- a/src/UserPointManagement.Web/Pages/UserManagement/UserManagement.razor
+++ b/src/UserPointManagement.Web/Pages/UserManagement/UserManagement.razor
@@ -92,7 +92,7 @@
-
+
diff --git a/src/UserPointManagement.Web/Pages/UserPointDetail/UserPointDetail.razor b/src/UserPointManagement.Web/Pages/UserPointDetail/UserPointDetail.razor
index 4c5c626..60ab9d9 100644
--- a/src/UserPointManagement.Web/Pages/UserPointDetail/UserPointDetail.razor
+++ b/src/UserPointManagement.Web/Pages/UserPointDetail/UserPointDetail.razor
@@ -36,23 +36,36 @@
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -68,7 +81,7 @@
@ref="@_form">