feat: Created a RESTFul API endpoint for MusicInfo.

This commit is contained in:
real-zony 2022-10-23 12:39:56 +08:00
parent d19b1d8d2a
commit 895f68184d
14 changed files with 157 additions and 116 deletions

View File

@ -16,11 +16,6 @@
<PackageReference Include="TagLibSharp" Version="2.3.0" /> <PackageReference Include="TagLibSharp" Version="2.3.0" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<Folder Include="Lyrics\Providers\Kugeci" />
<Folder Include="Lyrics\Providers\KuWo" />
</ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Remove="Lyrics\Providers\Kugeci\KugeciDownloader.cs" /> <Compile Remove="Lyrics\Providers\Kugeci\KugeciDownloader.cs" />
</ItemGroup> </ItemGroup>

View File

@ -0,0 +1,7 @@
namespace ZonyLrcTools.LocalServer.Contract.Dtos;
public class PagedListRequestDto
{
public int PageIndex { get; set; }
public int PageSize { get; set; }
}

View File

@ -0,0 +1,9 @@
namespace ZonyLrcTools.LocalServer.Contract.Dtos;
public class PagedListResultDto<T>
{
public int TotalCount { get; set; }
public int PageIndex { get; set; }
public int PageSize { get; set; }
public List<T> Items { get; set; } = new List<T>();
}

View File

@ -0,0 +1,24 @@
using Microsoft.AspNetCore.Mvc;
using ZonyLrcTools.Common.Infrastructure.DependencyInject;
using ZonyLrcTools.LocalServer.Contract.Dtos;
using ZonyLrcTools.LocalServer.Services.MusicInfo;
using ZonyLrcTools.LocalServer.Services.MusicInfo.Dtos;
namespace ZonyLrcTools.LocalServer.Controllers;
[Route("api/music-infos")]
public class MusicInfoController : Controller, IMusicInfoService, ITransientDependency
{
private readonly IMusicInfoService _musicInfoService;
public MusicInfoController(IMusicInfoService musicInfoService)
{
_musicInfoService = musicInfoService;
}
[HttpGet]
public Task<PagedListResultDto<MusicInfoListItemDto>> GetMusicInfoListAsync(MusicInfoListInput input)
{
return _musicInfoService.GetMusicInfoListAsync(input);
}
}

View File

@ -0,0 +1,15 @@
using SuperSocket.WebSocket.Server;
namespace ZonyLrcTools.LocalServer.EventBus;
public class SuperSocketListener
{
public async Task ListenAsync()
{
var host = WebSocketHostBuilder.Create()
.UseWebSocketMessageHandler(async (session, message) => { await session.SendAsync(message); })
.Build();
await host.StartAsync();
}
}

View File

@ -1,9 +1,17 @@
using System.Diagnostics; using System.Diagnostics;
using ZonyLrcTools.LocalServer; using System.Reflection;
using ZonyLrcTools.Common.Infrastructure.DependencyInject;
using ZonyLrcTools.LocalServer.EventBus;
#region Main Flow
var app = RegisterAndConfigureServices(); var app = RegisterAndConfigureServices();
await ListenServices(); await ListenServices();
#endregion
#region Configure Services
async Task ListenServices() async Task ListenServices()
{ {
await new SuperSocketListener().ListenAsync(); await new SuperSocketListener().ListenAsync();
@ -17,6 +25,7 @@ WebApplication? RegisterAndConfigureServices()
builder.Services.AddControllers(); builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer(); builder.Services.AddEndpointsApiExplorer();
builder.Services.BeginAutoDependencyInject<Program>();
var insideApp = builder.Build(); var insideApp = builder.Build();
insideApp.UseSpaStaticFiles(new StaticFileOptions insideApp.UseSpaStaticFiles(new StaticFileOptions
@ -24,13 +33,14 @@ WebApplication? RegisterAndConfigureServices()
RequestPath = "", RequestPath = "",
FileProvider = new Microsoft.Extensions.FileProviders FileProvider = new Microsoft.Extensions.FileProviders
.ManifestEmbeddedFileProvider( .ManifestEmbeddedFileProvider(
typeof(Program).Assembly, "UiStaticResources" Assembly.GetExecutingAssembly(), "UiStaticResources"
) )
}); });
insideApp.UseAuthorization();
insideApp.MapControllers(); insideApp.MapControllers();
// insideApp.Lifetime.ApplicationStarted.Register(OpenBrowser); #if !DEBUG
insideApp.Lifetime.ApplicationStarted.Register(OpenBrowser);
#endif
return insideApp; return insideApp;
} }
@ -52,3 +62,5 @@ void OpenBrowser()
Process.Start("xdg-open", url); Process.Start("xdg-open", url);
} }
} }
#endregion

