add some APIs
This commit is contained in:
parent
32464cb494
commit
8b759c94ec
108
.gitignore
vendored
108
.gitignore
vendored
@ -1,8 +1,7 @@
|
||||
# ---> VisualStudio
|
||||
## Ignore Visual Studio temporary files, build results, and
|
||||
## files generated by popular Visual Studio add-ons.
|
||||
##
|
||||
## Get latest from https://github.com/github/gitignore/blob/main/VisualStudio.gitignore
|
||||
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
|
||||
|
||||
flower.db*
|
||||
TestCase/
|
||||
@ -66,6 +65,9 @@ project.lock.json
|
||||
project.fragment.lock.json
|
||||
artifacts/
|
||||
|
||||
# Tye
|
||||
.tye/
|
||||
|
||||
# ASP.NET Scaffolding
|
||||
ScaffoldingReadMe.txt
|
||||
|
||||
@ -94,7 +96,6 @@ StyleCopReport.xml
|
||||
*.tmp_proj
|
||||
*_wpftmp.csproj
|
||||
*.log
|
||||
*.tlog
|
||||
*.vspscc
|
||||
*.vssscc
|
||||
.builds
|
||||
@ -298,17 +299,6 @@ node_modules/
|
||||
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
|
||||
*.vbw
|
||||
|
||||
# Visual Studio 6 auto-generated project file (contains which files were open etc.)
|
||||
*.vbp
|
||||
|
||||
# Visual Studio 6 workspace and project file (working project files containing files to include in project)
|
||||
*.dsw
|
||||
*.dsp
|
||||
|
||||
# Visual Studio 6 technical files
|
||||
*.ncb
|
||||
*.aps
|
||||
|
||||
# Visual Studio LightSwitch build output
|
||||
**/*.HTMLClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/GeneratedArtifacts
|
||||
@ -365,9 +355,6 @@ ASALocalRun/
|
||||
# Local History for Visual Studio
|
||||
.localhistory/
|
||||
|
||||
# Visual Studio History (VSHistory) files
|
||||
.vshistory/
|
||||
|
||||
# BeatPulse healthcheck temp database
|
||||
healthchecksdb
|
||||
|
||||
@ -380,24 +367,91 @@ MigrationBackup/
|
||||
# Fody - auto-generated XML schema
|
||||
FodyWeavers.xsd
|
||||
|
||||
# VS Code files for those working on multiple tools
|
||||
.vscode/*
|
||||
!.vscode/settings.json
|
||||
!.vscode/tasks.json
|
||||
!.vscode/launch.json
|
||||
!.vscode/extensions.json
|
||||
*.code-workspace
|
||||
##
|
||||
## Visual studio for Mac
|
||||
##
|
||||
|
||||
# Local History for Visual Studio Code
|
||||
.history/
|
||||
|
||||
# Windows Installer files from build outputs
|
||||
# globs
|
||||
Makefile.in
|
||||
*.userprefs
|
||||
*.usertasks
|
||||
config.make
|
||||
config.status
|
||||
aclocal.m4
|
||||
install-sh
|
||||
autom4te.cache/
|
||||
*.tar.gz
|
||||
tarballs/
|
||||
test-results/
|
||||
|
||||
# Mac bundle stuff
|
||||
*.dmg
|
||||
*.app
|
||||
|
||||
# content below from: https://github.com/github/gitignore/blob/master/Global/macOS.gitignore
|
||||
# General
|
||||
.DS_Store
|
||||
.AppleDouble
|
||||
.LSOverride
|
||||
|
||||
# Icon must end with two \r
|
||||
Icon
|
||||
|
||||
|
||||
# Thumbnails
|
||||
._*
|
||||
|
||||
# Files that might appear in the root of a volume
|
||||
.DocumentRevisions-V100
|
||||
.fseventsd
|
||||
.Spotlight-V100
|
||||
.TemporaryItems
|
||||
.Trashes
|
||||
.VolumeIcon.icns
|
||||
.com.apple.timemachine.donotpresent
|
||||
|
||||
# Directories potentially created on remote AFP share
|
||||
.AppleDB
|
||||
.AppleDesktop
|
||||
Network Trash Folder
|
||||
Temporary Items
|
||||
.apdisk
|
||||
|
||||
# content below from: https://github.com/github/gitignore/blob/master/Global/Windows.gitignore
|
||||
# Windows thumbnail cache files
|
||||
Thumbs.db
|
||||
ehthumbs.db
|
||||
ehthumbs_vista.db
|
||||
|
||||
# Dump file
|
||||
*.stackdump
|
||||
|
||||
# Folder config file
|
||||
[Dd]esktop.ini
|
||||
|
||||
# Recycle Bin used on file shares
|
||||
$RECYCLE.BIN/
|
||||
|
||||
# Windows Installer files
|
||||
*.cab
|
||||
*.msi
|
||||
*.msix
|
||||
*.msm
|
||||
*.msp
|
||||
|
||||
# Windows shortcuts
|
||||
*.lnk
|
||||
|
||||
# JetBrains Rider
|
||||
.idea/
|
||||
*.sln.iml
|
||||
|
||||
##
|
||||
## Visual Studio Code
|
||||
##
|
||||
.vscode/*
|
||||
!.vscode/settings.json
|
||||
!.vscode/tasks.json
|
||||
!.vscode/launch.json
|
||||
!.vscode/extensions.json
|
||||
|
135
Server/Constants.cs
Normal file
135
Server/Constants.cs
Normal file
@ -0,0 +1,135 @@
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Blahblah.FlowerStory.Server;
|
||||
|
||||
/// <summary>
|
||||
/// 常数类
|
||||
/// </summary>
|
||||
public sealed class Constants
|
||||
{
|
||||
/// <summary>
|
||||
/// 其他分类
|
||||
/// </summary>
|
||||
public const string CategoryOther = "other";
|
||||
/// <summary>
|
||||
/// 未知事件
|
||||
/// </summary>
|
||||
public const string EventUnknown = "unknown";
|
||||
|
||||
/// <summary>
|
||||
/// 类别字典
|
||||
/// </summary>
|
||||
public static readonly Dictionary<int, NamedItem> Categories = new()
|
||||
{
|
||||
[0] = new(CategoryOther, "其他"),
|
||||
[1] = new("cactus", "仙人球"),
|
||||
[2] = new("hibiscus", "扶桑花"),
|
||||
[3] = new("bougainvillea", "三角梅"),
|
||||
[4] = new("sunflower", "太阳花"),
|
||||
[5] = new("milanflower", "米兰花"),
|
||||
[6] = new("jasmine", "茉莉花"),
|
||||
[7] = new("periwinkle", "长春花"),
|
||||
[8] = new("nasturtium", "旱金莲"),
|
||||
[9] = new("mirabilis", "紫薇花"),
|
||||
[10] = new("tigerthornplum", "虎刺梅"),
|
||||
[11] = new("geranium", "天竺葵"),
|
||||
[12] = new("ballorchid", "球兰"),
|
||||
[13] = new("medalchrysanthemum", "勋章菊"),
|
||||
[14] = new("dianthus", "石竹"),
|
||||
[15] = new("fivecolorplum", "五色梅"),
|
||||
[16] = new("fuchsia", "倒挂金钟"),
|
||||
[17] = new("bamboocrabapple", "竹节海棠"),
|
||||
[18] = new("impatiens", "凤仙花"),
|
||||
[19] = new("beautysakura", "美女樱"),
|
||||
[20] = new("petunias", "矮牵牛"),
|
||||
[21] = new("desertrose", "沙漠玫瑰"),
|
||||
[22] = new("trailingcampanula", "蔓性风铃花"),
|
||||
[23] = new("chineserose", "月季花"),
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// 事件字典
|
||||
/// </summary>
|
||||
public static readonly Dictionary<int, Event> Events = new()
|
||||
{
|
||||
[(int)EventTypes.Unknown] = new(EventUnknown, "未知"),
|
||||
[(int)EventTypes.Buy] = new("buy", "购买", true),
|
||||
[(int)EventTypes.Born] = new("born", "出生", true),
|
||||
[3] = new("changebasin", "换盆"),
|
||||
[4] = new("watering", "浇水"),
|
||||
[5] = new("fertilize", "施肥"),
|
||||
[6] = new("germination", "发芽"),
|
||||
[7] = new("blossom", "开花"),
|
||||
[8] = new("fallenleaves", "落叶"),
|
||||
[9] = new("prune", "修剪"),
|
||||
[10] = new("sick", "生病"),
|
||||
[(int)EventTypes.Death] = new("death", "死亡", true),
|
||||
[(int)EventTypes.Sell] = new("sell", "出售", true),
|
||||
[(int)EventTypes.Share] = new("share", "分享"),
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 事件类型枚举
|
||||
/// </summary>
|
||||
public enum EventTypes
|
||||
{
|
||||
/// <summary>
|
||||
/// 未知
|
||||
/// </summary>
|
||||
Unknown = 0,
|
||||
/// <summary>
|
||||
/// 购买
|
||||
/// </summary>
|
||||
Buy = 1,
|
||||
/// <summary>
|
||||
/// 出生
|
||||
/// </summary>
|
||||
Born = 2,
|
||||
/// <summary>
|
||||
/// 死亡
|
||||
/// </summary>
|
||||
Death = 11,
|
||||
/// <summary>
|
||||
/// 出售
|
||||
/// </summary>
|
||||
Sell = 12,
|
||||
/// <summary>
|
||||
/// 分享
|
||||
/// </summary>
|
||||
Share = 13,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 事件类
|
||||
/// </summary>
|
||||
/// <param name="Key">名称</param>
|
||||
/// <param name="Description">描述</param>
|
||||
/// <param name="Unique">是否唯一</param>
|
||||
public record Event(string Key, string? Description = null, bool Unique = false) : NamedItem(Key, Description)
|
||||
{
|
||||
/// <summary>
|
||||
/// 是否唯一
|
||||
/// </summary>
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)]
|
||||
public bool Unique { get; init; } = Unique;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 命名对象类
|
||||
/// </summary>
|
||||
/// <param name="Key">名称</param>
|
||||
/// <param name="Description">描述</param>
|
||||
public record NamedItem(string Key, string? Description = null)
|
||||
{
|
||||
/// <summary>
|
||||
/// 名称
|
||||
/// </summary>
|
||||
public string Key { get; init; } = Key;
|
||||
|
||||
/// <summary>
|
||||
/// 描述
|
||||
/// </summary>
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)]
|
||||
public string? Description { get; init; } = Description;
|
||||
}
|
59
Server/Controller/ApiController.cs
Normal file
59
Server/Controller/ApiController.cs
Normal file
@ -0,0 +1,59 @@
|
||||
using Blahblah.FlowerStory.Server.Data;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace Blahblah.FlowerStory.Server.Controller;
|
||||
|
||||
/// <summary>
|
||||
/// 基础 API 服务
|
||||
/// </summary>
|
||||
[ApiController]
|
||||
[Produces("application/json")]
|
||||
[Route("api")]
|
||||
public partial class ApiController : BaseController
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public ApiController(FlowerDatabase database, ILogger<BaseController>? logger = null) : base(database, logger)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取版本号
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 请求示例:
|
||||
///
|
||||
/// GET /api/version
|
||||
///
|
||||
/// </remarks>
|
||||
/// <returns>版本号</returns>
|
||||
/// <response code="200">返回版本号</response>
|
||||
[Route("version", Name = "getVersion")]
|
||||
[HttpGet]
|
||||
[ResponseCache(NoStore = true, Location = ResponseCacheLocation.None)]
|
||||
public ActionResult<string> GetApiVersion()
|
||||
{
|
||||
return Ok(Program.Version);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取常量字典定义
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 请求示例:
|
||||
///
|
||||
/// GET /api/consts?{ver}
|
||||
///
|
||||
/// </remarks>
|
||||
/// <returns>字典集</returns>
|
||||
/// <response code="200">返回常量字典集</response>
|
||||
[Route("consts", Name = "getConsts")]
|
||||
[HttpGet]
|
||||
public ActionResult<DefinitionResult> GetDefinitions()
|
||||
{
|
||||
return Ok(new DefinitionResult
|
||||
{
|
||||
Categories = Constants.Categories,
|
||||
Events = Constants.Events,
|
||||
});
|
||||
}
|
||||
}
|
17
Server/Controller/ApiController.structs.cs
Normal file
17
Server/Controller/ApiController.structs.cs
Normal file
@ -0,0 +1,17 @@
|
||||
namespace Blahblah.FlowerStory.Server.Controller;
|
||||
|
||||
/// <summary>
|
||||
/// 字典、定义
|
||||
/// </summary>
|
||||
public record DefinitionResult
|
||||
{
|
||||
/// <summary>
|
||||
/// 花草分类
|
||||
/// </summary>
|
||||
public required Dictionary<int, NamedItem> Categories { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// 事件
|
||||
/// </summary>
|
||||
public required Dictionary<int, Event> Events { get; init; }
|
||||
}
|
@ -15,6 +15,17 @@ public abstract partial class BaseController : ControllerBase
|
||||
{
|
||||
private const string Salt = "Blah blah, o! Flower story, intimately help you record every bit of the garden.";
|
||||
|
||||
/// <summary>
|
||||
/// 临时 id
|
||||
/// </summary>
|
||||
protected const int TempId = -1;
|
||||
|
||||
private static string? uploadsDirectory;
|
||||
/// <summary>
|
||||
/// 文件上传路径
|
||||
/// </summary>
|
||||
protected static string UploadsDirectory => uploadsDirectory ??= Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "uploads");
|
||||
|
||||
/// <summary>
|
||||
/// 支持的图片文件签名
|
||||
/// </summary>
|
||||
@ -195,43 +206,52 @@ public abstract partial class BaseController : ControllerBase
|
||||
/// <returns>文件结果对象</returns>
|
||||
protected static FileResult? WrapFormFile(IFormFile file)
|
||||
{
|
||||
if (file == null)
|
||||
if (file?.Length > 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
using var stream = file.OpenReadStream();
|
||||
using var stream = file.OpenReadStream();
|
||||
|
||||
// check header
|
||||
var headers = new byte[PhotoSignatures.Max(s => s.Length)];
|
||||
int count = stream.Read(headers, 0, headers.Length);
|
||||
if (PhotoSignatures.Any(s => headers.Take(s.Length).SequenceEqual(s)))
|
||||
{
|
||||
using var ms = new MemoryStream();
|
||||
ms.Write(headers, 0, count);
|
||||
|
||||
// reading
|
||||
const int size = 16384;
|
||||
var buffer = new byte[size];
|
||||
while ((count = stream.Read(buffer, 0, size)) > 0)
|
||||
// check header
|
||||
var headers = new byte[PhotoSignatures.Max(s => s.Length)];
|
||||
int count = stream.Read(headers, 0, headers.Length);
|
||||
if (PhotoSignatures.Any(s => headers.Take(s.Length).SequenceEqual(s)))
|
||||
{
|
||||
ms.Write(buffer, 0, count);
|
||||
using var ms = new MemoryStream();
|
||||
ms.Write(headers, 0, count);
|
||||
|
||||
// reading
|
||||
const int size = 16384;
|
||||
var buffer = new byte[size];
|
||||
while ((count = stream.Read(buffer, 0, size)) > 0)
|
||||
{
|
||||
ms.Write(buffer, 0, count);
|
||||
}
|
||||
var data = ms.ToArray();
|
||||
var name = file.FileName;
|
||||
var ext = Path.GetExtension(name);
|
||||
var path = $"{WebUtility.UrlEncode(Path.GetFileNameWithoutExtension(name))}_{DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()}{ext}";
|
||||
|
||||
return new FileResult
|
||||
{
|
||||
Filename = name,
|
||||
FileType = ext,
|
||||
Path = path,
|
||||
Content = data
|
||||
};
|
||||
}
|
||||
var data = ms.ToArray();
|
||||
var name = file.FileName;
|
||||
var ext = Path.GetExtension(name);
|
||||
var path = $"{WebUtility.UrlEncode(Path.GetFileNameWithoutExtension(name))}_{DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()}{ext}";
|
||||
|
||||
return new FileResult
|
||||
{
|
||||
Filename = name,
|
||||
FileType = ext,
|
||||
Path = path,
|
||||
Content = data
|
||||
};
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static string GetFlowerDirectory(int fid, bool create = false)
|
||||
{
|
||||
var directory = Path.Combine(UploadsDirectory, fid.ToString());
|
||||
if (create && !Directory.Exists(directory))
|
||||
{
|
||||
Directory.CreateDirectory(directory);
|
||||
}
|
||||
return directory;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 写入文件到用户的花草目录中
|
||||
/// </summary>
|
||||
@ -240,11 +260,7 @@ public abstract partial class BaseController : ControllerBase
|
||||
/// <param name="token">取消令牌</param>
|
||||
protected static async Task WriteToFile(int fid, FileResult file, CancellationToken token = default)
|
||||
{
|
||||
var directory = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "uploads", fid.ToString());
|
||||
if (!Directory.Exists(directory))
|
||||
{
|
||||
Directory.CreateDirectory(directory);
|
||||
}
|
||||
var directory = GetFlowerDirectory(fid, true);
|
||||
var path = Path.Combine(directory, file.Path);
|
||||
await System.IO.File.WriteAllBytesAsync(path, file.Content, token);
|
||||
}
|
||||
@ -257,7 +273,7 @@ public abstract partial class BaseController : ControllerBase
|
||||
/// <returns>返回是否已删除</returns>
|
||||
protected static bool DeleteFile(int fid, string path)
|
||||
{
|
||||
var directory = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "uploads", fid.ToString());
|
||||
var directory = GetFlowerDirectory(fid);
|
||||
if (Directory.Exists(directory))
|
||||
{
|
||||
path = Path.Combine(directory, path);
|
||||
@ -270,6 +286,30 @@ public abstract partial class BaseController : ControllerBase
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 移动临时照片到花草目录
|
||||
/// </summary>
|
||||
/// <param name="fid">花草唯一 id</param>
|
||||
/// <param name="path">文件路径</param>
|
||||
protected static void MoveTempFileToFlower(int fid, string path)
|
||||
{
|
||||
var directory = GetFlowerDirectory(TempId);
|
||||
if (Directory.Exists(directory))
|
||||
{
|
||||
var file = Path.Combine(directory, path);
|
||||
if (System.IO.File.Exists(file))
|
||||
{
|
||||
directory = GetFlowerDirectory(fid, true);
|
||||
var to = Path.Combine(directory, path);
|
||||
if (System.IO.File.Exists(to))
|
||||
{
|
||||
System.IO.File.Move(to, $"{to}.bak");
|
||||
}
|
||||
System.IO.File.Move(file, to);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private const double EarthRadius = 6378137;
|
||||
|
||||
private static double Radius(double degree)
|
||||
|
@ -52,6 +52,7 @@ public class EventApiController : BaseController
|
||||
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
|
||||
[ProducesResponseType(StatusCodes.Status403Forbidden)]
|
||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||
[ProducesErrorResponseType(typeof(ErrorResponse))]
|
||||
[HttpGet]
|
||||
[ResponseCache(NoStore = true, Location = ResponseCacheLocation.None)]
|
||||
public ActionResult<RecordItem[]> GetRecords(
|
||||
@ -126,6 +127,7 @@ public class EventApiController : BaseController
|
||||
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
|
||||
[ProducesResponseType(StatusCodes.Status403Forbidden)]
|
||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||
[ProducesErrorResponseType(typeof(ErrorResponse))]
|
||||
[HttpDelete]
|
||||
public ActionResult<int> RemoveEvent([FromQuery][Required] int id)
|
||||
{
|
||||
@ -170,6 +172,7 @@ public class EventApiController : BaseController
|
||||
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
|
||||
[ProducesResponseType(StatusCodes.Status403Forbidden)]
|
||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||
[ProducesErrorResponseType(typeof(ErrorResponse))]
|
||||
[HttpPost]
|
||||
[Consumes("application/json")]
|
||||
public ActionResult<int> RemoveEvents([FromBody] int[] ids)
|
||||
@ -199,12 +202,16 @@ public class EventApiController : BaseController
|
||||
///
|
||||
/// POST /api/event/add
|
||||
/// Authorization: authorization id
|
||||
/// {
|
||||
/// "flowerId": 1,
|
||||
/// "eventId": 4, // 浇水
|
||||
/// "byUser": "朋友",
|
||||
/// "memo": "快干死了"
|
||||
/// }
|
||||
///
|
||||
/// 参数:
|
||||
///
|
||||
/// flowerId: 1
|
||||
/// eventId": 4 // 浇水
|
||||
/// byUser: "朋友"
|
||||
/// memo: "快干死了"
|
||||
/// lon: 29.5462794
|
||||
/// lat: 106.5380034
|
||||
/// photos: <photo>[]
|
||||
///
|
||||
/// </remarks>
|
||||
/// <param name="event">事件参数</param>
|
||||
@ -218,9 +225,12 @@ public class EventApiController : BaseController
|
||||
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
|
||||
[ProducesResponseType(StatusCodes.Status403Forbidden)]
|
||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||
[ProducesErrorResponseType(typeof(ErrorResponse))]
|
||||
[HttpPost]
|
||||
[Consumes("application/json")]
|
||||
public ActionResult<RecordItem> AddEvent([FromBody] EventParameter @event)
|
||||
[Consumes("multipart/form-data")]
|
||||
// 5 photos
|
||||
[RequestSizeLimit(75 * 1024 * 1024)]
|
||||
public async Task<ActionResult<RecordItem>> AddEvent([FromForm] EventParameter @event)
|
||||
{
|
||||
var (result, user) = CheckPermission();
|
||||
if (result != null)
|
||||
@ -232,19 +242,58 @@ public class EventApiController : BaseController
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
var now = user.ActiveDateUnixTime ?? DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
|
||||
var item = new RecordItem
|
||||
{
|
||||
OwnerId = user.Id,
|
||||
FlowerId = @event.FlowerId,
|
||||
EventId = @event.EventId,
|
||||
DateUnixTime = user.ActiveDateUnixTime ?? DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(),
|
||||
EventId = @event.CategoryId,
|
||||
DateUnixTime = now,
|
||||
ByUserId = @event.ByUser == null ? user.Id : null,
|
||||
ByUserName = @event.ByUser,
|
||||
Memo = @event.Memo
|
||||
Memo = @event.Memo,
|
||||
Latitude = @event.Latitude,
|
||||
Longitude = @event.Longitude
|
||||
};
|
||||
database.Records.Add(item);
|
||||
SaveDatabase();
|
||||
|
||||
if (@event.Photos?.Length > 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
await ExecuteTransaction(async token =>
|
||||
{
|
||||
foreach (var photo in @event.Photos)
|
||||
{
|
||||
var file = WrapFormFile(photo);
|
||||
if (file == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
var p = new PhotoItem
|
||||
{
|
||||
OwnerId = user.Id,
|
||||
FlowerId = @event.FlowerId,
|
||||
RecordId = item.Id,
|
||||
FileType = file.FileType,
|
||||
FileName = file.Filename,
|
||||
Path = file.Path,
|
||||
DateUploadUnixTime = now
|
||||
};
|
||||
AddPhotoItem(p);
|
||||
|
||||
await WriteToFile(@event.FlowerId, file, token);
|
||||
}
|
||||
});
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return Problem(ex.ToString(), "api/event/add");
|
||||
// TODO: Logger
|
||||
}
|
||||
}
|
||||
|
||||
return Ok(item);
|
||||
}
|
||||
|
||||
@ -256,13 +305,17 @@ public class EventApiController : BaseController
|
||||
///
|
||||
/// PUT /api/event/update
|
||||
/// Authorization: authorization id
|
||||
/// {
|
||||
/// "id": 1,
|
||||
/// "flowerId": 1,
|
||||
/// "eventId": 5, // 施肥
|
||||
/// "byUser": null,
|
||||
/// "memo": "花多多1号"
|
||||
/// }
|
||||
///
|
||||
/// 参数:
|
||||
///
|
||||
/// id: 1
|
||||
/// flowerId: 1
|
||||
/// eventId": 5 // 施肥
|
||||
/// byUser: null
|
||||
/// memo: "花多多1号"
|
||||
/// lon: 29.5462794
|
||||
/// lat: 106.5380034
|
||||
/// photos: <photo>[]
|
||||
///
|
||||
/// </remarks>
|
||||
/// <param name="update">修改参数</param>
|
||||
@ -276,9 +329,12 @@ public class EventApiController : BaseController
|
||||
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
|
||||
[ProducesResponseType(StatusCodes.Status403Forbidden)]
|
||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||
[ProducesErrorResponseType(typeof(ErrorResponse))]
|
||||
[HttpPut]
|
||||
[Consumes("application/json")]
|
||||
public ActionResult<RecordItem> Update([FromBody] EventUpdateParameter update)
|
||||
[Consumes("multipart/form-data")]
|
||||
// 5 photos
|
||||
[RequestSizeLimit(75 * 1024 * 1024)]
|
||||
public async Task<ActionResult<RecordItem>> Update([FromForm] EventUpdateParameter update)
|
||||
{
|
||||
var (result, user) = CheckPermission();
|
||||
if (result != null)
|
||||
@ -295,8 +351,10 @@ public class EventApiController : BaseController
|
||||
{
|
||||
return NotFound($"Event id {update.Id} not found");
|
||||
}
|
||||
var now = user.ActiveDateUnixTime ?? DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
|
||||
record.FlowerId = update.FlowerId;
|
||||
record.EventId = update.EventId;
|
||||
record.EventId = update.CategoryId;
|
||||
record.DateUnixTime = now;
|
||||
if (update.ByUser == null)
|
||||
{
|
||||
record.ByUserId = user.Id;
|
||||
@ -308,7 +366,60 @@ public class EventApiController : BaseController
|
||||
record.ByUserName = update.ByUser;
|
||||
}
|
||||
record.Memo = update.Memo;
|
||||
SaveDatabase();
|
||||
record.Latitude = update.Latitude;
|
||||
record.Longitude = update.Longitude;
|
||||
|
||||
if (update.Photos?.Length > 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
await ExecuteTransaction(async token =>
|
||||
{
|
||||
foreach (var photo in update.Photos)
|
||||
{
|
||||
var file = WrapFormFile(photo);
|
||||
if (file == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var photos = database.Photos.Where(p => p.RecordId == record.Id).ToList();
|
||||
if (photos.Count > 0)
|
||||
{
|
||||
database.Photos.Where(p => p.RecordId == record.Id).ExecuteDelete();
|
||||
foreach (var p in photos)
|
||||
{
|
||||
DeleteFile(update.FlowerId, p.Path);
|
||||
}
|
||||
}
|
||||
SaveDatabase();
|
||||
|
||||
var cover = new PhotoItem
|
||||
{
|
||||
OwnerId = user.Id,
|
||||
FlowerId = update.FlowerId,
|
||||
RecordId = record.Id,
|
||||
FileType = file.FileType,
|
||||
FileName = file.Filename,
|
||||
Path = file.Path,
|
||||
DateUploadUnixTime = now
|
||||
};
|
||||
AddPhotoItem(cover);
|
||||
|
||||
await WriteToFile(update.FlowerId, file, token);
|
||||
}
|
||||
});
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return Problem(ex.ToString(), "api/event/update");
|
||||
// TODO: Logger
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SaveDatabase();
|
||||
}
|
||||
|
||||
return Ok(user);
|
||||
}
|
||||
@ -344,6 +455,7 @@ public class EventApiController : BaseController
|
||||
[ProducesResponseType(StatusCodes.Status403Forbidden)]
|
||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||
[ProducesResponseType(StatusCodes.Status413PayloadTooLarge)]
|
||||
[ProducesErrorResponseType(typeof(ErrorResponse))]
|
||||
[HttpPost]
|
||||
[Consumes("multipart/form-data")]
|
||||
[RequestSizeLimit(15 * 1024 * 1024)]
|
||||
@ -380,6 +492,7 @@ public class EventApiController : BaseController
|
||||
{
|
||||
var p = new PhotoItem
|
||||
{
|
||||
OwnerId = user.Id,
|
||||
FlowerId = record.FlowerId,
|
||||
RecordId = id,
|
||||
FileType = file.FileType,
|
||||
@ -433,6 +546,7 @@ public class EventApiController : BaseController
|
||||
[ProducesResponseType(StatusCodes.Status403Forbidden)]
|
||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||
[ProducesResponseType(StatusCodes.Status413PayloadTooLarge)]
|
||||
[ProducesErrorResponseType(typeof(ErrorResponse))]
|
||||
[HttpPost]
|
||||
[Consumes("multipart/form-data")]
|
||||
// 5 photos
|
||||
@ -474,6 +588,7 @@ public class EventApiController : BaseController
|
||||
|
||||
var p = new PhotoItem
|
||||
{
|
||||
OwnerId = user.Id,
|
||||
FlowerId = record.FlowerId,
|
||||
RecordId = id,
|
||||
FileType = file.FileType,
|
||||
@ -526,6 +641,7 @@ public class EventApiController : BaseController
|
||||
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
|
||||
[ProducesResponseType(StatusCodes.Status403Forbidden)]
|
||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||
[ProducesErrorResponseType(typeof(ErrorResponse))]
|
||||
[HttpDelete]
|
||||
public ActionResult<int> RemoveEventPhoto([FromQuery][Required] int id)
|
||||
{
|
||||
@ -539,12 +655,13 @@ public class EventApiController : BaseController
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
var photo = database.Photos.Where(p => p.Id == id).Include(p => p.Record).SingleOrDefault();
|
||||
var photo = database.Photos.Find(id);
|
||||
if (photo == null)
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
if (photo.Record != null && photo.Record.OwnerId != user.Id)
|
||||
var item = database.Flowers.Find(photo.FlowerId);
|
||||
if (item == null || item.OwnerId != user.Id)
|
||||
{
|
||||
return Unauthorized();
|
||||
}
|
||||
@ -553,10 +670,7 @@ public class EventApiController : BaseController
|
||||
|
||||
SaveDatabase();
|
||||
|
||||
if (photo.Record != null)
|
||||
{
|
||||
DeleteFile(photo.Record.FlowerId, photo.Path);
|
||||
}
|
||||
DeleteFile(photo.FlowerId ?? TempId, photo.Path);
|
||||
|
||||
return NoContent();
|
||||
}
|
||||
@ -585,6 +699,7 @@ public class EventApiController : BaseController
|
||||
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
|
||||
[ProducesResponseType(StatusCodes.Status403Forbidden)]
|
||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||
[ProducesErrorResponseType(typeof(ErrorResponse))]
|
||||
[HttpPost]
|
||||
[Consumes("application/json")]
|
||||
public ActionResult<int> RemoveEventPhotos([FromBody] int[] ids)
|
||||
@ -604,17 +719,14 @@ public class EventApiController : BaseController
|
||||
return Unauthorized();
|
||||
}
|
||||
|
||||
var photos = database.Photos.Where(p => ids.Contains(p.Id)).Include(p => p.Record).ToList();
|
||||
var photos = database.Photos.Where(p => ids.Contains(p.Id)).ToList();
|
||||
var count = database.Photos.Where(p => ids.Contains(p.Id)).ExecuteDelete();
|
||||
|
||||
SaveDatabase();
|
||||
|
||||
foreach (var photo in photos)
|
||||
{
|
||||
if (photo.Record != null)
|
||||
{
|
||||
DeleteFile(photo.Record.FlowerId, photo.Path);
|
||||
}
|
||||
DeleteFile(photo.FlowerId ?? TempId, photo.Path);
|
||||
}
|
||||
|
||||
return Ok(count);
|
||||
@ -645,6 +757,7 @@ public class EventApiController : BaseController
|
||||
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
|
||||
[ProducesResponseType(StatusCodes.Status403Forbidden)]
|
||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||
[ProducesErrorResponseType(typeof(ErrorResponse))]
|
||||
[HttpGet]
|
||||
[ResponseCache(NoStore = true, Location = ResponseCacheLocation.None)]
|
||||
public ActionResult<PhotoItem[]> GetPhotos([Required][FromQuery] int id)
|
||||
|
@ -1,4 +1,5 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace Blahblah.FlowerStory.Server.Controller;
|
||||
|
||||
@ -11,24 +12,46 @@ public record EventParameter
|
||||
/// 花草唯一 id
|
||||
/// </summary>
|
||||
[Required]
|
||||
public int FlowerId { get; init; }
|
||||
[FromForm(Name = "flowerId")]
|
||||
public required int FlowerId { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// 事件 id
|
||||
/// 事件分类 id
|
||||
/// </summary>
|
||||
[Required]
|
||||
public int EventId { get; init; }
|
||||
[FromForm(Name = "categoryId")]
|
||||
public required int CategoryId { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// 操作人姓名
|
||||
/// </summary>
|
||||
[Required]
|
||||
public string? ByUser { get; init; }
|
||||
[FromForm(Name = "byUser")]
|
||||
public required string ByUser { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// 事件备注
|
||||
/// 备注
|
||||
/// </summary>
|
||||
public string? Memo { get; init; }
|
||||
[FromForm(Name = "memo")]
|
||||
public string? Memo { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 纬度
|
||||
/// </summary>
|
||||
[FromForm(Name = "lat")]
|
||||
public double? Latitude { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 经度
|
||||
/// </summary>
|
||||
[FromForm(Name = "lon")]
|
||||
public double? Longitude { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 关联的照片
|
||||
/// </summary>
|
||||
[FromForm(Name = "photos")]
|
||||
public IFormFile[]? Photos { get; init; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -40,5 +63,6 @@ public record EventUpdateParameter : EventParameter
|
||||
/// 事件唯一 id
|
||||
/// </summary>
|
||||
[Required]
|
||||
public int Id { get; set; }
|
||||
[FromForm(Name = "id")]
|
||||
public required int Id { get; set; }
|
||||
}
|
||||
|
@ -2,9 +2,7 @@
|
||||
using Blahblah.FlowerStory.Server.Data.Model;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Blahblah.FlowerStory.Server.Controller;
|
||||
|
||||
@ -68,6 +66,7 @@ public class FlowerApiController : BaseController
|
||||
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
|
||||
[ProducesResponseType(StatusCodes.Status403Forbidden)]
|
||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||
[ProducesErrorResponseType(typeof(ErrorResponse))]
|
||||
[HttpGet]
|
||||
[ResponseCache(NoStore = true, Location = ResponseCacheLocation.None)]
|
||||
public ActionResult<FlowerResult> GetFlowers(
|
||||
@ -96,7 +95,88 @@ public class FlowerApiController : BaseController
|
||||
|
||||
SaveDatabase();
|
||||
|
||||
IEnumerable<FlowerItem> flowers = database.Flowers.Where(f => f.OwnerId == user.Id);
|
||||
var flowers = GetFlowerResult(user.Id, null, categoryId, key, buyFrom, buyTo, costFrom, costTo, includePhoto, latitude, longitude, distance, page, pageSize);
|
||||
return Ok(flowers);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取最新、最近的花草
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 请求示例:
|
||||
///
|
||||
/// GET /api/flower/latest
|
||||
///
|
||||
/// 参数:
|
||||
///
|
||||
/// cid: int?
|
||||
/// key: string?
|
||||
/// from: long?
|
||||
/// to: long?
|
||||
/// cfrom: decimal?
|
||||
/// cto: decimal?
|
||||
/// photo: bool?
|
||||
/// lon: double?
|
||||
/// lat: double?
|
||||
/// distance: int?
|
||||
/// p: int?
|
||||
/// size: int?
|
||||
///
|
||||
/// </remarks>
|
||||
/// <param name="categoryId">类别 id</param>
|
||||
/// <param name="key">查询关键字</param>
|
||||
/// <param name="buyFrom">起始购买日期</param>
|
||||
/// <param name="buyTo">结束购买日期</param>
|
||||
/// <param name="costFrom">开销最小值</param>
|
||||
/// <param name="costTo">开销最大值</param>
|
||||
/// <param name="includePhoto">是否包含封面图片</param>
|
||||
/// <param name="latitude">纬度</param>
|
||||
/// <param name="longitude">经度</param>
|
||||
/// <param name="distance">距离(米)</param>
|
||||
/// <param name="page">页数</param>
|
||||
/// <param name="pageSize">分页大小</param>
|
||||
/// <returns>会话有效则返回符合条件的花草集</returns>
|
||||
/// <response code="200">返回符合条件的花草集</response>
|
||||
/// <response code="401">未找到登录会话或已过期</response>
|
||||
/// <response code="403">用户已禁用</response>
|
||||
/// <response code="404">未找到关联用户</response>
|
||||
[Route("latest", Name = "queryLatestFlowers")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[HttpGet]
|
||||
[ResponseCache(NoStore = true, Location = ResponseCacheLocation.None)]
|
||||
public ActionResult<FlowerResult> GetLatestFlowers(
|
||||
[FromQuery(Name = "cid")] int? categoryId,
|
||||
[FromQuery] string? key,
|
||||
[FromQuery(Name = "from")] long? buyFrom,
|
||||
[FromQuery(Name = "to")] long? buyTo,
|
||||
[FromQuery(Name = "cfrom")] decimal? costFrom,
|
||||
[FromQuery(Name = "cto")] decimal? costTo,
|
||||
[FromQuery(Name = "photo")] bool? includePhoto,
|
||||
[FromQuery(Name = "lat")] double? latitude,
|
||||
[FromQuery(Name = "lon")] double? longitude,
|
||||
[FromQuery] int? distance,
|
||||
[FromQuery(Name = "p")] int? page = 0,
|
||||
[FromQuery(Name = "size")] int? pageSize = 20)
|
||||
{
|
||||
var result = GetFlowerResult(null, (int)EventTypes.Share, categoryId, key, buyFrom, buyTo, costFrom, costTo, includePhoto, latitude, longitude, distance, page, pageSize);
|
||||
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
private FlowerResult GetFlowerResult(int? userId, int? eventId, int? categoryId, string? key,
|
||||
long? buyFrom, long? buyTo, decimal? costFrom, decimal? costTo,
|
||||
bool? includePhoto, double? latitude, double? longitude, int? distance,
|
||||
int? page = 0, int? pageSize = 20)
|
||||
{
|
||||
IEnumerable<FlowerItem> flowers;
|
||||
if (userId != null)
|
||||
{
|
||||
flowers = database.Flowers.Where(f => f.OwnerId == userId);
|
||||
}
|
||||
else
|
||||
{
|
||||
flowers = database.Flowers;
|
||||
}
|
||||
if (categoryId != null)
|
||||
{
|
||||
flowers = flowers.Where(f => f.CategoryId == categoryId);
|
||||
@ -125,6 +205,11 @@ public class FlowerApiController : BaseController
|
||||
flowers = flowers.Where(f => f.Cost != null && f.Cost <= costTo);
|
||||
}
|
||||
|
||||
if (eventId != null)
|
||||
{
|
||||
flowers = flowers.Where(f => database.Records.Any(r => r.FlowerId == f.Id && r.EventId == eventId));
|
||||
}
|
||||
|
||||
if (distance != null && latitude != null && longitude != null)
|
||||
{
|
||||
flowers = flowers.Where(f => f.Latitude != null && f.Longitude != null)
|
||||
@ -157,11 +242,11 @@ public class FlowerApiController : BaseController
|
||||
}
|
||||
}
|
||||
|
||||
return Ok(new FlowerResult
|
||||
return new()
|
||||
{
|
||||
Flowers = flowers.ToArray(),
|
||||
Count = count
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -191,6 +276,7 @@ public class FlowerApiController : BaseController
|
||||
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
|
||||
[ProducesResponseType(StatusCodes.Status403Forbidden)]
|
||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||
[ProducesErrorResponseType(typeof(ErrorResponse))]
|
||||
[HttpGet]
|
||||
[ResponseCache(NoStore = true, Location = ResponseCacheLocation.None)]
|
||||
public ActionResult<FlowerItem> GetFlower(
|
||||
@ -254,6 +340,7 @@ public class FlowerApiController : BaseController
|
||||
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
|
||||
[ProducesResponseType(StatusCodes.Status403Forbidden)]
|
||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||
[ProducesErrorResponseType(typeof(ErrorResponse))]
|
||||
[HttpDelete]
|
||||
public ActionResult<int> RemoveFlower([FromQuery][Required] int id)
|
||||
{
|
||||
@ -299,9 +386,10 @@ public class FlowerApiController : BaseController
|
||||
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
|
||||
[ProducesResponseType(StatusCodes.Status403Forbidden)]
|
||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||
[ProducesErrorResponseType(typeof(ErrorResponse))]
|
||||
[HttpPost]
|
||||
[Consumes("application/json")]
|
||||
public ActionResult<int> RemoveFlower([FromBody] int[] ids)
|
||||
public ActionResult<int> RemoveFlowers([FromBody] int[] ids)
|
||||
{
|
||||
var (result, user) = CheckPermission();
|
||||
if (result != null)
|
||||
@ -337,22 +425,29 @@ public class FlowerApiController : BaseController
|
||||
/// dateBuy: 1684919954743
|
||||
/// cost: 5.00
|
||||
/// purchase: "花鸟市场"
|
||||
/// memo: "备注信息"
|
||||
/// lon: 29.5462794
|
||||
/// lat: 106.5380034
|
||||
/// cid: 1
|
||||
/// cover: <photo>
|
||||
///
|
||||
/// </remarks>
|
||||
/// <param name="flower">花草参数</param>
|
||||
/// <returns>添加成功则返回已添加的花草对象</returns>
|
||||
/// <response code="200">返回已添加的花草对象</response>
|
||||
/// <response code="400">提交的内容不合法</response>
|
||||
/// <response code="401">未找到登录会话或已过期</response>
|
||||
/// <response code="403">用户已禁用</response>
|
||||
/// <response code="404">未找到关联用户</response>
|
||||
/// <response code="413">提交正文过大</response>
|
||||
[Route("add", Name = "addFlower")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
||||
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
|
||||
[ProducesResponseType(StatusCodes.Status403Forbidden)]
|
||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||
[ProducesResponseType(StatusCodes.Status413PayloadTooLarge)]
|
||||
[ProducesErrorResponseType(typeof(ErrorResponse))]
|
||||
[HttpPost]
|
||||
[Consumes("multipart/form-data")]
|
||||
[RequestSizeLimit(5 * 1024 * 1024)]
|
||||
@ -375,11 +470,15 @@ public class FlowerApiController : BaseController
|
||||
Name = flower.Name,
|
||||
DateBuyUnixTime = flower.DateBuy,
|
||||
Cost = flower.Cost,
|
||||
Purchase = flower.Purchase
|
||||
Purchase = flower.Purchase,
|
||||
Memo = flower.Memo,
|
||||
Latitude = flower.Latitude,
|
||||
Longitude = flower.Longitude
|
||||
};
|
||||
database.Flowers.Add(item);
|
||||
SaveDatabase();
|
||||
|
||||
var now = user.ActiveDateUnixTime ?? DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
|
||||
if (flower.Cover?.Length > 0)
|
||||
{
|
||||
var file = WrapFormFile(flower.Cover);
|
||||
@ -388,7 +487,6 @@ public class FlowerApiController : BaseController
|
||||
return BadRequest();
|
||||
}
|
||||
|
||||
var now = user.ActiveDateUnixTime ?? DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
|
||||
var record = database.Records.SingleOrDefault(r => r.FlowerId == item.Id && r.EventId == EventCover);
|
||||
if (record == null)
|
||||
{
|
||||
@ -399,8 +497,10 @@ public class FlowerApiController : BaseController
|
||||
EventId = EventCover,
|
||||
DateUnixTime = now,
|
||||
ByUserId = user.Id,
|
||||
ByUserName = user.Name
|
||||
//Memo = ""
|
||||
ByUserName = user.Name,
|
||||
//Memo = flower.Memo,
|
||||
Latitude = flower.Latitude,
|
||||
Longitude = flower.Longitude
|
||||
};
|
||||
database.Records.Add(record);
|
||||
}
|
||||
@ -412,6 +512,7 @@ public class FlowerApiController : BaseController
|
||||
{
|
||||
var cover = new PhotoItem
|
||||
{
|
||||
OwnerId = user.Id,
|
||||
FlowerId = item.Id,
|
||||
RecordId = record.Id,
|
||||
FileType = file.FileType,
|
||||
@ -426,14 +527,135 @@ public class FlowerApiController : BaseController
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return Problem(ex.ToString(), "api/flower/add");
|
||||
return Problem(ex.ToString(), "api/flower/add#WriteToFile");
|
||||
// TODO: Logger
|
||||
}
|
||||
}
|
||||
else if (flower.CoverId is int coverId)
|
||||
{
|
||||
var photo = database.Photos.SingleOrDefault(p => p.Id == coverId && p.OwnerId == user.Id);
|
||||
if (photo != null)
|
||||
{
|
||||
var record = database.Records.SingleOrDefault(r => r.FlowerId == item.Id && r.EventId == EventCover);
|
||||
if (record == null)
|
||||
{
|
||||
record = new RecordItem
|
||||
{
|
||||
OwnerId = user.Id,
|
||||
FlowerId = item.Id,
|
||||
EventId = EventCover,
|
||||
DateUnixTime = now,
|
||||
ByUserId = user.Id,
|
||||
ByUserName = user.Name,
|
||||
//Memo = flower.Memo,
|
||||
Latitude = flower.Latitude,
|
||||
Longitude = flower.Longitude
|
||||
};
|
||||
database.Records.Add(record);
|
||||
SaveDatabase();
|
||||
}
|
||||
|
||||
photo.FlowerId = item.Id;
|
||||
photo.RecordId = record.Id;
|
||||
SaveDatabase();
|
||||
|
||||
try
|
||||
{
|
||||
MoveTempFileToFlower(item.Id, photo.Path);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return Problem(ex.ToString(), "api/flower/add#MoveTempFileToFlower");
|
||||
// TODO: Logger
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Ok(item);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 用户上传封面
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 请求示例:
|
||||
///
|
||||
/// POST /api/flower/cover_upload
|
||||
/// Authorization: authorization id
|
||||
///
|
||||
/// 参数:
|
||||
///
|
||||
/// cover: <photo>
|
||||
///
|
||||
/// </remarks>
|
||||
/// <param name="p">封面参数</param>
|
||||
/// <returns>添加成功则返回封面 id</returns>
|
||||
/// <response code="200">返回已添加的封面 id</response>
|
||||
/// <response code="400">提交的内容不合法</response>
|
||||
/// <response code="401">未找到登录会话或已过期</response>
|
||||
/// <response code="403">用户已禁用</response>
|
||||
/// <response code="404">未找到关联用户</response>
|
||||
/// <response code="413">提交正文过大</response>
|
||||
[Route("cover_upload", Name = "uploadCover")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
||||
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
|
||||
[ProducesResponseType(StatusCodes.Status403Forbidden)]
|
||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||
[ProducesResponseType(StatusCodes.Status413PayloadTooLarge)]
|
||||
[ProducesErrorResponseType(typeof(ErrorResponse))]
|
||||
[HttpPost]
|
||||
[Consumes("multipart/form-data")]
|
||||
[RequestSizeLimit(5 * 1024 * 1024)]
|
||||
public async Task<ActionResult<int>> UploadCover([FromForm] CoverParameter p)
|
||||
{
|
||||
var (result, user) = CheckPermission();
|
||||
if (result != null)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
if (user == null)
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
if (p.Cover?.Length > 0)
|
||||
{
|
||||
var file = WrapFormFile(p.Cover);
|
||||
if (file == null)
|
||||
{
|
||||
return BadRequest();
|
||||
}
|
||||
|
||||
var now = user.ActiveDateUnixTime ?? DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
|
||||
|
||||
try
|
||||
{
|
||||
await WriteToFile(TempId, file);
|
||||
|
||||
var item = new PhotoItem
|
||||
{
|
||||
OwnerId = user.Id,
|
||||
FileType = file.FileType,
|
||||
FileName = file.Filename,
|
||||
Path = file.Path,
|
||||
DateUploadUnixTime = now
|
||||
};
|
||||
database.Photos.Add(item);
|
||||
SaveDatabase();
|
||||
|
||||
return Ok(item.Id);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return Problem(ex.ToString(), "api/flower/cover_upload");
|
||||
// TODO: Logger
|
||||
}
|
||||
}
|
||||
|
||||
return BadRequest();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 修改花草
|
||||
/// </summary>
|
||||
@ -451,22 +673,28 @@ public class FlowerApiController : BaseController
|
||||
/// dateBuy: 1684935276117
|
||||
/// cost: 15.40
|
||||
/// purchase: null
|
||||
/// memo: "备注"
|
||||
/// lon: 29.5462794
|
||||
/// lat: 106.5380034
|
||||
/// cover: <photo>
|
||||
///
|
||||
/// </remarks>
|
||||
/// <param name="update">修改参数</param>
|
||||
/// <returns>修改成功则返回已修改的花草对象</returns>
|
||||
/// <response code="200">返回已修改的花草对象</response>
|
||||
/// <response code="400">提交的内容不合法</response>
|
||||
/// <response code="401">未找到登录会话或已过期</response>
|
||||
/// <response code="403">用户已禁用</response>
|
||||
/// <response code="404">未找到关联用户或者未找到将修改的花草对象</response>
|
||||
/// <response code="413">提交正文过大</response>
|
||||
[Route("update", Name = "updateFlower")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
||||
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
|
||||
[ProducesResponseType(StatusCodes.Status403Forbidden)]
|
||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||
[ProducesResponseType(StatusCodes.Status413PayloadTooLarge)]
|
||||
[ProducesErrorResponseType(typeof(ErrorResponse))]
|
||||
[HttpPut]
|
||||
[Consumes("multipart/form-data")]
|
||||
[RequestSizeLimit(5 * 1024 * 1024)]
|
||||
@ -492,6 +720,9 @@ public class FlowerApiController : BaseController
|
||||
flower.DateBuyUnixTime = update.DateBuy;
|
||||
flower.Cost = update.Cost;
|
||||
flower.Purchase = update.Purchase;
|
||||
flower.Memo = update.Memo;
|
||||
flower.Latitude = update.Latitude;
|
||||
flower.Longitude = update.Longitude;
|
||||
|
||||
if (update.Cover?.Length > 0)
|
||||
{
|
||||
@ -512,8 +743,10 @@ public class FlowerApiController : BaseController
|
||||
EventId = EventCover,
|
||||
DateUnixTime = now,
|
||||
ByUserId = user.Id,
|
||||
ByUserName = user.Name
|
||||
//Memo = ""
|
||||
ByUserName = user.Name,
|
||||
//Memo = flower.Memo,
|
||||
Latitude = flower.Latitude,
|
||||
Longitude = flower.Longitude
|
||||
};
|
||||
database.Records.Add(record);
|
||||
}
|
||||
@ -537,6 +770,7 @@ public class FlowerApiController : BaseController
|
||||
{
|
||||
var cover = new PhotoItem
|
||||
{
|
||||
OwnerId = user.Id,
|
||||
FlowerId = update.Id,
|
||||
RecordId = record.Id,
|
||||
FileType = file.FileType,
|
||||
@ -575,11 +809,12 @@ public class FlowerApiController : BaseController
|
||||
/// 参数:
|
||||
///
|
||||
/// id: int
|
||||
/// lon: double?
|
||||
/// lat: double?
|
||||
/// photo: IFormFile
|
||||
///
|
||||
/// </remarks>
|
||||
/// <param name="id">花草唯一 id</param>
|
||||
/// <param name="photo">封面图片</param>
|
||||
/// <param name="param">封面修改参数</param>
|
||||
/// <returns>修改成功则返回 HTTP 204</returns>
|
||||
/// <response code="204">修改成功</response>
|
||||
/// <response code="400">照片格式非法</response>
|
||||
@ -594,10 +829,11 @@ public class FlowerApiController : BaseController
|
||||
[ProducesResponseType(StatusCodes.Status403Forbidden)]
|
||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||
[ProducesResponseType(StatusCodes.Status413PayloadTooLarge)]
|
||||
[ProducesErrorResponseType(typeof(ErrorResponse))]
|
||||
[HttpPost]
|
||||
[Consumes("multipart/form-data")]
|
||||
[RequestSizeLimit(5 * 1024 * 1024)]
|
||||
public async Task<ActionResult> UploadCovers([Required][FromQuery] int id, [Required] IFormFile photo)
|
||||
public async Task<ActionResult> UploadCovers([FromForm] FlowerCoverParameter param)
|
||||
{
|
||||
var (result, user) = CheckPermission();
|
||||
if (result != null)
|
||||
@ -609,35 +845,40 @@ public class FlowerApiController : BaseController
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
var flower = database.Flowers.SingleOrDefault(f => f.Id == id && f.OwnerId == user.Id);
|
||||
var flower = database.Flowers.SingleOrDefault(f => f.Id == param.Id && f.OwnerId == user.Id);
|
||||
if (flower == null)
|
||||
{
|
||||
return NotFound($"Flower id {id} not found");
|
||||
return NotFound($"Flower id {param.Id} not found");
|
||||
}
|
||||
if (photo.Length > 0)
|
||||
if (param.Cover?.Length > 0)
|
||||
{
|
||||
var file = WrapFormFile(photo);
|
||||
var file = WrapFormFile(param.Cover);
|
||||
if (file == null)
|
||||
{
|
||||
return BadRequest();
|
||||
}
|
||||
|
||||
var now = user.ActiveDateUnixTime ?? DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
|
||||
var record = database.Records.SingleOrDefault(r => r.FlowerId == id && r.EventId == EventCover);
|
||||
var record = database.Records.SingleOrDefault(r => r.FlowerId == param.Id && r.EventId == EventCover);
|
||||
if (record == null)
|
||||
{
|
||||
record = new RecordItem
|
||||
{
|
||||
OwnerId = user.Id,
|
||||
FlowerId = id,
|
||||
FlowerId = param.Id,
|
||||
EventId = EventCover,
|
||||
DateUnixTime = now,
|
||||
ByUserId = user.Id,
|
||||
ByUserName = user.Name
|
||||
//Memo = ""
|
||||
ByUserName = user.Name,
|
||||
//Memo = "",
|
||||
Latitude = param.Latitude,
|
||||
Longitude = param.Longitude
|
||||
};
|
||||
database.Records.Add(record);
|
||||
}
|
||||
|
||||
flower.Latitude = param.Latitude;
|
||||
flower.Longitude = param.Longitude;
|
||||
SaveDatabase();
|
||||
|
||||
try
|
||||
@ -646,7 +887,8 @@ public class FlowerApiController : BaseController
|
||||
{
|
||||
var cover = new PhotoItem
|
||||
{
|
||||
FlowerId = id,
|
||||
OwnerId = user.Id,
|
||||
FlowerId = param.Id,
|
||||
RecordId = record.Id,
|
||||
FileType = file.FileType,
|
||||
FileName = file.Filename,
|
||||
@ -655,7 +897,7 @@ public class FlowerApiController : BaseController
|
||||
};
|
||||
AddPhotoItem(cover);
|
||||
|
||||
await WriteToFile(id, file, token);
|
||||
await WriteToFile(param.Id, file, token);
|
||||
});
|
||||
}
|
||||
catch (Exception ex)
|
||||
@ -695,6 +937,7 @@ public class FlowerApiController : BaseController
|
||||
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
|
||||
[ProducesResponseType(StatusCodes.Status403Forbidden)]
|
||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||
[ProducesErrorResponseType(typeof(ErrorResponse))]
|
||||
[HttpGet]
|
||||
[ResponseCache(NoStore = true, Location = ResponseCacheLocation.None)]
|
||||
public ActionResult<PhotoItem[]> GetCovers([Required][FromQuery] int id, [FromQuery(Name = "eid")] int? eventId = 0)
|
||||
|
@ -4,17 +4,35 @@ using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace Blahblah.FlowerStory.Server.Controller;
|
||||
|
||||
/// <summary>
|
||||
/// 封面参数
|
||||
/// </summary>
|
||||
public record CoverParameter
|
||||
{
|
||||
/// <summary>
|
||||
/// 封面
|
||||
/// </summary>
|
||||
[FromForm(Name = "cover")]
|
||||
public IFormFile? Cover { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// 封面 id
|
||||
/// </summary>
|
||||
[FromForm(Name = "cid")]
|
||||
public int? CoverId { get; init; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 花草参数
|
||||
/// </summary>
|
||||
public record FlowerParameter
|
||||
public record FlowerParameter : CoverParameter
|
||||
{
|
||||
/// <summary>
|
||||
/// 类别 id
|
||||
/// </summary>
|
||||
[Required]
|
||||
[FromForm(Name = "categoryId")]
|
||||
public int CategoryId { get; init; }
|
||||
public required int CategoryId { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// 花草名称
|
||||
@ -28,7 +46,7 @@ public record FlowerParameter
|
||||
/// </summary>
|
||||
[Required]
|
||||
[FromForm(Name = "dateBuy")]
|
||||
public long DateBuy { get; init; }
|
||||
public required long DateBuy { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// 购买花费
|
||||
@ -43,10 +61,22 @@ public record FlowerParameter
|
||||
public string? Purchase { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// 花草封面
|
||||
/// 备注
|
||||
/// </summary>
|
||||
[FromForm(Name = "cover")]
|
||||
public IFormFile? Cover { get; init; }
|
||||
[FromForm(Name = "memo")]
|
||||
public string? Memo { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 纬度
|
||||
/// </summary>
|
||||
[FromForm(Name = "lat")]
|
||||
public double? Latitude { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 经度
|
||||
/// </summary>
|
||||
[FromForm(Name = "lon")]
|
||||
public double? Longitude { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -59,7 +89,32 @@ public record FlowerUpdateParameter : FlowerParameter
|
||||
/// </summary>
|
||||
[Required]
|
||||
[FromForm(Name = "id")]
|
||||
public int Id { get; init; }
|
||||
public required int Id { get; init; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 花草封面修改参数
|
||||
/// </summary>
|
||||
public record FlowerCoverParameter : CoverParameter
|
||||
{
|
||||
/// <summary>
|
||||
/// 花草唯一 id
|
||||
/// </summary>
|
||||
[Required]
|
||||
[FromForm(Name = "id")]
|
||||
public required int Id { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// 纬度
|
||||
/// </summary>
|
||||
[FromForm(Name = "lat")]
|
||||
public double? Latitude { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 经度
|
||||
/// </summary>
|
||||
[FromForm(Name = "lon")]
|
||||
public double? Longitude { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -103,6 +103,44 @@ public partial class UserApiController : BaseController
|
||||
return NoContent();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 判断当前会话是否有效
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 请求示例:
|
||||
///
|
||||
/// GET /api/user/validation
|
||||
/// Authorization: authorization id
|
||||
///
|
||||
/// </remarks>
|
||||
/// <returns>会话有效则返回会话对象</returns>
|
||||
/// <response code="200">返回会话对象</response>
|
||||
/// <response code="401">认证失败</response>
|
||||
[Route("validation", Name = "validation")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
|
||||
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
|
||||
[ProducesErrorResponseType(typeof(ErrorResponse))]
|
||||
[HttpGet]
|
||||
[ResponseCache(NoStore = true, Location = ResponseCacheLocation.None)]
|
||||
public ActionResult<TokenItem> Validation()
|
||||
{
|
||||
var (result, token) = CheckToken();
|
||||
if (result != null)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
if (token == null)
|
||||
{
|
||||
return Unauthorized();
|
||||
}
|
||||
|
||||
// update last active time
|
||||
SaveDatabase();
|
||||
|
||||
return Ok(token);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 注销当前登录会话
|
||||
/// </summary>
|
||||
|
@ -24,7 +24,7 @@ public class FlowerItem : ILocation
|
||||
[Column("uid")]
|
||||
[ForeignKey(nameof(Owner))]
|
||||
[Required]
|
||||
public int OwnerId { get; set; }
|
||||
public required int OwnerId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 所有人
|
||||
@ -37,7 +37,7 @@ public class FlowerItem : ILocation
|
||||
/// </summary>
|
||||
[Column("categoryid")]
|
||||
[Required]
|
||||
public int CategoryId { get; set; }
|
||||
public required int CategoryId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 花草名称
|
||||
@ -52,7 +52,7 @@ public class FlowerItem : ILocation
|
||||
[Column("datebuy")]
|
||||
[Required]
|
||||
[JsonPropertyName("dateBuy")]
|
||||
public long DateBuyUnixTime { get; set; }
|
||||
public required long DateBuyUnixTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 购买花费
|
||||
|
@ -18,16 +18,29 @@ public class PhotoItem
|
||||
[Required]
|
||||
public int Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 关联人 id
|
||||
/// </summary>
|
||||
[Column("uid")]
|
||||
[ForeignKey(nameof(Owner))]
|
||||
[Required]
|
||||
public required int OwnerId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 关联人
|
||||
/// </summary>
|
||||
[JsonIgnore]
|
||||
public UserItem? Owner { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 关联花草 id
|
||||
/// </summary>
|
||||
[Column("fid")]
|
||||
[ForeignKey(nameof(Flower))]
|
||||
[Required]
|
||||
public int FlowerId { get; set; }
|
||||
public int? FlowerId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 关联花草
|
||||
/// 关联的花草
|
||||
/// </summary>
|
||||
[JsonIgnore]
|
||||
public FlowerItem? Flower { get; set; }
|
||||
@ -37,8 +50,7 @@ public class PhotoItem
|
||||
/// </summary>
|
||||
[Column("rid")]
|
||||
[ForeignKey(nameof(Record))]
|
||||
[Required]
|
||||
public int RecordId { get; set; }
|
||||
public int? RecordId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 关联的事件
|
||||
@ -73,7 +85,7 @@ public class PhotoItem
|
||||
[Column("dateupload")]
|
||||
[Required]
|
||||
[JsonPropertyName("dateUpload")]
|
||||
public long DateUploadUnixTime { get; set; }
|
||||
public required long DateUploadUnixTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 上传时间
|
||||
|
@ -24,7 +24,7 @@ public class RecordItem : ILocation
|
||||
[Column("uid")]
|
||||
[ForeignKey(nameof(Owner))]
|
||||
[Required]
|
||||
public int OwnerId { get; set; }
|
||||
public required int OwnerId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 关联人
|
||||
@ -38,7 +38,7 @@ public class RecordItem : ILocation
|
||||
[Column("fid")]
|
||||
[ForeignKey(nameof(Flower))]
|
||||
[Required]
|
||||
public int FlowerId { get; set; }
|
||||
public required int FlowerId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 关联花草
|
||||
@ -51,7 +51,7 @@ public class RecordItem : ILocation
|
||||
/// </summary>
|
||||
[Column("eid")]
|
||||
[Required]
|
||||
public int EventId { get; set; }
|
||||
public required int EventId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 操作时间
|
||||
@ -59,7 +59,7 @@ public class RecordItem : ILocation
|
||||
[Column("date")]
|
||||
[Required]
|
||||
[JsonPropertyName("date")]
|
||||
public long DateUnixTime { get; set; }
|
||||
public required long DateUnixTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 操作人 uid
|
||||
|
@ -23,7 +23,7 @@ public class TokenItem
|
||||
/// </summary>
|
||||
[Column("uid")]
|
||||
[Required]
|
||||
public int UserId { get; set; }
|
||||
public required int UserId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 登录时间
|
||||
@ -31,7 +31,7 @@ public class TokenItem
|
||||
[Column("logondate")]
|
||||
[Required]
|
||||
[JsonPropertyName("logonDate")]
|
||||
public long LogonDateUnixTime { get; set; }
|
||||
public required long LogonDateUnixTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 活动时间
|
||||
@ -39,7 +39,7 @@ public class TokenItem
|
||||
[Column("activedate")]
|
||||
[Required]
|
||||
[JsonPropertyName("activeDate")]
|
||||
public long ActiveDateUnixTime { get; set; }
|
||||
public required long ActiveDateUnixTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 过期时间
|
||||
@ -47,14 +47,14 @@ public class TokenItem
|
||||
[Column("expiredate")]
|
||||
[Required]
|
||||
[JsonPropertyName("expireDate")]
|
||||
public long ExpireDateUnixTime { get; set; }
|
||||
public required long ExpireDateUnixTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 过期秒数
|
||||
/// </summary>
|
||||
[Column("expiresecs")]
|
||||
[Required]
|
||||
public int ExpireSeconds { get; set; }
|
||||
public required int ExpireSeconds { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 验证码
|
||||
|
@ -41,7 +41,7 @@ public class UserItem
|
||||
/// </summary>
|
||||
[Column("level")]
|
||||
[Required]
|
||||
public int Level { get; set; }
|
||||
public required int Level { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 注册时间
|
||||
@ -49,7 +49,7 @@ public class UserItem
|
||||
[Column("regdate")]
|
||||
[Required]
|
||||
[JsonPropertyName("registerDate")]
|
||||
public long RegisterDateUnixTime { get; set; }
|
||||
public required long RegisterDateUnixTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 最后变动时间
|
||||
|
@ -1,141 +0,0 @@
|
||||
// <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("20230522090224_InitialCreateDb")]
|
||||
partial class InitialCreateDb
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder.HasAnnotation("ProductVersion", "7.0.5");
|
||||
|
||||
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<DateTimeOffset>("DateBuy")
|
||||
.HasColumnType("numeric")
|
||||
.HasColumnName("datebuy");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT")
|
||||
.HasColumnName("name");
|
||||
|
||||
b.Property<byte[]>("Photo")
|
||||
.HasColumnType("BLOB")
|
||||
.HasColumnName("photo");
|
||||
|
||||
b.Property<string>("Purchase")
|
||||
.HasColumnType("TEXT")
|
||||
.HasColumnName("purchase");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("flowers");
|
||||
});
|
||||
|
||||
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<DateTimeOffset>("Date")
|
||||
.HasColumnType("numeric")
|
||||
.HasColumnName("date");
|
||||
|
||||
b.Property<int>("EventId")
|
||||
.HasColumnType("INTEGER")
|
||||
.HasColumnName("eid");
|
||||
|
||||
b.Property<byte[]>("Photo")
|
||||
.HasColumnType("BLOB")
|
||||
.HasColumnName("photo");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("records");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Blahblah.FlowerStory.Server.Data.Model.UserItem", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER")
|
||||
.HasColumnName("uid");
|
||||
|
||||
b.Property<DateTimeOffset?>("ActiveDate")
|
||||
.HasColumnType("numeric")
|
||||
.HasColumnName("activedate");
|
||||
|
||||
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<DateTimeOffset>("RegisterDate")
|
||||
.HasColumnType("numeric")
|
||||
.HasColumnName("regdate");
|
||||
|
||||
b.Property<string>("UserId")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT")
|
||||
.HasColumnName("id");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("users");
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
@ -1,83 +0,0 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Blahblah.FlowerStory.Server.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class InitialCreateDb : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.CreateTable(
|
||||
name: "flowers",
|
||||
columns: table => new
|
||||
{
|
||||
fid = table.Column<int>(type: "INTEGER", nullable: false)
|
||||
.Annotation("Sqlite:Autoincrement", true),
|
||||
categoryid = table.Column<int>(type: "INTEGER", nullable: false),
|
||||
name = table.Column<string>(type: "TEXT", nullable: false),
|
||||
datebuy = table.Column<DateTimeOffset>(type: "numeric", nullable: false),
|
||||
cost = table.Column<decimal>(type: "real", nullable: true),
|
||||
purchase = table.Column<string>(type: "TEXT", nullable: true),
|
||||
photo = table.Column<byte[]>(type: "BLOB", nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_flowers", x => x.fid);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "records",
|
||||
columns: table => new
|
||||
{
|
||||
rid = table.Column<int>(type: "INTEGER", nullable: false)
|
||||
.Annotation("Sqlite:Autoincrement", true),
|
||||
eid = table.Column<int>(type: "INTEGER", nullable: false),
|
||||
date = table.Column<DateTimeOffset>(type: "numeric", nullable: false),
|
||||
byuid = table.Column<int>(type: "INTEGER", nullable: true),
|
||||
byname = table.Column<string>(type: "TEXT", nullable: true),
|
||||
photo = table.Column<byte[]>(type: "BLOB", nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_records", x => x.rid);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "users",
|
||||
columns: table => new
|
||||
{
|
||||
uid = table.Column<int>(type: "INTEGER", nullable: false)
|
||||
.Annotation("Sqlite:Autoincrement", true),
|
||||
id = table.Column<string>(type: "TEXT", nullable: false),
|
||||
password = table.Column<string>(type: "TEXT", nullable: false),
|
||||
level = table.Column<int>(type: "INTEGER", nullable: false),
|
||||
regdate = table.Column<DateTimeOffset>(type: "numeric", nullable: false),
|
||||
activedate = table.Column<DateTimeOffset>(type: "numeric", nullable: true),
|
||||
name = table.Column<string>(type: "TEXT", nullable: false),
|
||||
email = table.Column<string>(type: "TEXT", nullable: true),
|
||||
mobile = table.Column<string>(type: "TEXT", nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_users", x => x.uid);
|
||||
});
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(
|
||||
name: "flowers");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "records");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "users");
|
||||
}
|
||||
}
|
||||
}
|
@ -1,141 +0,0 @@
|
||||
// <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("20230522143925_ChangeDateColumnType")]
|
||||
partial class ChangeDateColumnType
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder.HasAnnotation("ProductVersion", "7.0.5");
|
||||
|
||||
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");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT")
|
||||
.HasColumnName("name");
|
||||
|
||||
b.Property<byte[]>("Photo")
|
||||
.HasColumnType("BLOB")
|
||||
.HasColumnName("photo");
|
||||
|
||||
b.Property<string>("Purchase")
|
||||
.HasColumnType("TEXT")
|
||||
.HasColumnName("purchase");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("flowers");
|
||||
});
|
||||
|
||||
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");
|
||||
|
||||
b.Property<int>("EventId")
|
||||
.HasColumnType("INTEGER")
|
||||
.HasColumnName("eid");
|
||||
|
||||
b.Property<byte[]>("Photo")
|
||||
.HasColumnType("BLOB")
|
||||
.HasColumnName("photo");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("records");
|
||||
});
|
||||
|
||||
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<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");
|
||||
|
||||
b.Property<string>("UserId")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT")
|
||||
.HasColumnName("id");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("users");
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
@ -1,85 +0,0 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Blahblah.FlowerStory.Server.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class ChangeDateColumnType : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AlterColumn<long>(
|
||||
name: "regdate",
|
||||
table: "users",
|
||||
type: "INTEGER",
|
||||
nullable: false,
|
||||
oldClrType: typeof(DateTimeOffset),
|
||||
oldType: "numeric");
|
||||
|
||||
migrationBuilder.AlterColumn<long>(
|
||||
name: "activedate",
|
||||
table: "users",
|
||||
type: "INTEGER",
|
||||
nullable: true,
|
||||
oldClrType: typeof(DateTimeOffset),
|
||||
oldType: "numeric",
|
||||
oldNullable: true);
|
||||
|
||||
migrationBuilder.AlterColumn<long>(
|
||||
name: "date",
|
||||
table: "records",
|
||||
type: "INTEGER",
|
||||
nullable: false,
|
||||
oldClrType: typeof(DateTimeOffset),
|
||||
oldType: "numeric");
|
||||
|
||||
migrationBuilder.AlterColumn<long>(
|
||||
name: "datebuy",
|
||||
table: "flowers",
|
||||
type: "INTEGER",
|
||||
nullable: false,
|
||||
oldClrType: typeof(DateTimeOffset),
|
||||
oldType: "numeric");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AlterColumn<DateTimeOffset>(
|
||||
name: "regdate",
|
||||
table: "users",
|
||||
type: "numeric",
|
||||
nullable: false,
|
||||
oldClrType: typeof(long),
|
||||
oldType: "INTEGER");
|
||||
|
||||
migrationBuilder.AlterColumn<DateTimeOffset>(
|
||||
name: "activedate",
|
||||
table: "users",
|
||||
type: "numeric",
|
||||
nullable: true,
|
||||
oldClrType: typeof(long),
|
||||
oldType: "INTEGER",
|
||||
oldNullable: true);
|
||||
|
||||
migrationBuilder.AlterColumn<DateTimeOffset>(
|
||||
name: "date",
|
||||
table: "records",
|
||||
type: "numeric",
|
||||
nullable: false,
|
||||
oldClrType: typeof(long),
|
||||
oldType: "INTEGER");
|
||||
|
||||
migrationBuilder.AlterColumn<DateTimeOffset>(
|
||||
name: "datebuy",
|
||||
table: "flowers",
|
||||
type: "numeric",
|
||||
nullable: false,
|
||||
oldClrType: typeof(long),
|
||||
oldType: "INTEGER");
|
||||
}
|
||||
}
|
||||
}
|
191
Server/Migrations/20230523031232_AddTokens.Designer.cs
generated
191
Server/Migrations/20230523031232_AddTokens.Designer.cs
generated
@ -1,191 +0,0 @@
|
||||
// <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("20230523031232_AddTokens")]
|
||||
partial class AddTokens
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder.HasAnnotation("ProductVersion", "7.0.5");
|
||||
|
||||
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<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT")
|
||||
.HasColumnName("name");
|
||||
|
||||
b.Property<byte[]>("Photo")
|
||||
.HasColumnType("BLOB")
|
||||
.HasColumnName("photo");
|
||||
|
||||
b.Property<string>("Purchase")
|
||||
.HasColumnType("TEXT")
|
||||
.HasColumnName("purchase");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("flowers");
|
||||
});
|
||||
|
||||
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<byte[]>("Photo")
|
||||
.HasColumnType("BLOB")
|
||||
.HasColumnName("photo");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
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");
|
||||
|
||||
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");
|
||||
|
||||
b.Property<int>("ExpireSeconds")
|
||||
.HasColumnType("INTEGER")
|
||||
.HasColumnName("expiresecs");
|
||||
|
||||
b.Property<long>("LogonDateUnixTime")
|
||||
.HasColumnType("INTEGER")
|
||||
.HasColumnName("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<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");
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
@ -1,41 +0,0 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Blahblah.FlowerStory.Server.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class AddTokens : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.CreateTable(
|
||||
name: "tokens",
|
||||
columns: table => new
|
||||
{
|
||||
tid = table.Column<string>(type: "TEXT", nullable: false),
|
||||
uid = table.Column<int>(type: "INTEGER", nullable: false),
|
||||
logondate = table.Column<long>(type: "INTEGER", nullable: false),
|
||||
activedate = table.Column<long>(type: "INTEGER", nullable: false),
|
||||
expiredate = table.Column<long>(type: "INTEGER", nullable: false),
|
||||
expiresecs = table.Column<int>(type: "INTEGER", nullable: false),
|
||||
verifycode = table.Column<string>(type: "TEXT", nullable: true),
|
||||
clientapp = table.Column<string>(type: "TEXT", nullable: true),
|
||||
deviceid = table.Column<string>(type: "TEXT", nullable: true),
|
||||
clientagent = table.Column<string>(type: "TEXT", nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_tokens", x => x.tid);
|
||||
});
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(
|
||||
name: "tokens");
|
||||
}
|
||||
}
|
||||
}
|
202
Server/Migrations/20230524062207_AddOwner.Designer.cs
generated
202
Server/Migrations/20230524062207_AddOwner.Designer.cs
generated
@ -1,202 +0,0 @@
|
||||
// <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("20230524062207_AddOwner")]
|
||||
partial class AddOwner
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder.HasAnnotation("ProductVersion", "7.0.5");
|
||||
|
||||
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<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT")
|
||||
.HasColumnName("name");
|
||||
|
||||
b.Property<int>("OwnerId")
|
||||
.HasColumnType("INTEGER")
|
||||
.HasColumnName("uid");
|
||||
|
||||
b.Property<byte[]>("Photo")
|
||||
.HasColumnType("BLOB")
|
||||
.HasColumnName("photo");
|
||||
|
||||
b.Property<string>("Purchase")
|
||||
.HasColumnType("TEXT")
|
||||
.HasColumnName("purchase");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("flowers");
|
||||
});
|
||||
|
||||
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>("OwnerId")
|
||||
.HasColumnType("INTEGER")
|
||||
.HasColumnName("uid");
|
||||
|
||||
b.Property<byte[]>("Photo")
|
||||
.HasColumnType("BLOB")
|
||||
.HasColumnName("photo");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
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<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");
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
@ -1,40 +0,0 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Blahblah.FlowerStory.Server.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class AddOwner : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<int>(
|
||||
name: "uid",
|
||||
table: "records",
|
||||
type: "INTEGER",
|
||||
nullable: false,
|
||||
defaultValue: 0);
|
||||
|
||||
migrationBuilder.AddColumn<int>(
|
||||
name: "uid",
|
||||
table: "flowers",
|
||||
type: "INTEGER",
|
||||
nullable: false,
|
||||
defaultValue: 0);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(
|
||||
name: "uid",
|
||||
table: "records");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "uid",
|
||||
table: "flowers");
|
||||
}
|
||||
}
|
||||
}
|
@ -1,214 +0,0 @@
|
||||
// <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("20230525004719_AddAvatarMemo")]
|
||||
partial class AddAvatarMemo
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder.HasAnnotation("ProductVersion", "7.0.5");
|
||||
|
||||
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<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<byte[]>("Photo")
|
||||
.HasColumnType("BLOB")
|
||||
.HasColumnName("photo");
|
||||
|
||||
b.Property<string>("Purchase")
|
||||
.HasColumnType("TEXT")
|
||||
.HasColumnName("purchase");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("flowers");
|
||||
});
|
||||
|
||||
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<string>("Memo")
|
||||
.HasColumnType("TEXT")
|
||||
.HasColumnName("memo");
|
||||
|
||||
b.Property<int>("OwnerId")
|
||||
.HasColumnType("INTEGER")
|
||||
.HasColumnName("uid");
|
||||
|
||||
b.Property<byte[]>("Photo")
|
||||
.HasColumnType("BLOB")
|
||||
.HasColumnName("photo");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
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");
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
@ -1,48 +0,0 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Blahblah.FlowerStory.Server.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class AddAvatarMemo : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<byte[]>(
|
||||
name: "avatar",
|
||||
table: "users",
|
||||
type: "BLOB",
|
||||
nullable: true);
|
||||
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "memo",
|
||||
table: "records",
|
||||
type: "TEXT",
|
||||
nullable: true);
|
||||
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "memo",
|
||||
table: "flowers",
|
||||
type: "TEXT",
|
||||
nullable: true);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(
|
||||
name: "avatar",
|
||||
table: "users");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "memo",
|
||||
table: "records");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "memo",
|
||||
table: "flowers");
|
||||
}
|
||||
}
|
||||
}
|
300
Server/Migrations/20230525082941_AddPhotos.Designer.cs
generated
300
Server/Migrations/20230525082941_AddPhotos.Designer.cs
generated
@ -1,300 +0,0 @@
|
||||
// <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("20230525082941_AddPhotos")]
|
||||
partial class AddPhotos
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder.HasAnnotation("ProductVersion", "7.0.5");
|
||||
|
||||
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<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<string>("Path")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT")
|
||||
.HasColumnName("path");
|
||||
|
||||
b.Property<int>("RecordId")
|
||||
.HasColumnType("INTEGER")
|
||||
.HasColumnName("rid");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
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<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.RecordItem", "Record")
|
||||
.WithMany("Photo")
|
||||
.HasForeignKey("RecordId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
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.RecordItem", b =>
|
||||
{
|
||||
b.Navigation("Photo");
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
@ -1,143 +0,0 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Blahblah.FlowerStory.Server.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class AddPhotos : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(
|
||||
name: "photo",
|
||||
table: "records");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "photo",
|
||||
table: "flowers");
|
||||
|
||||
migrationBuilder.AddColumn<int>(
|
||||
name: "fid",
|
||||
table: "records",
|
||||
type: "INTEGER",
|
||||
nullable: false,
|
||||
defaultValue: 0);
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "photos",
|
||||
columns: table => new
|
||||
{
|
||||
pid = table.Column<int>(type: "INTEGER", nullable: false)
|
||||
.Annotation("Sqlite:Autoincrement", true),
|
||||
rid = table.Column<int>(type: "INTEGER", nullable: false),
|
||||
filetype = table.Column<string>(type: "TEXT", nullable: false),
|
||||
filename = table.Column<string>(type: "TEXT", nullable: false),
|
||||
path = table.Column<string>(type: "TEXT", nullable: false),
|
||||
dateupload = table.Column<long>(type: "INTEGER", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_photos", x => x.pid);
|
||||
table.ForeignKey(
|
||||
name: "FK_photos_records_rid",
|
||||
column: x => x.rid,
|
||||
principalTable: "records",
|
||||
principalColumn: "rid",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_records_fid",
|
||||
table: "records",
|
||||
column: "fid");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_records_uid",
|
||||
table: "records",
|
||||
column: "uid");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_flowers_uid",
|
||||
table: "flowers",
|
||||
column: "uid");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_photos_rid",
|
||||
table: "photos",
|
||||
column: "rid");
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_flowers_users_uid",
|
||||
table: "flowers",
|
||||
column: "uid",
|
||||
principalTable: "users",
|
||||
principalColumn: "uid",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_records_flowers_fid",
|
||||
table: "records",
|
||||
column: "fid",
|
||||
principalTable: "flowers",
|
||||
principalColumn: "fid",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_records_users_uid",
|
||||
table: "records",
|
||||
column: "uid",
|
||||
principalTable: "users",
|
||||
principalColumn: "uid",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_flowers_users_uid",
|
||||
table: "flowers");
|
||||
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_records_flowers_fid",
|
||||
table: "records");
|
||||
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_records_users_uid",
|
||||
table: "records");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "photos");
|
||||
|
||||
migrationBuilder.DropIndex(
|
||||
name: "IX_records_fid",
|
||||
table: "records");
|
||||
|
||||
migrationBuilder.DropIndex(
|
||||
name: "IX_records_uid",
|
||||
table: "records");
|
||||
|
||||
migrationBuilder.DropIndex(
|
||||
name: "IX_flowers_uid",
|
||||
table: "flowers");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "fid",
|
||||
table: "records");
|
||||
|
||||
migrationBuilder.AddColumn<byte[]>(
|
||||
name: "photo",
|
||||
table: "records",
|
||||
type: "BLOB",
|
||||
nullable: true);
|
||||
|
||||
migrationBuilder.AddColumn<byte[]>(
|
||||
name: "photo",
|
||||
table: "flowers",
|
||||
type: "BLOB",
|
||||
nullable: true);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,58 +0,0 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Blahblah.FlowerStory.Server.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class AddLatitudeLongitude : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<double>(
|
||||
name: "latitude",
|
||||
table: "records",
|
||||
type: "REAL",
|
||||
nullable: true);
|
||||
|
||||
migrationBuilder.AddColumn<double>(
|
||||
name: "longitude",
|
||||
table: "records",
|
||||
type: "REAL",
|
||||
nullable: true);
|
||||
|
||||
migrationBuilder.AddColumn<double>(
|
||||
name: "latitude",
|
||||
table: "flowers",
|
||||
type: "REAL",
|
||||
nullable: true);
|
||||
|
||||
migrationBuilder.AddColumn<double>(
|
||||
name: "longitude",
|
||||
table: "flowers",
|
||||
type: "REAL",
|
||||
nullable: true);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(
|
||||
name: "latitude",
|
||||
table: "records");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "longitude",
|
||||
table: "records");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "latitude",
|
||||
table: "flowers");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "longitude",
|
||||
table: "flowers");
|
||||
}
|
||||
}
|
||||
}
|
@ -11,8 +11,8 @@ using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
namespace Blahblah.FlowerStory.Server.Migrations
|
||||
{
|
||||
[DbContext(typeof(FlowerDatabase))]
|
||||
[Migration("20230705083734_Add-Latitude-Longitude")]
|
||||
partial class AddLatitudeLongitude
|
||||
[Migration("20230712091736_InitialDb")]
|
||||
partial class InitialDb
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
@ -40,11 +40,11 @@ namespace Blahblah.FlowerStory.Server.Migrations
|
||||
.HasColumnName("datebuy")
|
||||
.HasAnnotation("Relational:JsonPropertyName", "dateBuy");
|
||||
|
||||
b.Property<double?>("LastLatitude")
|
||||
b.Property<double?>("Latitude")
|
||||
.HasColumnType("REAL")
|
||||
.HasColumnName("latitude");
|
||||
|
||||
b.Property<double?>("LastLongitude")
|
||||
b.Property<double?>("Longitude")
|
||||
.HasColumnType("REAL")
|
||||
.HasColumnName("longitude");
|
||||
|
||||
@ -94,7 +94,7 @@ namespace Blahblah.FlowerStory.Server.Migrations
|
||||
.HasColumnType("TEXT")
|
||||
.HasColumnName("filetype");
|
||||
|
||||
b.Property<int>("FlowerId")
|
||||
b.Property<int?>("FlowerId")
|
||||
.HasColumnType("INTEGER")
|
||||
.HasColumnName("fid");
|
||||
|
||||
@ -103,7 +103,7 @@ namespace Blahblah.FlowerStory.Server.Migrations
|
||||
.HasColumnType("TEXT")
|
||||
.HasColumnName("path");
|
||||
|
||||
b.Property<int>("RecordId")
|
||||
b.Property<int?>("RecordId")
|
||||
.HasColumnType("INTEGER")
|
||||
.HasColumnName("rid");
|
||||
|
||||
@ -286,15 +286,11 @@ namespace Blahblah.FlowerStory.Server.Migrations
|
||||
{
|
||||
b.HasOne("Blahblah.FlowerStory.Server.Data.Model.FlowerItem", "Flower")
|
||||
.WithMany("Photos")
|
||||
.HasForeignKey("FlowerId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
.HasForeignKey("FlowerId");
|
||||
|
||||
b.HasOne("Blahblah.FlowerStory.Server.Data.Model.RecordItem", "Record")
|
||||
.WithMany("Photos")
|
||||
.HasForeignKey("RecordId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
.HasForeignKey("RecordId");
|
||||
|
||||
b.Navigation("Flower");
|
||||
|
187
Server/Migrations/20230712091736_InitialDb.cs
Normal file
187
Server/Migrations/20230712091736_InitialDb.cs
Normal file
@ -0,0 +1,187 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Blahblah.FlowerStory.Server.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class InitialDb : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.CreateTable(
|
||||
name: "tokens",
|
||||
columns: table => new
|
||||
{
|
||||
tid = table.Column<string>(type: "TEXT", nullable: false),
|
||||
uid = table.Column<int>(type: "INTEGER", nullable: false),
|
||||
logondate = table.Column<long>(type: "INTEGER", nullable: false),
|
||||
activedate = table.Column<long>(type: "INTEGER", nullable: false),
|
||||
expiredate = table.Column<long>(type: "INTEGER", nullable: false),
|
||||
expiresecs = table.Column<int>(type: "INTEGER", nullable: false),
|
||||
verifycode = table.Column<string>(type: "TEXT", nullable: true),
|
||||
clientapp = table.Column<string>(type: "TEXT", nullable: true),
|
||||
deviceid = table.Column<string>(type: "TEXT", nullable: true),
|
||||
clientagent = table.Column<string>(type: "TEXT", nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_tokens", x => x.tid);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "users",
|
||||
columns: table => new
|
||||
{
|
||||
uid = table.Column<int>(type: "INTEGER", nullable: false)
|
||||
.Annotation("Sqlite:Autoincrement", true),
|
||||
id = table.Column<string>(type: "TEXT", nullable: false),
|
||||
password = table.Column<string>(type: "TEXT", nullable: false),
|
||||
level = table.Column<int>(type: "INTEGER", nullable: false),
|
||||
regdate = table.Column<long>(type: "INTEGER", nullable: false),
|
||||
activedate = table.Column<long>(type: "INTEGER", nullable: true),
|
||||
name = table.Column<string>(type: "TEXT", nullable: false),
|
||||
email = table.Column<string>(type: "TEXT", nullable: true),
|
||||
mobile = table.Column<string>(type: "TEXT", nullable: true),
|
||||
avatar = table.Column<byte[]>(type: "BLOB", nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_users", x => x.uid);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "flowers",
|
||||
columns: table => new
|
||||
{
|
||||
fid = table.Column<int>(type: "INTEGER", nullable: false)
|
||||
.Annotation("Sqlite:Autoincrement", true),
|
||||
uid = table.Column<int>(type: "INTEGER", nullable: false),
|
||||
categoryid = table.Column<int>(type: "INTEGER", nullable: false),
|
||||
name = table.Column<string>(type: "TEXT", nullable: false),
|
||||
datebuy = table.Column<long>(type: "INTEGER", nullable: false),
|
||||
cost = table.Column<decimal>(type: "real", nullable: true),
|
||||
purchase = table.Column<string>(type: "TEXT", nullable: true),
|
||||
memo = table.Column<string>(type: "TEXT", nullable: true),
|
||||
latitude = table.Column<double>(type: "REAL", nullable: true),
|
||||
longitude = table.Column<double>(type: "REAL", nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_flowers", x => x.fid);
|
||||
table.ForeignKey(
|
||||
name: "FK_flowers_users_uid",
|
||||
column: x => x.uid,
|
||||
principalTable: "users",
|
||||
principalColumn: "uid",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "records",
|
||||
columns: table => new
|
||||
{
|
||||
rid = table.Column<int>(type: "INTEGER", nullable: false)
|
||||
.Annotation("Sqlite:Autoincrement", true),
|
||||
uid = table.Column<int>(type: "INTEGER", nullable: false),
|
||||
fid = table.Column<int>(type: "INTEGER", nullable: false),
|
||||
eid = table.Column<int>(type: "INTEGER", nullable: false),
|
||||
date = table.Column<long>(type: "INTEGER", nullable: false),
|
||||
byuid = table.Column<int>(type: "INTEGER", nullable: true),
|
||||
byname = table.Column<string>(type: "TEXT", nullable: true),
|
||||
memo = table.Column<string>(type: "TEXT", nullable: true),
|
||||
latitude = table.Column<double>(type: "REAL", nullable: true),
|
||||
longitude = table.Column<double>(type: "REAL", nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_records", x => x.rid);
|
||||
table.ForeignKey(
|
||||
name: "FK_records_flowers_fid",
|
||||
column: x => x.fid,
|
||||
principalTable: "flowers",
|
||||
principalColumn: "fid",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
table.ForeignKey(
|
||||
name: "FK_records_users_uid",
|
||||
column: x => x.uid,
|
||||
principalTable: "users",
|
||||
principalColumn: "uid",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "photos",
|
||||
columns: table => new
|
||||
{
|
||||
pid = table.Column<int>(type: "INTEGER", nullable: false)
|
||||
.Annotation("Sqlite:Autoincrement", true),
|
||||
fid = table.Column<int>(type: "INTEGER", nullable: true),
|
||||
rid = table.Column<int>(type: "INTEGER", nullable: true),
|
||||
filetype = table.Column<string>(type: "TEXT", nullable: false),
|
||||
filename = table.Column<string>(type: "TEXT", nullable: false),
|
||||
path = table.Column<string>(type: "TEXT", nullable: false),
|
||||
dateupload = table.Column<long>(type: "INTEGER", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_photos", x => x.pid);
|
||||
table.ForeignKey(
|
||||
name: "FK_photos_flowers_fid",
|
||||
column: x => x.fid,
|
||||
principalTable: "flowers",
|
||||
principalColumn: "fid");
|
||||
table.ForeignKey(
|
||||
name: "FK_photos_records_rid",
|
||||
column: x => x.rid,
|
||||
principalTable: "records",
|
||||
principalColumn: "rid");
|
||||
});
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_flowers_uid",
|
||||
table: "flowers",
|
||||
column: "uid");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_photos_fid",
|
||||
table: "photos",
|
||||
column: "fid");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_photos_rid",
|
||||
table: "photos",
|
||||
column: "rid");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_records_fid",
|
||||
table: "records",
|
||||
column: "fid");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_records_uid",
|
||||
table: "records",
|
||||
column: "uid");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(
|
||||
name: "photos");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "tokens");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "records");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "flowers");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "users");
|
||||
}
|
||||
}
|
||||
}
|
@ -11,8 +11,8 @@ using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
namespace Blahblah.FlowerStory.Server.Migrations
|
||||
{
|
||||
[DbContext(typeof(FlowerDatabase))]
|
||||
[Migration("20230525091254_AddPhotosFlowerForeignKey")]
|
||||
partial class AddPhotosFlowerForeignKey
|
||||
[Migration("20230712093151_AddPhotoOwnerKey")]
|
||||
partial class AddPhotoOwnerKey
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
@ -40,6 +40,14 @@ namespace Blahblah.FlowerStory.Server.Migrations
|
||||
.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");
|
||||
@ -86,16 +94,20 @@ namespace Blahblah.FlowerStory.Server.Migrations
|
||||
.HasColumnType("TEXT")
|
||||
.HasColumnName("filetype");
|
||||
|
||||
b.Property<int>("FlowerId")
|
||||
b.Property<int?>("FlowerId")
|
||||
.HasColumnType("INTEGER")
|
||||
.HasColumnName("fid");
|
||||
|
||||
b.Property<int>("OwnerId")
|
||||
.HasColumnType("INTEGER")
|
||||
.HasColumnName("uid");
|
||||
|
||||
b.Property<string>("Path")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT")
|
||||
.HasColumnName("path");
|
||||
|
||||
b.Property<int>("RecordId")
|
||||
b.Property<int?>("RecordId")
|
||||
.HasColumnType("INTEGER")
|
||||
.HasColumnName("rid");
|
||||
|
||||
@ -103,6 +115,8 @@ namespace Blahblah.FlowerStory.Server.Migrations
|
||||
|
||||
b.HasIndex("FlowerId");
|
||||
|
||||
b.HasIndex("OwnerId");
|
||||
|
||||
b.HasIndex("RecordId");
|
||||
|
||||
b.ToTable("photos");
|
||||
@ -136,6 +150,14 @@ namespace Blahblah.FlowerStory.Server.Migrations
|
||||
.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");
|
||||
@ -270,18 +292,22 @@ namespace Blahblah.FlowerStory.Server.Migrations
|
||||
{
|
||||
b.HasOne("Blahblah.FlowerStory.Server.Data.Model.FlowerItem", "Flower")
|
||||
.WithMany("Photos")
|
||||
.HasForeignKey("FlowerId")
|
||||
.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")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
.HasForeignKey("RecordId");
|
||||
|
||||
b.Navigation("Flower");
|
||||
|
||||
b.Navigation("Owner");
|
||||
|
||||
b.Navigation("Record");
|
||||
});
|
||||
|
@ -5,29 +5,29 @@
|
||||
namespace Blahblah.FlowerStory.Server.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class AddPhotosFlowerForeignKey : Migration
|
||||
public partial class AddPhotoOwnerKey : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<int>(
|
||||
name: "fid",
|
||||
name: "uid",
|
||||
table: "photos",
|
||||
type: "INTEGER",
|
||||
nullable: false,
|
||||
defaultValue: 0);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_photos_fid",
|
||||
name: "IX_photos_uid",
|
||||
table: "photos",
|
||||
column: "fid");
|
||||
column: "uid");
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_photos_flowers_fid",
|
||||
name: "FK_photos_users_uid",
|
||||
table: "photos",
|
||||
column: "fid",
|
||||
principalTable: "flowers",
|
||||
principalColumn: "fid",
|
||||
column: "uid",
|
||||
principalTable: "users",
|
||||
principalColumn: "uid",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
}
|
||||
|
||||
@ -35,15 +35,15 @@ namespace Blahblah.FlowerStory.Server.Migrations
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_photos_flowers_fid",
|
||||
name: "FK_photos_users_uid",
|
||||
table: "photos");
|
||||
|
||||
migrationBuilder.DropIndex(
|
||||
name: "IX_photos_fid",
|
||||
name: "IX_photos_uid",
|
||||
table: "photos");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "fid",
|
||||
name: "uid",
|
||||
table: "photos");
|
||||
}
|
||||
}
|
@ -37,11 +37,11 @@ namespace Blahblah.FlowerStory.Server.Migrations
|
||||
.HasColumnName("datebuy")
|
||||
.HasAnnotation("Relational:JsonPropertyName", "dateBuy");
|
||||
|
||||
b.Property<double?>("LastLatitude")
|
||||
b.Property<double?>("Latitude")
|
||||
.HasColumnType("REAL")
|
||||
.HasColumnName("latitude");
|
||||
|
||||
b.Property<double?>("LastLongitude")
|
||||
b.Property<double?>("Longitude")
|
||||
.HasColumnType("REAL")
|
||||
.HasColumnName("longitude");
|
||||
|
||||
@ -66,7 +66,7 @@ namespace Blahblah.FlowerStory.Server.Migrations
|
||||
|
||||
b.HasIndex("OwnerId");
|
||||
|
||||
b.ToTable("flowers", (string)null);
|
||||
b.ToTable("flowers");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Blahblah.FlowerStory.Server.Data.Model.PhotoItem", b =>
|
||||
@ -91,16 +91,20 @@ namespace Blahblah.FlowerStory.Server.Migrations
|
||||
.HasColumnType("TEXT")
|
||||
.HasColumnName("filetype");
|
||||
|
||||
b.Property<int>("FlowerId")
|
||||
b.Property<int?>("FlowerId")
|
||||
.HasColumnType("INTEGER")
|
||||
.HasColumnName("fid");
|
||||
|
||||
b.Property<int>("OwnerId")
|
||||
.HasColumnType("INTEGER")
|
||||
.HasColumnName("uid");
|
||||
|
||||
b.Property<string>("Path")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT")
|
||||
.HasColumnName("path");
|
||||
|
||||
b.Property<int>("RecordId")
|
||||
b.Property<int?>("RecordId")
|
||||
.HasColumnType("INTEGER")
|
||||
.HasColumnName("rid");
|
||||
|
||||
@ -108,9 +112,11 @@ namespace Blahblah.FlowerStory.Server.Migrations
|
||||
|
||||
b.HasIndex("FlowerId");
|
||||
|
||||
b.HasIndex("OwnerId");
|
||||
|
||||
b.HasIndex("RecordId");
|
||||
|
||||
b.ToTable("photos", (string)null);
|
||||
b.ToTable("photos");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Blahblah.FlowerStory.Server.Data.Model.RecordItem", b =>
|
||||
@ -163,7 +169,7 @@ namespace Blahblah.FlowerStory.Server.Migrations
|
||||
|
||||
b.HasIndex("OwnerId");
|
||||
|
||||
b.ToTable("records", (string)null);
|
||||
b.ToTable("records");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Blahblah.FlowerStory.Server.Data.Model.TokenItem", b =>
|
||||
@ -213,7 +219,7 @@ namespace Blahblah.FlowerStory.Server.Migrations
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("tokens", (string)null);
|
||||
b.ToTable("tokens");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Blahblah.FlowerStory.Server.Data.Model.UserItem", b =>
|
||||
@ -265,7 +271,7 @@ namespace Blahblah.FlowerStory.Server.Migrations
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("users", (string)null);
|
||||
b.ToTable("users");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Blahblah.FlowerStory.Server.Data.Model.FlowerItem", b =>
|
||||
@ -283,18 +289,22 @@ namespace Blahblah.FlowerStory.Server.Migrations
|
||||
{
|
||||
b.HasOne("Blahblah.FlowerStory.Server.Data.Model.FlowerItem", "Flower")
|
||||
.WithMany("Photos")
|
||||
.HasForeignKey("FlowerId")
|
||||
.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")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
.HasForeignKey("RecordId");
|
||||
|
||||
b.Navigation("Flower");
|
||||
|
||||
b.Navigation("Owner");
|
||||
|
||||
b.Navigation("Record");
|
||||
});
|
||||
|
||||
|
@ -11,7 +11,7 @@ public class Program
|
||||
/// <inheritdoc/>
|
||||
public const string ProjectName = "Flower Story";
|
||||
/// <inheritdoc/>
|
||||
public const string Version = "0.5.705";
|
||||
public const string Version = "0.6.713";
|
||||
|
||||
/// <inheritdoc/>
|
||||
public static void Main(string[] args)
|
||||
@ -29,7 +29,7 @@ public class Program
|
||||
|
||||
var scheme = new OpenApiSecurityScheme
|
||||
{
|
||||
Description = "授权头。 示例: \"RG//HkvcTZdBospBOT6OuoWfsc1GS+P/js9zFdflBr0=\"",
|
||||
Description = "授权头。 示例: \"RF4mfoUur0vHtWzHwD42ka0FhIfGaPnBxoQgrXOYEDg=\"",
|
||||
Reference = new OpenApiReference
|
||||
{
|
||||
Type = ReferenceType.SecurityScheme,
|
||||
|
Loading…
x
Reference in New Issue
Block a user