home page for App

This commit is contained in:
2023-07-27 22:07:24 +08:00
parent 02ac33fc07
commit befbc7fc9b
40 changed files with 1175 additions and 398 deletions

View File

@ -103,10 +103,10 @@ public enum EventTypes
/// <summary>
/// 事件类
/// </summary>
/// <param name="Key">名称</param>
/// <param name="Name">名称</param>
/// <param name="Description">描述</param>
/// <param name="Unique">是否唯一</param>
public record Event(string Key, string? Description = null, bool Unique = false) : NamedItem(Key, Description)
public record Event(string Name, string? Description = null, bool Unique = false) : NamedItem(Name, Description)
{
/// <summary>
/// 是否唯一
@ -118,14 +118,14 @@ public record Event(string Key, string? Description = null, bool Unique = false)
/// <summary>
/// 命名对象类
/// </summary>
/// <param name="Key">名称</param>
/// <param name="Name">名称</param>
/// <param name="Description">描述</param>
public record NamedItem(string Key, string? Description = null)
public record NamedItem(string Name, string? Description = null)
{
/// <summary>
/// 名称
/// </summary>
public string Key { get; init; } = Key;
public string Name { get; init; } = Name;
/// <summary>
/// 描述

View File

@ -52,6 +52,7 @@ public partial class ApiController : BaseController
{
return Ok(new DefinitionResult
{
ApiVersion = Program.Version,
Categories = Constants.Categories,
Events = Constants.Events,
});

View File

@ -5,6 +5,11 @@
/// </summary>
public record DefinitionResult
{
/// <summary>
/// API 版本号
/// </summary>
public required string ApiVersion { get; init; }
/// <summary>
/// 花草分类
/// </summary>

View File

@ -218,6 +218,7 @@ public abstract partial class BaseController : ControllerBase
using var ms = new MemoryStream();
ms.Write(headers, 0, count);
#if __OLD_READER__
// reading
const int size = 16384;
var buffer = new byte[size];
@ -225,17 +226,24 @@ public abstract partial class BaseController : ControllerBase
{
ms.Write(buffer, 0, count);
}
#else
stream.CopyTo(ms);
#endif
var data = ms.ToArray();
var name = file.FileName;
var ext = Path.GetExtension(name);
var path = $"{WebUtility.UrlEncode(Path.GetFileNameWithoutExtension(name))}_{DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()}{ext}";
var image = SkiaSharp.SKImage.FromEncodedData(data);
return new FileResult
{
Filename = name,
FileType = ext,
Path = path,
Content = data
Content = data,
Width = image.Width,
Height = image.Height
};
}
}
@ -364,30 +372,20 @@ public record FileResult
/// <summary>
/// 储存路径
/// </summary>
public required string Path { get; set; }
public required string Path { get; init; }
/// <summary>
/// 文件内容
/// </summary>
[Required]
public required byte[] Content { get; init; }
/// <summary>
/// 照片宽度
/// </summary>
public required int Width { get; init; }
/// <summary>
/// 照片高度
/// </summary>
public required int Height { get; init; }
}
/// <summary>
/// 照片参数
/// </summary>
public record PhotoParameter
{
/// <summary>
/// 花草 id
/// </summary>
[Required]
public int Id { get; set; }
/// <summary>
/// 封面照片
/// </summary>
[Required]
public required IFormFile Photo { get; set; }
}

View File

@ -88,6 +88,6 @@ partial class BaseController
/// <returns></returns>
protected int AddPhotoItem(PhotoItem item)
{
return database.Database.ExecuteSql($"INSERT INTO \"photos\"(\"fid\",\"rid\",\"filetype\",\"filename\",\"path\",\"dateupload\") VALUES({item.FlowerId},{item.RecordId},{item.FileType},{item.FileName},{item.Path},{item.DateUploadUnixTime})");
return database.Database.ExecuteSql($"INSERT INTO \"photos\"(\"fid\",\"uid\",\"rid\",\"filetype\",\"filename\",\"path\",\"dateupload\",\"width\",\"height\") VALUES({item.FlowerId},{item.OwnerId},{item.RecordId},{item.FileType},{item.FileName},{item.Path},{item.DateUploadUnixTime},{item.Width},{item.Height})");
}
}

View File