View File

@ -0,0 +1,16 @@
using ZonyLrcTools.LocalServer.Contract.Dtos;
namespace ZonyLrcTools.LocalServer.Services.MusicInfo.Dtos;
public class MusicInfoListItemDto
{
public string Name { get; set; }
public int Size { get; set; }
public int Status { get; set; }
}
public class MusicInfoListInput : PagedListRequestDto
{
}

View File

@ -0,0 +1,9 @@
using ZonyLrcTools.LocalServer.Contract.Dtos;
using ZonyLrcTools.LocalServer.Services.MusicInfo.Dtos;
namespace ZonyLrcTools.LocalServer.Services.MusicInfo;
public interface IMusicInfoService
{
Task<PagedListResultDto<MusicInfoListItemDto>> GetMusicInfoListAsync(MusicInfoListInput input);
}

View File

@ -0,0 +1,38 @@
using ZonyLrcTools.Common.Infrastructure.DependencyInject;
using ZonyLrcTools.LocalServer.Contract.Dtos;
using ZonyLrcTools.LocalServer.Services.MusicInfo.Dtos;
namespace ZonyLrcTools.LocalServer.Services.MusicInfo;
public class MusicInfoService : ITransientDependency, IMusicInfoService
{
public async Task<PagedListResultDto<MusicInfoListItemDto>> GetMusicInfoListAsync(MusicInfoListInput input)
{
await Task.CompletedTask;
return new PagedListResultDto<MusicInfoListItemDto>
{
Items = new List<MusicInfoListItemDto>
{
new MusicInfoListItemDto
{
Name = "测试歌曲",
Size = 1024,
Status = 1
},
new MusicInfoListItemDto
{
Name = "测试歌曲2",
Size = 1024,
Status = 1
},
new MusicInfoListItemDto
{
Name = "测试歌曲3",
Size = 1024,
Status = 1
},
}
};
}
}

View File

@ -1,72 +0,0 @@
using Newtonsoft.Json;
using SuperSocket.WebSocket.Server;
namespace ZonyLrcTools.LocalServer;
public class SuperSocketListener
{
public async Task ListenAsync()
{
var host = WebSocketHostBuilder.Create()
.UseWebSocketMessageHandler(async (session, message) =>
{
await session.SendAsync(JsonConvert.SerializeObject(new CommunicateEvent<OutputEvent>
{
Action = "output",
Type = ActionType.ResponseAction,
Data = new OutputEvent()
}));
for (int index = 0; index < 50; index++)
{
var data = new List<GetFileInfoEvent>();
for (int j = 0; j < 500; j++)
{
data.Add(new GetFileInfoEvent
{
Name = j.ToString(),
Size = j.ToString()
});
}
await session.SendAsync(JsonConvert.SerializeObject(new CommunicateEvent<List<GetFileInfoEvent>>
{
Action = "getFileInfo",
Type = ActionType.ResponseAction,
Data = data
}));
}
await Task.Delay(100);
})
.Build();
await host.StartAsync();
}
}
public class CommunicateEvent<T> where T : class
{
[JsonProperty("action")] public string? Action { get; set; }
[JsonProperty("type")] public ActionType Type { get; set; }
[JsonProperty("data")] public T? Data { get; set; }
}
public class OutputEvent
{
[JsonProperty("text")] public string Text => DateTime.Now.ToString("HH:mm:ss");
}
public class GetFileInfoEvent
{
[JsonProperty("name")] public string Name { get; set; }
[JsonProperty("size")] public string Size { get; set; }
}
public enum ActionType
{
RequestAction,
ResponseAction
}

View File

