From 6c89894f668e5c0864fc94132d476b14b7857939 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=8D=E5=81=9A=E7=A0=81=E5=86=9C?= <599854767@qq.com> Date: Sun, 12 Dec 2021 13:34:33 +0800 Subject: [PATCH 01/24] =?UTF-8?q?=E7=BB=9F=E4=B8=80=E5=89=8D=E7=AB=AF?= =?UTF-8?q?=E5=AF=BC=E5=87=BA=E6=95=B0=E6=8D=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ZR.Vue/src/views/monitor/operlog/index.vue | 27 +++++----- ZR.Vue/src/views/system/post/index.vue | 10 +--- ZR.Vue/src/views/system/user/index.vue | 57 ++++++++++++---------- ZR.Vue/src/views/tool/gen/index.vue | 6 +-- 4 files changed, 47 insertions(+), 53 deletions(-) diff --git a/ZR.Vue/src/views/monitor/operlog/index.vue b/ZR.Vue/src/views/monitor/operlog/index.vue index d6eba23..77ba877 100644 --- a/ZR.Vue/src/views/monitor/operlog/index.vue +++ b/ZR.Vue/src/views/monitor/operlog/index.vue @@ -5,7 +5,8 @@ - + @@ -18,8 +19,8 @@ - - + 搜索 @@ -29,13 +30,15 @@ - 删除 + 删除 清空 - 导出 + 导出 + @@ -52,7 +55,8 @@ @@ -63,7 +67,8 @@ @@ -124,11 +129,8 @@ import { cleanOperlog, exportOperlog, } from "@/api/monitor/operlog"; -import DateRangePicker from "@/components/DateRangePicker"; -import { downloadFile } from "@/utils/zipdownload.js"; export default { - components: { DateRangePicker }, name: "Operlog", data() { return { @@ -267,10 +269,7 @@ export default { const { code, data } = response; if (code == 200) { this.msgSuccess("导出成功"); - downloadFile( - process.env.VUE_APP_BASE_API + data.path, - data.fileName - ); + this.download(data.path); } else { this.msgError("导出失败"); } diff --git a/ZR.Vue/src/views/system/post/index.vue b/ZR.Vue/src/views/system/post/index.vue index 993ede9..f1700e0 100644 --- a/ZR.Vue/src/views/system/post/index.vue +++ b/ZR.Vue/src/views/system/post/index.vue @@ -29,7 +29,7 @@ 删除 - 导出 + 导出 @@ -98,7 +98,6 @@ import { updatePost, exportPost, } from "@/api/system/post"; -import { downloadFile } from "@/utils/zipdownload.js"; export default { name: "Post", @@ -269,12 +268,7 @@ export default { return exportPost(queryParams); }) .then((response) => { - console.log(response) - // this.download(response.msg); - downloadFile( - process.env.VUE_APP_BASE_API + response.data.path, - response.data.fileName - ); + this.download(response.data.path); }); }, }, diff --git a/ZR.Vue/src/views/system/user/index.vue b/ZR.Vue/src/views/system/user/index.vue index eefb908..baf5db7 100644 --- a/ZR.Vue/src/views/system/user/index.vue +++ b/ZR.Vue/src/views/system/user/index.vue @@ -7,17 +7,20 @@
- +
- + - + @@ -25,7 +28,8 @@ - + 搜索 @@ -38,16 +42,19 @@ 新增 - 修改 + 修改 - 删除 + 删除 - + - 导出 + 导出 + @@ -78,8 +85,10 @@ @@ -148,14 +157,16 @@ - + + - + + @@ -176,8 +187,9 @@ - +
将文件拖到此处,或 @@ -209,13 +221,12 @@ import { exportUser, resetUserPwd, changeUserStatus, - // importTemplate, + importTemplate, } from "@/api/system/user"; import { getToken } from "@/utils/auth"; import { treeselect } from "@/api/system/dept"; import Treeselect from "@riophae/vue-treeselect"; import "@riophae/vue-treeselect/dist/vue-treeselect.css"; -import { downloadFile } from "@/utils/zipdownload.js"; export default { name: "User", @@ -273,7 +284,7 @@ export default { // 是否更新已经存在的用户数据 updateSupport: 0, // 设置上传的请求头部 - headers: { Authorization: 'Bearer ' + getToken() }, + headers: { Authorization: "Bearer " + getToken() }, // 上传的地址 url: process.env.VUE_APP_BASE_API + "system/user/importData", }, @@ -548,14 +559,10 @@ export default { type: "warning", }).then(() => { exportUser(queryParams).then((response) => { - console.log(JSON.stringify(response)); const { code, data } = response; if (code == 200) { this.msgSuccess("导出成功"); - downloadFile( - process.env.VUE_APP_BASE_API + data.path, - data.fileName - ); + this.download(data.fileName); } else { this.msgError("导出失败"); } @@ -569,9 +576,7 @@ export default { }, /** 下载模板操作 */ importTemplate() { - // importTemplate().then((response) => { - downLoadExcel("system/user/importTemplate", "用户数据导入模板"); - // }); + this.download("/system/user/importTemplate", "用户数据导入模板"); }, // 文件上传中处理 handleFileUploadProgress(event, file, fileList) { diff --git a/ZR.Vue/src/views/tool/gen/index.vue b/ZR.Vue/src/views/tool/gen/index.vue index edfc8ec..fcf8662 100644 --- a/ZR.Vue/src/views/tool/gen/index.vue +++ b/ZR.Vue/src/views/tool/gen/index.vue @@ -95,7 +95,6 @@ import { delTable, previewTable, } from "@/api/tool/gen"; -import { downloadFile } from "@/utils/zipdownload.js"; import importTable from "./importTable"; import { Loading } from "element-ui"; import hljs from "highlight.js"; @@ -230,10 +229,7 @@ export default { if (code == 200) { this.showGenerate = false; this.msgSuccess("恭喜你,代码生成完成!"); - downloadFile( - process.env.VUE_APP_BASE_API + data.zipPath, - data.fileName - ); + this.download(data.fileName); } else { this.msgError(res.msg); } From 8f1fc2677d4119ac0d1ce9d1c6480fb4d1380d3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=8D=E5=81=9A=E7=A0=81=E5=86=9C?= <599854767@qq.com> Date: Sun, 12 Dec 2021 13:34:47 +0800 Subject: [PATCH 02/24] =?UTF-8?q?=E5=88=A0=E9=99=A4=E6=B2=A1=E7=94=A8?= =?UTF-8?q?=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/components/DateRangePicker/index.vue | 45 ---- ZR.Vue/src/utils/datetime.js | 216 ------------------ ZR.Vue/src/utils/shortcuts.js | 108 --------- 3 files changed, 369 deletions(-) delete mode 100644 ZR.Vue/src/components/DateRangePicker/index.vue delete mode 100644 ZR.Vue/src/utils/datetime.js delete mode 100644 ZR.Vue/src/utils/shortcuts.js diff --git a/ZR.Vue/src/components/DateRangePicker/index.vue b/ZR.Vue/src/components/DateRangePicker/index.vue deleted file mode 100644 index eef79bd..0000000 --- a/ZR.Vue/src/components/DateRangePicker/index.vue +++ /dev/null @@ -1,45 +0,0 @@ - diff --git a/ZR.Vue/src/utils/datetime.js b/ZR.Vue/src/utils/datetime.js deleted file mode 100644 index 67f808a..0000000 --- a/ZR.Vue/src/utils/datetime.js +++ /dev/null @@ -1,216 +0,0 @@ -/* eslint-disable */ - -/** - * Date对象的补充函数,包括类似Python中的strftime() - * 阿债 https://gitee.com/azhai/datetime.js - */ - -Date.prototype.toMidnight = function() { - this.setHours(0) - this.setMinutes(0) - this.setSeconds(0) - this.setMilliseconds(0) - return this -} - -Date.prototype.daysAgo = function(days, midnight) { - days = days ? days - 0 : 0 - const date = new Date(this.getTime() - days * 8.64E7) - return midnight ? date.toMidnight() : date -} - -Date.prototype.monthBegin = function(offset) { - offset = offset ? offset - 0 : 0 - const days = this.getDate() - 1 - offset - return this.daysAgo(days, true) -} - -Date.prototype.quarterBegin = function() { - const month = this.getMonth() - this.getMonth() % 3 - return new Date(this.getFullYear(), month, 1).toMidnight() -} - -Date.prototype.yearBegin = function() { - return new Date(this.getFullYear(), 0, 1).toMidnight() -} - -Date.prototype.strftime = function(format, local) { - if (!format) { - const str = new Date(this.getTime() + 2.88E7).toISOString() - return str.substr(0, 16).replace('T', ' ') - } - local = local && local.startsWith('zh') ? 'zh' : 'en' - const padZero = function(str, len) { - const pads = len - str.toString().length - return (pads && pads > 0 ? '0'.repeat(pads) : '') + str - } - format = format.replace('%F', '%Y-%m-%d') - format = format.replace(/%D|%x/, '%m/%d/%y') - format = format.replace(/%T|%X/, '%H:%M:%S') - format = format.replace('%R', '%H:%M') - format = format.replace('%r', '%H:%M:%S %p') - format = format.replace('%c', '%a %b %e %H:%M:%S %Y') - const _this = this - return format.replace(/%[A-Za-z%]/g, function(f) { - let ans = f - switch (f) { - case '%%': - ans = '%' - break - - case '%Y': - case '%G': - ans = _this.getFullYear() - break - - case '%y': - ans = _this.getFullYear() % 100 - break - - case '%C': - ans = _this.getFullYear() / 100 - break - - case '%m': - case '%n': - ans = _this.getMonth() + 1 - break - - case '%B': - local = local.startsWith('en') ? 'english' : local - - case '%b': - const m = _this.getMonth() - ans = local_labels.monthes[local][m] - break - - case '%d': - case '%e': - ans = _this.getDate() - break - - case '%j': - ans = _this.getDaysOfYear() - break - - case '%U': - case '%W': - const ws = _this.getWeeksOfYear(f === '%W') - ans = padZero(ws, 2) - break - - case '%w': - ans = _this.getDay() - - case '%u': - ans = ans === 0 ? 7 : ans - break - - case '%A': - local = local.startsWith('en') ? 'english' : local - - case '%a': - const d = _this.getDay() - ans = local_labels.weekdays[local][d] - break - - case '%H': - case '%k': - ans = _this.getHours() - break - - case '%I': - case '%l': - ans = _this.getHours() - ans = ans % 12 - break - - case '%M': - ans = _this.getMinutes() - break - - case '%S': - ans = _this.getSeconds() - break - - case '%s': - ans = parseInt(_this.getTime() / 1E3) - break - - case '%f': - const ms = _this.getMilliseconds() - ans = padZero(ms * 1E3, 6) - break - - case '%P': - local = local.startsWith('en') ? 'english' : local - - case '%p': - const h = _this.getHours() - ans = local_labels.meridians[local][h < 12 ? 0 : 1] - break - - case '%z': - let tzo = _this.getTimezoneOffset() - const sign = tzo < 0 ? '-' : '+' - tzo = Math.abs(tzo) - const ho = padZero(tzo / 60, 2) - const mo = padZero(tzo % 60, 2) - ans = sign + ho + mo - break - - default: - break - } - if (f === '%C' || f === '%y' || f === '%m' || f === '%d' || f === '%H' || f === '%M' || f === '%S') { - ans = padZero(ans, 2) - } - return ans.toString() - }) -} - -Date.prototype.humanize = function(local) { - local = local && local.startsWith('zh') ? 'zh' : 'en' - const result = this.strftime('', local) - const days = (Date.today() - this.toMidnight().getTime()) / 8.64E7 - if (days <= -10 || days >= 10) { - return result - } - const labels = local_labels.dayagos[local] - let lbl = '' - if (days === 0 || days === 1) { - lbl = labels[days] - } else if (days === -1) { - lbl = labels[2] - } else if (days >= 2) { - lbl = days + labels[3] - } else { - lbl = days + labels[4] - } - return lbl + result.substr(10, 6) -} - -const local_labels = { - monthes: { - english: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'], - en: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], - zh: ['一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月'] - }, - weekdays: { - english: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], - en: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], - zh: ['日', '一', '二', '三', '四', '五', '六'] - }, - meridians: { - english: ['a.m.', 'p.m.'], - en: ['AM', 'PM'], - zh: ['上午', '下午'] - }, - dayagos: { - english: ['Today', 'Yesterday', 'Tomorrow', ' days ago', ' days late'], - en: ['Today', 'Yesterday', 'Tomorrow', ' days ago', ' days late'], - zh: ['今天', '昨天', '明天', '天前', '天后'] - } -} - -export default Date diff --git a/ZR.Vue/src/utils/shortcuts.js b/ZR.Vue/src/utils/shortcuts.js deleted file mode 100644 index eff6686..0000000 --- a/ZR.Vue/src/utils/shortcuts.js +++ /dev/null @@ -1,108 +0,0 @@ -import Date from './datetime.js' - -export const calendarBaseShortcuts = [{ - text: '今天', - onClick(picker) { - const startTime = new Date(new Date().setHours(0, 0, 0)) - const endTime = new Date(new Date().setHours(23, 59, 59)) - picker.$emit('pick', [startTime, endTime]) - } -}, { - text: '昨天', - onClick(picker) { - const startTime = new Date(new Date().daysAgo(1).setHours(0, 0, 0)) - const endTime = new Date(new Date().daysAgo(1).setHours(23, 59, 59)) - picker.$emit('pick', [startTime, endTime]) - } -}, { - text: '最近一周', - onClick(picker) { - const startTime = new Date(new Date().daysAgo(7).setHours(0, 0, 0)) - const endTime = new Date(new Date().setHours(23, 59, 59)) - picker.$emit('pick', [startTime, endTime]) - } -}, { - text: '最近30天', - onClick(picker) { - const startTime = new Date(new Date().daysAgo(30).setHours(0, 0, 0)) - const endTime = new Date(new Date().setHours(23, 59, 59)) - picker.$emit('pick', [startTime, endTime]) - } -}, { - text: '这个月', - onClick(picker) { - const startTime = new Date(new Date().monthBegin().setHours(0, 0, 0)) - const endTime = new Date(new Date().setHours(23, 59, 59)) - picker.$emit('pick', [startTime, endTime]) - } -}, { - text: '本季度', - onClick(picker) { - const startTime = new Date(new Date().quarterBegin().setHours(0, 0, 0)) - const endTime = new Date(new Date().setHours(23, 59, 59)) - picker.$emit('pick', [startTime, endTime]) - } -}] - -export const calendarMoveShortcuts = [{ - text: '‹ 往前一天 ', - onClick(picker) { - let startTime = new Date(new Date().daysAgo(1).setHours(0, 0, 0)) - let endTime = new Date(new Date().daysAgo(1).setHours(23, 59, 59)) - if (!picker.value) { - picker.value = [startTime, endTime] - } - startTime = picker.value[0].daysAgo(1) - endTime = picker.value[1].daysAgo(1) - picker.$emit('pick', [startTime, picker]) - } -}, { - text: ' 往后一天 ›', - onClick(picker) { - let startTime = new Date(new Date().setHours(0, 0, 0)) - let endTime = new Date(new Date().setHours(23, 59, 59)) - if (!picker.value) { - picker.value = [startTime, endTime] - } - startTime = picker.value[0].daysAgo(-1) - endTime = picker.value[1].daysAgo(-1) - picker.$emit('pick', [startTime, endTime]) - } -}, { - text: '« 往前一周 ', - onClick(picker) { - let startTime = new Date(new Date().setHours(0, 0, 0)) - let endTime = new Date(new Date().setHours(23, 59, 59)) - if (!picker.value) { - picker.value = [startTime.daysAgo(new Date().getDay()), - endTime.daysAgo(new Date().getDay() + 1)] - } else { - picker.value = [picker.value[0].daysAgo(picker.value[0].getDay()), - picker.value[1].daysAgo(picker.value[1].getDay() + 1)] - } - startTime = picker.value[0].daysAgo(7) - endTime = picker.value[1] - picker.$emit('pick', [startTime, endTime]) - } -}, { - text: ' 往后一周 »', - onClick(picker) { - let startTime = new Date(new Date().setHours(0, 0, 0)) - let endTime = new Date(new Date().setHours(23, 59, 59)) - if (!picker.value) { - picker.value = [startTime.daysAgo(new Date().getDay() - 7), - endTime.daysAgo(new Date().getDay() - 6)] - } else { - picker.value = [picker.value[0].daysAgo(picker.value[0].getDay() - 7), - picker.value[1].daysAgo(picker.value[1].getDay() - 6)] - } - startTime = picker.value[0] - endTime = picker.value[1].daysAgo(-7) - picker.$emit('pick', [startTime, endTime]) - } -}] - -export const calendarShortcuts = [ - ...calendarBaseShortcuts, - ...calendarMoveShortcuts -] From 377fa0aadfe985782545177aee4ff312aa81bed1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=8D=E5=81=9A=E7=A0=81=E5=86=9C?= <599854767@qq.com> Date: Sun, 12 Dec 2021 13:35:16 +0800 Subject: [PATCH 03/24] =?UTF-8?q?=E8=A7=92=E8=89=B2=E5=88=86=E9=85=8D?= =?UTF-8?q?=E6=96=B0=E5=A2=9E=E5=8A=A0=E4=BA=8B=E5=8A=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Controllers/System/SysRoleController.cs | 15 +++++++++------ ZR.Service/System/IService/ISysRoleService.cs | 6 +++--- ZR.Service/System/SysRoleService.cs | 6 +++--- 3 files changed, 15 insertions(+), 12 deletions(-) diff --git a/ZR.Admin.WebApi/Controllers/System/SysRoleController.cs b/ZR.Admin.WebApi/Controllers/System/SysRoleController.cs index 5c1859a..800ad0f 100644 --- a/ZR.Admin.WebApi/Controllers/System/SysRoleController.cs +++ b/ZR.Admin.WebApi/Controllers/System/SysRoleController.cs @@ -129,15 +129,18 @@ namespace ZR.Admin.WebApi.Controllers.System if (sysRoleDto == null || sysRoleDto.RoleId <= 0) return ToResponse(ApiResult.Error(101, "请求参数错误")); sysRoleDto.Create_by = HttpContext.GetName(); - //删除角色菜单 - sysRoleService.DeleteRoleMenuByRoleId(sysRoleDto.RoleId); - sysRoleService.InsertRoleMenu(sysRoleDto); + bool result = sysRoleService.UseTran2(() => + { + //删除角色菜单 + sysRoleService.DeleteRoleMenuByRoleId(sysRoleDto.RoleId); + sysRoleService.InsertRoleMenu(sysRoleDto); + }); - return SUCCESS(true); + return SUCCESS(result); } /// - /// 角色删除 √ + /// 角色删除 /// /// /// @@ -153,7 +156,7 @@ namespace ZR.Admin.WebApi.Controllers.System } /// - /// 修改角色状态 √ + /// 修改角色状态 /// /// 角色对象 /// diff --git a/ZR.Service/System/IService/ISysRoleService.cs b/ZR.Service/System/IService/ISysRoleService.cs index 9c9f4a4..2df2b54 100644 --- a/ZR.Service/System/IService/ISysRoleService.cs +++ b/ZR.Service/System/IService/ISysRoleService.cs @@ -4,7 +4,7 @@ using ZR.Model.System; namespace ZR.Service.System.IService { - public interface ISysRoleService + public interface ISysRoleService : IBaseService { /// /// 根据条件分页查询角色数据 @@ -12,7 +12,7 @@ namespace ZR.Service.System.IService /// 角色信息 /// /// 角色数据集合信息 - public PagedInfo SelectRoleList(SysRole role, Model.PagerInfo pager); + public PagedInfo SelectRoleList(SysRole role, PagerInfo pager); /// /// 查询所有角色 @@ -113,7 +113,7 @@ namespace ZR.Service.System.IService /// /// public List SelectUserRoles(long userId); - + /// /// 获取用户权限字符串集合 /// diff --git a/ZR.Service/System/SysRoleService.cs b/ZR.Service/System/SysRoleService.cs index f0df631..d04a820 100644 --- a/ZR.Service/System/SysRoleService.cs +++ b/ZR.Service/System/SysRoleService.cs @@ -17,14 +17,14 @@ namespace ZR.Service /// 角色 /// [AppService(ServiceType = typeof(ISysRoleService), ServiceLifetime = LifeTime.Transient)] - public class SysRoleService: ISysRoleService + public class SysRoleService : BaseService, ISysRoleService { private SysRoleRepository SysRoleRepository; private ISysUserRoleService SysUserRoleService; public SysRoleService( - SysRoleRepository sysRoleRepository, - ISysUserRoleService sysUserRoleService) + SysRoleRepository sysRoleRepository, + ISysUserRoleService sysUserRoleService) : base(sysRoleRepository) { SysRoleRepository = sysRoleRepository; SysUserRoleService = sysUserRoleService; From b40cd33abbb18da13b98ccb9ffdbe3bd56ffdb10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=8D=E5=81=9A=E7=A0=81=E5=86=9C?= <599854767@qq.com> Date: Sun, 12 Dec 2021 13:35:44 +0800 Subject: [PATCH 04/24] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E7=94=9F=E6=88=90?= =?UTF-8?q?=E6=A8=A1=E6=9D=BF=E6=96=B0=E5=A2=9E=E5=8A=A0table=E5=8A=A0?= =?UTF-8?q?=E8=BD=BD=E5=8A=A8=E7=94=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ZR.Admin.WebApi/wwwroot/CodeGenTemplate/TplVue.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ZR.Admin.WebApi/wwwroot/CodeGenTemplate/TplVue.txt b/ZR.Admin.WebApi/wwwroot/CodeGenTemplate/TplVue.txt index 76d6a07..bcdd903 100644 --- a/ZR.Admin.WebApi/wwwroot/CodeGenTemplate/TplVue.txt +++ b/ZR.Admin.WebApi/wwwroot/CodeGenTemplate/TplVue.txt @@ -33,7 +33,7 @@ $end - + ${VueViewListContent} @@ -166,10 +166,12 @@ $if(item.HtmlType == "datetime" && item.IsQuery == true) $end $end console.log(JSON.stringify(this.queryParams)); + this.loading = true; list${genTable.BusinessName}(this.queryParams).then(res => { if (res.code == 200) { this.dataList = res.data.result; this.total = res.data.totalNum; + this.loading = false; } }) }, From 77aec2ed3d9b9f7b11d6cd404d8a62711bc395b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=8D=E5=81=9A=E7=A0=81=E5=86=9C?= <599854767@qq.com> Date: Sun, 12 Dec 2021 13:37:43 +0800 Subject: [PATCH 05/24] =?UTF-8?q?=E7=BB=9F=E4=B8=80=E5=89=8D=E7=AB=AF?= =?UTF-8?q?=E5=AF=BC=E5=87=BA=E6=95=B0=E6=8D=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ZR.Vue/src/views/system/user/index.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ZR.Vue/src/views/system/user/index.vue b/ZR.Vue/src/views/system/user/index.vue index baf5db7..52b4239 100644 --- a/ZR.Vue/src/views/system/user/index.vue +++ b/ZR.Vue/src/views/system/user/index.vue @@ -562,7 +562,7 @@ export default { const { code, data } = response; if (code == 200) { this.msgSuccess("导出成功"); - this.download(data.fileName); + this.download(data.path); } else { this.msgError("导出失败"); } From 1e1e494d5bc0506884b9acee7067cd277a443dc8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=8D=E5=81=9A=E7=A0=81=E5=86=9C?= <599854767@qq.com> Date: Sun, 12 Dec 2021 16:37:52 +0800 Subject: [PATCH 06/24] =?UTF-8?q?=E4=BC=98=E5=8C=96=E4=B8=8A=E4=BC=A0?= =?UTF-8?q?=E6=88=90=E5=8A=9F=E6=96=B9=E6=B3=95=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ZR.Vue/src/components/FileUpload/index.vue | 6 ++++-- ZR.Vue/src/components/UploadImage/index.vue | 9 +++++++-- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/ZR.Vue/src/components/FileUpload/index.vue b/ZR.Vue/src/components/FileUpload/index.vue index ad5d6e5..9617600 100644 --- a/ZR.Vue/src/components/FileUpload/index.vue +++ b/ZR.Vue/src/components/FileUpload/index.vue @@ -144,10 +144,12 @@ export default { }, // 上传成功回调 handleUploadSuccess(res, file) { + if (res.code != 200) { + this.msgError(`上传失败,原因:${res.msg}!`); + return; + } this.msgSuccess("上传成功"); - console.log(res.data.fileName, res.data.url); this.fileList.push({ name: res.data.fileName, url: res.data.url }); - this.$emit("input", this.column, this.listToString(this.fileList)); }, // 删除文件 diff --git a/ZR.Vue/src/components/UploadImage/index.vue b/ZR.Vue/src/components/UploadImage/index.vue index 72aafdb..d2fc509 100644 --- a/ZR.Vue/src/components/UploadImage/index.vue +++ b/ZR.Vue/src/components/UploadImage/index.vue @@ -111,9 +111,14 @@ export default { }, //上传成功回调 handleUploadSuccess(res) { + console.log(res); + this.loading.close(); + if (res.code != 200) { + this.msgError(`上传失败,原因:${res.msg}!`); + return; + } this.fileList.push({ name: res.data.fileName, url: res.data.url }); this.$emit(`input`, this.column, this.listToString(this.fileList)); - this.loading.close(); }, // 上传前loading加载 handleBeforeUpload(file) { @@ -167,7 +172,7 @@ export default { for (let i in list) { strs += list[i].url.replace(this.baseUrl, "") + separator; } - return strs != '' ? strs.substr(0, strs.length - 1) : ''; + return strs != "" ? strs.substr(0, strs.length - 1) : ""; }, handleUploadError() { this.$message({ From b84e8b677412c8b4daa7318fcdfd07d4594d664b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=8D=E5=81=9A=E7=A0=81=E5=86=9C?= <599854767@qq.com> Date: Sun, 12 Dec 2021 16:39:33 +0800 Subject: [PATCH 07/24] =?UTF-8?q?=E4=BC=98=E5=8C=96=E4=B8=8A=E4=BC=A0?= =?UTF-8?q?=E6=9D=83=E9=99=90=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ZR.Admin.WebApi/Controllers/CommonController.cs | 4 ++-- ZR.Admin.WebApi/Filters/ActionPermissionFilter.cs | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/ZR.Admin.WebApi/Controllers/CommonController.cs b/ZR.Admin.WebApi/Controllers/CommonController.cs index 7e3424c..1f3ba07 100644 --- a/ZR.Admin.WebApi/Controllers/CommonController.cs +++ b/ZR.Admin.WebApi/Controllers/CommonController.cs @@ -79,7 +79,7 @@ namespace ZR.Admin.WebApi.Controllers /// [HttpPost()] [Verify] - [ActionPermissionFilter(Permission = "system")] + [ActionPermissionFilter(Permission = "common")] public IActionResult UploadFile([FromForm(Name = "file")] IFormFile formFile) { if (formFile == null) throw new CustomException(ResultCode.PARAM_ERROR, "上传文件不能为空"); @@ -114,7 +114,7 @@ namespace ZR.Admin.WebApi.Controllers /// [HttpPost] [Verify] - [ActionPermissionFilter(Permission = "system")] + [ActionPermissionFilter(Permission = "common")] public IActionResult UploadFileAliyun([FromForm(Name = "file")] IFormFile formFile, string fileDir = "") { if (formFile == null) throw new CustomException(ResultCode.PARAM_ERROR, "上传文件不能为空"); diff --git a/ZR.Admin.WebApi/Filters/ActionPermissionFilter.cs b/ZR.Admin.WebApi/Filters/ActionPermissionFilter.cs index 3cf32ca..a677859 100644 --- a/ZR.Admin.WebApi/Filters/ActionPermissionFilter.cs +++ b/ZR.Admin.WebApi/Filters/ActionPermissionFilter.cs @@ -55,12 +55,12 @@ namespace ZR.Admin.WebApi.Filters bool isDemoMode = ConfigUtils.Instance.GetAppConfig("DemoMode", false); //演示公开环境屏蔽权限 - string[] denyPerms = new string[] { "update", "add", "remove", "add", "edit", "delete", "import", "run", "start", "stop", "clear", "send" ,"export"}; - if (isDemoMode && (denyPerms.Any(f => Permission.ToLower().Contains(f.ToLower())) || Permission.Equals("system"))) + string[] denyPerms = new string[] { "update", "add", "remove", "add", "edit", "delete", "import", "run", "start", "stop", "clear", "send" ,"export", "upload", "common"}; + if (isDemoMode && denyPerms.Any(f => Permission.ToLower().Contains(f))) { context.Result = new JsonResult(new { code = ResultCode.FORBIDDEN, msg = "演示模式 , 不允许操作" }); } - if (!HasPermi && !Permission.Equals("system")) + if (!HasPermi && !Permission.Equals("common")) { logger.Info($"用户{info.NickName}没有权限访问{context.HttpContext.Request.Path},当前权限[{Permission}]"); context.Result = new JsonResult(new { code = ResultCode.FORBIDDEN, msg = "你没有权限访问" }); From 9dbd5eb6540ab7bb2967d78f6cad06b7e9557959 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=8D=E5=81=9A=E7=A0=81=E5=86=9C?= <599854767@qq.com> Date: Sun, 12 Dec 2021 16:41:33 +0800 Subject: [PATCH 08/24] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E5=8A=A0=E7=94=A8?= =?UTF-8?q?=E6=88=B7=E5=AF=BC=E5=85=A5=E3=80=81Excel=E9=80=9A=E7=94=A8?= =?UTF-8?q?=E5=AF=BC=E5=85=A5=E6=96=B9=E6=B3=95=E5=B0=81=E8=A3=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ZR.Admin.WebApi/Controllers/BaseController.cs | 35 +++- .../Controllers/System/SysUserController.cs | 69 ++++---- ZR.Common/ExcelHelper.cs | 156 ++++++++++++++++++ ZR.Vue/src/views/system/user/index.vue | 18 +- 4 files changed, 228 insertions(+), 50 deletions(-) create mode 100644 ZR.Common/ExcelHelper.cs diff --git a/ZR.Admin.WebApi/Controllers/BaseController.cs b/ZR.Admin.WebApi/Controllers/BaseController.cs index b34e50e..6ee924d 100644 --- a/ZR.Admin.WebApi/Controllers/BaseController.cs +++ b/ZR.Admin.WebApi/Controllers/BaseController.cs @@ -1,7 +1,6 @@ using Infrastructure; using Infrastructure.Model; using Microsoft.AspNetCore.Hosting; -using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Newtonsoft.Json; using Newtonsoft.Json.Serialization; @@ -9,8 +8,6 @@ using OfficeOpenXml; using System; using System.Collections.Generic; using System.IO; -using System.Linq; -using System.Reflection; using ZR.Admin.WebApi.Filters; namespace ZR.Admin.WebApi.Controllers @@ -134,5 +131,37 @@ namespace ZR.Admin.WebApi.Controllers return sFileName; } + + /// + /// 下载导入模板 + /// + /// + /// + /// + /// 下载文件名 + /// + protected string DownloadImportTemplate(List list, Stream stream, string fileName) + { + IWebHostEnvironment webHostEnvironment = (IWebHostEnvironment)App.ServiceProvider.GetService(typeof(IWebHostEnvironment)); + string sFileName = $"{fileName}模板.xlsx"; + string newFileName = Path.Combine(webHostEnvironment.WebRootPath, "importTemplate", sFileName); + //调试模式需要加上 + ExcelPackage.LicenseContext = LicenseContext.NonCommercial; + if (!Directory.Exists(newFileName)) + { + Directory.CreateDirectory(Path.GetDirectoryName(newFileName)); + } + using (ExcelPackage package = new(new FileInfo(newFileName))) + { + // 添加worksheet + ExcelWorksheet worksheet = package.Workbook.Worksheets.Add(fileName); + + //全部字段导出 + worksheet.Cells.LoadFromCollection(list, true, OfficeOpenXml.Table.TableStyles.Light13); + package.SaveAs(stream); + } + + return sFileName; + } } } diff --git a/ZR.Admin.WebApi/Controllers/System/SysUserController.cs b/ZR.Admin.WebApi/Controllers/System/SysUserController.cs index fd2242e..ff92959 100644 --- a/ZR.Admin.WebApi/Controllers/System/SysUserController.cs +++ b/ZR.Admin.WebApi/Controllers/System/SysUserController.cs @@ -1,6 +1,7 @@ using Infrastructure.Attribute; using Infrastructure.Enums; using Infrastructure.Model; +using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; @@ -8,7 +9,9 @@ using OfficeOpenXml; using System; using System.Collections.Generic; using System.IO; +using System.Reflection; using ZR.Admin.WebApi.Filters; +using ZR.Common; using ZR.Model; using ZR.Model.System; using ZR.Service; @@ -170,43 +173,37 @@ namespace ZR.Admin.WebApi.Controllers.System return ToResponse(ToJson(result)); } - ///// - ///// 导入 ok - ///// - ///// 使用IFromFile必须使用name属性否则获取不到文件 - ///// - //[HttpPost("importData")] - //[Log(Title = "用户导入", BusinessType = BusinessType.IMPORT)] - //[ActionPermissionFilter(Permission = "system:user:import")] - //public IActionResult ImportData([FromForm(Name = "file")] IFormFile formFile) - //{ - // var mapper = new Mapper(formFile.OpenReadStream());// 从流获取 - // //读取的sheet信息 - // var rows = mapper.Take(0); - // foreach (var item in rows) - // { - // SysUser u = item.Value; - // } - // //TODO 业务逻辑 - // return SUCCESS(1); - //} + /// + /// 导入 + /// + /// 使用IFromFile必须使用name属性否则获取不到文件 + /// + [HttpPost("importData")] + [Log(Title = "用户导入", BusinessType = BusinessType.IMPORT)] + [ActionPermissionFilter(Permission = "system:user:import")] + public IActionResult ImportData([FromForm(Name = "file")] IFormFile formFile) + { + IEnumerable users = ExcelHelper.ImportData(formFile.OpenReadStream()); - ///// - ///// 用户模板 ok - ///// - ///// - //[HttpGet("importTemplate")] - //[Log(Title = "用户模板", BusinessType = BusinessType.EXPORT)] - //[ActionPermissionFilter(Permission = "system:user:export")] - //public IActionResult ImportTemplateExcel() - //{ - // List user = new List(); - // var mapper = new Mapper(); - // MemoryStream stream = new MemoryStream(); - // mapper.Save(stream, user, "sheel1", overwrite: true, xlsx: true); - // //Response.Headers.Append("content-disposition", "attachment;filename=sysUser.xlsx"); - // return File(stream.ToArray(), "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "sysUser.xlsx"); - //} + //TODO 业务逻辑,自行插入数据到db + return SUCCESS(users); + } + + /// + /// 用户导入模板下载 + /// + /// + [HttpGet("importTemplate")] + [Log(Title = "用户模板", BusinessType = BusinessType.EXPORT)] + [AllowAnonymous] + public IActionResult ImportTemplateExcel() + { + List user = new List(); + MemoryStream stream = new MemoryStream(); + + string sFileName = DownloadImportTemplate(user, stream, "用户列表"); + return File(stream.ToArray(), "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", $"{sFileName}"); + } /// /// 用户导出 diff --git a/ZR.Common/ExcelHelper.cs b/ZR.Common/ExcelHelper.cs new file mode 100644 index 0000000..d40a98a --- /dev/null +++ b/ZR.Common/ExcelHelper.cs @@ -0,0 +1,156 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Reflection; +using OfficeOpenXml; +namespace ZR.Common +{ + public class ExcelHelper where T : new() + { + /// + /// 导入数据 + /// + /// + /// + public static IEnumerable ImportData(Stream stream) + { + using ExcelPackage package = new(stream); + ExcelPackage.LicenseContext = LicenseContext.NonCommercial; + ExcelWorksheet worksheet = package.Workbook.Worksheets[0];//读取第1个sheet + //获取表格的列数和行数 + + int colStart = worksheet.Dimension.Start.Column; + int colEnd = worksheet.Dimension.End.Column; + int rowStart = worksheet.Dimension.Start.Row; + int rowEnd = worksheet.Dimension.End.Row; + //int rowCount = worksheet.Dimension.Rows; + //int ColCount = worksheet.Dimension.Columns; + + List resultList = new(); + List propertyInfos = new();// new(typeof(T).GetProperties()); + Dictionary dictHeader = new(); + for (int i = colStart; i < colEnd; i++) + { + var name = worksheet.Cells[rowStart, i].Value.ToString(); + dictHeader[name] = i; + + PropertyInfo propertyInfo = MapPropertyInfo(name); + if (propertyInfo != null) + { + propertyInfos.Add(propertyInfo); + } + } + for (int row = rowStart + 1; row <= rowEnd; row++) + { + T result = new(); + + foreach (PropertyInfo p in propertyInfos) + { + try + { + ExcelRange cell = worksheet.Cells[row, dictHeader[p.Name]]; + if (cell.Value == null) + { + continue; + } + switch (p.PropertyType.Name.ToLower()) + { + case "string": + p.SetValue(result, cell.GetValue()); + break; + case "int16": + p.SetValue(result, cell.GetValue()); break; + case "int32": + p.SetValue(result, cell.GetValue()); break; + case "int64": + p.SetValue(result, cell.GetValue()); break; + case "decimal": + p.SetValue(result, cell.GetValue()); + break; + case "double": + p.SetValue(result, cell.GetValue()); break; + case "datetime": + p.SetValue(result, cell.GetValue()); break; + case "boolean": + p.SetValue(result, cell.GetValue()); break; + case "char": + p.SetValue(result, cell.GetValue()); break; + default: + break; + } + } + catch (KeyNotFoundException ex) + { + Console.WriteLine("未找到该列将继续循环," + ex.Message); + continue; + } + } + resultList.Add(result); + } + + return resultList; + } + + /// + /// 查找Excel列名对应的实体属性 + /// + /// + /// + public static PropertyInfo MapPropertyInfo(string columnName) + { + PropertyInfo[] propertyList = GetProperties(typeof(T)); + PropertyInfo propertyInfo = propertyList.Where(p => p.Name == columnName).FirstOrDefault(); + if (propertyInfo != null) + { + return propertyInfo; + } + else + { + foreach (PropertyInfo tempPropertyInfo in propertyList) + { + System.ComponentModel.DescriptionAttribute[] attributes = (System.ComponentModel.DescriptionAttribute[])tempPropertyInfo.GetCustomAttributes(typeof(System.ComponentModel.DescriptionAttribute), false); + if (attributes.Length > 0) + { + if (attributes[0].Description == columnName) + { + return tempPropertyInfo; + } + } + } + } + return null; + } + + /// + /// 得到类里面的属性集合 + /// + /// + /// + /// + public static PropertyInfo[] GetProperties(Type type, string[] columns = null) + { + PropertyInfo[] properties = null; + properties = type.GetProperties(); + + if (columns != null && columns.Length > 0) + { + // 按columns顺序返回属性 + var columnPropertyList = new List(); + foreach (var column in columns) + { + var columnProperty = properties.Where(p => p.Name == column).FirstOrDefault(); + if (columnProperty != null) + { + columnPropertyList.Add(columnProperty); + } + } + return columnPropertyList.ToArray(); + } + else + { + return properties; + } + } + } +} diff --git a/ZR.Vue/src/views/system/user/index.vue b/ZR.Vue/src/views/system/user/index.vue index 52b4239..30a4ea8 100644 --- a/ZR.Vue/src/views/system/user/index.vue +++ b/ZR.Vue/src/views/system/user/index.vue @@ -191,16 +191,13 @@ :action="upload.url + '?updateSupport=' + upload.updateSupport" :disabled="upload.isUploading" :on-progress="handleFileUploadProgress" :on-success="handleFileSuccess" :auto-upload="false" drag> -
- 将文件拖到此处,或 - 点击上传 -
-
- 是否更新已经存在的用户数据 - 下载模板 -
-
- 提示:仅允许导入“xls”或“xlsx”格式文件! +
将文件拖到此处,或点击上传
+
+
+ 是否更新已经存在的用户数据 +
+ 仅允许导入xls、xlsx格式文件。 + 下载模板