@ -279,7 +279,9 @@ public class EventApiController : BaseController
FileType = file.FileType,
FileName = file.Filename,
Path = file.Path,
DateUploadUnixTime = now
DateUploadUnixTime = now,
Width = file.Width,
Height = file.Height
};
AddPhotoItem(p);
@ -402,7 +404,9 @@ public class EventApiController : BaseController
FileType = file.FileType,
FileName = file.Filename,
Path = file.Path,
DateUploadUnixTime = now
DateUploadUnixTime = now,
Width = file.Width,
Height = file.Height
};
AddPhotoItem(cover);
@ -498,7 +502,9 @@ public class EventApiController : BaseController
FileType = file.FileType,
FileName = file.Filename,
Path = file.Path,
DateUploadUnixTime = user.ActiveDateUnixTime ?? DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()
DateUploadUnixTime = user.ActiveDateUnixTime ?? DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(),
Width = file.Width,
Height = file.Height
};
AddPhotoItem(p);
@ -594,7 +600,9 @@ public class EventApiController : BaseController
FileType = file.FileType,
FileName = file.Filename,
Path = file.Path,
DateUploadUnixTime = user.ActiveDateUnixTime ?? DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()
DateUploadUnixTime = user.ActiveDateUnixTime ?? DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(),
Width = file.Width,
Height = file.Height
};
AddPhotoItem(p);

View File

@ -518,7 +518,9 @@ public class FlowerApiController : BaseController
FileType = file.FileType,
FileName = file.Filename,
Path = file.Path,
DateUploadUnixTime = now
DateUploadUnixTime = now,
Width = file.Width,
Height = file.Height
};
AddPhotoItem(cover);
@ -639,7 +641,9 @@ public class FlowerApiController : BaseController
FileType = file.FileType,
FileName = file.Filename,
Path = file.Path,
DateUploadUnixTime = now
DateUploadUnixTime = now,
Width = file.Width,
Height = file.Height
};
database.Photos.Add(item);
SaveDatabase();
@ -776,7 +780,9 @@ public class FlowerApiController : BaseController
FileType = file.FileType,
FileName = file.Filename,
Path = file.Path,
DateUploadUnixTime = now
DateUploadUnixTime = now,
Width = file.Width,
Height = file.Height
};
AddPhotoItem(cover);
@ -893,7 +899,9 @@ public class FlowerApiController : BaseController
FileType = file.FileType,
FileName = file.Filename,
Path = file.Path,
DateUploadUnixTime = now
DateUploadUnixTime = now,
Width = file.Width,
Height = file.Height
};
AddPhotoItem(cover);

View File

@ -94,6 +94,18 @@ public class PhotoItem
[JsonIgnore]
public DateTimeOffset DateUpload => DateTimeOffset.FromUnixTimeMilliseconds(DateUploadUnixTime);
/// <summary>
/// 图片宽度
/// </summary>
[Column("width")]
public int? Width { get; set; }
/// <summary>
/// 图片高度
/// </summary>
[Column("height")]
public int? Height { get; set; }
/// <summary>
/// 前端显示的 URL
/// </summary>

View File