@ -1,12 +0,0 @@
namespace ZonyLrcTools.LocalServer;
public class WeatherForecast
{
public DateTime Date { get; set; }
public int TemperatureC { get; set; }
public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
public string? Summary { get; set; }
}

View File

@ -8,6 +8,8 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="AutoMapper" Version="12.0.0" />
<PackageReference Include="AutoMapper.Extensions.Microsoft.DependencyInjection" Version="12.0.0" />
<PackageReference Include="Microsoft.AspNetCore.SpaServices.Extensions" Version="6.0.9" /> <PackageReference Include="Microsoft.AspNetCore.SpaServices.Extensions" Version="6.0.9" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="6.0.0" /> <PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="6.0.0" />
<PackageReference Include="Microsoft.Extensions.FileProviders.Embedded" Version="6.0.9" /> <PackageReference Include="Microsoft.Extensions.FileProviders.Embedded" Version="6.0.9" />
@ -21,7 +23,6 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Folder Include="Controllers" />
<EmbeddedResource Include="UiStaticResources\**" /> <EmbeddedResource Include="UiStaticResources\**" />
</ItemGroup> </ItemGroup>

View File

@ -1,6 +1,8 @@
import Vue from 'vue' import Vue from 'vue'
import VueRouter from 'vue-router' import VueRouter from 'vue-router'
import HomeView from '../views/HomeView.vue' import HomeView from '../views/HomeView.vue'
import AboutView from '../views/AboutView.vue'
import SettingView from "@/views/SettingView"
Vue.use(VueRouter) Vue.use(VueRouter)
@ -13,12 +15,12 @@ const routes = [
{ {
path: '/about', path: '/about',
name: 'about', name: 'about',
component: () => import( '../views/AboutView.vue') component: AboutView
}, },
{ {
path: '/setting', path: '/setting',
name: 'setting', name: 'setting',
component: () => import('../views/SettingView.vue') component: SettingView
} }
] ]

View File

@ -1,5 +1,7 @@
<template> <template>
<div class="container"> <div class="container">
<!-- Operation Buttons Group -->
<div class="button-group"> <div class="button-group">
<v-btn @click="openDir"> <v-btn @click="openDir">
扫描文件 扫描文件
@ -8,6 +10,7 @@
<v-btn class="ml-5" disabled>开始下载</v-btn> <v-btn class="ml-5" disabled>开始下载</v-btn>
</div> </div>
<div class="file-list mt-5"> <div class="file-list mt-5">
<v-data-table <v-data-table
:headers="headers" :headers="headers"
@ -20,6 +23,7 @@
<v-icon v-else>mdi-minus</v-icon> <v-icon v-else>mdi-minus</v-icon>
</template> </template>
</v-data-table> </v-data-table>
<div class="output mt-8"> <div class="output mt-8">
<v-textarea disabled outlined label="日志信息" :value='outputText'/> <v-textarea disabled outlined label="日志信息" :value='outputText'/>
</div> </div>
@ -46,14 +50,7 @@ export default {
{text: '状态', value: 'status'}, {text: '状态', value: 'status'},
{text: '操作', value: 'action'}, {text: '操作', value: 'action'},
], ],
items: [ items: [],
{
name: 'Frozen Yogurt',
size: 159,
status: 'success',
action: 4.0,
}
],
outputText: '' outputText: ''
} }
}, },
@ -70,17 +67,17 @@ export default {
// eventBus.$on('getFile', (msgData) => { // eventBus.$on('getFile', (msgData) => {
// console.log(msgData); // console.log(msgData);
// }); // });
eventBus.$on('getFileInfo', (msgData) => { // eventBus.$on('getFileInfo', (msgData) => {
this.items = [...this.items, ...msgData.data.map(item => { // this.items = [...this.items, ...msgData.data.map(item => {
return { // return {
name: item.name, // name: item.name,
size: item.size, // size: item.size,
status: 'success', // status: 'success',
action: 4.0, // action: 4.0,
} // }
})] // })]
}); // });
//
eventBus.$on('output', (msgData) => { eventBus.$on('output', (msgData) => {
this.outputText = this.outputText.concat(msgData.data.text).concat('\n'); this.outputText = this.outputText.concat(msgData.data.text).concat('\n');
}); });