mirror of
https://github.com/real-zony/ZonyLrcToolsX.git
synced 2025-07-01 20:23:22 +00:00
feat: Created a RESTFul API endpoint for MusicInfo.
This commit is contained in:
parent
d19b1d8d2a
commit
895f68184d
@ -16,11 +16,6 @@
|
||||
<PackageReference Include="TagLibSharp" Version="2.3.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="Lyrics\Providers\Kugeci" />
|
||||
<Folder Include="Lyrics\Providers\KuWo" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Remove="Lyrics\Providers\Kugeci\KugeciDownloader.cs" />
|
||||
</ItemGroup>
|
||||
|
@ -0,0 +1,7 @@
|
||||
namespace ZonyLrcTools.LocalServer.Contract.Dtos;
|
||||
|
||||
public class PagedListRequestDto
|
||||
{
|
||||
public int PageIndex { get; set; }
|
||||
public int PageSize { get; set; }
|
||||
}
|
@ -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>();
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
15
src/ZonyLrcTools.LocalServer/EventBus/SuperSocketListener.cs
Normal file
15
src/ZonyLrcTools.LocalServer/EventBus/SuperSocketListener.cs
Normal 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();
|
||||
}
|
||||
}
|
@ -1,9 +1,17 @@
|
||||
using System.Diagnostics;
|
||||
using ZonyLrcTools.LocalServer;
|
||||
using System.Reflection;
|
||||
using ZonyLrcTools.Common.Infrastructure.DependencyInject;
|
||||
using ZonyLrcTools.LocalServer.EventBus;
|
||||
|
||||
#region Main Flow
|
||||
|
||||
var app = RegisterAndConfigureServices();
|
||||
await ListenServices();
|
||||
|
||||
#endregion
|
||||
|
||||
#region Configure Services
|
||||
|
||||
async Task ListenServices()
|
||||
{
|
||||
await new SuperSocketListener().ListenAsync();
|
||||
@ -17,6 +25,7 @@ WebApplication? RegisterAndConfigureServices()
|
||||
|
||||
builder.Services.AddControllers();
|
||||
builder.Services.AddEndpointsApiExplorer();
|
||||
builder.Services.BeginAutoDependencyInject<Program>();
|
||||
|
||||
var insideApp = builder.Build();
|
||||
insideApp.UseSpaStaticFiles(new StaticFileOptions
|
||||
@ -24,13 +33,14 @@ WebApplication? RegisterAndConfigureServices()
|
||||
RequestPath = "",
|
||||
FileProvider = new Microsoft.Extensions.FileProviders
|
||||
.ManifestEmbeddedFileProvider(
|
||||
typeof(Program).Assembly, "UiStaticResources"
|
||||
Assembly.GetExecutingAssembly(), "UiStaticResources"
|
||||
)
|
||||
});
|
||||
|
||||
insideApp.UseAuthorization();
|
||||
insideApp.MapControllers();
|
||||
// insideApp.Lifetime.ApplicationStarted.Register(OpenBrowser);
|
||||
#if !DEBUG
|
||||
insideApp.Lifetime.ApplicationStarted.Register(OpenBrowser);
|
||||
#endif
|
||||
|
||||
return insideApp;
|
||||
}
|
||||
@ -51,4 +61,6 @@ void OpenBrowser()
|
||||
{
|
||||
Process.Start("xdg-open", url);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
@ -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
|
||||
{
|
||||
}
|
@ -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);
|
||||
}
|
@ -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
|
||||
},
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
@ -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
|
||||
}
|
@ -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; }
|
||||
}
|
@ -8,6 +8,8 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<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.Extensions.DependencyInjection" Version="6.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.FileProviders.Embedded" Version="6.0.9" />
|
||||
@ -21,7 +23,6 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="Controllers" />
|
||||
<EmbeddedResource Include="UiStaticResources\**" />
|
||||
</ItemGroup>
|
||||
|
||||
|
@ -1,6 +1,8 @@
|
||||
import Vue from 'vue'
|
||||
import VueRouter from 'vue-router'
|
||||
import HomeView from '../views/HomeView.vue'
|
||||
import AboutView from '../views/AboutView.vue'
|
||||
import SettingView from "@/views/SettingView"
|
||||
|
||||
Vue.use(VueRouter)
|
||||
|
||||
@ -13,12 +15,12 @@ const routes = [
|
||||
{
|
||||
path: '/about',
|
||||
name: 'about',
|
||||
component: () => import( '../views/AboutView.vue')
|
||||
component: AboutView
|
||||
},
|
||||
{
|
||||
path: '/setting',
|
||||
name: 'setting',
|
||||
component: () => import('../views/SettingView.vue')
|
||||
component: SettingView
|
||||
}
|
||||
]
|
||||
|
||||
|
@ -1,5 +1,7 @@
|
||||
<template>
|
||||
<div class="container">
|
||||
|
||||
<!-- Operation Buttons Group -->
|
||||
<div class="button-group">
|
||||
<v-btn @click="openDir">
|
||||
扫描文件
|
||||
@ -8,6 +10,7 @@
|
||||
|
||||
<v-btn class="ml-5" disabled>开始下载</v-btn>
|
||||
</div>
|
||||
|
||||
<div class="file-list mt-5">
|
||||
<v-data-table
|
||||
:headers="headers"
|
||||
@ -20,6 +23,7 @@
|
||||
<v-icon v-else>mdi-minus</v-icon>
|
||||
</template>
|
||||
</v-data-table>
|
||||
|
||||
<div class="output mt-8">
|
||||
<v-textarea disabled outlined label="日志信息" :value='outputText'/>
|
||||
</div>
|
||||
@ -46,14 +50,7 @@ export default {
|
||||
{text: '状态', value: 'status'},
|
||||
{text: '操作', value: 'action'},
|
||||
],
|
||||
items: [
|
||||
{
|
||||
name: 'Frozen Yogurt',
|
||||
size: 159,
|
||||
status: 'success',
|
||||
action: 4.0,
|
||||
}
|
||||
],
|
||||
items: [],
|
||||
outputText: ''
|
||||
}
|
||||
},
|
||||
@ -70,17 +67,17 @@ export default {
|
||||
// eventBus.$on('getFile', (msgData) => {
|
||||
// console.log(msgData);
|
||||
// });
|
||||
eventBus.$on('getFileInfo', (msgData) => {
|
||||
this.items = [...this.items, ...msgData.data.map(item => {
|
||||
return {
|
||||
name: item.name,
|
||||
size: item.size,
|
||||
status: 'success',
|
||||
action: 4.0,
|
||||
}
|
||||
})]
|
||||
});
|
||||
|
||||
// eventBus.$on('getFileInfo', (msgData) => {
|
||||
// this.items = [...this.items, ...msgData.data.map(item => {
|
||||
// return {
|
||||
// name: item.name,
|
||||
// size: item.size,
|
||||
// status: 'success',
|
||||
// action: 4.0,
|
||||
// }
|
||||
// })]
|
||||
// });
|
||||
//
|
||||
eventBus.$on('output', (msgData) => {
|
||||
this.outputText = this.outputText.concat(msgData.data.text).concat('\n');
|
||||
});
|
||||
|
Loading…
x
Reference in New Issue
Block a user