diff --git a/ZR.Admin.WebApi/Controllers/CommonController.cs b/ZR.Admin.WebApi/Controllers/CommonController.cs index 678b629..7295ea0 100644 --- a/ZR.Admin.WebApi/Controllers/CommonController.cs +++ b/ZR.Admin.WebApi/Controllers/CommonController.cs @@ -7,9 +7,11 @@ using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Options; using Newtonsoft.Json; +using Snowflake.Core; using System; using System.IO; using System.Linq; +using System.Threading.Tasks; using ZR.Admin.WebApi.Extensions; using ZR.Admin.WebApi.Filters; using ZR.Common; @@ -158,25 +160,29 @@ namespace ZR.Admin.WebApi.Controllers [HttpPost] [Verify] [ActionPermissionFilter(Permission = "common")] - public IActionResult UploadFileAliyun([FromForm(Name = "file")] IFormFile formFile, string fileName = "", string fileDir = "") + public async Task UploadFileAliyun([FromForm(Name = "file")] IFormFile formFile, string fileName = "", string fileDir = "") { + if (fileDir.IsEmpty()) fileDir = "uploads"; if (formFile == null) throw new CustomException(ResultCode.PARAM_ERROR, "上传文件不能为空"); - string fileExt = Path.GetExtension(formFile.FileName); - string[] AllowedFileExtensions = new string[] { ".jpg", ".gif", ".png", ".jpeg", ".webp", ".svga", ".xls", ".doc", ".zip", ".json", ".txt", ".bundle" }; - int MaxContentLength = 1024 * 1024 * 15; - double fileSize = formFile.Length / 1024; - if (!AllowedFileExtensions.Contains(fileExt)) + string fileExt = Path.GetExtension(formFile.FileName);//文件后缀 + double fileSize = formFile.Length / 1024.0;//文件大小KB + string[] NotAllowedFileExtensions = new string[] { ".bat", ".exe", ".jar", ".js" }; + int MaxContentLength = 15; + if (NotAllowedFileExtensions.Contains(fileExt)) { return ToResponse(ResultCode.CUSTOM_ERROR, "上传失败,未经允许上传类型"); } - - if (formFile.Length > MaxContentLength) + if ((fileSize / 1024) > MaxContentLength) { - return ToResponse(ResultCode.CUSTOM_ERROR, "上传文件过大,不能超过 " + (MaxContentLength / 1024).ToString() + " MB"); + return ToResponse(ResultCode.CUSTOM_ERROR, "上传文件过大,不能超过 " + MaxContentLength + " MB"); } - (bool, string, string) result = SysFileService.SaveFile(fileDir, formFile, fileName); - long fileId = SysFileService.InsertFile(new SysFile() + (bool, string, string) result = new(); + await Task.Run(() => + { + result = SysFileService.SaveFile(fileDir, formFile, fileName, ""); + }); + long id = SysFileService.InsertFile(new SysFile() { AccessUrl = result.Item2, Create_by = HttpContext.GetName(), @@ -193,7 +199,7 @@ namespace ZR.Admin.WebApi.Controllers { url = result.Item2, fileName = result.Item3, - fileId + fileId = id }); } #endregion diff --git a/ZR.Admin.WebApi/Controllers/System/SysFileController.cs b/ZR.Admin.WebApi/Controllers/System/SysFileController.cs index 2044973..8900235 100644 --- a/ZR.Admin.WebApi/Controllers/System/SysFileController.cs +++ b/ZR.Admin.WebApi/Controllers/System/SysFileController.cs @@ -46,7 +46,7 @@ namespace ZR.Admin.WebApi.Controllers predicate = predicate.AndIF(parm.FileId != null, m => m.Id == parm.FileId); //搜索条件查询语法参考Sqlsugar - var response = _SysFileService.GetPages(predicate.ToExpression(), parm); + var response = _SysFileService.GetPages(predicate.ToExpression(), parm, x => x.Id, OrderByType.Desc); return SUCCESS(response); } @@ -57,74 +57,13 @@ namespace ZR.Admin.WebApi.Controllers /// [HttpGet("{Id}")] [ActionPermissionFilter(Permission = "tool:file:query")] - public IActionResult GetSysFile(int Id) + public IActionResult GetSysFile(long Id) { var response = _SysFileService.GetFirst(x => x.Id == Id); return SUCCESS(response); } - ///// - ///// 添加文件存储 - ///// - ///// - //[HttpPost] - //[ActionPermissionFilter(Permission = "tool:file:add")] - //[Log(Title = "文件存储", BusinessType = BusinessType.INSERT)] - //public IActionResult AddSysFile([FromBody] SysFileDto parm) - //{ - // if (parm == null) - // { - // throw new CustomException("请求参数错误"); - // } - // //从 Dto 映射到 实体 - // var model = parm.Adapt().ToCreate(HttpContext); - - // var response = _SysFileService.Insert(model, it => new - // { - // it.FileName, - // it.FileUrl, - // it.StorePath, - // it.FileSize, - // it.FileExt, - // it.Create_by, - // it.Create_time, - // it.StoreType, - // it.AccessUrl, - // }); - // return ToResponse(response); - //} - - ///// - ///// 更新文件存储 - ///// - ///// - //[HttpPut] - //[ActionPermissionFilter(Permission = "tool:file:update")] - //[Log(Title = "文件存储", BusinessType = BusinessType.UPDATE)] - //public IActionResult UpdateSysFile([FromBody] SysFileDto parm) - //{ - // if (parm == null) - // { - // throw new CustomException("请求实体不能为空"); - // } - // //从 Dto 映射到 实体 - // var model = parm.Adapt().ToUpdate(HttpContext); - - // var response = _SysFileService.Update(w => w.Id == model.Id, it => new SysFile() - // { - // //Update 字段映射 - // FileUrl = model.FileUrl, - // StorePath = model.StorePath, - // FileSize = model.FileSize, - // FileExt = model.FileExt, - // StoreType = model.StoreType, - // AccessUrl = model.AccessUrl, - // }); - - // return ToResponse(response); - //} - /// /// 删除文件存储 /// @@ -134,7 +73,7 @@ namespace ZR.Admin.WebApi.Controllers [Log(Title = "文件存储", BusinessType = BusinessType.DELETE)] public IActionResult DeleteSysFile(string ids) { - int[] idsArr = Tools.SpitIntArrary(ids); + long[] idsArr = Tools.SpitLongArrary(ids); if (idsArr.Length <= 0) { return ToResponse(ApiResult.Error($"删除失败Id 不能为空")); } var response = _SysFileService.Delete(idsArr); diff --git a/ZR.Common/AliyunOssHelper.cs b/ZR.Common/AliyunOssHelper.cs index 55108ef..4c9bf97 100644 --- a/ZR.Common/AliyunOssHelper.cs +++ b/ZR.Common/AliyunOssHelper.cs @@ -21,7 +21,7 @@ namespace ZR.Common /// 存储桶 如果为空默认取配置文件 public static System.Net.HttpStatusCode PutObjectFromFile(Stream filestreams, string dirPath, string bucketName = "") { - OssClient client = new OssClient(endpoint, accessKeyId, accessKeySecret); + OssClient client = new(endpoint, accessKeyId, accessKeySecret); if (string.IsNullOrEmpty(bucketName)) { bucketName = bucketName1; } try { diff --git a/ZR.Model/System/Dto/SysFileQueryDto.cs b/ZR.Model/System/Dto/SysFileQueryDto.cs index c86b135..fc860f8 100644 --- a/ZR.Model/System/Dto/SysFileQueryDto.cs +++ b/ZR.Model/System/Dto/SysFileQueryDto.cs @@ -9,7 +9,7 @@ namespace ZR.Model.System.Dto /// public class SysFileDto { - public int Id { get; set; } + public long Id { get; set; } public string FileName { get; set; } public string FileUrl { get; set; } public string StorePath { get; set; } @@ -25,6 +25,6 @@ namespace ZR.Model.System.Dto public DateTime? BeginCreate_time { get; set; } public DateTime? EndCreate_time { get; set; } public int? StoreType { get; set; } - public int? FileId { get; set; } + public long? FileId { get; set; } } } diff --git a/ZR.Model/System/SysFile.cs b/ZR.Model/System/SysFile.cs index 56f3e5c..f229cab 100644 --- a/ZR.Model/System/SysFile.cs +++ b/ZR.Model/System/SysFile.cs @@ -1,4 +1,5 @@ -using SqlSugar; +using Newtonsoft.Json; +using SqlSugar; using System; using System.Collections.Generic; using System.Text; @@ -13,7 +14,8 @@ namespace ZR.Model.System /// 描述 : 自增id /// 空值 : false /// - [SugarColumn(IsPrimaryKey = true, IsIdentity = true)] + [JsonConverter(typeof(ValueToStringConverter))] + [SugarColumn(IsPrimaryKey = true)] public long Id { get; set; } /// /// 文件真实名 diff --git a/ZR.Service/System/IService/ISysFileService.cs b/ZR.Service/System/IService/ISysFileService.cs index 6b8c319..62b4f6e 100644 --- a/ZR.Service/System/IService/ISysFileService.cs +++ b/ZR.Service/System/IService/ISysFileService.cs @@ -16,7 +16,7 @@ namespace ZR.Service.System.IService /// /// 结果、地址、文件名 (bool, string, string) SaveFile(string picdir, IFormFile formFile); - (bool, string, string) SaveFile(string picdir, IFormFile formFile, string customFileName); + (bool, string, string) SaveFile(string picdir, IFormFile formFile, string customFileName, string bucketName); /// /// 按时间来创建文件夹 /// diff --git a/ZR.Service/System/SysFileService.cs b/ZR.Service/System/SysFileService.cs index eeff8f6..dd89c2f 100644 --- a/ZR.Service/System/SysFileService.cs +++ b/ZR.Service/System/SysFileService.cs @@ -11,6 +11,7 @@ using System.Net; using ZR.Model.System; using ZR.Repository.System; using Infrastructure.Extensions; +using SqlSugar.DistributedSystem.Snowflake; namespace ZR.Service.System { @@ -36,18 +37,28 @@ namespace ZR.Service.System /// public (bool, string, string) SaveFile(string picdir, IFormFile formFile) { - return SaveFile(picdir, formFile, ""); + return SaveFile(picdir, formFile, "", ""); } - public (bool, string, string) SaveFile(string picdir, IFormFile formFile, string customFileName) + + /// + /// 存储文件 + /// + /// 文件夹 + /// + /// 自定义文件名 + /// 存储桶 + /// + public (bool, string, string) SaveFile(string picdir, IFormFile formFile, string customFileName, string bucketName) { // eg: uploads/2020/08/18 - string dir = GetdirPath(picdir.ToString()); + //string dir = GetdirPath(picdir.ToString()); + string tempName = customFileName.IsEmpty() ? HashFileName() : customFileName; string fileExt = Path.GetExtension(formFile.FileName); - string fileName = $"{tempName}{fileExt}"; - string webUrl = $"{domainUrl}/{dir}/{fileName}"; + string fileName = tempName + fileExt; + string webUrl = string.Concat(domainUrl, "/", picdir, "/", fileName); - HttpStatusCode statusCode = AliyunOssHelper.PutObjectFromFile(formFile.OpenReadStream(), Path.Combine(dir, fileName)); + HttpStatusCode statusCode = AliyunOssHelper.PutObjectFromFile(formFile.OpenReadStream(), Path.Combine(picdir, fileName), bucketName); return (statusCode == HttpStatusCode.OK, webUrl, fileName); } @@ -81,13 +92,13 @@ namespace ZR.Service.System { try { - return InsertReturnBigIdentity(file); + return Insertable(file).ExecuteReturnSnowflakeId();//单条插入返回雪花ID; } catch (Exception ex) { Console.WriteLine("存储图片失败" + ex.Message); + throw new Exception(ex.Message); } - return 1; } } } diff --git a/ZR.Vue/src/components/FileUpload/index.vue b/ZR.Vue/src/components/FileUpload/index.vue index 80129f2..6523b74 100644 --- a/ZR.Vue/src/components/FileUpload/index.vue +++ b/ZR.Vue/src/components/FileUpload/index.vue @@ -1,9 +1,12 @@ \ No newline at end of file diff --git a/ZR.Vue/src/store/modules/socket.js b/ZR.Vue/src/store/modules/socket.js index a7c68f2..5d9935b 100644 --- a/ZR.Vue/src/store/modules/socket.js +++ b/ZR.Vue/src/store/modules/socket.js @@ -16,7 +16,7 @@ const actions = { changeOnlineNum({ commit }, data) { commit('SET_ONLINEUSER_NUM', data) }, - // 更新系统通知 + // 更新系统通知 getNoticeList({ commit }, data) { commit('SET_NOTICE_list', data) } diff --git a/ZR.Vue/src/utils/signalR.js b/ZR.Vue/src/utils/signalR.js index 13631e9..d666321 100644 --- a/ZR.Vue/src/utils/signalR.js +++ b/ZR.Vue/src/utils/signalR.js @@ -13,31 +13,38 @@ export default { init(url) { const connection = new signalR.HubConnectionBuilder() .withUrl(url, { accessTokenFactory: () => getToken() }) + .withAutomaticReconnect()//自动重新连接 + .configureLogging(signalR.LogLevel.Information) .build(); this.SR = connection; // 断线重连 connection.onclose(async () => { console.log('断开连接了') + console.assert(connection.state === signalR.HubConnectionState.Disconnected); + // 建议用户重新刷新浏览器 await this.start(); }) connection.onreconnected(() => { - console.log('断线重连') + console.log('断线重新连接成功') }) this.receiveMsg(connection); // 启动 // this.start(); }, + /** + * 调用 this.signalR.start().then(async () => { await this.SR.invoke("method")}) + * @returns + */ async start() { var that = this; try { //使用async和await 或 promise的then 和catch 处理来自服务端的异常 - await this.SR.start(); - //console.assert(this.SR.state === signalR.HubConnectionState.Connected); console.log('signalR 连接成功了', this.SR.state); + return true; } catch (error) { that.failNum--; console.log(`失败重试剩余次数${that.failNum}`, error) @@ -46,6 +53,7 @@ export default { await this.SR.start() }, 5000); } + return false; } }, // 接收消息处理 diff --git a/ZR.Vue/src/views/tool/build/index.vue b/ZR.Vue/src/views/tool/build/index.vue index 92291e9..c5a6d69 100644 --- a/ZR.Vue/src/views/tool/build/index.vue +++ b/ZR.Vue/src/views/tool/build/index.vue @@ -11,19 +11,9 @@
输入型组件
- -
+ +
{{ element.label }} @@ -33,21 +23,9 @@
选择型组件
- -
+ +
{{ element.label }} @@ -57,15 +35,9 @@
布局型组件
- -
+ +
{{ element.label }} @@ -90,25 +62,12 @@
- + - +
从左侧拖入或点选组件进行表单设计 @@ -118,19 +77,9 @@
- + - +
@@ -149,10 +98,16 @@ import { formConf } from '@/utils/generator/config' import { - exportDefault, beautifierConf, isNumberStr, titleCase + exportDefault, + beautifierConf, + isNumberStr, + titleCase } from '@/utils/index' import { - makeUpHtml, vueTemplate, vueScript, cssStyle + makeUpHtml, + vueTemplate, + vueScript, + cssStyle } from '@/utils/generator/html' import { makeUpJs } from '@/utils/generator/js' import { makeUpCss } from '@/utils/generator/css' @@ -161,7 +116,7 @@ import logo from '@/assets/logo/logo.png' import CodeTypeDialog from './CodeTypeDialog' import DraggableItem from './DraggableItem' -const emptyActiveData = { style: {}, autosize: {} } +const emptyActiveData = { style: {}, autosize: {}} let oldActiveId let tempActiveData @@ -193,19 +148,19 @@ export default { activeData: drawingDefalut[0] } }, - computed: { - }, + computed: {}, watch: { // eslint-disable-next-line func-names - 'activeData.label': function (val, oldVal) { + 'activeData.label': function(val, oldVal) { if ( - this.activeData.placeholder === undefined - || !this.activeData.tag - || oldActiveId !== this.activeId + this.activeData.placeholder === undefined || + !this.activeData.tag || + oldActiveId !== this.activeId ) { return } - this.activeData.placeholder = this.activeData.placeholder.replace(oldVal, '') + val + this.activeData.placeholder = + this.activeData.placeholder.replace(oldVal, '') + val }, activeId: { handler(val) { @@ -216,7 +171,7 @@ export default { }, mounted() { const clipboard = new ClipboardJS('#copyNode', { - text: trigger => { + text: (trigger) => { const codeStr = this.generateCode() this.$notify({ title: '成功', @@ -226,7 +181,7 @@ export default { return codeStr } }) - clipboard.on('error', e => { + clipboard.on('error', (e) => { this.$message.error('代码复制失败') }) }, @@ -309,7 +264,9 @@ export default { item.componentName = `row${this.idGlobal}` } if (Array.isArray(item.children)) { - item.children = item.children.map(childItem => this.createIdAndKey(childItem)) + item.children = item.children.map((childItem) => + this.createIdAndKey(childItem) + ) } return item }, @@ -353,9 +310,11 @@ export default { delete this.activeData.tag delete this.activeData.tagIcon delete this.activeData.document - Object.keys(newTag).forEach(key => { - if (this.activeData[key] !== undefined - && typeof this.activeData[key] === typeof newTag[key]) { + Object.keys(newTag).forEach((key) => { + if ( + this.activeData[key] !== undefined && + typeof this.activeData[key] === typeof newTag[key] + ) { newTag[key] = this.activeData[key] } }) @@ -363,12 +322,12 @@ export default { this.updateDrawingList(newTag, this.drawingList) }, updateDrawingList(newTag, list) { - const index = list.findIndex(item => item.formId === this.activeId) + const index = list.findIndex((item) => item.formId === this.activeId) if (index > -1) { list.splice(index, 1, newTag) } else { - list.forEach(item => { - if (Array.isArray(item.children)) this.updateDrawingList(newTag, item.children) + list.forEach((item) => { + if (Array.isArray(item.children)) { this.updateDrawingList(newTag, item.children) } }) } } @@ -377,30 +336,34 @@ export default { diff --git a/ZR.Vue/src/views/tool/file/index.vue b/ZR.Vue/src/views/tool/file/index.vue index e23fd17..0cc75e0 100644 --- a/ZR.Vue/src/views/tool/file/index.vue +++ b/ZR.Vue/src/views/tool/file/index.vue @@ -6,7 +6,7 @@ - @@ -34,15 +34,13 @@ - + @@ -62,6 +60,10 @@ @@ -69,11 +71,11 @@ - - + + - + @@ -81,32 +83,25 @@ - - - 存储文件夹前缀 - - - - - + + - - + + - - + - @@ -139,7 +134,12 @@ {{formView.fileUrl}} - {{formView.accessUrl}} + {{formView.accessUrl}} + + 复制 + + @@ -147,14 +147,14 @@