mirror of
https://github.com/nsnail/NetAdmin.git
synced 2025-04-23 14:42:51 +08:00
refactor: ♻️ 文件上传功能调整
This commit is contained in:
parent
6fed7ec752
commit
e0a4a40314
@ -15,7 +15,7 @@
|
|||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="Microsoft.VisualStudio.Threading.Analyzers" Version="17.13.2">
|
<PackageReference Include="Microsoft.VisualStudio.Threading.Analyzers" Version="17.14.2-alpha">
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
{
|
{
|
||||||
"version": "2.3.1",
|
"version": "2.3.1",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"cz-git": "^1.11.0",
|
"cz-git": "^1.11.1",
|
||||||
"commitizen": "^4.3.1",
|
"commitizen": "^4.3.1",
|
||||||
"prettier": "^3.5.0",
|
"prettier": "^3.5.3",
|
||||||
"standard-version": "^9.5.0"
|
"standard-version": "^9.5.0"
|
||||||
},
|
},
|
||||||
"config": {
|
"config": {
|
||||||
|
@ -1 +1 @@
|
|||||||
Subproject commit 2f58f3291ae7a31bf935ed26d23fd587d181fb2b
|
Subproject commit b16b1a35559281a9f53d6914f1195a204c9b4185
|
@ -1 +1 @@
|
|||||||
Subproject commit f5509a75ffb26175f7024fb609579050f6f5250d
|
Subproject commit 15717df4499d284ec77c624a281c199a29280a4e
|
@ -1 +1 @@
|
|||||||
Subproject commit d4a92aca6f18b68875126f1974baa15fd2ab1fab
|
Subproject commit 322cbc32df1363755d4b0588923ee7324676c3b6
|
@ -1,4 +1,4 @@
|
|||||||
#r "nuget: NSExt, 2.3.3"
|
#r "nuget: NSExt, 2.3.4"
|
||||||
using NSExt.Extensions;
|
using NSExt.Extensions;
|
||||||
|
|
||||||
Console.WriteLine("请输入原始名称(NetAdmin):");
|
Console.WriteLine("请输入原始名称(NetAdmin):");
|
||||||
|
@ -0,0 +1,17 @@
|
|||||||
|
namespace NetAdmin.Domain.Dto.Sys.File;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 响应:文件上传
|
||||||
|
/// </summary>
|
||||||
|
public record UploadFileRsp : DataAbstraction
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 文件名
|
||||||
|
/// </summary>
|
||||||
|
public string FileName { get; init; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 可访问的url地址
|
||||||
|
/// </summary>
|
||||||
|
public string Url { get; init; }
|
||||||
|
}
|
@ -5,7 +5,7 @@ namespace NetAdmin.Domain.Dto.Sys.Job;
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public sealed record EditJobReq : CreateJobReq
|
public sealed record EditJobReq : CreateJobReq
|
||||||
{
|
{
|
||||||
/// <inheritdoc cref="System.Version" />
|
/// <inheritdoc cref="IFieldVersion.Version" />
|
||||||
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
|
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
|
||||||
public override long Version { get; init; }
|
public override long Version { get; init; }
|
||||||
}
|
}
|
@ -11,7 +11,7 @@ public sealed record SetAvatarReq : Sys_User
|
|||||||
[Url(ErrorMessageResourceType = typeof(Ln), ErrorMessageResourceName = nameof(Ln.网络地址不正确))]
|
[Url(ErrorMessageResourceType = typeof(Ln), ErrorMessageResourceName = nameof(Ln.网络地址不正确))]
|
||||||
public override string Avatar { get; init; }
|
public override string Avatar { get; init; }
|
||||||
|
|
||||||
/// <inheritdoc cref="System.Version" />
|
/// <inheritdoc cref="IFieldVersion.Version" />
|
||||||
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
|
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
|
||||||
public override long Version { get; init; }
|
public override long Version { get; init; }
|
||||||
}
|
}
|
@ -4,7 +4,7 @@
|
|||||||
<ProjectReference Include="../NetAdmin.Infrastructure/NetAdmin.Infrastructure.csproj"/>
|
<ProjectReference Include="../NetAdmin.Infrastructure/NetAdmin.Infrastructure.csproj"/>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="CronExpressionDescriptor" Version="2.38.0"/>
|
<PackageReference Include="CronExpressionDescriptor" Version="2.39.0"/>
|
||||||
<PackageReference Include="Cronos" Version="0.9.0"/>
|
<PackageReference Include="Cronos" Version="0.9.0"/>
|
||||||
<PackageReference Include="NetAdmin.CsvHelper" Version="1.0.0"/>
|
<PackageReference Include="NetAdmin.CsvHelper" Version="1.0.0"/>
|
||||||
<PackageReference Include="Yitter.IdGenerator" Version="1.0.14"/>
|
<PackageReference Include="Yitter.IdGenerator" Version="1.0.14"/>
|
||||||
|
@ -34,7 +34,6 @@ public sealed class ExampleController(IExampleCache cache) : ControllerBase<IExa
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 示例分组计数
|
/// 示例分组计数
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[NonAction]
|
|
||||||
public Task<IOrderedEnumerable<KeyValuePair<IImmutableDictionary<string, string>, int>>> CountByAsync(QueryReq<QueryExampleReq> req)
|
public Task<IOrderedEnumerable<KeyValuePair<IImmutableDictionary<string, string>, int>>> CountByAsync(QueryReq<QueryExampleReq> req)
|
||||||
{
|
{
|
||||||
return Cache.CountByAsync(req);
|
return Cache.CountByAsync(req);
|
||||||
|
@ -5,10 +5,10 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="NetAdmin.FreeSql.DbContext" Version="1.1.2" Label="refs"/>
|
<PackageReference Include="NetAdmin.FreeSql.DbContext" Version="1.1.2" Label="refs"/>
|
||||||
<PackageReference Include="NetAdmin.FreeSql.Provider.Sqlite" Version="1.1.2" Label="refs"/>
|
<PackageReference Include="NetAdmin.FreeSql.Provider.Sqlite" Version="1.1.2" Label="refs"/>
|
||||||
<PackageReference Include="Gurion" Version="1.2.11" Label="refs"/>
|
<PackageReference Include="Gurion" Version="1.2.12" Label="refs"/>
|
||||||
<PackageReference Include="Microsoft.Extensions.Caching.StackExchangeRedis" Version="9.0.2"/>
|
<PackageReference Include="Microsoft.Extensions.Caching.StackExchangeRedis" Version="9.0.2"/>
|
||||||
<PackageReference Include="Minio" Version="6.0.4"/>
|
<PackageReference Include="Minio" Version="6.0.4"/>
|
||||||
<PackageReference Include="NSExt" Version="2.3.3"/>
|
<PackageReference Include="NSExt" Version="2.3.4"/>
|
||||||
<PackageReference Include="SixLabors.ImageSharp.Drawing" Version="2.1.5"/>
|
<PackageReference Include="SixLabors.ImageSharp.Drawing" Version="2.1.5"/>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
@ -15,8 +15,8 @@ public sealed class MinioHelper(IOptions<UploadOptions> uploadOptions) : IScoped
|
|||||||
/// <param name="fileStream">文件流</param>
|
/// <param name="fileStream">文件流</param>
|
||||||
/// <param name="contentType">文件类型</param>
|
/// <param name="contentType">文件类型</param>
|
||||||
/// <param name="fileSize">文件大小</param>
|
/// <param name="fileSize">文件大小</param>
|
||||||
/// <returns>可访问的url地址</returns>
|
/// <returns>文件名,可访问的url地址</returns>
|
||||||
public async Task<string> UploadAsync(string objectName, Stream fileStream, string contentType, long fileSize)
|
public async Task<(string FileName, string Url)> UploadAsync(string objectName, Stream fileStream, string contentType, long fileSize)
|
||||||
{
|
{
|
||||||
using var minio = new MinioClient().WithEndpoint(uploadOptions.Value.Minio.ServerAddress)
|
using var minio = new MinioClient().WithEndpoint(uploadOptions.Value.Minio.ServerAddress)
|
||||||
.WithCredentials( //
|
.WithCredentials( //
|
||||||
@ -38,6 +38,6 @@ public sealed class MinioHelper(IOptions<UploadOptions> uploadOptions) : IScoped
|
|||||||
.WithContentType(contentType);
|
.WithContentType(contentType);
|
||||||
_ = await minio.PutObjectAsync(putArgs).ConfigureAwait(false);
|
_ = await minio.PutObjectAsync(putArgs).ConfigureAwait(false);
|
||||||
|
|
||||||
return $"{uploadOptions.Value.Minio.AccessUrl}/{uploadOptions.Value.Minio.BucketName}/{objectName}";
|
return (objectName, $"{uploadOptions.Value.Minio.AccessUrl}/{uploadOptions.Value.Minio.BucketName}/{objectName}");
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,3 +1,5 @@
|
|||||||
|
using NetAdmin.Domain.Dto.Sys.File;
|
||||||
|
|
||||||
namespace NetAdmin.SysComponent.Application.Modules.Sys;
|
namespace NetAdmin.SysComponent.Application.Modules.Sys;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -8,5 +10,5 @@ public interface IFileModule
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 文件上传
|
/// 文件上传
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Task<string> UploadAsync(IFormFile file);
|
Task<UploadFileRsp> UploadAsync(IFormFile file);
|
||||||
}
|
}
|
@ -1,3 +1,5 @@
|
|||||||
|
using NetAdmin.Domain.Dto.Sys.File;
|
||||||
|
|
||||||
namespace NetAdmin.SysComponent.Application.Services.Sys;
|
namespace NetAdmin.SysComponent.Application.Services.Sys;
|
||||||
|
|
||||||
/// <inheritdoc cref="IFileService" />
|
/// <inheritdoc cref="IFileService" />
|
||||||
@ -8,7 +10,7 @@ public sealed class FileService(IOptions<UploadOptions> uploadOptions, MinioHelp
|
|||||||
/// <exception cref="NetAdminInvalidOperationException">文件不能为空</exception>
|
/// <exception cref="NetAdminInvalidOperationException">文件不能为空</exception>
|
||||||
/// <exception cref="NetAdminInvalidOperationException">允许上传的文件格式</exception>
|
/// <exception cref="NetAdminInvalidOperationException">允许上传的文件格式</exception>
|
||||||
/// <exception cref="NetAdminInvalidOperationException">允许的文件大小</exception>
|
/// <exception cref="NetAdminInvalidOperationException">允许的文件大小</exception>
|
||||||
public async Task<string> UploadAsync(IFormFile file)
|
public async Task<UploadFileRsp> UploadAsync(IFormFile file)
|
||||||
{
|
{
|
||||||
if (file == null || file.Length < 1) {
|
if (file == null || file.Length < 1) {
|
||||||
throw new NetAdminInvalidOperationException(Ln.文件不能为空);
|
throw new NetAdminInvalidOperationException(Ln.文件不能为空);
|
||||||
@ -22,9 +24,9 @@ public sealed class FileService(IOptions<UploadOptions> uploadOptions, MinioHelp
|
|||||||
throw new NetAdminInvalidOperationException($"{Ln.允许的文件大小} {uploadOptions.Value.MaxSize}");
|
throw new NetAdminInvalidOperationException($"{Ln.允许的文件大小} {uploadOptions.Value.MaxSize}");
|
||||||
}
|
}
|
||||||
|
|
||||||
var fileName = $"{Guid.NewGuid()}{Path.GetExtension(file.FileName)}";
|
var objectName = $"{UserToken.Id}/{file.FileName}";
|
||||||
var objectName = $"{UserToken.Id}/{fileName}";
|
|
||||||
await using var fs = file.OpenReadStream();
|
await using var fs = file.OpenReadStream();
|
||||||
return await minioHelper.UploadAsync(objectName, fs, file.ContentType, file.Length).ConfigureAwait(false);
|
var (fileName, url) = await minioHelper.UploadAsync(objectName, fs, file.ContentType, file.Length).ConfigureAwait(false);
|
||||||
|
return new UploadFileRsp { FileName = fileName, Url = url };
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,3 +1,5 @@
|
|||||||
|
using NetAdmin.Domain.Dto.Sys.File;
|
||||||
|
|
||||||
namespace NetAdmin.SysComponent.Cache.Sys;
|
namespace NetAdmin.SysComponent.Cache.Sys;
|
||||||
|
|
||||||
/// <inheritdoc cref="IFileCache" />
|
/// <inheritdoc cref="IFileCache" />
|
||||||
@ -5,7 +7,7 @@ public sealed class FileCache(IDistributedCache cache, IFileService service) //
|
|||||||
: DistributedCache<IFileService>(cache, service), IScoped, IFileCache
|
: DistributedCache<IFileService>(cache, service), IScoped, IFileCache
|
||||||
{
|
{
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public Task<string> UploadAsync(IFormFile file)
|
public Task<UploadFileRsp> UploadAsync(IFormFile file)
|
||||||
{
|
{
|
||||||
return Service.UploadAsync(file);
|
return Service.UploadAsync(file);
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
using NetAdmin.Domain.Dto.Sys.File;
|
||||||
|
|
||||||
namespace NetAdmin.SysComponent.Host.Controllers.Sys;
|
namespace NetAdmin.SysComponent.Host.Controllers.Sys;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -10,7 +12,7 @@ public sealed class FileController(IFileCache cache) : ControllerBase<IFileCache
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 文件上传
|
/// 文件上传
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Task<string> UploadAsync(IFormFile file)
|
public Task<UploadFileRsp> UploadAsync(IFormFile file)
|
||||||
{
|
{
|
||||||
return Cache.UploadAsync(file);
|
return Cache.UploadAsync(file);
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
<ProjectReference Include="../NetAdmin.Host/NetAdmin.Host.csproj"/>
|
<ProjectReference Include="../NetAdmin.Host/NetAdmin.Host.csproj"/>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="9.0.2"/>
|
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="9.0.3"/>
|
||||||
<PackageReference Include="xunit" Version="2.9.3"/>
|
<PackageReference Include="xunit" Version="2.9.3"/>
|
||||||
<PackageReference Include="xunit.runner.visualstudio" Version="3.0.2">
|
<PackageReference Include="xunit.runner.visualstudio" Version="3.0.2">
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
using NetAdmin.Domain.Dto.Sys.File;
|
||||||
|
|
||||||
namespace UnitTests.Sys;
|
namespace UnitTests.Sys;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -11,7 +13,7 @@ public class FileTests(WebTestApplicationFactory<Startup> factory, ITestOutputHe
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
[InlineData(null)]
|
[InlineData(null)]
|
||||||
[Theory]
|
[Theory]
|
||||||
public async Task<string> UploadAsync(IFormFile file)
|
public async Task<UploadFileRsp> UploadAsync(IFormFile file)
|
||||||
{
|
{
|
||||||
var rsp = await PostJsonAsync(typeof(FileController), file);
|
var rsp = await PostJsonAsync(typeof(FileController), file);
|
||||||
Assert.True(rsp.IsSuccessStatusCode);
|
Assert.True(rsp.IsSuccessStatusCode);
|
||||||
|
@ -52,9 +52,9 @@ public abstract class WebApiTestBase<T>(WebTestApplicationFactory<T> factory, IT
|
|||||||
var req = new LoginByPwdReq //
|
var req = new LoginByPwdReq //
|
||||||
{
|
{
|
||||||
Password
|
Password
|
||||||
= Environment.GetEnvironmentVariable(nameof(WebTestApplicationFactory<T>.TEST_PASSWORD)) ??
|
= Environment.GetEnvironmentVariable(nameof(WebTestApplicationFactory<>.TEST_PASSWORD)) ??
|
||||||
WebTestApplicationFactory<T>.TEST_PASSWORD
|
WebTestApplicationFactory<T>.TEST_PASSWORD
|
||||||
, Account = Environment.GetEnvironmentVariable(nameof(WebTestApplicationFactory<T>.TEST_ACCOUNT)) ??
|
, Account = Environment.GetEnvironmentVariable(nameof(WebTestApplicationFactory<>.TEST_ACCOUNT)) ??
|
||||||
WebTestApplicationFactory<T>.TEST_ACCOUNT
|
WebTestApplicationFactory<T>.TEST_ACCOUNT
|
||||||
};
|
};
|
||||||
var loginAccount = JsonContent.Create(req);
|
var loginAccount = JsonContent.Create(req);
|
||||||
|
@ -10,12 +10,12 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@element-plus/icons-vue": "2.3.1",
|
"@element-plus/icons-vue": "2.3.1",
|
||||||
"ace-builds": "1.38.0",
|
"ace-builds": "1.39.0",
|
||||||
"aieditor": "1.3.5",
|
"aieditor": "1.3.5",
|
||||||
"axios": "1.7.9",
|
"axios": "1.8.1",
|
||||||
"crypto-js": "4.2.0",
|
"crypto-js": "4.2.0",
|
||||||
"echarts": "5.6.0",
|
"echarts": "5.6.0",
|
||||||
"element-plus": "2.9.4",
|
"element-plus": "2.9.5",
|
||||||
"json-bigint": "1.0.0",
|
"json-bigint": "1.0.0",
|
||||||
"markdown-it": "14.1.0",
|
"markdown-it": "14.1.0",
|
||||||
"markdown-it-emoji": "3.0.0",
|
"markdown-it-emoji": "3.0.0",
|
||||||
@ -23,7 +23,7 @@
|
|||||||
"sortablejs": "1.15.6",
|
"sortablejs": "1.15.6",
|
||||||
"vkbeautify": "0.99.3",
|
"vkbeautify": "0.99.3",
|
||||||
"vue": "3.5.13",
|
"vue": "3.5.13",
|
||||||
"vue-i18n": "11.1.1",
|
"vue-i18n": "11.1.2",
|
||||||
"vue-router": "4.5.0",
|
"vue-router": "4.5.0",
|
||||||
"vue3-ace-editor": "2.2.4",
|
"vue3-ace-editor": "2.2.4",
|
||||||
"vue3-json-viewer": "2.2.2",
|
"vue3-json-viewer": "2.2.2",
|
||||||
@ -32,11 +32,11 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@vitejs/plugin-vue": "5.2.1",
|
"@vitejs/plugin-vue": "5.2.1",
|
||||||
"prettier": "3.5.0",
|
"prettier": "3.5.3",
|
||||||
"prettier-plugin-organize-attributes": "1.0.0",
|
"prettier-plugin-organize-attributes": "1.0.0",
|
||||||
"sass": "1.84.0",
|
"sass": "1.85.1",
|
||||||
"terser": "5.38.2",
|
"terser": "5.39.0",
|
||||||
"vite": "6.1.0"
|
"vite": "6.2.1"
|
||||||
},
|
},
|
||||||
"browserslist": [
|
"browserslist": [
|
||||||
"> 1%",
|
"> 1%",
|
||||||
|
@ -27,6 +27,17 @@ export default {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 示例分组计数
|
||||||
|
*/
|
||||||
|
countBy: {
|
||||||
|
url: `${config.API_URL}/api/tpl/example/count.by`,
|
||||||
|
name: `示例分组计数`,
|
||||||
|
post: async function (data = {}, config = {}) {
|
||||||
|
return await http.post(this.url, data, config)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 创建示例
|
* 创建示例
|
||||||
*/
|
*/
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
:on-success="success"
|
:on-success="success"
|
||||||
:show-file-list="showFileList">
|
:show-file-list="showFileList">
|
||||||
<slot>
|
<slot>
|
||||||
<el-button :disabled="disabled" type="primary">Click to upload</el-button>
|
<el-button :disabled="disabled" type="primary">点击上传</el-button>
|
||||||
</slot>
|
</slot>
|
||||||
<template #tip>
|
<template #tip>
|
||||||
<div v-if="tip" class="el-upload__tip">{{ tip }}</div>
|
<div v-if="tip" class="el-upload__tip">{{ tip }}</div>
|
||||||
|
@ -134,8 +134,8 @@ export default {
|
|||||||
//默认值转换为数组
|
//默认值转换为数组
|
||||||
toArr(str) {
|
toArr(str) {
|
||||||
const _arr = []
|
const _arr = []
|
||||||
const arr = str.split(',')
|
const arr = str?.split(',')
|
||||||
arr.forEach((item) => {
|
arr?.forEach((item) => {
|
||||||
if (item) {
|
if (item) {
|
||||||
const urlArr = item.split('/')
|
const urlArr = item.split('/')
|
||||||
const fileName = urlArr[urlArr.length - 1]
|
const fileName = urlArr[urlArr.length - 1]
|
||||||
|
@ -10,8 +10,8 @@ export default {
|
|||||||
parseData: function (res) {
|
parseData: function (res) {
|
||||||
return {
|
return {
|
||||||
code: res.code, //分析状态字段结构
|
code: res.code, //分析状态字段结构
|
||||||
// fileName: null, //分析文件名称
|
fileName: res.data.fileName, //分析文件名称
|
||||||
src: res.data, //分析图片远程地址结构
|
src: res.data.url, //分析图片远程地址结构
|
||||||
msg: res.msg, //分析描述字段结构
|
msg: res.msg, //分析描述字段结构
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
Loading…
x
Reference in New Issue
Block a user