diff --git a/src/Modules/SettleAccount/src/SettleAccount.Application.Contracts/Entities/WMSKanBan/IWMSVWKanBanAppService.cs b/src/Modules/SettleAccount/src/SettleAccount.Application.Contracts/Entities/WMSKanBan/IWMSVWKanBanAppService.cs index 1ef8185e..35b74168 100644 --- a/src/Modules/SettleAccount/src/SettleAccount.Application.Contracts/Entities/WMSKanBan/IWMSVWKanBanAppService.cs +++ b/src/Modules/SettleAccount/src/SettleAccount.Application.Contracts/Entities/WMSKanBan/IWMSVWKanBanAppService.cs @@ -21,7 +21,7 @@ namespace Win.Sfs.SettleAccount.Entities.WMSKanBan /// 上传的文件(前端已经限制只能上传一个附件) /// - Task WMSVWKanBanUploadExcelImport([FromForm] IFormFileCollection files, Guid branchId, string year, string period, string version, string customerCode); + // Task WMSVWKanBanUploadExcelImport([FromForm] IFormFileCollection files, Guid branchId, string year, string period, string version, string customerCode); diff --git a/src/Modules/SettleAccount/src/SettleAccount.Application.Contracts/Entities/WMSSparePart/IWMSSparePartAppService.cs b/src/Modules/SettleAccount/src/SettleAccount.Application.Contracts/Entities/WMSSparePart/IWMSSparePartAppService.cs index 6696223f..56ee2272 100644 --- a/src/Modules/SettleAccount/src/SettleAccount.Application.Contracts/Entities/WMSSparePart/IWMSSparePartAppService.cs +++ b/src/Modules/SettleAccount/src/SettleAccount.Application.Contracts/Entities/WMSSparePart/IWMSSparePartAppService.cs @@ -17,8 +17,8 @@ namespace Win.Sfs.SettleAccount.Entities.WMSSparePart /// 上传的文件(前端已经限制只能上传一个附件) /// - Task WMSSparePartUploadExcelImport([FromForm] IFormFileCollection files, Guid branchId, - string year, string period, string version, string customerCode); + //Task WMSSparePartUploadExcelImport([FromForm] IFormFileCollection files, Guid branchId, + // string year, string period, string version, string customerCode); /// /// 按ID获取唯一实体 diff --git a/src/Modules/SettleAccount/src/SettleAccount.Application/Entities/WMS-KanBan/WMSKanBanAppService.cs b/src/Modules/SettleAccount/src/SettleAccount.Application/Entities/WMS-KanBan/WMSKanBanAppService.cs new file mode 100644 index 00000000..07c1a9ee --- /dev/null +++ b/src/Modules/SettleAccount/src/SettleAccount.Application/Entities/WMS-KanBan/WMSKanBanAppService.cs @@ -0,0 +1,322 @@ +using Magicodes.ExporterAndImporter.Core; +using Magicodes.ExporterAndImporter.Csv; +using Magicodes.ExporterAndImporter.Excel; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Volo.Abp.Guids; +using Win.Sfs.BaseData.ImportExcelCommon; +using Win.Sfs.SettleAccount.Entities.WMSKanBan; +using Win.Sfs.Shared.Filter; +using Shouldly; +using Microsoft.AspNetCore.Mvc; +using Volo.Abp.Caching; +using Win.Abp.Snowflakes; +using Win.Sfs.SettleAccount.CommonManagers; +using Volo.Abp; +using Microsoft.AspNetCore.Http; +using Win.Sfs.SettleAccount.ExcelImporter; +using EFCore.BulkExtensions; +using Win.Sfs.SettleAccount.ExportReports; +using Volo.Abp.Domain.Repositories; +using Win.Sfs.SettleAccount.Constant; +using Microsoft.AspNetCore.Authorization; +using Volo.Abp.Application.Dtos; + +namespace Win.Sfs.SettleAccount.Entities.WMS_KanBan +{ + /// + /// 大众看板发货明细 + /// + //[Authorize(SettleAccountPermissions.SettleAccounts.Default)] + //[AllowAnonymous] + [Route("api/settleaccount/WMSVWKanBan")] + public class WMSKanBanAppService : SettleAccountApplicationBase, IWMSVWKanBanAppService + { + private readonly IGuidGenerator _guidGenerator; + + private readonly IExcelImportAppService _excelImportService; + + private readonly ISettleAccountBranchEfCoreRepository _versionRepository; + + private readonly ISettleAccountBranchEfCoreRepository _repository; + /// + /// 构建方法 + /// + /// 构建UID + /// 仓储接口 + /// 缓存 + public WMSKanBanAppService(IGuidGenerator guidGenerator, + ISettleAccountBranchEfCoreRepository versionRepository, + ISettleAccountBranchEfCoreRepository repository, + IDistributedCache cache, + IExcelImportAppService excelImportService, + ISnowflakeIdGenerator snowflakeIdGenerator, + ICommonManager commonManager + ) : base(cache, excelImportService, snowflakeIdGenerator, commonManager) + { + _versionRepository = versionRepository; + _guidGenerator = guidGenerator; + _excelImportService = excelImportService; + _repository = repository; + } + + + /// + /// 导入功能 + /// + /// 上传的文件(前端已经限制只能上传一个附件) + /// + [HttpPost] + [Route("ExcelImport")] + [DisableRequestSizeLimit] + //[Authorize(SettleAccountPermissions.SettleAccounts.Default)] + public async Task WMSVWKanBanUploadExcelImport([FromForm] IFormFileCollection files, Guid branchId, string year, string period, string version, string customerCode) + { + if (string.IsNullOrEmpty(version)) + { + throw new BusinessException("版本不能空,必须传入!"); + } + List listImport = new List(); + ExportImporter _exportImporter = new ExportImporter(); + var result = await _exportImporter.UploadExcelImport(files, _excelImportService); + var entityList = ObjectMapper.Map, List>(result); + //删除版本 + var _versionQuery = _versionRepository.Where(p => p.Version == version); + await _versionQuery.BatchDeleteAsync(); + //删除明细 + var _query = _repository.Where(p => p.Version == version); + await _query.BatchDeleteAsync(); + //插入数据前检验 + var checkList = new List(); + var _group = entityList.GroupBy(x => new { x.Kanban, x.MaterialCode, x.Version }).Select(p => new { Count = p.Count(), Kanban = p.Key.Kanban, MaterialCode = p.Key.MaterialCode }); + foreach (var itm in _group) + { + if (itm.Count > 1) + { + checkList.Add(new ErrorExportDto(version, customerCode, string.Empty, string.Empty, string.Empty, string.Empty, string.Format("导入的零件号{0},其看板条码号{1}有重复数据,请检查!", itm.MaterialCode, itm.Kanban), string.Empty)); + } + } + var _id = GuidGenerator.Create(); + var _bomList = new List(); + _bomList.Add(new WMSKanBanVersion(_id, branchId, year, period, version, customerCode)); + foreach (var itm in entityList) + { + itm.SetValue(GuidGenerator.Create(), branchId, year, period, version, _id); + } + if (checkList.Count > 0) + { + return await ExportErrorReportAsync(checkList); + } + await _repository.GetDbContext().BulkInsertAsync(entityList); + await _versionRepository.GetDbContext().BulkInsertAsync(_bomList); + return ApplicationConsts.SuccessStr; + } + + /// + /// 按ID获取唯一实体 + /// + /// + /// 返回实体全部属性 + /// + /// ID + /// 实体DTO + [HttpGet] + [Route("{id}")] + [Authorize(SettleAccountPermissions.SettleAccounts.Default)] + virtual public async Task GetAsync(Guid id) + { + var result = await GetFromCacheAsync(id); + var dto = ObjectMapper.Map(result); + return dto; + } + + + private async Task GetFromCacheAsync(Guid id) + { + var result = await _repository.GetAsync(id); + return result; + } + + + private async Task GetCountAsync(WMSVWKanBanRequestDto input) + { + return await _repository.GetCountByFilterAsync(input.BranchId, input.Filters); + } + + private async Task GetCountAsync(WMSVWKanBanVersionRequestDto input) + { + return await _versionRepository.GetCountByFilterAsync(input.BranchId, input.Filters); + } + + + /// + /// 导出文件 + /// + /// + /// + [HttpPost] + [Route("Export")] + //[Authorize(SettleAccountPermissions.SettleAccounts.Default)] + virtual public async Task ExportAsync(WMSVWKanBanRequestDto input) + { + + IExporter _csv = new CsvExporter(); + IExporter _excel = new ExcelExporter(); + + if (!string.IsNullOrEmpty(input.Version)) + { + input.Filters.Add(new FilterCondition() { Action = EnumFilterAction.Equal, Column = "Version", Logic = EnumFilterLogic.And, Value = input.Version }); + } + var entities = await _repository.GetListByFilterAsync(GuidGenerator.Create(), input.Filters, input.Sorting, int.MaxValue, + 0, true); + + var dtoDetails = ObjectMapper.Map, List>(entities); + + string _fileName = string.Empty; + //声明导出容器 + + byte[] result = null; + switch (input.FileType) + { + case 0: + _fileName = string.Format("大众看板发货明细_{0}.csv", input.UserId.ToString()); + result = await _csv.ExportAsByteArray(dtoDetails); + break; + case 1: + _fileName = string.Format("大众看板发货明细_{0}.xlsx", input.UserId.ToString()); + result = await _excel.ExportAsByteArray(dtoDetails); + break; + } + result.ShouldNotBeNull(); + + //保存导出文件到服务器存成二进制 + await _excelImportService.SaveBlobAsync( + new SaveExcelImportInputDto + { + Name = _fileName, + Content = result + } + ); + return _fileName; + } + + + /// + /// 根据筛选条件获取实体列表 + /// + /// + /// 请求条件包括:筛选条件列表,排序条件,数据数量,页码 + /// + /// 请求条件 + /// 实体DTO列表 + [HttpPost] + [Route("list")] + //[Authorize(SettleAccountPermissions.SettleAccounts.Default)] + virtual public async Task> GetListAsync(WMSVWKanBanRequestDto input) + { + + if (!string.IsNullOrEmpty(input.Version)) + { + input.Filters.Add(new FilterCondition() { Action = EnumFilterAction.Equal, Column = "Version", Logic = EnumFilterLogic.And, Value = input.Version }); + } + else + { + return new PagedResultDto(0, new List()); + } + var entities = await _repository.GetListByFilterAsync(GuidGenerator.Create(), input.Filters, input.Sorting, input.MaxResultCount, + input.SkipCount, true); + var totalCount = await GetCountAsync(input); + var dtos = ObjectMapper.Map, List>(entities); + return new PagedResultDto(totalCount, dtos); + } + + + /// + /// 获取实体总数 + /// + /// 实体总数 + [HttpGet] + [Route("count")] + [Authorize(SettleAccountPermissions.SettleAccounts.Default)] + virtual public async Task GetTotalCountAsync(Guid branchId) + { + return await _repository.GetCountAsync(branchId); + } + + /// + /// 获取全部实体列表 + /// + /// 实体DTO列表 + [HttpGet] + [Route("all")] + //[Authorize(SettleAccountPermissions.SettleAccounts.Default)] + virtual public async Task> GetAllAsync(Guid branchId) + { + var entities = await _repository.GetAllAsync(branchId, true); + + + var dtos = ObjectMapper.Map, List>(entities); + + + return new ListResultDto(dtos); + } + + + + /// + /// 删除实体 + /// + /// ID + /// + [HttpDelete] + [Route("{id}")] + /// [Authorize(SettleAccountPermissions.SettleAccounts.Delete)] + virtual public async Task DeleteAsync(Guid id) + { + await _repository.DeleteAsync(id); + } + + /// + /// 按IDs删除实体列表 + /// + /// IDs + /// 是否执行成功 + [HttpPost] + [Route("delete")] + // [Authorize(SettleAccountPermissions.SettleAccounts.Delete)] + virtual public async Task DeleteListAsync(List ids) + { + foreach (var id in ids) + { + var entity = await GetFromCacheAsync(id); + //await Cache.DeleteAsync(id.ToString()); + } + + return await _repository.DeleteListAsync(ids); + } + + + + /// + /// 版本列表查询 + /// + /// + /// + [HttpPost] + [Route("listversion")] + public async Task> GetVersionListAsync(WMSVWKanBanVersionRequestDto input) + { + var entities = await _versionRepository.GetListByFilterAsync(input.BranchId, input.Filters, input.Sorting, int.MaxValue, + input.SkipCount, true); + + var totalCount = await GetCountAsync(input); + var dtos = ObjectMapper.Map, List>(entities); + + return new PagedResultDto(totalCount, dtos); + } + + } +} diff --git a/src/Modules/SettleAccount/src/SettleAccount.Application/Entities/WMS-SparePart/WMSSparePartAppService.cs b/src/Modules/SettleAccount/src/SettleAccount.Application/Entities/WMS-SparePart/WMSSparePartAppService.cs new file mode 100644 index 00000000..59bd24f0 --- /dev/null +++ b/src/Modules/SettleAccount/src/SettleAccount.Application/Entities/WMS-SparePart/WMSSparePartAppService.cs @@ -0,0 +1,326 @@ +using EFCore.BulkExtensions; +using Magicodes.ExporterAndImporter.Core; +using Magicodes.ExporterAndImporter.Csv; +using Magicodes.ExporterAndImporter.Excel; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Volo.Abp; +using Volo.Abp.Application.Dtos; +using Volo.Abp.Caching; +using Volo.Abp.Domain.Repositories; +using Volo.Abp.Guids; +using Win.Abp.Snowflakes; +using Win.Sfs.BaseData.ImportExcelCommon; +using Win.Sfs.SettleAccount.CommonManagers; +using Win.Sfs.SettleAccount.Constant; +using Win.Sfs.SettleAccount.Entities.WMSSparePart; +using Win.Sfs.SettleAccount.ExcelImporter; +using Win.Sfs.SettleAccount.ExportReports; +using Win.Sfs.Shared.Filter; +using Shouldly; + + + + +namespace Win.Sfs.SettleAccount.Entities.WMS_SparePart +{ + /// + /// 大众备件服务 + /// + [Route("api/settleaccount/WMSSparePart")] + public class WMSSparePartAppService : SettleAccountApplicationBase, IWMSSparePartAppService + { + private readonly IGuidGenerator _guidGenerator; + + private readonly IExcelImportAppService _excelImportService; + + private readonly ISettleAccountBranchEfCoreRepository _versionRepository; + + private readonly ISettleAccountBranchEfCoreRepository _repository; + /// + /// 构建方法 + /// + /// 构建UID + /// 仓储接口 + /// 缓存 + public WMSSparePartAppService(IGuidGenerator guidGenerator, + ISettleAccountBranchEfCoreRepository versionRepository, + ISettleAccountBranchEfCoreRepository repository, + IDistributedCache cache, + IExcelImportAppService excelImportService, + ISnowflakeIdGenerator snowflakeIdGenerator, + ICommonManager commonManager + ) : base(cache, excelImportService, snowflakeIdGenerator, commonManager) + { + _versionRepository = versionRepository; + _guidGenerator = guidGenerator; + _excelImportService = excelImportService; + _repository = repository; + } + + + /// + /// 导入功能 + /// + /// 上传的文件(前端已经限制只能上传一个附件) + /// + [HttpPost] + [Route("ExcelImport")] + [DisableRequestSizeLimit] + //[Authorize(SettleAccountPermissions.SettleAccounts.Default)] + public async Task WMSSparePartUploadExcelImport([FromForm] IFormFileCollection files, Guid branchId, string year, string period, string version, string customerCode) + { + if (string.IsNullOrEmpty(version)) + { + throw new BusinessException("版本不能空,必须传入!"); + } + ExportImporter _exportImporter = new ExportImporter(); + var result = await _exportImporter.UploadExcelImport(files, _excelImportService); + var entityList = ObjectMapper.Map, List>(result); + //删除版本 + var _versionQuery = _versionRepository.Where(p => p.Version == version); + await _versionQuery.BatchDeleteAsync(); + //删除明细 + var _query = _repository.Where(p => p.Version == version); + await _query.BatchDeleteAsync(); + //插入数据前检验 + var checkList = new List(); + var _group = entityList.GroupBy(x => new { x.LineNumber, x.MaterialCode, x.Version }).Select(p => new { Count = p.Count(), LineNumber = p.Key.LineNumber, MaterialCode = p.Key.MaterialCode }); + foreach (var itm in _group) + { + if (string.IsNullOrEmpty(itm.MaterialCode)) + { + checkList.Add(new ErrorExportDto(version, customerCode, string.Empty, string.Empty, string.Empty, string.Empty, string.Format("导入的行号为{0}的物料代码为空,请检查!", itm.LineNumber), string.Empty)); + } + } + var _id = GuidGenerator.Create(); + var _bomList = new List(); + _bomList.Add(new WMSSparePartVersion(_id, branchId, year, period, version, customerCode)); + foreach (var itm in entityList) + { + itm.SetValue(GuidGenerator.Create(), branchId, year, period, version); + } + if (checkList.Count > 0) + { + return await ExportErrorReportAsync(checkList); + } + await _repository.GetDbContext().BulkInsertAsync(entityList); + await _versionRepository.GetDbContext().BulkInsertAsync(_bomList); + return ApplicationConsts.SuccessStr; + } + + /// + /// 按ID获取唯一实体 + /// + /// + /// 返回实体全部属性 + /// + /// ID + /// 实体DTO + [HttpGet] + [Route("{id}")] + //[Authorize(SettleAccountPermissions.SettleAccounts.Default)] + virtual public async Task GetAsync(Guid id) + { + var result = await GetFromCacheAsync(id); + var dto = ObjectMapper.Map(result); + return dto; + } + + + private async Task GetFromCacheAsync(Guid id) + { + var result = await _repository.GetAsync(id); + return result; + } + + + private async Task GetCountAsync(WMSSparePartRequestDto input) + { + return await _repository.GetCountByFilterAsync(input.BranchId, input.Filters); + } + + private async Task GetCountAsync(WMSSparePartVersionRequestDto input) + { + return await _versionRepository.GetCountByFilterAsync(input.BranchId, input.Filters); + } + + + /// + /// 导出文件 + /// + /// + /// + [HttpPost] + [Route("Export")] + //[Authorize(SettleAccountPermissions.SettleAccounts.Default)] + virtual public async Task ExportAsync(WMSSparePartRequestDto input) + { + if (string.IsNullOrEmpty(input.Version)) + { + throw new BusinessException("版本不能空,必须传入!"); + } + IExporter _csv = new CsvExporter(); + IExporter _excel = new ExcelExporter(); + if (!string.IsNullOrEmpty(input.Version)) + { + input.Filters.Add(new FilterCondition() { Action = EnumFilterAction.Equal, Column = "Version", Logic = EnumFilterLogic.And, Value = input.Version }); + } + var entities = await _repository.GetListByFilterAsync(input.BranchId, input.Filters, input.Sorting, int.MaxValue, + 0, true); + + var dtoDetails = ObjectMapper.Map, List>(entities); + + string _fileName = string.Empty; + //声明导出容器 + + byte[] result = null; + switch (input.FileType) + { + case 0: + _fileName = string.Format("大众备件发货明细_{0}.csv", input.UserId.ToString()); + result = await _csv.ExportAsByteArray(dtoDetails); + break; + case 1: + _fileName = string.Format("大众备件发货明细_{0}.xlsx", input.UserId.ToString()); + result = await _excel.ExportAsByteArray(dtoDetails); + break; + } + result.ShouldNotBeNull(); + + //保存导出文件到服务器存成二进制 + await _excelImportService.SaveBlobAsync( + new SaveExcelImportInputDto + { + Name = _fileName, + Content = result + } + ); + return _fileName; + } + + + /// + /// 根据筛选条件获取实体列表 + /// + /// + /// 请求条件包括:筛选条件列表,排序条件,数据数量,页码 + /// + /// 请求条件 + /// 实体DTO列表 + [HttpPost] + [Route("list")] + //[Authorize(SettleAccountPermissions.SettleAccounts.Default)] + virtual public async Task> GetListAsync(WMSSparePartRequestDto input) + { + if (!string.IsNullOrEmpty(input.Version)) + { + input.Filters.Add(new FilterCondition() { Action = EnumFilterAction.Equal, Column = "Version", Logic = EnumFilterLogic.And, Value = input.Version }); + } + else + { + return new PagedResultDto(0, new List()); + } + + var entities = await _repository.GetListByFilterAsync(input.BranchId, input.Filters, input.Sorting, input.MaxResultCount, + input.SkipCount, true); + + var totalCount = await GetCountAsync(input); + var dtos = ObjectMapper.Map, List>(entities); + + return new PagedResultDto(totalCount, dtos); + } + + + /// + /// 获取实体总数 + /// + /// 实体总数 + [HttpGet] + [Route("count")] + [Authorize(SettleAccountPermissions.SettleAccounts.Default)] + virtual public async Task GetTotalCountAsync(Guid branchId) + { + return await _repository.GetCountAsync(branchId); + } + + /// + /// 获取全部实体列表 + /// + /// 实体DTO列表 + [HttpGet] + [Route("all")] + //[Authorize(SettleAccountPermissions.SettleAccounts.Default)] + virtual public async Task> GetAllAsync(Guid branchId) + { + var entities = await _repository.GetAllAsync(branchId, true); + + + var dtos = ObjectMapper.Map, List>(entities); + + + return new ListResultDto(dtos); + } + + + + /// + /// 删除实体 + /// + /// ID + /// + [HttpDelete] + [Route("{id}")] + /// [Authorize(SettleAccountPermissions.SettleAccounts.Delete)] + virtual public async Task DeleteAsync(Guid id) + { + await _repository.DeleteAsync(id); + } + + /// + /// 按IDs删除实体列表 + /// + /// IDs + /// 是否执行成功 + [HttpPost] + [Route("delete")] + // [Authorize(SettleAccountPermissions.SettleAccounts.Delete)] + virtual public async Task DeleteListAsync(List ids) + { + foreach (var id in ids) + { + var entity = await GetFromCacheAsync(id); + //await Cache.DeleteAsync(id.ToString()); + } + + return await _repository.DeleteListAsync(ids); + } + + + + /// + /// 版本列表查询 + /// + /// + /// + [HttpPost] + [Route("listversion")] + public async Task> GetVersionListAsync(WMSSparePartVersionRequestDto input) + { + var entities = await _versionRepository.GetListByFilterAsync(input.BranchId, input.Filters, input.Sorting, int.MaxValue, + input.SkipCount, true); + + var totalCount = await GetCountAsync(input); + var dtos = ObjectMapper.Map, List>(entities); + + return new PagedResultDto(totalCount, dtos); + } + + } +} diff --git a/src/Modules/SettleAccount/src/SettleAccount.Application/SettleAccount.Application.xml b/src/Modules/SettleAccount/src/SettleAccount.Application/SettleAccount.Application.xml index 17a52d32..929d29bb 100644 --- a/src/Modules/SettleAccount/src/SettleAccount.Application/SettleAccount.Application.xml +++ b/src/Modules/SettleAccount/src/SettleAccount.Application/SettleAccount.Application.xml @@ -1739,6 +1739,166 @@ + + + 大众看板发货明细 + + + + + 构建方法 + + 构建UID + 仓储接口 + 缓存 + + + + 导入功能 + + 上传的文件(前端已经限制只能上传一个附件) + + + + + 按ID获取唯一实体 + + + 返回实体全部属性 + + ID + 实体DTO + + + + 导出文件 + + + + + + + 根据筛选条件获取实体列表 + + + 请求条件包括:筛选条件列表,排序条件,数据数量,页码 + + 请求条件 + 实体DTO列表 + + + + 获取实体总数 + + 实体总数 + + + + 获取全部实体列表 + + 实体DTO列表 + + + + 删除实体 + + ID + + + + + 按IDs删除实体列表 + + IDs + 是否执行成功 + + + + 版本列表查询 + + + + + + + 大众备件服务 + + + + + 构建方法 + + 构建UID + 仓储接口 + 缓存 + + + + 导入功能 + + 上传的文件(前端已经限制只能上传一个附件) + + + + + 按ID获取唯一实体 + + + 返回实体全部属性 + + ID + 实体DTO + + + + 导出文件 + + + + + + + 根据筛选条件获取实体列表 + + + 请求条件包括:筛选条件列表,排序条件,数据数量,页码 + + 请求条件 + 实体DTO列表 + + + + 获取实体总数 + + 实体总数 + + + + 获取全部实体列表 + + 实体DTO列表 + + + + 删除实体 + + ID + + + + + 按IDs删除实体列表 + + IDs + 是否执行成功 + + + + 版本列表查询 + + + + 区域相关应用服务