@ -0,0 +1,353 @@
// <auto-generated />
using System;
using Blahblah.FlowerStory.Server.Data;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
#nullable disable
namespace Blahblah.FlowerStory.Server.Migrations
{
[DbContext(typeof(FlowerDatabase))]
[Migration("20230724084100_Add-Photo-Size")]
partial class AddPhotoSize
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder.HasAnnotation("ProductVersion", "7.0.9");
modelBuilder.Entity("Blahblah.FlowerStory.Server.Data.Model.FlowerItem", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER")
.HasColumnName("fid");
b.Property<int>("CategoryId")
.HasColumnType("INTEGER")
.HasColumnName("categoryid");
b.Property<decimal?>("Cost")
.HasColumnType("real")
.HasColumnName("cost");
b.Property<long>("DateBuyUnixTime")
.HasColumnType("INTEGER")
.HasColumnName("datebuy")
.HasAnnotation("Relational:JsonPropertyName", "dateBuy");
b.Property<double?>("Latitude")
.HasColumnType("REAL")
.HasColumnName("latitude");
b.Property<double?>("Longitude")
.HasColumnType("REAL")
.HasColumnName("longitude");
b.Property<string>("Memo")
.HasColumnType("TEXT")
.HasColumnName("memo");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("TEXT")
.HasColumnName("name");
b.Property<int>("OwnerId")
.HasColumnType("INTEGER")
.HasColumnName("uid");
b.Property<string>("Purchase")
.HasColumnType("TEXT")
.HasColumnName("purchase");
b.HasKey("Id");
b.HasIndex("OwnerId");
b.ToTable("flowers");
});
modelBuilder.Entity("Blahblah.FlowerStory.Server.Data.Model.PhotoItem", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER")
.HasColumnName("pid");
b.Property<long>("DateUploadUnixTime")
.HasColumnType("INTEGER")
.HasColumnName("dateupload")
.HasAnnotation("Relational:JsonPropertyName", "dateUpload");
b.Property<string>("FileName")
.IsRequired()
.HasColumnType("TEXT")
.HasColumnName("filename");
b.Property<string>("FileType")
.IsRequired()
.HasColumnType("TEXT")
.HasColumnName("filetype");
b.Property<int?>("FlowerId")
.HasColumnType("INTEGER")
.HasColumnName("fid");
b.Property<int?>("Height")
.HasColumnType("INTEGER")
.HasColumnName("height");
b.Property<int>("OwnerId")
.HasColumnType("INTEGER")
.HasColumnName("uid");
b.Property<string>("Path")
.IsRequired()
.HasColumnType("TEXT")
.HasColumnName("path");
b.Property<int?>("RecordId")
.HasColumnType("INTEGER")
.HasColumnName("rid");
b.Property<int?>("Width")
.HasColumnType("INTEGER")
.HasColumnName("width");
b.HasKey("Id");
b.HasIndex("FlowerId");
b.HasIndex("OwnerId");
b.HasIndex("RecordId");
b.ToTable("photos");
});
modelBuilder.Entity("Blahblah.FlowerStory.Server.Data.Model.RecordItem", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER")
.HasColumnName("rid");
b.Property<int?>("ByUserId")
.HasColumnType("INTEGER")
.HasColumnName("byuid");
b.Property<string>("ByUserName")
.HasColumnType("TEXT")
.HasColumnName("byname");
b.Property<long>("DateUnixTime")
.HasColumnType("INTEGER")
.HasColumnName("date")
.HasAnnotation("Relational:JsonPropertyName", "date");
b.Property<int>("EventId")
.HasColumnType("INTEGER")
.HasColumnName("eid");
b.Property<int>("FlowerId")
.HasColumnType("INTEGER")
.HasColumnName("fid");
b.Property<double?>("Latitude")
.HasColumnType("REAL")
.HasColumnName("latitude");
b.Property<double?>("Longitude")
.HasColumnType("REAL")
.HasColumnName("longitude");
b.Property<string>("Memo")
.HasColumnType("TEXT")
.HasColumnName("memo");
b.Property<int>("OwnerId")
.HasColumnType("INTEGER")
.HasColumnName("uid");
b.HasKey("Id");
b.HasIndex("FlowerId");
b.HasIndex("OwnerId");
b.ToTable("records");
});
modelBuilder.Entity("Blahblah.FlowerStory.Server.Data.Model.TokenItem", b =>
{
b.Property<string>("Id")
.HasColumnType("TEXT")
.HasColumnName("tid");
b.Property<long>("ActiveDateUnixTime")
.HasColumnType("INTEGER")
.HasColumnName("activedate")
.HasAnnotation("Relational:JsonPropertyName", "activeDate");
b.Property<string>("ClientAgent")
.HasColumnType("TEXT")
.HasColumnName("clientagent");
b.Property<string>("ClientApp")
.HasColumnType("TEXT")
.HasColumnName("clientapp");
b.Property<string>("DeviceId")
.HasColumnType("TEXT")
.HasColumnName("deviceid");
b.Property<long>("ExpireDateUnixTime")
.HasColumnType("INTEGER")
.HasColumnName("expiredate")
.HasAnnotation("Relational:JsonPropertyName", "expireDate");
b.Property<int>("ExpireSeconds")
.HasColumnType("INTEGER")
.HasColumnName("expiresecs");
b.Property<long>("LogonDateUnixTime")
.HasColumnType("INTEGER")
.HasColumnName("logondate")
.HasAnnotation("Relational:JsonPropertyName", "logonDate");
b.Property<int>("UserId")
.HasColumnType("INTEGER")
.HasColumnName("uid");
b.Property<string>("VerifyCode")
.HasColumnType("TEXT")
.HasColumnName("verifycode");
b.HasKey("Id");
b.ToTable("tokens");
});
modelBuilder.Entity("Blahblah.FlowerStory.Server.Data.Model.UserItem", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER")
.HasColumnName("uid");
b.Property<long?>("ActiveDateUnixTime")
.HasColumnType("INTEGER")
.HasColumnName("activedate");
b.Property<byte[]>("Avatar")
.HasColumnType("BLOB")
.HasColumnName("avatar");
b.Property<string>("Email")
.HasColumnType("TEXT")
.HasColumnName("email");
b.Property<int>("Level")
.HasColumnType("INTEGER")
.HasColumnName("level");
b.Property<string>("Mobile")
.HasColumnType("TEXT")
.HasColumnName("mobile");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("TEXT")
.HasColumnName("name");
b.Property<string>("Password")
.IsRequired()
.HasColumnType("TEXT")
.HasColumnName("password");
b.Property<long>("RegisterDateUnixTime")
.HasColumnType("INTEGER")
.HasColumnName("regdate")
.HasAnnotation("Relational:JsonPropertyName", "registerDate");
b.Property<string>("UserId")
.IsRequired()
.HasColumnType("TEXT")
.HasColumnName("id");
b.HasKey("Id");
b.ToTable("users");
});
modelBuilder.Entity("Blahblah.FlowerStory.Server.Data.Model.FlowerItem", b =>
{
b.HasOne("Blahblah.FlowerStory.Server.Data.Model.UserItem", "Owner")
.WithMany()
.HasForeignKey("OwnerId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Owner");
});
modelBuilder.Entity("Blahblah.FlowerStory.Server.Data.Model.PhotoItem", b =>
{
b.HasOne("Blahblah.FlowerStory.Server.Data.Model.FlowerItem", "Flower")
.WithMany("Photos")
.HasForeignKey("FlowerId");
b.HasOne("Blahblah.FlowerStory.Server.Data.Model.UserItem", "Owner")
.WithMany()
.HasForeignKey("OwnerId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("Blahblah.FlowerStory.Server.Data.Model.RecordItem", "Record")
.WithMany("Photos")
.HasForeignKey("RecordId");
b.Navigation("Flower");
b.Navigation("Owner");
b.Navigation("Record");
});
modelBuilder.Entity("Blahblah.FlowerStory.Server.Data.Model.RecordItem", b =>
{
b.HasOne("Blahblah.FlowerStory.Server.Data.Model.FlowerItem", "Flower")
.WithMany()
.HasForeignKey("FlowerId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("Blahblah.FlowerStory.Server.Data.Model.UserItem", "Owner")
.WithMany()
.HasForeignKey("OwnerId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Flower");
b.Navigation("Owner");
});
modelBuilder.Entity("Blahblah.FlowerStory.Server.Data.Model.FlowerItem", b =>
{
b.Navigation("Photos");
});
modelBuilder.Entity("Blahblah.FlowerStory.Server.Data.Model.RecordItem", b =>
{
b.Navigation("Photos");
});
#pragma warning restore 612, 618
}
}
}

View File

@ -0,0 +1,38 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace Blahblah.FlowerStory.Server.Migrations
{
/// <inheritdoc />
public partial class AddPhotoSize : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<int>(
name: "height",
table: "photos",
type: "INTEGER",
nullable: true);
migrationBuilder.AddColumn<int>(
name: "width",
table: "photos",
type: "INTEGER",
nullable: true);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "height",
table: "photos");
migrationBuilder.DropColumn(
name: "width",
table: "photos");
}
}
}

View File

@ -15,7 +15,7 @@ namespace Blahblah.FlowerStory.Server.Migrations
protected override void BuildModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder.HasAnnotation("ProductVersion", "7.0.5");
modelBuilder.HasAnnotation("ProductVersion", "7.0.9");
modelBuilder.Entity("Blahblah.FlowerStory.Server.Data.Model.FlowerItem", b =>
{
@ -95,6 +95,10 @@ namespace Blahblah.FlowerStory.Server.Migrations
.HasColumnType("INTEGER")
.HasColumnName("fid");
b.Property<int?>("Height")
.HasColumnType("INTEGER")
.HasColumnName("height");
b.Property<int>("OwnerId")
.HasColumnType("INTEGER")
.HasColumnName("uid");
@ -108,6 +112,10 @@ namespace Blahblah.FlowerStory.Server.Migrations
.HasColumnType("INTEGER")
.HasColumnName("rid");
b.Property<int?>("Width")
.HasColumnType("INTEGER")
.HasColumnName("width");
b.HasKey("Id");
b.HasIndex("FlowerId");

View File

@ -11,7 +11,7 @@ public class Program
/// <inheritdoc/>
public const string ProjectName = "Flower Story";
/// <inheritdoc/>
public const string Version = "0.6.713";
public const string Version = "0.7.727";
/// <inheritdoc/>
public static void Main(string[] args)

View File

@ -11,12 +11,13 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="7.0.5" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="7.0.5" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="7.0.5">
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="7.0.9" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="7.0.9" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="7.0.9">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="SkiaSharp" Version="2.88.3" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.5.0" />
</ItemGroup>