Compare commits
2 Commits
master
...
vue-next-a
| Author | SHA1 | Date |
|---|---|---|
|
|
67e79a5786 | |
|
|
a9e1b6770a |
8
.env
|
|
@ -1,8 +0,0 @@
|
|||
# port 端口号
|
||||
VITE_PORT = 8888
|
||||
|
||||
# open 运行 npm run dev 时自动打开浏览器
|
||||
VITE_OPEN = false
|
||||
|
||||
# public path 配置线上环境路径(打包)、本地通过 http-server 访问时,请置空即可
|
||||
VITE_PUBLIC_PATH = /vue-next-admin-preview/
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
# 本地环境
|
||||
ENV = 'development'
|
||||
|
||||
# 本地环境接口地址
|
||||
VITE_API_URL = 'http://localhost:8888/'
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
# 线上环境
|
||||
ENV = 'production'
|
||||
|
||||
# 线上环境接口地址
|
||||
VITE_API_URL = 'https://lyt-top.gitee.io/vue-next-admin-preview/'
|
||||
|
|
@ -1,23 +1,11 @@
|
|||
.DS_Store
|
||||
node_modules
|
||||
/dist
|
||||
.vscode/*
|
||||
!.vscode/settings.json
|
||||
!.vscode/tasks.json
|
||||
!.vscode/launch.json
|
||||
!.vscode/extensions.json
|
||||
*.code-workspace
|
||||
|
||||
|
||||
# local env files
|
||||
.env.local
|
||||
.env.*.local
|
||||
|
||||
# Log files
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
pnpm-debug.log*
|
||||
|
||||
# Editor directories and files
|
||||
.idea
|
||||
.vscode
|
||||
*.suo
|
||||
*.ntvs*
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw?
|
||||
# Local History for Visual Studio Code
|
||||
.history/
|
||||
frontend/LICENSE
|
||||
*.zip
|
||||
388
CHANGELOG.md
|
|
@ -1,388 +0,0 @@
|
|||
# <a href="https://gitee.com/lyt-top/vue-next-admin" target="_blank">vue-next-admin 更新日志</a>
|
||||
|
||||
🎉🎉🔥 `vue-next-admin` 基于 vue3.x 、Typescript、vite、Element plus 等,适配手机、平板、pc 的后台开源免费模板库(vue2.x 请切换 vue-prev-admin 分支)
|
||||
|
||||
## 2.3.0
|
||||
|
||||
`2022.11.16`
|
||||
|
||||
- 🌟 更新 依赖更新最新版本
|
||||
- 🎉 新增 新版登录页
|
||||
- 🎉 新增 tagsview 鼠标中键 `关闭当前 tagsview`
|
||||
- 🎉 新增 `分栏菜单鼠标悬停预加载`。[分栏模式如何去掉鼠标悬浮父级菜单,分栏菜单自动加载的功能啊](https://gitee.com/lyt-top/vue-next-admin/issues/I5RUY7)。操作路径:`布局配置 -> 分栏设置`
|
||||
- 🐞 修复 [vue-i18n](https://vue-i18n.intlify.dev/api/general.html#createi18n) 报错,[!39 修复 i18n 兼容性问题](https://toscode.gitee.com/lyt-top/vue-next-admin/pulls/39/files),感谢[@随心](https://toscode.gitee.com/jiangqiang1996)
|
||||
- 🐞 修复 顶栏搜索功能点击蒙蔽弹窗不关闭
|
||||
- 🐞 修复 [!38 fix: bug refreshRouterViewKey 值为 null 导致路由缓存第一次无效](https://toscode.gitee.com/lyt-top/vue-next-admin/pulls/38/files),感谢[@P)](https://toscode.gitee.com/foxp8y)
|
||||
- 🐞 修复 `路由参数 -> 普通路由/动态路由` 国际化演示时,`tagsView` 和 `浏览器标题` 显示异常。[演示中:路由参数界面 -> 动态路由,国际化显示时面包屑、浏览器标题有 bug](https://gitee.com/lyt-top/vue-next-admin/issues/I5JRJG)
|
||||
- 🐞 修复 `路由参数 -> 普通路由/动态路由` 动态设置 `tagsViewName` 时,`tagsView 右键菜单刷新` 功能失效(也就是路由后面有参数时,query、params)。[普通或动态路由新建页面后点击 tagview 刷新无效](https://gitee.com/lyt-top/vue-next-admin/issues/I5K3YO),感谢[@dejavuuuuu](https://gitee.com/zc19951010)
|
||||
- 🐞 修复 [表单(el-form)中,字体图标偏移问题](https://gitee.com/lyt-top/vue-next-admin/issues/I5K1PM)
|
||||
- 🐞 修复 路由 `router.addRoute` 时,一直提示 `No match found for location with path 'xxx'`
|
||||
- 🎯 优化 全局 `getCurrentInstance` 替换成 [`provide/inject`](https://cn.vuejs.org/api/application.html#app-provide) 或通过 `ref` 处理
|
||||
- 🎯 优化 引入组件方式 `(import xxx from xxx)` 改成 `defineAsyncComponent(() => import(xxx))`
|
||||
- 🎯 优化 页面高度 100% 问题,重写布局配置 `界面设置 -> 固定 Header` 多余的 `el-scrollbar` 逻辑、重写各界面需 `计算属性 computed` 设置动态高度问题(改为 css `flex` 设置自适应高度,具体查看文档:[设置可视区高度 100%](https://lyt-top.gitee.io/vue-next-admin-doc-preview/config/otherIssues/#%E8%AE%BE%E7%BD%AE%E5%8F%AF%E8%A7%86%E5%8C%BA%E9%AB%98%E5%BA%A6-100)。[!31 修复页面样式无法通过百分比设置的问题](https://toscode.gitee.com/lyt-top/vue-next-admin/pulls/31),感谢[@LostDeer](https://toscode.gitee.com/lyt-top/vue-next-admin/pulls/31/files)。`(改动较大,删除多余代码)`
|
||||
- 🎯 优化 [wangeditor](https://www.wangeditor.com/) 组件,`@wangeditor/editor-for-vue`。可自行修改,组件位置:`/src/components/editor`。相关 Issues:[wangeditor 编辑器多个菜单不能回弹](https://gitee.com/lyt-top/vue-next-admin/issues/I5M5H7)
|
||||
- 🌈 重构 外链、内嵌 iframe 逻辑 + 美化,iframe 支持缓存
|
||||
|
||||
## 2.2.0
|
||||
|
||||
`2022.07.10`
|
||||
|
||||
⚡⚡⚡ [/sec/stores/userInfo.ts](https://gitee.com/lyt-top/vue-next-admin/blob/master/src/stores/userInfo.ts) 下添加了 `getApiUserInfo` 接口模拟数据 `setTimeout` 为 3 秒
|
||||
|
||||
- 🌟 更新 依赖更新最新版本
|
||||
- 🐞 修复 [主界面重新授权按钮点击卡死不跳转登录界面#I5C3JS](https://gitee.com/lyt-top/vue-next-admin/issues/I5C3JS),感谢[@Hero-Typ](https://gitee.com/tian_yu_peng)
|
||||
- 🐞 修复 编译警告[#I5CVSB](https://gitee.com/lyt-top/vue-next-admin/issues/I5CVSB),全局替换成 `:deep(attr)`,感谢[@Linvas](https://gitee.com/linvas)。参考文档:[vue3 sfc-style](https://v3.cn.vuejs.org/api/sfc-style.html#style-scoped)。`node_modules\print-js\dist\print.js` 需 `print-js` 作者适配或去除 `package.json` 中的 `"print-js": "^1.6.0"`
|
||||
- 🐞 修复 [vue-next-admin-template-js 版本前端控制路由:userInfo.js 请求用户信息接口报错,加载不到路由 可以写个定时器模拟一下接口 一样的报错#I5F1HP](https://gitee.com/lyt-top/vue-next-admin/issues/I5F1HP),感谢[@白开水](https://gitee.com/libin951223)
|
||||
|
||||
## 2.1.1
|
||||
|
||||
`2022.05.27`
|
||||
|
||||
- 🌟 更新 依赖更新最新版本
|
||||
- 🎯 优化 深色模式下,`<el-button text></el-button>` 时,`:active` 样式
|
||||
- 🎯 优化 [页面缓存在刷新之后失效 #I58U75](https://gitee.com/lyt-top/vue-next-admin/issues/I58U75)),感谢[@ls0428](https://gitee.com/ls0428)
|
||||
- 🎯 优化 [SvgIcon 对下载的 Svg 图像设置颜色无效 #I59ND0](https://gitee.com/lyt-top/vue-next-admin/issues/I59ND0)),感谢[@elus_z](https://gitee.com/elus_z)
|
||||
- 🎯 优化 `/src/utils/toolsValidate.ts` 工具类
|
||||
- 🐞 修复 [布局切换,TagsView 显示的 tab 会多一个出来 #I58WGM](https://gitee.com/lyt-top/vue-next-admin/issues/I58WGM),感谢[@lg_boy](https://gitee.com/lg_boy)
|
||||
- 🐞 修复 [如果设置顶部面包屑导航开启图标 isBreadcrumbIcon=true 后,样式有点问题 如果不开启就是正常的 #I58VB8](https://gitee.com/lyt-top/vue-next-admin/issues/I58VB8)
|
||||
- 🐞 修复 地址栏路由地址输入错误时,返回首页后,再次输入路由地址错误时,不跳转 404 问题
|
||||
- 🐞 修复 [2.1.0 版本的图标选择组件多次点击后功能失效 #I590TH](https://gitee.com/lyt-top/vue-next-admin/issues/I590TH),感谢[@quber](https://gitee.com/quber)
|
||||
|
||||
## 2.1.0
|
||||
|
||||
`2022.04.18`
|
||||
|
||||
⚡⚡⚡ 此版本为破环性更新,优化内容如下:(谨慎更新!谨慎更新!!谨慎更新!!!)。因为 `vuex` 替换成 `pinia`
|
||||
|
||||
- 🌟 更新 依赖更新最新版本
|
||||
- 🎯 优化 部分界面图片不显示问题(更换 gitee 在线图片地址源)
|
||||
- 🎯 优化 各界面方法引入与逻辑之间添加一行空行,方便区分内容
|
||||
- 🎯 优化 图标选择器 [#I4YAHB](https://gitee.com/lyt-top/vue-next-admin/issues/I4YAHB),感谢[@真有你的](https://gitee.com/sunliusen)
|
||||
- 🎯 优化 图标选择器 icon type 类型为 all 时,类型 ali、ele、awe 回显问题
|
||||
- 🎯 优化 去掉开发环境 i18n 控制台警告,页面代码:[i18n/index.ts](https://gitee.com/lyt-top/vue-next-admin/blob/master/src/i18n/index.ts)
|
||||
- 🎯 优化 `NextLoading.start()` 方法,防止第一次进入界面时出现短暂空白
|
||||
- 🎯 优化 地址栏有参数退出登录,再次登录不跳之前界面问题 `src/layout/navBars/breadcrumb/user.vue`
|
||||
- 🎯 优化 `SvgIcon` 组件,防止 `开启 Tagsview 图标` 时,`tagsView 右键菜单关闭` 报错问题,工作流不可连线、全屏时关闭按钮消失问题
|
||||
- 🎯 优化 [如果 url 中有中文等特殊字符,第一次切换该 tab 时 keep-alive 失效#I55JS7](https://gitee.com/lyt-top/vue-next-admin/issues/I55JS7),感谢[yuyong1566](https://gitee.com/yuyong1566)
|
||||
- 🎯 优化 [wangEditor](https://www.wangeditor.com/) 更新到 v5,[vue3 版本线上示例中 wangeditor 富文本编辑器 demo 实例,无法换行#I5565B](https://gitee.com/lyt-top/vue-next-admin/issues/I5565B),感谢@[jenchih](https://gitee.com/jenchih)
|
||||
- 🎯 优化 [在关闭 tagview 时,高度刷新时会会变化,出现滚动条](https://gitee.com/lyt-top/vue-next-admin/issues/I55FHM),感谢[张松](https://gitee.com/zs310071113)
|
||||
- 🎯 优化 [路由参数](https://lyt-top.gitee.io/vue-next-admin-preview/#/params/common)演示
|
||||
- 🎉 新增 [vuex](https://vuex.vuejs.org/) 替换成 [pinia](https://pinia.vuejs.org/getting-started.html)
|
||||
- 🎉 新增 tagsView 支持自定义 tagsView 名称(文章详情时有用),前往体验:[路由参数/普通路由](https://lyt-top.gitee.io/vue-next-admin-preview/#/params/common)。新增 tagsView 支持自定义名称国际化,感谢[@q7but](https://gitee.com/q7but)、[!22 add 添加自定义 tagVIewName 拓展,支持国际化](https://gitee.com/lyt-top/vue-next-admin/pulls/22/files)、感谢[@tony_tong_xin](https://gitee.com/tony_tong_xin)
|
||||
- 🐞 修复 适配 `"element-plus": "^2.1.9",2.2.0` 版本
|
||||
- 🐞 修复 [导航栏横向布局后,一级菜单显示问题#I4Z3M3](https://gitee.com/lyt-top/vue-next-admin/issues/I4Z3M3)
|
||||
- 🐞 修复 横向布局三级及以上导航菜单高亮、导航高度不统一问题
|
||||
- 🐞 修复 分栏模式下,选中的菜单是 primary 样式,鼠标移入字也变成 primary 色了,感谢群友@孤夜-流殇
|
||||
- 🐞 修复 [vuex 里面改了颜色 但是不生效 #I4WFMA](https://gitee.com/lyt-top/vue-next-admin/issues/I4WFMA)
|
||||
- 🐞 修复 全局主题 primary 清空颜色后报错,[#I4X0LG](https://gitee.com/lyt-top/vue-next-admin/issues/I4X0LG),感谢[面向 BUG 编程](https://gitee.com/fhtfy)
|
||||
- 🐞 修复 [.eslintrc.js 文件 rules 标签名错误 #I53IPK](https://gitee.com/lyt-top/vue-next-admin/issues/I53IPK),感谢[yuyong1566](https://gitee.com/yuyong1566)
|
||||
- 🐞 修复 `开启 Tagsview 图标` 时,`tagsView 右键菜单关闭` 报错问题
|
||||
- 🐞 修复 `router.push` 路径找不到时报错问题,`404、401 界面` 已移入到 `main` 主布局里(之前全屏)
|
||||
- 🐞 修复 [全局修改组件大小失效了](https://gitee.com/lyt-top/vue-next-admin/issues/I551RP),感谢[lg_boy](https://gitee.com/lg_boy)
|
||||
- 🐞 修复 [修改一下配置时,需要每次都清理 `window.localStorage` 浏览器永久缓存,配置才会生效,问题解决#I567R1](https://gitee.com/lyt-top/vue-next-admin/issues/I567R1),感谢[@lanbao123](https://gitee.com/lanbao123)
|
||||
- 🐞 修复 [标记为需要缓存的 tab 页后,再次从左侧菜单打开,还是显示被缓存的页面内容#I4UY3G](https://gitee.com/lyt-top/vue-next-admin/issues/I4UY3G),感谢@axcc1234、特别感谢群友@华仔
|
||||
- 🌈 重构 路由(`/src/router/index.ts`)解决 No match found for location with path "xxx"(前端控制,后端控制未解决) 问题
|
||||
|
||||
## 2.0.2
|
||||
|
||||
`2022.03.04`
|
||||
|
||||
- 🌟 更新 依赖更新最新版本
|
||||
- 🎯 优化 Alert 提示添加边框
|
||||
- 🎯 优化 功能 / 数字滚动 演示界面
|
||||
- 🐞 修复 全局主题按钮颜色 :active 问题
|
||||
- 🐞 修复 Dropdown 下拉菜单样式问题
|
||||
- 🐞 修复 SvgIcon 图标组件动态切换时报警告问题,[SvgIcon 改变 name 时可能导致图像不显示](https://gitee.com/lyt-top/vue-next-admin/issues/I4VGE0),感谢@axcc1234
|
||||
|
||||
## 2.0.1
|
||||
|
||||
`2022.02.25`
|
||||
|
||||
- 🌟 更新 依赖更新最新版本
|
||||
- 🎯 优化 svgIcon 图标组件
|
||||
- 🎯 优化 vite.config.ts 打包,感谢群友@YourObjec
|
||||
- 🐞 修复 tagViews 开启图标不显示问题(风格 5),感谢群友@坏人
|
||||
- 🐞 修复 [Element Plus 1.2.0-beta.6 以后的版本 el-table 在移动端无法左右滑动](https://gitee.com/lyt-top/vue-next-admin/issues/I4UPTP),感谢@YGDada
|
||||
|
||||
## 2.0.0
|
||||
|
||||
`2022.02.21`
|
||||
|
||||
⚡⚡⚡ 此版本为破环性更新,优化内容如下:(谨慎更新!谨慎更新!!谨慎更新!!!)。演示界面建议直接覆盖文件。如需使用之前版本,请前往[gitee 发行版](https://gitee.com/lyt-top/vue-next-admin/releases) 进行对应版本下载。基础版会基于 `master` 分支进行修改
|
||||
|
||||
- 🌟 更新 依赖更新最新版本
|
||||
- 🌟 更新 登录页、首页
|
||||
- 💔 移除 vue-web-screen-shot
|
||||
- 💔 移除 城市多级联动,完整 json 数据请去 [vue-next-admin-images/menu](https://gitee.com/lyt-top/vue-next-admin-images/tree/master/menu) 仓库查看
|
||||
- 💔 移除 功能/echartsTree 树图
|
||||
- 💔 移除 其它设置/Tagsview 风格 2、Tagsview 风格 3
|
||||
- 💔 移除 功能/验证器
|
||||
- 🚧 调整 src/api 编写方式
|
||||
- 🚧 调整 自定义封装公用组件演示,更好的维护
|
||||
- 🎉 新增 Volar 支持,vs code 配置参考 [Vue Language Features (Volar)](https://lyt-top.gitee.io/vue-next-admin-doc-preview/home/vscode/)
|
||||
- 🎉 新增 `SvgIcon` 支持本地 svg 图标使用
|
||||
- 🎉 新增 表单表格验证演示
|
||||
- 🎯 优化 全局主题(移除 success、info、warning、danger)
|
||||
- 🎯 优化 工作流(开源)
|
||||
- 🎯 优化 element plus svg 图标,`elementXXX` 改成 `ele-XXX`
|
||||
- 🌈 重构 深色模式
|
||||
- 🌹 合并 [处理 parent 的 h100 由于外层有 min-height 导致失效的问题](https://gitee.com/lyt-top/vue-next-admin/pulls/20),感谢@MaxNull、@21030442-mao
|
||||
- 🐞 修复 element plus 升级 `^1.3.0-beta.5` 后 组件 size 大小问题(大改:涉及布局、演示界面)
|
||||
- 🐞 修复 vs code 使用 Vue Language Features (Volar) 插件 代码报红问题(可以把公用的 ts 类型定义封装起来公用)
|
||||
|
||||
## 1.2.2
|
||||
|
||||
`2021.12.21`
|
||||
|
||||
- 🌟 更新 依赖更新最新版本
|
||||
- 🎯 优化 iframes 滚动条问题
|
||||
- 🎯 优化 部署后每次都要强制刷新清浏览器缓存问题
|
||||
- 🎉 新增 工具类百分比验证演示
|
||||
- 🐞 修复 [tag-view 标签右键会超出浏览器 #I4KN78](https://gitee.com/lyt-top/vue-next-admin/issues/I4KN78)
|
||||
|
||||
## 1.2.1
|
||||
|
||||
`2021.12.12`
|
||||
|
||||
- 🌟 更新 依赖更新最新版本
|
||||
- 🎯 优化 cropper 裁剪时卡顿问题 [#I4M2VQ](https://gitee.com/lyt-top/vue-next-admin/issues/I4M2VQ)
|
||||
- 🎯 优化 Wangeditor 富文本编辑器的问题 [#I4LPC1](https://gitee.com/lyt-top/vue-next-admin/issues/I4LPC1)、[#I4LM7I](https://gitee.com/lyt-top/vue-next-admin/issues/I4LM7I)
|
||||
- 🐞 修复 浏览器标题问题
|
||||
- 🐞 修复 element plus svg 图标引入
|
||||
- 🐞 修复 工作流不可以拖线连接问题
|
||||
|
||||
## 1.2.0
|
||||
|
||||
`2021.11.28`
|
||||
|
||||
- 🌟 更新 依赖更新最新版本
|
||||
- 🎯 优化 深色模式
|
||||
- 🎯 优化 `/@/utils` 文件夹,合并删除单一内容
|
||||
- 🎯 优化 系统设置:菜单管理(新增、修改)、角色管理(新增菜单权限)、用户管理、部门管理、字典管理
|
||||
- 🎯 优化 登录界面逻辑、权限管理逻辑
|
||||
- 🎯 优化 同步 [vue-next-admin-images](https://gitee.com/lyt-top/vue-next-admin-images/tree/master/menu) 后端控制菜单模拟数据
|
||||
- 🎉 新增 适配 Font Icon 向 SVG Icon 迁移(改动大,"element-plus": "^1.2.0-beta.4" 谨慎更新)
|
||||
- 🐞 修复 热更新问题,感谢@甜蜜蜜
|
||||
- 🐞 修复 页面/element 字体图标演示
|
||||
- 🐞 修复 功能/图标选择器演示,新增高级功能 [issues #I4GJXQ](https://gitee.com/lyt-top/vue-next-admin/issues/I4GJXQ)
|
||||
|
||||
## 1.1.2
|
||||
|
||||
`2021.10.17`
|
||||
|
||||
- 🌟 更新 依赖更新最新版本
|
||||
- 🐞 修复 开启全屏时,刷新界面被还原成未全屏的状态
|
||||
- 🎯 优化 tagsView 右键菜单关闭逻辑
|
||||
- 🎯 优化 wangeditor 富文本编辑器(增加双向绑定)
|
||||
- 🎉 新增 工作流(暂不开源)
|
||||
- 🎉 新增 基础版 ts(不带国际化),切换 `vue-next-admin-template` 分支
|
||||
|
||||
## 1.1.1
|
||||
|
||||
`2021.09.25`
|
||||
|
||||
- 🌟 更新 依赖更新最新版本(`"element-plus": "^1.1.0-beta.13"` 版本运行错误,`^1.1.0-beta.16`修复横向菜单卡死问题)
|
||||
- 🐞 修复 Dialog 弹窗位置错误、Drawer 抽屉内边距、el-menu 菜单收起时背景色问题
|
||||
- 🎯 优化 锁屏界面自动锁屏(s/秒)必须设置至少 1 秒
|
||||
- 🎉 新增 分栏布局,鼠标移入当前项时,显示当前项菜单内容
|
||||
- 🎉 新增 工作流(未完成)
|
||||
|
||||
## 1.1.0
|
||||
|
||||
`2021.09.10`
|
||||
|
||||
- 🌟 更新 依赖更新最新版本
|
||||
- 🎯 优化 小屏模式下登录页二维码遮挡标题问题
|
||||
- 🎉 新增 图片验证器
|
||||
- 🎉 新增 动态复杂表单
|
||||
- 🎉 新增 工作流(未完成)
|
||||
- 🎉 新增 深色主题(伪深色,样式变动大,谨慎更新)
|
||||
|
||||
## 1.0.18
|
||||
|
||||
`2021.08.29`
|
||||
|
||||
- 🌟 更新 依赖更新最新版本
|
||||
- 🎯 优化 权限组件去掉顶级 div(`/src/components/auth`)
|
||||
- 🎉 新增 布局配置添加恢复默认按钮
|
||||
- 🐞 修复 升级 <a href="https://element-plus.gitee.io/#/zh-CN/component/changelog" target="_blank">element plus 1.1.0-beta.7</a>后项目无法启动、el-menu 菜单
|
||||
- 🐞 修复 表格固定列时的层级、设置了相对定位时,遮挡左侧导航菜单问题
|
||||
|
||||
## 1.0.17
|
||||
|
||||
`2021.08.22`
|
||||
|
||||
- 🌟 更新 依赖更新最新版本
|
||||
- 🎯 优化 去除设置布局切换,重置主题样式(initSetLayoutChange),切换布局需手动设置样式,设置的样式自动同步各布局
|
||||
- 🎯 优化 Dropdown 下拉菜单用户账号靠边时换行问题
|
||||
- 🎯 优化 左侧导航菜单,共用菜单树,防止 `布局配置` 设置 `菜单 / 顶栏` 时,样式丢失等问题
|
||||
- 🐞 修复 固定 header 后没有回到顶部的 bug,拉取项目后运行不起来的 bug。<a href="https://gitee.com/lyt-top/vue-next-admin/pulls/14" target="_blank">!14</a>,感谢<a href="https://gitee.com/wjs0509" target="_blank">@wjs0509</a>
|
||||
- 🐞 修复 tagView 右键全屏后,浏览器窗口大小发生任何变化都会导致左边菜单显示出来,并且可点击打开对应页面。<a href="https://gitee.com/lyt-top/vue-next-admin/issues/I46E6T" target="_blank">I46E6T</a>
|
||||
- 🐞 修复 默认设置 `菜单 / 顶栏` 样式不生效问题(/@/src/store/modules/themeConfig.ts)
|
||||
|
||||
## 1.0.16
|
||||
|
||||
`2021.08.14`
|
||||
|
||||
- 🌟 更新 依赖更新最新版本
|
||||
- 🎯 优化 菜单高亮(详情且详情设置了 meta.isHide 时,顶级菜单高亮),感谢群友@YourObject
|
||||
- 🎯 优化 详情路径写法:如父级(/pages/filtering),那么详情为(/pages/filtering/details?id=1)。这样写可实现(详情时,父级菜单高亮),否则写成(/pages/filteringDetails?id=1)顶级菜单将不会高亮。可参考:`页面/过滤筛选组件`,点击当前图片进行测试
|
||||
- 🎯 优化 tagsView 右键菜单全屏时,打开的界面高度问题
|
||||
- 🎯 优化 图表批量 resize 问题
|
||||
- 🐞 修复 菜单收起时(设置全局主题:primary 且有二级菜单时),文字高亮颜色不对
|
||||
- 🐞 修复 国际化 <a href="https://gitee.com/lyt-top/vue-next-admin/issues/I43NPE" target="_blank">#I43NPE</a>。可参考:`页面/过滤筛选组件`,点击顶部语言切换,进行底部分页国际化查看
|
||||
|
||||
## 1.0.15
|
||||
|
||||
`2021.08.06`
|
||||
|
||||
- 🌟 更新 依赖更新最新版本
|
||||
- 🎯 优化 tagsView 右键菜单点击时的字段名(id 已修改成 contextMenuClickId)与路由中返回的 id 名冲突问题,感谢群友@伯牙已遇钟子期
|
||||
- 🎉 新增 多个 form 表单验证界面演示
|
||||
|
||||
## 1.0.14
|
||||
|
||||
`2021.07.29`
|
||||
|
||||
- 🌟 更新 依赖更新最新版本(vue、vuex、vue-router),出现问题,请手动降级。版本查看:<a href="https://www.npmjs.com/" target="_blank">vnpm</a>
|
||||
- 🎯 优化 数据可视化图表演示加载卡顿问题、优化有图表的演示界面
|
||||
- 🎯 优化 路由参数演示界面
|
||||
- 🎯 优化 tagsView 操作演示界面,由于存在相同路由多标签,必须要传全部参数值(query 或者 params)
|
||||
- 🎉 新增 开启 TagsView 共用,开启时:(多个路由菜单共用一个详情组件(参数为后点击的覆盖前面点击的),tagsView 中只会出现一个(不支持同时出现多个 tagsView 标签))。关闭时:(多个路由菜单共用一个详情组件,参数不同,会同时出现多个 tagsView 标签)
|
||||
- 🐞 修复 tagsView 共用(单标签)时,右键菜单功能点击,参数不对的问题(第 2n+个参数未覆盖第一个参数值)
|
||||
- 🐞 修复 多 tagsView 标签(参数不同)、单个 tagsView 标签公用(参数不同)所带来的刷新功能、横向自动滚动等问题
|
||||
- 🐞 修复 处理全屏若干问题,<a href="https://gitee.com/lyt-top/vue-next-admin/pulls/12" target="_blank">pr!12</a>,感谢群友@另一个前端
|
||||
|
||||
## 1.0.13
|
||||
|
||||
`2021.07.25`
|
||||
|
||||
- 🌟 更新 依赖更新最新版本
|
||||
- 🎉 新增 数据可视化演示界面(/visualizingDemo1、/visualizingDemo2)
|
||||
- 🎉 新增 登录页扫码登录
|
||||
|
||||
## 1.0.12
|
||||
|
||||
`2021.07.16`
|
||||
|
||||
- 🌟 更新 依赖更新最新版本
|
||||
- 🎉 新增 数据可视化演示空界面(待完善)
|
||||
- 🎯 优化 tagsView 动态路由(xxx/:id/:name)时的右键菜单刷新、关闭其它时参数丢失问题(2021.07.15 优化)
|
||||
- 🐞 修复 路由带参数时,复制路径到登录页,跳转后参数消失的问题
|
||||
- 🐞 修复 设置多个外链,点击后,页面内容停留在上一个内容(内容未改变)、国际化处理、打开新窗口 sessionStorage 共享等
|
||||
|
||||
## 1.0.11
|
||||
|
||||
`2021.07.14`
|
||||
|
||||
- 🌟 更新 依赖更新最新版本
|
||||
- 🎉 新增 路由参数、图片懒加载界面演示
|
||||
- ⚠️ 警告 Form 表单 `binding value must be a string or number`,解决:加上 `label-position="top"` 不报警告(等待官方修复)
|
||||
- 🎯 优化 锁屏界面动画效果、首页图表显示
|
||||
- 🎯 优化 tagsView 右键菜单 `关闭` 功能逻辑
|
||||
- 🐞 修复 开启 TagsView 拖拽报错及小于 `1000px` 时自动设置禁止拖拽(<a href="https://gitee.com/lyt-top/vue-next-admin/issues/I3ZRRI" target="_blank">#I3ZRRI</a>)
|
||||
- 🐞 修复 `iframe 内嵌、外链` 高度问题,使用 computed 进行计算
|
||||
- 🐞 修复 默认布局开启 `侧边栏 Logo` 与关闭 `菜单水平折叠`,切换到横向布局时,菜单看不见的问题
|
||||
- 🐞 修复 切换不同布局时,再去开启 `经典布局分割菜单` 功能不生效问题
|
||||
- 🐞 修复 浏览器窗口标题中/英文切换不实时生效的问题
|
||||
- 🐞 修复 切换布局时,某些功能不可以使用。部分界面不需要取消事件监听(proxy.mittBus.off('xxx'))
|
||||
- 🐞 修复 动态路由带参数,router-link 跳转问题(<a href="hhttps://gitee.com/lyt-top/vue-next-admin/issues/I3YX6G" target="_blank">#I3YX6G</a>)
|
||||
- 🐞 修复 横向菜单有二级菜单时,点击子级菜单不高亮问题
|
||||
- 🐞 修复 功能 tagsView 操作演示不生效
|
||||
|
||||
## 1.0.10
|
||||
|
||||
`2021.07.07`
|
||||
|
||||
- 🌟 更新 依赖更新最新版本(字体图标无问题)
|
||||
- 🎯 优化 内嵌 iframe、外链,解决 tagsView 刷新问题
|
||||
|
||||
## 1.0.9
|
||||
|
||||
`2021.07.02`
|
||||
|
||||
- 🌟 更新 依赖更新最新版本
|
||||
- 🎯 优化 图标选择器设置宽度、v-model 等问题
|
||||
- 🎯 优化 滚动通知栏在手机上的体验
|
||||
- 🎯 优化 系统管理/新增菜单(编辑菜单),使用 `图标选择器` 进行模拟
|
||||
- 🎯 优化 字体图标(自动载入) 逻辑
|
||||
- 🐞 修复 screenfull 全屏时,按键盘 esc 键图标不改变问题,感谢群友@伯牙已遇钟子期
|
||||
|
||||
## 1.0.8
|
||||
|
||||
`2021.06.29`
|
||||
|
||||
- 🌟 更新 依赖更新最新版本
|
||||
- 🎉 新增 表单中英文切换演示
|
||||
- 🎯 优化 登录页查看密码 icon 图标
|
||||
- 🎯 优化 图标选择器
|
||||
- 🎯 优化 拖动指令
|
||||
- 🐞 修复 form 表单在页面小于 576px 时的排版问题
|
||||
|
||||
## 1.0.7
|
||||
|
||||
`2021.06.24`
|
||||
|
||||
- 🌟 更新 依赖更新最新版本
|
||||
- 🎉 新增 拖动指令及其演示界面
|
||||
- 🎯 优化 锁屏界面,解锁提示
|
||||
- 🎯 优化 登录页在手机上显示的效果
|
||||
|
||||
## 1.0.6
|
||||
|
||||
`2021.06.23`
|
||||
|
||||
- 🎯 优化 去掉内嵌 iframe 内边距(padding)
|
||||
- 🎯 优化 城市多级联动组件
|
||||
- 🎯 优化 Tree 树形控件改成表格组件
|
||||
- 🐞 修复 Cascader 级联选择器高度问题
|
||||
|
||||
## 1.0.5
|
||||
|
||||
`2021.06.22`
|
||||
|
||||
- 🌟 更新 vite 降级为@vite2.3.7,降级方法 `cnpm install vite@2.3.7`,防止 element plus 字体图标消失
|
||||
- 🐞 修复 开启后端控制路由(isRequestRoutes = true)时,内嵌 iframe、外链不可使用的问题
|
||||
|
||||
## 1.0.4
|
||||
|
||||
`2021.06.19`
|
||||
|
||||
- 🌟 更新 依赖更新最新版本("vite": "^2.3.7")热更新无问题
|
||||
- 🎉 新增 深克隆工具,方便开发,感谢<a href="https://gitee.com/kangert" target="_blank">@kangert</a>(<a href="https://gitee.com/lyt-top/vue-next-admin/pulls/6" target="_blank">#6</a>)
|
||||
- 🎯 优化 vuex 模块自动导入。感谢<a href="https://gitee.com/kangert" target="_blank">@kangert</a>(<a href="https://gitee.com/lyt-top/vue-next-admin/pulls/4" target="_blank">#4</a>),感谢群友@web 小学生-第五君
|
||||
- 🎯 优化 类型定义提高编码体验,修复不能将类型“string | undefined”分配给类型“string”的问题。感谢<a href="https://gitee.com/kangert" target="_blank">@kangert</a>(<a href="https://gitee.com/lyt-top/vue-next-admin/pulls/5" target="_blank">#5</a>)
|
||||
- 🎯 优化 `layout` 文件夹移动到与 `views` 文件夹同级(改动较大,`/@/views/layout` 变成 `/@/layout`)
|
||||
- 🎯 优化 页面有 `console.log` 时 `eslint` 不生效问题
|
||||
- 🎯 优化 页面、ts 中 `any` 类型问题(改动较大)
|
||||
- 🎯 优化 登录页在手机上显示的效果
|
||||
- 🎯 优化 多行注释信息,鼠标放到方法名即可查看,更加直观的知道方法参数等。引入方法时需去掉以 `.ts` 结尾的后缀(改动较大)
|
||||
- 🎯 优化 移除 `utils/storage.ts` 下的旧写法(改动较大)
|
||||
- 🎯 优化 拆分 `router` 下内容,路由、前端、后端控制分开写,方便理解
|
||||
- 🐞 修复 鼠标移入顶部用户信息栏 `开/关全屏` 文字反向问题
|
||||
- 🐞 修复 热更新时,NextLoading(界面 loading) 不消失问题 `window.nextLoading === undefined`
|
||||
- 🐞 修复 vuex 中不可以使用 `/@/api/xxx` 下的接口调用问题
|
||||
|
||||
## 1.0.3
|
||||
|
||||
`2021.06.02`
|
||||
|
||||
- ❄️ 删除 G6 思维导图界面
|
||||
- 🌟 更新 手动更新 vue、vue-router、vuex 到最近最多人使用的版本,出现不可预测的问题请降低版本。版本查看:<a href="https://www.npmjs.com/package/vue" target="_blank">vue 版本查看</a>
|
||||
- 🐞 修复 开启后端控制路由 `isRequestRoutes` 在非首页刷新页面后,回到首页的问题,感谢群友@伯牙已遇钟子期
|
||||
|
||||
## 1.0.2
|
||||
|
||||
`2021.06.01`
|
||||
|
||||
- 🌟 更新 依赖更新最新版本
|
||||
- 🐞 修复 菜单搜索中文不可以搜索的问题,感谢群友@逍遥天意
|
||||
|
||||
## 1.0.1
|
||||
|
||||
`2021.05.31`
|
||||
|
||||
- 🎉 新增 更新日志文件 `CHANGELOG.md`,以后每次更新都会在这里显示对应内容
|
||||
- 🌟 更新 依赖更新最新版本
|
||||
- 🐞 修复 分栏、经典布局路由设置 `meta.isHide` 为 `true` 时报错问题,感谢群友@29、@芭芭拉
|
||||
- 🐞 修复 经典布局点击 `tagsView` 左侧菜单数据不变问题
|
||||
2
LICENSE
|
|
@ -1,6 +1,6 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2021 lyt-Top
|
||||
Copyright (c) 2022 倔强嘴角留下一抹殇
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
|
|
|||
|
|
@ -0,0 +1,25 @@
|
|||
module.exports = {
|
||||
parser: '@typescript-eslint/parser',
|
||||
parserOptions: {
|
||||
project: 'tsconfig.json',
|
||||
tsconfigRootDir : __dirname,
|
||||
sourceType: 'module',
|
||||
},
|
||||
plugins: ['@typescript-eslint/eslint-plugin'],
|
||||
extends: [
|
||||
'plugin:@typescript-eslint/recommended',
|
||||
'plugin:prettier/recommended',
|
||||
],
|
||||
root: true,
|
||||
env: {
|
||||
node: true,
|
||||
jest: true,
|
||||
},
|
||||
ignorePatterns: ['.eslintrc.js'],
|
||||
rules: {
|
||||
'@typescript-eslint/interface-name-prefix': 'off',
|
||||
'@typescript-eslint/explicit-function-return-type': 'off',
|
||||
'@typescript-eslint/explicit-module-boundary-types': 'off',
|
||||
'@typescript-eslint/no-explicit-any': 'off',
|
||||
},
|
||||
};
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
# compiled output
|
||||
/dist
|
||||
/node_modules
|
||||
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
pnpm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
lerna-debug.log*
|
||||
package-lock.json
|
||||
# OS
|
||||
.DS_Store
|
||||
|
||||
# Tests
|
||||
/coverage
|
||||
/.nyc_output
|
||||
|
||||
# IDEs and editors
|
||||
/.idea
|
||||
.project
|
||||
.classpath
|
||||
.c9/
|
||||
*.launch
|
||||
.settings/
|
||||
*.sublime-workspace
|
||||
|
||||
# IDE - VSCode
|
||||
.vscode/*
|
||||
!.vscode/settings.json
|
||||
!.vscode/tasks.json
|
||||
!.vscode/launch.json
|
||||
!.vscode/extensions.json
|
||||
|
||||
*.lock
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"singleQuote": true,
|
||||
"trailingComma": "all"
|
||||
}
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"$schema": "https://json.schemastore.org/nest-cli",
|
||||
"collection": "@nestjs/schematics",
|
||||
"sourceRoot": "src"
|
||||
}
|
||||
|
|
@ -0,0 +1,90 @@
|
|||
{
|
||||
"name": "tsplatform",
|
||||
"version": "1.1.0",
|
||||
"description": "nestjs backend",
|
||||
"author": "SweetHoney",
|
||||
"private": true,
|
||||
"license": "UNLICENSED",
|
||||
"scripts": {
|
||||
"prebuild": "rimraf dist",
|
||||
"build": "nest build",
|
||||
"format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
|
||||
"start": "nest start",
|
||||
"start:dev": "nest start --watch",
|
||||
"start:debug": "nest start --debug --watch",
|
||||
"start:prod": "node dist/main",
|
||||
"lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix",
|
||||
"test": "jest",
|
||||
"test:watch": "jest --watch",
|
||||
"test:cov": "jest --coverage",
|
||||
"test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand",
|
||||
"test:e2e": "jest --config ./test/jest-e2e.json"
|
||||
},
|
||||
"dependencies": {
|
||||
"@fastify/static": "^6.5.0",
|
||||
"@nestjs/common": "^9.0.0",
|
||||
"@nestjs/config": "^2.2.0",
|
||||
"@nestjs/core": "^9.0.0",
|
||||
"@nestjs/jwt": "^9.0.0",
|
||||
"@nestjs/platform-express": "^9.0.0",
|
||||
"@nestjs/platform-fastify": "^9.2.0",
|
||||
"@nestjs/swagger": "^6.1.3",
|
||||
"@nestjs/typeorm": "^9.0.1",
|
||||
"class-transformer": "^0.5.1",
|
||||
"class-validator": "^0.13.2",
|
||||
"cookie-parser": "^1.4.6",
|
||||
"csurf": "^1.11.0",
|
||||
"express-rate-limit": "^6.7.0",
|
||||
"fastify-swagger": "^5.2.0",
|
||||
"fs": "^0.0.1-security",
|
||||
"helmet": "^6.0.0",
|
||||
"mysql2": "^2.3.3",
|
||||
"passport-jwt": "^4.0.0",
|
||||
"reflect-metadata": "^0.1.13",
|
||||
"rimraf": "^3.0.2",
|
||||
"rxjs": "^7.2.0",
|
||||
"ts-md5": "^1.3.1",
|
||||
"typeorm": "^0.3.10"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@nestjs/cli": "^9.0.0",
|
||||
"@nestjs/schematics": "^9.0.0",
|
||||
"@nestjs/testing": "^9.0.0",
|
||||
"@types/express": "^4.17.13",
|
||||
"@types/jest": "28.1.8",
|
||||
"@types/node": "^16.0.0",
|
||||
"@types/passport-jwt": "^3.0.7",
|
||||
"@types/supertest": "^2.0.11",
|
||||
"@typescript-eslint/eslint-plugin": "^5.0.0",
|
||||
"@typescript-eslint/parser": "^5.0.0",
|
||||
"eslint": "^8.0.1",
|
||||
"eslint-config-prettier": "^8.3.0",
|
||||
"eslint-plugin-prettier": "^4.0.0",
|
||||
"jest": "28.1.3",
|
||||
"prettier": "^2.3.2",
|
||||
"source-map-support": "^0.5.20",
|
||||
"supertest": "^6.1.3",
|
||||
"ts-jest": "28.0.8",
|
||||
"ts-loader": "^9.2.3",
|
||||
"ts-node": "^10.0.0",
|
||||
"tsconfig-paths": "4.1.0",
|
||||
"typescript": "^4.7.4"
|
||||
},
|
||||
"jest": {
|
||||
"moduleFileExtensions": [
|
||||
"js",
|
||||
"json",
|
||||
"ts"
|
||||
],
|
||||
"rootDir": "src",
|
||||
"testRegex": ".*\\.spec\\.ts$",
|
||||
"transform": {
|
||||
"^.+\\.(t|j)s$": "ts-jest"
|
||||
},
|
||||
"collectCoverageFrom": [
|
||||
"**/*.(t|j)s"
|
||||
],
|
||||
"coverageDirectory": "../coverage",
|
||||
"testEnvironment": "node"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* @Author: '490912587@qq.com' '490912587@qq.com'
|
||||
* @Date: 2022-11-17 10:59:16
|
||||
* @LastEditors: '490912587@qq.com' '490912587@qq.com'
|
||||
* @LastEditTime: 2022-11-24 10:58:50
|
||||
* @FilePath: \tsplatform\backend\src\Config\Index.ts
|
||||
* @Description: 系统全局配置
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* 系统配置
|
||||
*/
|
||||
export const AppConfig = {
|
||||
debug: false,
|
||||
port: 3000,
|
||||
jwt: {
|
||||
secret: "4vRk^ga52xVP$B2vYK$%r8a8hctLgbU9",
|
||||
expiresIn: "60000s"
|
||||
},
|
||||
md5Key: `4vRk^ga52xVP$B2vYK$%r8a8hctLgbU9`
|
||||
}
|
||||
/**
|
||||
* 数据库配置
|
||||
*/
|
||||
export const DataBaseConfig = {
|
||||
DataBase: {
|
||||
type: 'mysql',
|
||||
host: '127.0.0.1',
|
||||
port: 3306,
|
||||
database: 'sweet_honey',
|
||||
username: 'root',
|
||||
password: 'root',
|
||||
//是否自动迁移同步
|
||||
synchronize: true,
|
||||
},
|
||||
DataBase1: {
|
||||
type: 'mysql',
|
||||
host: '127.0.0.1',
|
||||
port: 3306,
|
||||
database: 'test1',
|
||||
username: 'root',
|
||||
password: 'root',
|
||||
//是否自动迁移同步
|
||||
synchronize: true,
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,123 @@
|
|||
/*
|
||||
* @Author: '490912587@qq.com' '490912587@qq.com'
|
||||
* @Date: 2022-11-17 17:06:21
|
||||
* @LastEditors: '490912587@qq.com' '490912587@qq.com'
|
||||
* @LastEditTime: 2022-11-24 11:11:11
|
||||
* @FilePath: \tsplatform\backend\src\Controller\AuthController.ts
|
||||
* @Description: 系统授权控制器
|
||||
*/
|
||||
import { Body, Controller, Get, Post, Request, Req, UseGuards } from '@nestjs/common';
|
||||
import { RestfulReturn } from 'src/Expand/RestfulReturn';
|
||||
import {
|
||||
ApiBearerAuth,
|
||||
ApiOperation,
|
||||
ApiTags,
|
||||
} from '@nestjs/swagger';
|
||||
import { UserService } from 'src/Service/UserService';
|
||||
import { RestfulHttpCodeEnum } from 'src/Enum/Global';
|
||||
import { JwtService } from '@nestjs/jwt';
|
||||
import { LoginDto } from 'src/EntiyDto/LoginDto';
|
||||
import { AppConfig } from 'src/Config/Index';
|
||||
import { RoleService } from 'src/Service/RoleService';
|
||||
import { MenuService } from 'src/Service/MenuService';
|
||||
|
||||
@ApiBearerAuth()
|
||||
@ApiTags('系统授权管理')
|
||||
@Controller('/auth')
|
||||
export class AuthController {
|
||||
constructor(
|
||||
public readonly _restful: RestfulReturn,
|
||||
public readonly _service: UserService,
|
||||
public readonly _roleService: RoleService,
|
||||
public readonly _menuService: MenuService,
|
||||
public readonly _jwt: JwtService
|
||||
) { }
|
||||
|
||||
@ApiOperation({
|
||||
summary: '获取账号登录验证码',
|
||||
description: '获取账号登录验证码'
|
||||
})
|
||||
@Get('/captcha')
|
||||
async captcha() {
|
||||
return await this._restful.toJson(
|
||||
RestfulHttpCodeEnum.SUCCESS, ""
|
||||
);
|
||||
}
|
||||
|
||||
@ApiOperation({
|
||||
summary: '账号密码登录',
|
||||
description: '账号密码登录'
|
||||
})
|
||||
@Post('/login')
|
||||
async login(@Body() dto: LoginDto) {
|
||||
const result = await this._service.repository.findOne({ where: { UserName: dto.UserName, Password: dto.Password } });
|
||||
if (result && result.Id > 0) {
|
||||
const token = await this._jwt.signAsync({ uid: result.Id }, {
|
||||
secret: AppConfig.jwt.secret,
|
||||
expiresIn: AppConfig.jwt.expiresIn,
|
||||
});
|
||||
return await this._restful.toJson(
|
||||
RestfulHttpCodeEnum.SUCCESS, { userinfo: result, token: token }
|
||||
);
|
||||
} else {
|
||||
return await this._restful.toJson(
|
||||
RestfulHttpCodeEnum.FAIL, "账号密码有误!"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ApiOperation({
|
||||
summary: '根据token获取用户信息',
|
||||
description: '根据token获取用户信息'
|
||||
})
|
||||
|
||||
@Get('/getUserInfo')
|
||||
async getUserInfo(@Req() request: Request) {
|
||||
try {
|
||||
const token = request.headers["authorization"];
|
||||
const jwtResult = await this._jwt.verifyAsync(token, { secret: AppConfig.jwt.secret, ignoreExpiration: false })
|
||||
const uid = jwtResult.uid;
|
||||
const result = await this._service.getById(uid);
|
||||
const menuRole = await this._roleService.getMenusByRoleId(result.RoleId);
|
||||
const menuIds: number[] = [];
|
||||
for await (const info of menuRole) {
|
||||
menuIds.push(info.MenuId);
|
||||
}
|
||||
const menus = await this._menuService.repository.createQueryBuilder().whereInIds(menuIds).getMany()
|
||||
const permissions: string[] = [];
|
||||
for await (const info of menus) {
|
||||
permissions.push(info.Permission);
|
||||
}
|
||||
return await this._restful.toJson(
|
||||
RestfulHttpCodeEnum.SUCCESS, { userInfo: result, permission: permissions }
|
||||
);
|
||||
}
|
||||
catch (ex) {
|
||||
return await this._restful.toJson(
|
||||
RestfulHttpCodeEnum.FAIL, ex
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ApiOperation({
|
||||
summary: '根据token退出登录',
|
||||
description: '根据token退出登录'
|
||||
})
|
||||
@Get('/loginOut')
|
||||
async loginOut(@Req() request: Request) {
|
||||
try {
|
||||
const token = request.headers["authorization"];
|
||||
const jwtResult = await this._jwt.verifyAsync(token, { secret: AppConfig.jwt.secret, ignoreExpiration: false })
|
||||
const uid = jwtResult.uid;
|
||||
const result = await this._service.getById(uid);
|
||||
return await this._restful.toJson(
|
||||
RestfulHttpCodeEnum.SUCCESS, result
|
||||
);
|
||||
}
|
||||
catch (ex) {
|
||||
return await this._restful.toJson(
|
||||
RestfulHttpCodeEnum.FAIL, ex
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,143 @@
|
|||
/*
|
||||
* @Author: '490912587@qq.com' '490912587@qq.com'
|
||||
* @Date: 2022-11-17 17:05:40
|
||||
* @LastEditors: '490912587@qq.com' '490912587@qq.com'
|
||||
* @LastEditTime: 2022-11-24 11:11:20
|
||||
* @FilePath: \tsplatform\backend\src\Controller\RoleController.ts
|
||||
* @Description: 省市区控制器
|
||||
*/
|
||||
|
||||
import { Body, Controller, Get, Post, Query } from '@nestjs/common';
|
||||
import { RestfulReturn } from 'src/Expand/RestfulReturn';
|
||||
import {
|
||||
ApiBearerAuth,
|
||||
ApiOperation,
|
||||
ApiTags,
|
||||
} from '@nestjs/swagger';
|
||||
import { IdDto, IdsDto, ListDto, PageDto } from 'src/EntiyDto/CommonDto';
|
||||
import { RestfulHttpCodeEnum } from 'src/Enum/Global';
|
||||
import { CityService } from 'src/Service/CityService';
|
||||
import { SysCity } from 'src/Entity/SysCity';
|
||||
import { Equal, Not } from 'typeorm';
|
||||
@ApiBearerAuth()
|
||||
@ApiTags('省市区管理')
|
||||
@Controller('/city')
|
||||
export class CityController {
|
||||
constructor(
|
||||
public readonly restful: RestfulReturn,
|
||||
public readonly service: CityService
|
||||
) {
|
||||
}
|
||||
//#region 基础控制器
|
||||
@ApiOperation({
|
||||
summary: '分页查询省市区列表',
|
||||
description: '分页查询省市区列表'
|
||||
})
|
||||
@Get('/getPage')
|
||||
async getPage(@Query() dto: PageDto) {
|
||||
const result = await this.service.getPage(dto.Page, dto.PageSize, dto.Keywords, dto.OrderBy);
|
||||
return await this.restful.toJson(
|
||||
RestfulHttpCodeEnum.SUCCESS,
|
||||
{
|
||||
total: result[1],
|
||||
page: 1,
|
||||
pageSize: 10,
|
||||
rows: result[0],
|
||||
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@ApiOperation({
|
||||
summary: '查询省市区列表',
|
||||
description: '查询省市区列表'
|
||||
})
|
||||
@Get('/getList')
|
||||
async getList(@Query() dto: ListDto) {
|
||||
const result = await this.service.getList(dto.Keywords, dto.OrderBy);
|
||||
return await this.restful.toJson(
|
||||
RestfulHttpCodeEnum.SUCCESS, result
|
||||
);
|
||||
}
|
||||
|
||||
@ApiOperation({
|
||||
summary: '根据ID查询省市区',
|
||||
description: '根据ID查询省市区'
|
||||
})
|
||||
@Get('/getById')
|
||||
async getById(@Query() dto: IdDto) {
|
||||
const result = await this.service.getById(dto.Id);
|
||||
return await this.restful.toJson(
|
||||
RestfulHttpCodeEnum.SUCCESS, result
|
||||
);
|
||||
}
|
||||
|
||||
@ApiOperation({
|
||||
summary: '根据ID数组查询省市区',
|
||||
description: '根据ID数组查询省市区'
|
||||
})
|
||||
@Get('/getByIds')
|
||||
async getByIds(@Query() dto: IdsDto) {
|
||||
const result = await this.service.getByIds(dto.Ids);
|
||||
return await this.restful.toJson(
|
||||
RestfulHttpCodeEnum.SUCCESS, result
|
||||
);
|
||||
}
|
||||
|
||||
@ApiOperation({
|
||||
summary: '新增省市区',
|
||||
description: '新增省市区'
|
||||
})
|
||||
@Post('/add')
|
||||
async add(@Body() model: SysCity) {
|
||||
const isRepeat = await this.service.repository.createQueryBuilder()
|
||||
.orWhere({ RegionName: Equal(model.RegionName.trim()), })
|
||||
.orWhere({ RegionCode: Equal(model.RegionCode.trim()) }).getCount();
|
||||
if (isRepeat > 0) {
|
||||
return await this.restful.toJson(
|
||||
RestfulHttpCodeEnum.FAIL, "地区名称或者行政编号重复!"
|
||||
);
|
||||
} else {
|
||||
const result = await this.service.save(new SysCity());
|
||||
return await this.restful.toJson(
|
||||
RestfulHttpCodeEnum.SUCCESS, result
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ApiOperation({
|
||||
summary: '修改省市区',
|
||||
description: '修改省市区'
|
||||
})
|
||||
@Post('/edit')
|
||||
async edit(@Body() model: SysCity) {
|
||||
const isRepeat = await this.service.repository.createQueryBuilder()
|
||||
.where({ Id: Not(model.Id) })
|
||||
.andWhere([{ RegionName: Equal(model.RegionName.trim()) }, { RegionCode: Equal(model.RegionCode.trim()) }])
|
||||
.getCount();
|
||||
if (isRepeat > 0) {
|
||||
return await this.restful.toJson(
|
||||
RestfulHttpCodeEnum.FAIL, "地区名称或者行政编号重复!"
|
||||
);
|
||||
} else {
|
||||
const result = await this.service.save(new SysCity());
|
||||
return await this.restful.toJson(
|
||||
RestfulHttpCodeEnum.SUCCESS, result
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ApiOperation({
|
||||
summary: '假删除省市区',
|
||||
description: '假删除省市区'
|
||||
})
|
||||
@Post('/del')
|
||||
async del(@Body() dto: IdDto) {
|
||||
const result = await this.service.destroy(dto.Id);
|
||||
return await this.restful.toJson(
|
||||
RestfulHttpCodeEnum.SUCCESS, result
|
||||
);
|
||||
}
|
||||
//#endregion
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* @Author: '490912587@qq.com' '490912587@qq.com'
|
||||
* @Date: 2022-11-17 17:05:41
|
||||
* @LastEditors: '490912587@qq.com' '490912587@qq.com'
|
||||
* @LastEditTime: 2022-11-24 10:11:01
|
||||
* @FilePath: \tsplatform\backend\src\Controller\UserController.ts
|
||||
* @Description: 系统用户控制器
|
||||
*/
|
||||
import { Controller, Get } from '@nestjs/common';
|
||||
import { RestfulReturn } from 'src/Expand/RestfulReturn';
|
||||
import {
|
||||
ApiBearerAuth,
|
||||
ApiOperation,
|
||||
ApiTags,
|
||||
} from '@nestjs/swagger';
|
||||
import { RestfulHttpCodeEnum } from 'src/Enum/Global';
|
||||
import { CityService } from 'src/Service/CityService';
|
||||
import { RoleService } from 'src/Service/RoleService';
|
||||
import { MenuService } from 'src/Service/MenuService';
|
||||
import { UserService } from 'src/Service/UserService';
|
||||
@ApiBearerAuth()
|
||||
@ApiTags('系统管理')
|
||||
@Controller('/')
|
||||
export class IndexController {
|
||||
constructor(
|
||||
public readonly restful: RestfulReturn,
|
||||
public readonly role_service: RoleService,
|
||||
public readonly menu_service: MenuService,
|
||||
public readonly user_service: UserService,
|
||||
public readonly city_service: CityService,
|
||||
) {
|
||||
}
|
||||
|
||||
@ApiOperation({
|
||||
summary: '数据初始化',
|
||||
description: '数据初始化'
|
||||
})
|
||||
@Get('/seed')
|
||||
async seedData() {
|
||||
//初始化账号数据
|
||||
const userCount = await this.user_service.seedData();
|
||||
//初始化菜单数据
|
||||
const menuCount = await this.menu_service.seedData();
|
||||
//初始化角色数据
|
||||
const roleCounts = await this.role_service.seedData();
|
||||
//初始化省市区数据
|
||||
const cityCount = await this.city_service.seedData();
|
||||
return await this.restful.toJson(
|
||||
RestfulHttpCodeEnum.SUCCESS,
|
||||
`一共Seed${userCount}条记录!\r\n` +
|
||||
`一共Seed${menuCount}条记录!\r\n` +
|
||||
`一共Seed${roleCounts[0]}条记录!\r\n` +
|
||||
`一共Seed${roleCounts[0]}条记录!\r\n` +
|
||||
`一共Seed${cityCount}条记录!`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,294 @@
|
|||
/*
|
||||
* @Author: '490912587@qq.com' '490912587@qq.com'
|
||||
* @Date: 2022-11-17 09:19:20
|
||||
* @LastEditors: '490912587@qq.com' '490912587@qq.com'
|
||||
* @LastEditTime: 2022-11-24 00:23:12
|
||||
* @FilePath: \tsplatform\backend\src\Controller\MenuController.ts
|
||||
* @Description: 系统菜单控制器
|
||||
*/
|
||||
|
||||
import { Body, Controller, Get, HttpException, HttpStatus, Post, Query } from '@nestjs/common';
|
||||
import { RestfulReturn } from 'src/Expand/RestfulReturn';
|
||||
import {
|
||||
ApiBearerAuth,
|
||||
ApiOperation,
|
||||
ApiProperty,
|
||||
ApiTags,
|
||||
} from '@nestjs/swagger';
|
||||
import { SysMenu } from 'src/Entity/SysMenu';
|
||||
import { plainToClass } from 'class-transformer';
|
||||
import { IdDto, IdsDto, IdStatusDto, ListDto, PageDto, RoleIdDto } from 'src/EntiyDto/CommonDto';
|
||||
import { MenuService } from 'src/Service/MenuService';
|
||||
import { RestfulHttpCodeEnum } from 'src/Enum/Global';
|
||||
import { MenuDto } from 'src/EntiyDto/MenuDto';
|
||||
import { RouteMenu } from 'src/EntiyDto/RouteMenu';
|
||||
import { Equal, In, Not } from 'typeorm';
|
||||
import { RoleService } from 'src/Service/RoleService';
|
||||
|
||||
@Controller('/menu')
|
||||
@ApiBearerAuth()
|
||||
@ApiTags('系统菜单管理')
|
||||
export class MenuController {
|
||||
constructor(
|
||||
public readonly restful: RestfulReturn,
|
||||
public readonly service: MenuService,
|
||||
public readonly _roleService: RoleService,
|
||||
) {
|
||||
}
|
||||
|
||||
@ApiOperation({
|
||||
summary: '获取所有菜单Tree,菜单列表使用',
|
||||
description: '获取所有菜单Tree'
|
||||
})
|
||||
@Get('/getMenuTree')
|
||||
async getMenuTree() {
|
||||
const result = await this.MenuTree(0);
|
||||
return await this.restful.toJson(
|
||||
RestfulHttpCodeEnum.SUCCESS, result
|
||||
);
|
||||
}
|
||||
@ApiOperation({
|
||||
summary: '根据角色ID获取用户授权的菜单Tree,前端router使用',
|
||||
description: '根据角色ID获取用户授权的菜单Tree'
|
||||
})
|
||||
@Get('/getAuthMenuTree')
|
||||
async getAuthMenuTree(@Query() dto: RoleIdDto) {
|
||||
if (dto.RoleId > 0) {
|
||||
const result = await this.RouteTree(0, dto.RoleId);
|
||||
return await this.restful.toJson(
|
||||
RestfulHttpCodeEnum.SUCCESS, result
|
||||
);
|
||||
} else {
|
||||
throw new HttpException("角色Id不能为空!", HttpStatus.INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
}
|
||||
//递归获取菜单Tree
|
||||
private async MenuTree(parentId: number): Promise<SysMenu[]> {
|
||||
const result = await this.service.repository.createQueryBuilder()
|
||||
.where({ ParentId: parentId })
|
||||
.orderBy("sort", "ASC")
|
||||
.getMany();
|
||||
const treeList: SysMenu[] = new Array<SysMenu>;
|
||||
for await (let info of result) {
|
||||
const children = await this.MenuTree(info.Id);
|
||||
const node: any = {
|
||||
Id: info.Id,
|
||||
ParentId: info.ParentId,
|
||||
Type: info.Type,
|
||||
Title: info.Title,
|
||||
Path: info.Path,
|
||||
Permission: info.Permission,
|
||||
Component: info.Component,
|
||||
Icon: info.Icon,
|
||||
Name: info.Name,
|
||||
Redirect: info.Redirect,
|
||||
IsLink: info.IsLink,
|
||||
IsHide: info.IsHide,
|
||||
IsKeepAlive: info.IsKeepAlive,
|
||||
IsAffix: info.IsAffix,
|
||||
IsIframe: info.IsIframe,
|
||||
Children: [],
|
||||
Sort: info.Sort,
|
||||
};
|
||||
if (children.length > 0) {
|
||||
node.Children = children;
|
||||
}
|
||||
treeList.push(node);
|
||||
}
|
||||
return treeList;
|
||||
}
|
||||
//递归获取前端路由Tree
|
||||
private async RouteTree(parentId: number, RoleId: number): Promise<RouteMenu[]> {
|
||||
const menuRole = await this._roleService.getMenusByRoleId(RoleId);
|
||||
const menuIds: number[] = [];
|
||||
for await (const info of menuRole) {
|
||||
menuIds.push(info.MenuId);
|
||||
}
|
||||
const result = await this.service.repository.createQueryBuilder()
|
||||
.where({ ParentId: parentId, Id: In(menuIds) })
|
||||
.orderBy("sort", "ASC")
|
||||
.getMany();
|
||||
const treeList: RouteMenu[] = new Array<RouteMenu>;
|
||||
for await (let info of result) {
|
||||
const children = await this.RouteTree(info.Id, RoleId);
|
||||
const node: RouteMenu = {
|
||||
name: info.Name,
|
||||
path: info.Path,
|
||||
component: info.Component,
|
||||
redirect: info.Redirect,
|
||||
meta: {
|
||||
title: info.Title,
|
||||
icon: info.Icon,
|
||||
isLink: info.IsLink,
|
||||
isHide: info.IsHide,
|
||||
isKeepAlive: info.IsKeepAlive,
|
||||
isAffix: info.IsAffix,
|
||||
isIframe: info.IsIframe,
|
||||
permission: info.Permission,
|
||||
},
|
||||
children: [],
|
||||
};
|
||||
if (children.length > 0) {
|
||||
for await (let item of children) {
|
||||
node.children.push({
|
||||
name: item.name,
|
||||
path: item.path,
|
||||
component: item.component,
|
||||
redirect: item.redirect,
|
||||
meta: {
|
||||
title: item.meta.title,
|
||||
icon: item.meta.icon,
|
||||
isLink: item.meta.isLink,
|
||||
isHide: item.meta.isHide,
|
||||
isKeepAlive: item.meta.isKeepAlive,
|
||||
isAffix: item.meta.isAffix,
|
||||
isIframe: item.meta.isIframe,
|
||||
permission: item.meta.permission,
|
||||
},
|
||||
children: [],
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
treeList.push(node);
|
||||
}
|
||||
return treeList;
|
||||
}
|
||||
//#region 基础控制器
|
||||
@ApiOperation({
|
||||
summary: '分页查询菜单列表',
|
||||
description: '分页查询菜单列表'
|
||||
})
|
||||
@ApiProperty()
|
||||
@Get('/getPage')
|
||||
async getPage(@Query() dto: PageDto) {
|
||||
const result = await this.service.getPage(dto.Page, dto.PageSize, dto.Keywords, dto.OrderBy);
|
||||
return await this.restful.toJson(
|
||||
RestfulHttpCodeEnum.SUCCESS,
|
||||
{
|
||||
total: result[1],
|
||||
page: 1,
|
||||
pageSize: 10,
|
||||
rows: result[0],
|
||||
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@ApiOperation({
|
||||
summary: '查询菜单列表',
|
||||
description: '查询菜单列表'
|
||||
})
|
||||
@Get('/getList')
|
||||
async getList(@Query() dto: ListDto) {
|
||||
const result = await this.service.getList(dto.Keywords, dto.OrderBy);
|
||||
return await this.restful.toJson(
|
||||
RestfulHttpCodeEnum.SUCCESS, result
|
||||
);
|
||||
}
|
||||
|
||||
@ApiOperation({
|
||||
summary: '根据ID查询菜单',
|
||||
description: '根据ID查询菜单'
|
||||
})
|
||||
@Get('/getById')
|
||||
async getById(@Query() dto: IdDto) {
|
||||
const result = await this.service.getById(dto.Id);
|
||||
return await this.restful.toJson(
|
||||
RestfulHttpCodeEnum.SUCCESS, result
|
||||
);
|
||||
}
|
||||
|
||||
@ApiOperation({
|
||||
summary: '根据ID数组查询菜单',
|
||||
description: '根据ID数组查询菜单'
|
||||
})
|
||||
@Get('/getByIds')
|
||||
async getByIds(@Query() dto: IdsDto) {
|
||||
const result = await this.service.getByIds(dto.Ids);
|
||||
return await this.restful.toJson(
|
||||
RestfulHttpCodeEnum.SUCCESS, result
|
||||
);
|
||||
}
|
||||
|
||||
@ApiOperation({
|
||||
summary: '新增菜单',
|
||||
description: '新增菜单'
|
||||
})
|
||||
@Post('/add')
|
||||
async add(@Body() dto: MenuDto) {
|
||||
const model = plainToClass(SysMenu, dto);
|
||||
const isRepeat = await this.service.repository.createQueryBuilder()
|
||||
.orWhere({ Name: Equal(model.Name.trim()), })
|
||||
.orWhere({ Permission: Equal(model.Permission.trim()) }).getCount();
|
||||
if (isRepeat > 0) {
|
||||
return await this.restful.toJson(
|
||||
RestfulHttpCodeEnum.FAIL, "路由名称或者权限标识重复!"
|
||||
);
|
||||
} else {
|
||||
const result = await this.service.save(model);
|
||||
return await this.restful.toJson(
|
||||
RestfulHttpCodeEnum.SUCCESS, result
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ApiOperation({
|
||||
summary: '修改菜单',
|
||||
description: '修改菜单'
|
||||
})
|
||||
@Post('/edit')
|
||||
async edit(@Body() dto: MenuDto) {
|
||||
const model = plainToClass(SysMenu, dto);
|
||||
const isRepeat = await this.service.repository.createQueryBuilder()
|
||||
.where({ Id: Not(model.Id) })
|
||||
.andWhere([{ Name: Equal(model.Name.trim()) }, { Permission: Equal(model.Permission.trim()) }])
|
||||
.getCount();
|
||||
if (isRepeat > 0) {
|
||||
return await this.restful.toJson(
|
||||
RestfulHttpCodeEnum.FAIL, "路由名称或者权限标识重复!"
|
||||
);
|
||||
} else {
|
||||
const result = await this.service.save(model);
|
||||
return await this.restful.toJson(
|
||||
RestfulHttpCodeEnum.SUCCESS, result
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ApiOperation({
|
||||
summary: '假删除菜单',
|
||||
description: '假删除菜单'
|
||||
})
|
||||
@Post('/del')
|
||||
async del(@Body() dto: IdDto) {
|
||||
const result = await this.service.destroy(dto.Id);
|
||||
return await this.restful.toJson(
|
||||
RestfulHttpCodeEnum.SUCCESS, result
|
||||
);
|
||||
}
|
||||
@ApiOperation({
|
||||
summary: '修改菜单状态',
|
||||
description: '修改菜单状态'
|
||||
})
|
||||
@Post('/setStatus')
|
||||
async setStatus(@Body() dto: IdStatusDto) {
|
||||
const result = await this.service.repository.createQueryBuilder()
|
||||
.update()
|
||||
.set({
|
||||
Status: dto.Status
|
||||
})
|
||||
.where("Id = :Id", { Id: dto.Id })
|
||||
.execute();
|
||||
if (result.affected > 0) {
|
||||
return await this.restful.toJson(
|
||||
RestfulHttpCodeEnum.SUCCESS, result
|
||||
);
|
||||
} else {
|
||||
return await this.restful.toJson(
|
||||
RestfulHttpCodeEnum.FAIL, result
|
||||
);
|
||||
}
|
||||
}
|
||||
//#endregion
|
||||
}
|
||||
|
|
@ -0,0 +1,189 @@
|
|||
/*
|
||||
* @Author: '490912587@qq.com' '490912587@qq.com'
|
||||
* @Date: 2022-11-17 17:05:40
|
||||
* @LastEditors: '490912587@qq.com' '490912587@qq.com'
|
||||
* @LastEditTime: 2022-11-23 22:32:29
|
||||
* @FilePath: \tsplatform\backend\src\Controller\RoleController.ts
|
||||
* @Description: 系统角色控制器
|
||||
*/
|
||||
|
||||
import { Body, Controller, Get, Post, Query } from '@nestjs/common';
|
||||
import { RestfulReturn } from 'src/Expand/RestfulReturn';
|
||||
import {
|
||||
ApiBearerAuth,
|
||||
ApiOperation,
|
||||
ApiTags,
|
||||
} from '@nestjs/swagger';
|
||||
import { RoleService } from 'src/Service/RoleService';
|
||||
import { IdDto, IdsDto, IdStatusDto, ListDto, PageDto } from 'src/EntiyDto/CommonDto';
|
||||
import { RestfulHttpCodeEnum } from 'src/Enum/Global';
|
||||
import { SysRole } from 'src/Entity/SysRole';
|
||||
import { RoleDto } from 'src/EntiyDto/RoleDto';
|
||||
import { plainToClass } from 'class-transformer';
|
||||
import { Not } from 'typeorm';
|
||||
@ApiBearerAuth()
|
||||
@ApiTags('系统角色管理')
|
||||
@Controller('/role')
|
||||
export class RoleController {
|
||||
constructor(
|
||||
public readonly restful: RestfulReturn,
|
||||
public readonly service: RoleService
|
||||
) {
|
||||
}
|
||||
|
||||
//#region 基础控制器
|
||||
@ApiOperation({
|
||||
summary: '分页查询角色列表',
|
||||
description: '分页查询角色列表'
|
||||
})
|
||||
@Get('/getPage')
|
||||
async getPage(@Query() dto: PageDto) {
|
||||
const result = await this.service.getPage(dto.Page, dto.PageSize, dto.Keywords, dto.OrderBy);
|
||||
return await this.restful.toJson(
|
||||
RestfulHttpCodeEnum.SUCCESS,
|
||||
{
|
||||
total: result[1],
|
||||
page: 1,
|
||||
pageSize: 10,
|
||||
rows: result[0],
|
||||
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@ApiOperation({
|
||||
summary: '查询角色列表',
|
||||
description: '查询角色列表'
|
||||
})
|
||||
@Get('/getList')
|
||||
async getList(@Query() dto: ListDto) {
|
||||
const result = await this.service.getList(dto.Keywords, dto.OrderBy);
|
||||
return await this.restful.toJson(
|
||||
RestfulHttpCodeEnum.SUCCESS, result
|
||||
);
|
||||
}
|
||||
|
||||
@ApiOperation({
|
||||
summary: '根据ID查询角色',
|
||||
description: '根据ID查询角色'
|
||||
})
|
||||
@Get('/getById')
|
||||
async getById(@Query() dto: IdDto) {
|
||||
const result = await this.service.getById(dto.Id);
|
||||
return await this.restful.toJson(
|
||||
RestfulHttpCodeEnum.SUCCESS, result
|
||||
);
|
||||
}
|
||||
|
||||
@ApiOperation({
|
||||
summary: '根据ID数组查询角色',
|
||||
description: '根据ID数组查询角色'
|
||||
})
|
||||
@Get('/getByIds')
|
||||
async getByIds(@Query() dto: IdsDto) {
|
||||
const result = await this.service.getByIds(dto.Ids);
|
||||
return await this.restful.toJson(
|
||||
RestfulHttpCodeEnum.SUCCESS, result
|
||||
);
|
||||
}
|
||||
|
||||
@ApiOperation({
|
||||
summary: '新增角色',
|
||||
description: '新增角色'
|
||||
})
|
||||
@Post('/add')
|
||||
async add(@Body() dto: RoleDto) {
|
||||
const model = plainToClass(SysRole, dto);
|
||||
const isRepeat = await this.service.repository.count({
|
||||
where: { Name: model.Name.trim() }
|
||||
});
|
||||
if (isRepeat > 0) {
|
||||
return await this.restful.toJson(
|
||||
RestfulHttpCodeEnum.FAIL, "角色名称重复!"
|
||||
);
|
||||
} else {
|
||||
const result = await this.service.save(model);
|
||||
if (result) {
|
||||
return await this.restful.toJson(
|
||||
RestfulHttpCodeEnum.SUCCESS, result
|
||||
);
|
||||
} else {
|
||||
return await this.restful.toJson(
|
||||
RestfulHttpCodeEnum.FAIL, result
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ApiOperation({
|
||||
summary: '修改角色',
|
||||
description: '修改角色'
|
||||
})
|
||||
@Post('/edit')
|
||||
async edit(@Body() dto: RoleDto) {
|
||||
const model = plainToClass(SysRole, dto);
|
||||
const isRepeat = await this.service.repository.count({
|
||||
where: { Id: Not(model.Id), Name: model.Name.trim() }
|
||||
});
|
||||
if (isRepeat > 0) {
|
||||
return await this.restful.toJson(
|
||||
RestfulHttpCodeEnum.FAIL, "角色名称重复!"
|
||||
);
|
||||
} else {
|
||||
const result = await this.service.save(model);
|
||||
if (result) {
|
||||
return await this.restful.toJson(
|
||||
RestfulHttpCodeEnum.SUCCESS, result
|
||||
);
|
||||
} else {
|
||||
return await this.restful.toJson(
|
||||
RestfulHttpCodeEnum.FAIL, result
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ApiOperation({
|
||||
summary: '删除角色',
|
||||
description: '删除角色'
|
||||
})
|
||||
@Post('/del')
|
||||
async del(@Body() dto: IdDto) {
|
||||
const result = await this.service.destroy(dto.Id);
|
||||
if (result) {
|
||||
return await this.restful.toJson(
|
||||
RestfulHttpCodeEnum.SUCCESS, result
|
||||
);
|
||||
} else {
|
||||
return await this.restful.toJson(
|
||||
RestfulHttpCodeEnum.FAIL, result
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ApiOperation({
|
||||
summary: '修改角色状态',
|
||||
description: '修改角色状态'
|
||||
})
|
||||
@Post('/setStatus')
|
||||
async setStatus(@Body() dto: IdStatusDto) {
|
||||
const result = await this.service.repository.createQueryBuilder()
|
||||
.update()
|
||||
.set({
|
||||
Status: dto.Status
|
||||
})
|
||||
.where("Id = :Id", { Id: dto.Id })
|
||||
.execute();
|
||||
if (result.affected > 0) {
|
||||
return await this.restful.toJson(
|
||||
RestfulHttpCodeEnum.SUCCESS, result
|
||||
);
|
||||
} else {
|
||||
return await this.restful.toJson(
|
||||
RestfulHttpCodeEnum.FAIL, result
|
||||
);
|
||||
}
|
||||
}
|
||||
//#endregion
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,188 @@
|
|||
/*
|
||||
* @Author: '490912587@qq.com' '490912587@qq.com'
|
||||
* @Date: 2022-11-17 17:05:41
|
||||
* @LastEditors: '490912587@qq.com' '490912587@qq.com'
|
||||
* @LastEditTime: 2022-11-23 22:49:42
|
||||
* @FilePath: \tsplatform\backend\src\Controller\UserController.ts
|
||||
* @Description: 系统用户控制器
|
||||
*/
|
||||
import { Body, Controller, Get, Post, Query } from '@nestjs/common';
|
||||
import { RestfulReturn } from 'src/Expand/RestfulReturn';
|
||||
import {
|
||||
ApiBearerAuth,
|
||||
ApiOperation,
|
||||
ApiTags,
|
||||
} from '@nestjs/swagger';
|
||||
import { UserService } from 'src/Service/UserService';
|
||||
import { SysUser } from 'src/Entity/SysUser';
|
||||
import { IdDto, IdsDto, IdStatusDto, ListDto, PageDto } from 'src/EntiyDto/CommonDto';
|
||||
import { RestfulHttpCodeEnum } from 'src/Enum/Global';
|
||||
import { plainToClass } from 'class-transformer';
|
||||
import { AppConfig } from 'src/Config/Index';
|
||||
import { Md5 } from 'ts-md5';
|
||||
import { UserDto } from 'src/EntiyDto/UserDto';
|
||||
import { Equal, Not } from 'typeorm';
|
||||
@ApiBearerAuth()
|
||||
@ApiTags('系统用户管理')
|
||||
@Controller('/user')
|
||||
export class UserController {
|
||||
constructor(
|
||||
public readonly restful: RestfulReturn,
|
||||
public readonly service: UserService
|
||||
) {
|
||||
}
|
||||
//#region 基础控制器
|
||||
@ApiOperation({
|
||||
summary: '分页查询用户列表',
|
||||
description: '分页查询用户列表'
|
||||
})
|
||||
@Get('/getPage')
|
||||
async getPage(@Query() dto: PageDto) {
|
||||
const result = await this.service.getPage(dto.Page, dto.PageSize, dto.Keywords, dto.OrderBy);
|
||||
return await this.restful.toJson(
|
||||
RestfulHttpCodeEnum.SUCCESS,
|
||||
{
|
||||
total: result[1],
|
||||
page: 1,
|
||||
pageSize: 10,
|
||||
rows: result[0],
|
||||
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@ApiOperation({
|
||||
summary: '查询用户列表',
|
||||
description: '查询用户列表'
|
||||
})
|
||||
@Get('/getList')
|
||||
async getList(@Query() dto: ListDto) {
|
||||
const result = await this.service.getList(dto.Keywords, dto.OrderBy);
|
||||
return await this.restful.toJson(
|
||||
RestfulHttpCodeEnum.SUCCESS, result
|
||||
);
|
||||
}
|
||||
|
||||
@ApiOperation({
|
||||
summary: '根据ID查询用户',
|
||||
description: '根据ID查询用户'
|
||||
})
|
||||
@Get('/getById')
|
||||
async getById(@Query() dto: IdDto) {
|
||||
const result = await this.service.getById(dto.Id);
|
||||
return await this.restful.toJson(
|
||||
RestfulHttpCodeEnum.SUCCESS, result
|
||||
);
|
||||
}
|
||||
|
||||
@ApiOperation({
|
||||
summary: '根据ID数组查询用户',
|
||||
description: '根据ID数组查询用户'
|
||||
})
|
||||
@Get('/getByIds')
|
||||
async getByIds(@Query() dto: IdsDto) {
|
||||
const result = await this.service.getByIds(dto.Ids);
|
||||
return await this.restful.toJson(
|
||||
RestfulHttpCodeEnum.SUCCESS, result
|
||||
);
|
||||
}
|
||||
|
||||
@ApiOperation({
|
||||
summary: '新增用户',
|
||||
description: '新增用户'
|
||||
})
|
||||
@Post('/add')
|
||||
async add(@Body() dto: UserDto) {
|
||||
const model = plainToClass(SysUser, dto);
|
||||
const isRepeat = await this.service.repository.createQueryBuilder()
|
||||
.orWhere({ UserName: Equal(model.UserName.trim()), })
|
||||
.orWhere({ Phone: Equal(model.Phone.trim()) })
|
||||
.orWhere({ Email: Equal(model.Email.trim()) }).getCount();
|
||||
if (isRepeat > 0) {
|
||||
return await this.restful.toJson(
|
||||
RestfulHttpCodeEnum.FAIL, "账号/手机号/邮箱重复!"
|
||||
);
|
||||
} else {
|
||||
//给新用户设置个默认密码:888888,用户登录后可以自行修改密码
|
||||
model.Password = Md5.hashStr(Md5.hashStr("888888") + AppConfig.md5Key);
|
||||
const result = await this.service.save(model);
|
||||
if (result) {
|
||||
return await this.restful.toJson(
|
||||
RestfulHttpCodeEnum.SUCCESS, result
|
||||
);
|
||||
} else {
|
||||
return await this.restful.toJson(
|
||||
RestfulHttpCodeEnum.FAIL, result
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ApiOperation({
|
||||
summary: '修改用户',
|
||||
description: '修改用户'
|
||||
})
|
||||
@Post('/edit')
|
||||
async edit(@Body() dto: UserDto) {
|
||||
const model = plainToClass(SysUser, dto);
|
||||
const isRepeat = await this.service.repository.createQueryBuilder()
|
||||
.where({ Id: Not(model.Id) })
|
||||
.andWhere([{ UserName: Equal(model.UserName.trim()) }, { Phone: Equal(model.Phone.trim()) }, { Email: Equal(model.Email.trim()) }])
|
||||
.getCount();
|
||||
if (isRepeat > 0) {
|
||||
return await this.restful.toJson(
|
||||
RestfulHttpCodeEnum.FAIL, "账号/手机号/邮箱重复!"
|
||||
);
|
||||
} else {
|
||||
//给新用户设置个默认密码:888888,用户登录后可以自行修改密码
|
||||
model.Password = Md5.hashStr(Md5.hashStr("888888") + AppConfig.md5Key);
|
||||
const result = await this.service.save(model);
|
||||
if (result) {
|
||||
return await this.restful.toJson(
|
||||
RestfulHttpCodeEnum.SUCCESS, result
|
||||
);
|
||||
} else {
|
||||
return await this.restful.toJson(
|
||||
RestfulHttpCodeEnum.FAIL, result
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ApiOperation({
|
||||
summary: '假删除用户',
|
||||
description: '假删除用户'
|
||||
})
|
||||
@Post('/del')
|
||||
async del(@Body() dto: IdDto) {
|
||||
const result = await this.service.destroy(dto.Id);
|
||||
return await this.restful.toJson(
|
||||
RestfulHttpCodeEnum.SUCCESS, result
|
||||
);
|
||||
}
|
||||
|
||||
@ApiOperation({
|
||||
summary: '修改用户状态',
|
||||
description: '修改用户状态'
|
||||
})
|
||||
@Post('/setStatus')
|
||||
async setStatus(@Body() dto: IdStatusDto) {
|
||||
const result = await this.service.repository.createQueryBuilder()
|
||||
.update()
|
||||
.set({
|
||||
Status: dto.Status
|
||||
})
|
||||
.where("Id = :Id", { Id: dto.Id })
|
||||
.execute();
|
||||
if (result.affected > 0) {
|
||||
return await this.restful.toJson(
|
||||
RestfulHttpCodeEnum.SUCCESS, result
|
||||
);
|
||||
} else {
|
||||
return await this.restful.toJson(
|
||||
RestfulHttpCodeEnum.FAIL, result
|
||||
);
|
||||
}
|
||||
}
|
||||
//#endregion
|
||||
}
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* @Author: '490912587@qq.com' '490912587@qq.com'
|
||||
* @Date: 2022-11-17 11:26:13
|
||||
* @LastEditors: '490912587@qq.com' '490912587@qq.com'
|
||||
* @LastEditTime: 2022-11-22 21:57:27
|
||||
* @FilePath: \tsplatform\backend\src\Entity\SysBase.ts
|
||||
* @Description: 系统基类实体模型
|
||||
*/
|
||||
|
||||
import { Entity, Column, PrimaryColumn, PrimaryGeneratedColumn, CreateDateColumn, UpdateDateColumn, VersionColumn } from 'typeorm';
|
||||
@Entity()
|
||||
export class SysBase {
|
||||
@PrimaryGeneratedColumn()
|
||||
@PrimaryColumn({ comment: "ID" })
|
||||
Id: number;
|
||||
|
||||
@Column({ comment: "状态", default: 0, nullable: true })
|
||||
Status: number;
|
||||
|
||||
@Column({ comment: "商户/站点ID", default: 0, nullable: true })
|
||||
MerchantId: number;
|
||||
|
||||
//自动为实体插入日期
|
||||
@CreateDateColumn()
|
||||
CreateTime: Date;
|
||||
|
||||
//每次调用实体管理器或存储库的save时,自动更新实体日期
|
||||
@UpdateDateColumn()
|
||||
UpdateTime: Date;
|
||||
|
||||
@Column({ comment: "操作人ID", default: 0, nullable: true })
|
||||
OperatorId: number;
|
||||
|
||||
@Column({ comment: "修改人ID", default: 0, nullable: true })
|
||||
UpdateUserId: number;
|
||||
|
||||
@Column({ comment: "是否删除", default: false, nullable: true })
|
||||
IsDelete: boolean;
|
||||
|
||||
//每次调用实体管理器或存储库的save时自动增长实体版本
|
||||
@VersionColumn()
|
||||
Version: number;
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* @Author: '490912587@qq.com' '490912587@qq.com'
|
||||
* @Date: 2022-11-17 13:12:19
|
||||
* @LastEditors: '490912587@qq.com' '490912587@qq.com'
|
||||
* @LastEditTime: 2022-11-18 14:18:50
|
||||
* @FilePath: \tsplatform\backend\src\Entity\SysCity.ts
|
||||
* @Description: 系统城市实体模型
|
||||
*/
|
||||
|
||||
import { Entity, Column, PrimaryColumn, PrimaryGeneratedColumn } from 'typeorm';
|
||||
@Entity()
|
||||
export class SysCity {
|
||||
|
||||
@PrimaryGeneratedColumn()
|
||||
@PrimaryColumn({ comment: "ID" })
|
||||
Id: number;
|
||||
|
||||
@Column({ comment: "地区编号" })
|
||||
RegionId: string;
|
||||
|
||||
@Column({ comment: "地区名称" })
|
||||
RegionName: string;
|
||||
|
||||
@Column({ comment: "地区简称", nullable: true })
|
||||
RegionShortName: string;
|
||||
|
||||
@Column({ comment: "地区行政编号", nullable: true })
|
||||
RegionCode: string;
|
||||
|
||||
@Column({ comment: "地区父级ID" })
|
||||
RegionParentId: string;
|
||||
|
||||
@Column({ comment: "地区级别" })
|
||||
RegionLevel: number;
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
* @Author: '490912587@qq.com' '490912587@qq.com'
|
||||
* @Date: 2022-11-17 13:10:02
|
||||
* @LastEditors: '490912587@qq.com' '490912587@qq.com'
|
||||
* @LastEditTime: 2022-11-22 15:08:00
|
||||
* @FilePath: \tsplatform\backend\src\Entity\SysDictionaries.ts
|
||||
* @Description: 系统字典实体模型
|
||||
*/
|
||||
|
||||
import { Entity, Column } from 'typeorm';
|
||||
import { SysBase } from 'src/Entity/SysBase';
|
||||
@Entity()
|
||||
export class SysDictionaries extends SysBase {
|
||||
@Column({ comment: "字典名称" })
|
||||
Name: string;
|
||||
|
||||
@Column({ comment: "备注", nullable: true })
|
||||
Remark: string;
|
||||
}
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* @Author: '490912587@qq.com' '490912587@qq.com'
|
||||
* @Date: 2022-11-17 11:21:40
|
||||
* @LastEditors: '490912587@qq.com' '490912587@qq.com'
|
||||
* @LastEditTime: 2022-11-23 21:52:49
|
||||
* @FilePath: \tsplatform\backend\src\Entity\SysMenu.ts
|
||||
* @Description: 系统菜单实体模型
|
||||
*/
|
||||
|
||||
import { Entity, Column } from 'typeorm';
|
||||
import { SysBase } from 'src/Entity/SysBase';
|
||||
import { MenuEnum } from 'src/Enum/Global';
|
||||
@Entity()
|
||||
export class SysMenu extends SysBase {
|
||||
@Column({ comment: "父级ID", default: 0 })
|
||||
ParentId: number;
|
||||
|
||||
@Column({ comment: "菜单类型", default: 0 })
|
||||
Type: MenuEnum;
|
||||
|
||||
@Column({ comment: "路由名称", unique: true })
|
||||
Name: string;
|
||||
|
||||
@Column({ comment: "路由地址", nullable: true })
|
||||
Path: string;
|
||||
|
||||
@Column({ comment: "组件名称", nullable: true })
|
||||
Component: string;
|
||||
|
||||
@Column({ comment: "重定向路径", nullable: true })
|
||||
Redirect: string;
|
||||
|
||||
@Column({ comment: "菜单名称" })
|
||||
Title: string;
|
||||
|
||||
@Column({ comment: "是否外链,开启外链条件,`1、isLink: 链接地址不为空 2、isIframe:false`", nullable: true })
|
||||
IsLink: string;
|
||||
|
||||
@Column({ comment: "是否隐藏此路由" })
|
||||
IsHide: boolean;
|
||||
|
||||
@Column({ comment: "是否缓存组件状态" })
|
||||
IsKeepAlive: boolean;
|
||||
|
||||
@Column({ comment: "是否固定在 tagsView 栏上" })
|
||||
IsAffix: boolean;
|
||||
|
||||
@Column({ comment: "是否内嵌窗口,开启条件,`1、isIframe:true 2、isLink:链接地址不为空`" })
|
||||
IsIframe: boolean;
|
||||
|
||||
@Column({ comment: "路由权限标识", unique: true })
|
||||
Permission: string;
|
||||
|
||||
@Column({ comment: "菜单图标", nullable: true })
|
||||
Icon: string;
|
||||
|
||||
@Column({ comment: "排序", nullable: true, default: 0 })
|
||||
Sort: number;
|
||||
|
||||
Children: SysMenu[];
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
/*
|
||||
* @Author: '490912587@qq.com' '490912587@qq.com'
|
||||
* @Date: 2022-11-17 13:08:01
|
||||
* @LastEditors: '490912587@qq.com' '490912587@qq.com'
|
||||
* @LastEditTime: 2022-11-23 16:46:20
|
||||
* @FilePath: \tsplatform\backend\src\Entity\SysRole.ts
|
||||
* @Description: 系统角色实体模型
|
||||
*/
|
||||
|
||||
import { Entity, Column } from 'typeorm';
|
||||
import { SysBase } from 'src/Entity/SysBase';
|
||||
import { SysRoleMenu } from 'src/Entity/SysRoleMenu';
|
||||
@Entity()
|
||||
export class SysRole extends SysBase {
|
||||
@Column({ comment: "角色名称", unique: true })
|
||||
Name: string;
|
||||
|
||||
@Column({ comment: "备注", nullable: true })
|
||||
Remark: string;
|
||||
|
||||
SysRoleMenu: SysRoleMenu[];
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* @Author: '490912587@qq.com' '490912587@qq.com'
|
||||
* @Date: 2022-11-17 13:54:50
|
||||
* @LastEditors: '490912587@qq.com' '490912587@qq.com'
|
||||
* @LastEditTime: 2022-11-23 17:32:38
|
||||
* @FilePath: \tsplatform\backend\src\Entity\SysRoleMenu.ts
|
||||
* @Description: 系统角色菜单映射实体模型
|
||||
*/
|
||||
|
||||
import { Entity, Column, ManyToOne } from 'typeorm';
|
||||
import { SysBase } from 'src/Entity/SysBase';
|
||||
@Entity()
|
||||
export class SysRoleMenu extends SysBase {
|
||||
@Column({ comment: "菜单Id", default: 0 })
|
||||
MenuId: number;
|
||||
@Column({ comment: "角色Id", default: 0 })
|
||||
RoleId: number;
|
||||
}
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* @Author: '490912587@qq.com' '490912587@qq.com'
|
||||
* @Date: 2022-11-17 13:55:35
|
||||
* @LastEditors: '490912587@qq.com' '490912587@qq.com'
|
||||
* @LastEditTime: 2022-11-23 23:13:45
|
||||
* @FilePath: \tsplatform\backend\src\Entity\SysUser.ts
|
||||
* @Description: 系统用户映射实体模型
|
||||
*/
|
||||
import { Entity, Column, Index } from 'typeorm';
|
||||
import { SysBase } from 'src/Entity/SysBase';
|
||||
import { SexEnum, UserTypeEnum } from 'src/Enum/Global';
|
||||
@Entity()
|
||||
export class SysUser extends SysBase {
|
||||
@Column({ comment: "账号类型", default: 1 })
|
||||
UserType: UserTypeEnum;
|
||||
|
||||
@Column({ comment: "账号", unique: true })
|
||||
UserName: string;
|
||||
|
||||
@Column({ comment: "密码" })
|
||||
Password: string;
|
||||
|
||||
@Column({ comment: "昵称", nullable: true })
|
||||
NickName: string;
|
||||
|
||||
@Column({ comment: "头像", nullable: true })
|
||||
Avatar: string;
|
||||
|
||||
@Column({ comment: "出生日期", nullable: true })
|
||||
Birthday: string;
|
||||
|
||||
@Column({ comment: "性别", nullable: true, default: 0 })
|
||||
Sex: SexEnum;
|
||||
|
||||
@Column({ comment: "邮箱", unique: true })
|
||||
Email: string;
|
||||
|
||||
@Column({ comment: "手机号码", unique: true })
|
||||
Phone: string;
|
||||
|
||||
@Column({ comment: "真实姓名", nullable: true })
|
||||
RealName: string;
|
||||
|
||||
@Column({ comment: "身份证号", nullable: true })
|
||||
IdCard: string;
|
||||
|
||||
@Column({ comment: "个性签名", nullable: true })
|
||||
Signature: string;
|
||||
@Column({ comment: "个人简介", nullable: true })
|
||||
Introduction: string;
|
||||
|
||||
@Column({ comment: "备注", nullable: true })
|
||||
Remark: string;
|
||||
|
||||
@Column({ comment: "角色Id", default: 0 })
|
||||
RoleId: number;
|
||||
}
|
||||
|
|
@ -0,0 +1,78 @@
|
|||
/*
|
||||
* @Author: '490912587@qq.com' '490912587@qq.com'
|
||||
* @Date: 2022-11-18 09:02:28
|
||||
* @LastEditors: '490912587@qq.com' '490912587@qq.com'
|
||||
* @LastEditTime: 2022-11-24 00:20:22
|
||||
* @FilePath: \tsplatform\backend\src\Expand\CommonDto.ts
|
||||
* @Description: 公共DTO服务
|
||||
*/
|
||||
|
||||
import { Injectable } from "@nestjs/common";
|
||||
import { ApiProperty } from "@nestjs/swagger";
|
||||
import { IsArray, IsNotEmpty, IsNumber, IsNumberString } from "class-validator";
|
||||
//分页查询DTO
|
||||
@Injectable()
|
||||
export class PageDto {
|
||||
@IsNotEmpty()
|
||||
@IsNumberString()
|
||||
@ApiProperty({ name: "Page", required: true })
|
||||
Page: number
|
||||
|
||||
@IsNotEmpty()
|
||||
@IsNumberString()
|
||||
@ApiProperty({ name: "PageSize", required: true })
|
||||
PageSize: number
|
||||
|
||||
@ApiProperty({ name: "Keywords", required: false })
|
||||
Keywords: string
|
||||
|
||||
@ApiProperty({ name: "OrderBy", required: false })
|
||||
OrderBy: string
|
||||
}
|
||||
|
||||
//列表查询DTO
|
||||
@Injectable()
|
||||
export class ListDto {
|
||||
@ApiProperty({ name: "Keywords", required: false })
|
||||
Keywords: string
|
||||
|
||||
@ApiProperty({ name: "OrderBy", required: false })
|
||||
OrderBy: string
|
||||
}
|
||||
|
||||
//ids DTO
|
||||
@Injectable()
|
||||
export class IdsDto {
|
||||
@IsNotEmpty()
|
||||
@IsArray()
|
||||
@ApiProperty({ name: "Ids", required: true })
|
||||
Ids: number[]
|
||||
}
|
||||
//id DTO
|
||||
@Injectable()
|
||||
export class IdDto {
|
||||
@IsNotEmpty()
|
||||
@IsNumber()
|
||||
@ApiProperty({ name: "Id", required: true })
|
||||
Id: number
|
||||
}
|
||||
@Injectable()
|
||||
export class RoleIdDto {
|
||||
@ApiProperty({ name: "RoleId" })
|
||||
RoleId: number;
|
||||
}
|
||||
|
||||
|
||||
//Id Status DTO
|
||||
@Injectable()
|
||||
export class IdStatusDto {
|
||||
@IsNotEmpty()
|
||||
@IsNumber()
|
||||
@ApiProperty({ name: "Id", required: true })
|
||||
Id: number
|
||||
|
||||
@IsNotEmpty()
|
||||
@IsNumber()
|
||||
@ApiProperty({ name: "Status", required: true })
|
||||
Status: number
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
/*
|
||||
* @Author: '490912587@qq.com' '490912587@qq.com'
|
||||
* @Date: 2022-11-18 17:35:08
|
||||
* @LastEditors: '490912587@qq.com' '490912587@qq.com'
|
||||
* @LastEditTime: 2022-11-23 12:12:42
|
||||
* @FilePath: \tsplatform\backend\src\EntiyDto\Login.ts
|
||||
* @Description: DTO类
|
||||
*/
|
||||
import { ApiProperty } from "@nestjs/swagger";
|
||||
import { IsNotEmpty, IsString } from "class-validator";
|
||||
export class LoginDto {
|
||||
@IsNotEmpty()
|
||||
@IsString()
|
||||
@ApiProperty({ name: "UserName", required: true })
|
||||
UserName: string;
|
||||
|
||||
@IsNotEmpty()
|
||||
@IsString()
|
||||
@ApiProperty({ name: "Password", required: true })
|
||||
Password: string;
|
||||
}
|
||||
|
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
* @Author: '490912587@qq.com' '490912587@qq.com'
|
||||
* @Date: 2022-11-18 17:35:08
|
||||
* @LastEditors: '490912587@qq.com' '490912587@qq.com'
|
||||
* @LastEditTime: 2022-11-24 00:14:13
|
||||
* @FilePath: \tsplatform\backend\src\EntiyDto\MenuDto.ts
|
||||
* @Description: SysMenu DTO类
|
||||
*/
|
||||
import { ApiProperty } from "@nestjs/swagger";
|
||||
import { IsBoolean, IsNotEmpty, IsNumber, IsString } from "class-validator";
|
||||
import { MenuEnum } from "src/Enum/Global";
|
||||
|
||||
export class MenuDto {
|
||||
@ApiProperty({ name: "ParentId" })
|
||||
ParentId: number;
|
||||
|
||||
@IsNotEmpty()
|
||||
@IsNumber()
|
||||
@ApiProperty({ name: "Type", required: true })
|
||||
Type: MenuEnum;
|
||||
|
||||
@ApiProperty({ name: "Name", required: false })
|
||||
Name: string;
|
||||
|
||||
@ApiProperty({ name: "Path", required: false })
|
||||
Path: string;
|
||||
|
||||
@ApiProperty({ name: "Component", required: false })
|
||||
Component: string;
|
||||
|
||||
@ApiProperty({ name: "Redirect", required: false })
|
||||
Redirect: string;
|
||||
|
||||
@IsNotEmpty()
|
||||
@IsString()
|
||||
@ApiProperty({ name: "Title", required: true })
|
||||
Title: string;
|
||||
|
||||
|
||||
@ApiProperty({ name: "IsLink", required: false })
|
||||
IsLink: string;
|
||||
|
||||
@IsNotEmpty()
|
||||
@IsBoolean()
|
||||
@ApiProperty({ name: "IsHide", required: true })
|
||||
IsHide: boolean;
|
||||
|
||||
@IsNotEmpty()
|
||||
@IsBoolean()
|
||||
@ApiProperty({ name: "IsKeepAlive", required: true })
|
||||
IsKeepAlive: boolean;
|
||||
|
||||
@IsNotEmpty()
|
||||
@IsBoolean()
|
||||
@ApiProperty({ name: "IsAffix", required: true })
|
||||
IsAffix: boolean;
|
||||
|
||||
@IsNotEmpty()
|
||||
@IsBoolean()
|
||||
@ApiProperty({ name: "IsIframe", required: true })
|
||||
IsIframe: boolean;
|
||||
|
||||
@IsNotEmpty()
|
||||
@IsString()
|
||||
@ApiProperty({ name: "Permission", required: true })
|
||||
Permission: string;
|
||||
|
||||
@ApiProperty({ name: "Icon", required: false })
|
||||
Icon: string;
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* @Author: '490912587@qq.com' '490912587@qq.com'
|
||||
* @Date: 2022-11-22 16:16:08
|
||||
* @LastEditors: '490912587@qq.com' '490912587@qq.com'
|
||||
* @LastEditTime: 2022-11-23 12:12:56
|
||||
* @FilePath: \backend\src\EntiyDto\RoleDto.ts
|
||||
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
|
||||
*/
|
||||
|
||||
import { ApiProperty } from "@nestjs/swagger";
|
||||
import { IsArray, IsNotEmpty } from "class-validator";
|
||||
|
||||
export class RoleDto {
|
||||
@IsNotEmpty()
|
||||
@ApiProperty({ name: "Name", required: true })
|
||||
Name: string;
|
||||
|
||||
@ApiProperty({ name: "Remark" })
|
||||
Remark: string;
|
||||
|
||||
@IsNotEmpty()
|
||||
@IsArray()
|
||||
@ApiProperty({ name: "SysRoleMenu", required: true })
|
||||
SysRoleMenu: number[];
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* @Author: '490912587@qq.com' '490912587@qq.com'
|
||||
* @Date: 2022-11-18 17:35:08
|
||||
* @LastEditors: '490912587@qq.com' '490912587@qq.com'
|
||||
* @LastEditTime: 2022-11-23 12:13:13
|
||||
* @FilePath: \tsplatform\backend\src\EntiyDto\RouteMenu.ts
|
||||
* @Description: RouteMenu类 菜单树查询,不需要dto映射
|
||||
*/
|
||||
export class RouteMenu {
|
||||
name: string;
|
||||
path: string;
|
||||
component: string;
|
||||
redirect: string;
|
||||
meta: Meta;
|
||||
children: RouteMenu[];
|
||||
}
|
||||
export class Meta {
|
||||
title: string;
|
||||
isLink: string;
|
||||
isHide: boolean;
|
||||
isKeepAlive: boolean;
|
||||
isAffix: boolean;
|
||||
isIframe: boolean;
|
||||
permission: string;
|
||||
icon: string;
|
||||
}
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
* @Author: '490912587@qq.com' '490912587@qq.com'
|
||||
* @Date: 2022-11-22 16:16:19
|
||||
* @LastEditors: '490912587@qq.com' '490912587@qq.com'
|
||||
* @LastEditTime: 2022-11-23 21:32:25
|
||||
* @FilePath: \backend\src\EntiyDto\UserDto.ts
|
||||
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
|
||||
*/
|
||||
|
||||
import { ApiProperty } from "@nestjs/swagger";
|
||||
import { IsNotEmpty, IsNumber, IsNumberString } from "class-validator";
|
||||
|
||||
export class UserDto {
|
||||
@IsNotEmpty()
|
||||
@IsNumber()
|
||||
@ApiProperty({ name: "UserType", required: true })
|
||||
UserType: number;
|
||||
|
||||
@IsNotEmpty()
|
||||
@ApiProperty({ name: "Name", required: true })
|
||||
UserName: string;
|
||||
|
||||
@ApiProperty({ name: "Password" })
|
||||
Password: string;
|
||||
|
||||
@ApiProperty({ name: "NickName" })
|
||||
NickName: string;
|
||||
|
||||
@ApiProperty({ name: "Avatar" })
|
||||
Avatar: string;
|
||||
|
||||
@ApiProperty({ name: "Birthday" })
|
||||
Birthday: string;
|
||||
|
||||
@IsNotEmpty()
|
||||
@IsNumber()
|
||||
@ApiProperty({ name: "Sex" })
|
||||
Sex: number;
|
||||
|
||||
@ApiProperty({ name: "Email", required: true })
|
||||
Email: string;
|
||||
|
||||
@IsNotEmpty()
|
||||
@IsNumberString()
|
||||
@ApiProperty({ name: "Phone", required: true })
|
||||
Phone: string;
|
||||
|
||||
@ApiProperty({ name: "RealName" })
|
||||
RealName: string;
|
||||
|
||||
@ApiProperty({ name: "IdCard" })
|
||||
IdCard: string;
|
||||
|
||||
@ApiProperty({ name: "Signature" })
|
||||
Signature: string;
|
||||
|
||||
@ApiProperty({ name: "Introduction" })
|
||||
Introduction: string;
|
||||
|
||||
@ApiProperty({ name: "Remark" })
|
||||
Remark: string;
|
||||
|
||||
@ApiProperty({ name: "RoleId", required: true })
|
||||
RoleId: number;
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* @Author: '490912587@qq.com' '490912587@qq.com'
|
||||
* @Date: 2022-11-17 13:25:43
|
||||
* @LastEditors: '490912587@qq.com' '490912587@qq.com'
|
||||
* @LastEditTime: 2022-11-18 09:15:04
|
||||
* @FilePath: \tsplatform\backend\src\Enum\Global.ts
|
||||
* @Description: 全局枚举类
|
||||
*/
|
||||
|
||||
export enum RestfulHttpCodeEnum {
|
||||
SUCCESS = 200,
|
||||
FAIL = 300,
|
||||
NODATA = 201,
|
||||
}
|
||||
export enum UserTypeEnum {
|
||||
Admin = 0,
|
||||
None = 1,
|
||||
SuperAdmin = 999,
|
||||
}
|
||||
export enum SexEnum {
|
||||
Man = 0,
|
||||
WoMan = 1
|
||||
}
|
||||
export enum MenuEnum {
|
||||
Directory = 0,
|
||||
Menu = 1,
|
||||
Btn = 2
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* @Author: '490912587@qq.com' '490912587@qq.com'
|
||||
* @Date: 2022-11-17 09:19:20
|
||||
* @LastEditors: '490912587@qq.com' '490912587@qq.com'
|
||||
* @LastEditTime: 2022-11-18 09:10:15
|
||||
* @FilePath: \tsplatform\backend\src\Expand\RestfulReturn.ts
|
||||
* @Description: RestfulAPI全局响应结构
|
||||
*/
|
||||
import { Injectable } from "@nestjs/common";
|
||||
import { RestfulHttpCodeEnum } from "src/Enum/Global";
|
||||
@Injectable()
|
||||
export class RestfulReturn {
|
||||
//HttpStatus=200时的状态码规则
|
||||
toJson(code: RestfulHttpCodeEnum, data: any) {
|
||||
return {
|
||||
code: code,
|
||||
msg: code === RestfulHttpCodeEnum.SUCCESS ? "操作成功!" :
|
||||
code === RestfulHttpCodeEnum.FAIL ? "操作失败!" :
|
||||
code === RestfulHttpCodeEnum.NODATA ? "数据为空!" : "未知错误!",
|
||||
data: data,
|
||||
timespan: new Date().getTime()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
/*
|
||||
* @Author: '490912587@qq.com' '490912587@qq.com'
|
||||
* @Date: 2022-11-18 09:02:28
|
||||
* @LastEditors: '490912587@qq.com' '490912587@qq.com'
|
||||
* @LastEditTime: 2022-11-24 10:13:53
|
||||
* @FilePath: \tsplatform\backend\src\Logging\LoggerPrint.ts
|
||||
* @Description: 全局日志打印服务
|
||||
*/
|
||||
|
||||
import { Injectable, Logger } from "@nestjs/common";
|
||||
@Injectable()
|
||||
export class LoggerPrint {
|
||||
constructor(private readonly logger: Logger) {
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* @Author: '490912587@qq.com' '490912587@qq.com'
|
||||
* @Date: 2022-11-21 11:57:30
|
||||
* @LastEditors: '490912587@qq.com' '490912587@qq.com'
|
||||
* @LastEditTime: 2022-11-22 10:41:09
|
||||
* @FilePath: \tsplatform\backend\src\Middleware\JwtHandle.ts
|
||||
* @Description: 授权中间件
|
||||
*/
|
||||
import { HttpException, HttpStatus, Injectable, NestMiddleware } from '@nestjs/common';
|
||||
import { JwtService } from '@nestjs/jwt';
|
||||
import { NextFunction } from 'express';
|
||||
import { AppConfig } from 'src/Config/Index';
|
||||
|
||||
@Injectable()
|
||||
export class JwtHandle implements NestMiddleware {
|
||||
constructor(
|
||||
public readonly _jwt: JwtService
|
||||
) { }
|
||||
async use(req: Request, res: Response, next: NextFunction) {
|
||||
try {
|
||||
const token = req.headers["authorization"];
|
||||
if (!token) {
|
||||
throw new HttpException("Token指令牌不存在!", HttpStatus.UNAUTHORIZED);
|
||||
} else {
|
||||
await this._jwt.verifyAsync(token, { secret: AppConfig.jwt.secret, ignoreExpiration: false })
|
||||
next();
|
||||
}
|
||||
}
|
||||
catch (ex) {
|
||||
throw new HttpException(ex.message, HttpStatus.UNAUTHORIZED);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,216 @@
|
|||
/*
|
||||
* @Author: '490912587@qq.com' '490912587@qq.com'
|
||||
* @Date: 2022-11-24 09:22:50
|
||||
* @LastEditors: '490912587@qq.com' '490912587@qq.com'
|
||||
* @LastEditTime: 2022-11-24 09:58:45
|
||||
* @FilePath: \backend\src\SeedData\Menu.ts
|
||||
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
|
||||
*/
|
||||
export const menus = [{
|
||||
"Id": 8,
|
||||
"Status": 0,
|
||||
"MerchantId": 0,
|
||||
"CreateTime": "2022-11-23T07:53:21.453Z",
|
||||
"UpdateTime": "2022-11-24T01:29:41.000Z",
|
||||
"OperatorId": 0,
|
||||
"UpdateUserId": 0,
|
||||
"IsDelete": false,
|
||||
"Version": 5,
|
||||
"ParentId": 2,
|
||||
"Type": 1,
|
||||
"Name": "system.city",
|
||||
"Path": "/system/city",
|
||||
"Component": "/system/city/index",
|
||||
"Redirect": "",
|
||||
"Title": "message.router.system.city",
|
||||
"IsLink": "",
|
||||
"IsHide": false,
|
||||
"IsKeepAlive": true,
|
||||
"IsAffix": false,
|
||||
"IsIframe": false,
|
||||
"Permission": "system.city",
|
||||
"Icon": "ele-OfficeBuilding",
|
||||
"Sort": 101
|
||||
},
|
||||
{
|
||||
"Id": 7,
|
||||
"Status": 0,
|
||||
"MerchantId": 0,
|
||||
"CreateTime": "2022-11-23T07:50:37.192Z",
|
||||
"UpdateTime": "2022-11-24T01:21:19.762Z",
|
||||
"OperatorId": 0,
|
||||
"UpdateUserId": 0,
|
||||
"IsDelete": false,
|
||||
"Version": 4,
|
||||
"ParentId": 2,
|
||||
"Type": 1,
|
||||
"Name": "system.dic",
|
||||
"Path": "/system/dic",
|
||||
"Component": "/system/dic/index",
|
||||
"Redirect": "",
|
||||
"Title": "message.router.system.dic",
|
||||
"IsLink": "",
|
||||
"IsHide": false,
|
||||
"IsKeepAlive": true,
|
||||
"IsAffix": false,
|
||||
"IsIframe": false,
|
||||
"Permission": "system.dic",
|
||||
"Icon": "iconfont icon-zhongyingwen1",
|
||||
"Sort": 100
|
||||
},
|
||||
{
|
||||
"Id": 6,
|
||||
"Status": 0,
|
||||
"MerchantId": 0,
|
||||
"CreateTime": "2022-11-22T13:59:37.445Z",
|
||||
"UpdateTime": "2022-11-23T05:56:53.726Z",
|
||||
"OperatorId": 0,
|
||||
"UpdateUserId": 0,
|
||||
"IsDelete": false,
|
||||
"Version": 0,
|
||||
"ParentId": 0,
|
||||
"Type": 0,
|
||||
"Name": "personal",
|
||||
"Path": "/personal",
|
||||
"Component": "personal/index",
|
||||
"Redirect": null,
|
||||
"Title": "message.router.personal",
|
||||
"IsLink": "",
|
||||
"IsHide": true,
|
||||
"IsKeepAlive": false,
|
||||
"IsAffix": false,
|
||||
"IsIframe": false,
|
||||
"Permission": "personal",
|
||||
"Icon": "iconfont icon-gerenzhongxin",
|
||||
"Sort": 6
|
||||
},
|
||||
{
|
||||
"Id": 5,
|
||||
"Status": 0,
|
||||
"MerchantId": 0,
|
||||
"CreateTime": "2022-11-22T13:59:37.445Z",
|
||||
"UpdateTime": "2022-11-23T08:05:06.779Z",
|
||||
"OperatorId": 0,
|
||||
"UpdateUserId": 0,
|
||||
"IsDelete": false,
|
||||
"Version": 0,
|
||||
"ParentId": 2,
|
||||
"Type": 1,
|
||||
"Name": "system.role",
|
||||
"Path": "/system/role",
|
||||
"Component": "system/role/index",
|
||||
"Redirect": null,
|
||||
"Title": "message.router.system.role",
|
||||
"IsLink": "",
|
||||
"IsHide": false,
|
||||
"IsKeepAlive": true,
|
||||
"IsAffix": false,
|
||||
"IsIframe": false,
|
||||
"Permission": "system.role",
|
||||
"Icon": "fa fa-street-view",
|
||||
"Sort": 5
|
||||
},
|
||||
{
|
||||
"Id": 4,
|
||||
"Status": 0,
|
||||
"MerchantId": 0,
|
||||
"CreateTime": "2022-11-22T13:59:37.445Z",
|
||||
"UpdateTime": "2022-11-23T08:05:03.689Z",
|
||||
"OperatorId": 0,
|
||||
"UpdateUserId": 0,
|
||||
"IsDelete": false,
|
||||
"Version": 0,
|
||||
"ParentId": 2,
|
||||
"Type": 1,
|
||||
"Name": "system.user",
|
||||
"Path": "/system/user",
|
||||
"Component": "system/user/index",
|
||||
"Redirect": null,
|
||||
"Title": "message.router.system.user",
|
||||
"IsLink": null,
|
||||
"IsHide": false,
|
||||
"IsKeepAlive": true,
|
||||
"IsAffix": false,
|
||||
"IsIframe": false,
|
||||
"Permission": "system.user",
|
||||
"Icon": "iconfont icon-icon-",
|
||||
"Sort": 4
|
||||
},
|
||||
{
|
||||
"Id": 3,
|
||||
"Status": 0,
|
||||
"MerchantId": 0,
|
||||
"CreateTime": "2022-11-22T13:59:37.445Z",
|
||||
"UpdateTime": "2022-11-23T08:05:00.650Z",
|
||||
"OperatorId": 0,
|
||||
"UpdateUserId": 0,
|
||||
"IsDelete": false,
|
||||
"Version": 0,
|
||||
"ParentId": 2,
|
||||
"Type": 1,
|
||||
"Name": "system.menu",
|
||||
"Path": "/system/menu",
|
||||
"Component": "system/menu/index",
|
||||
"Redirect": null,
|
||||
"Title": "message.router.system.menu",
|
||||
"IsLink": "",
|
||||
"IsHide": false,
|
||||
"IsKeepAlive": true,
|
||||
"IsAffix": false,
|
||||
"IsIframe": false,
|
||||
"Permission": "system.menu",
|
||||
"Icon": "iconfont icon-caidan",
|
||||
"Sort": 3
|
||||
},
|
||||
{
|
||||
"Id": 2,
|
||||
"Status": 0,
|
||||
"MerchantId": 0,
|
||||
"CreateTime": "2022-11-22T13:59:37.445Z",
|
||||
"UpdateTime": "2022-11-23T08:05:16.188Z",
|
||||
"OperatorId": 0,
|
||||
"UpdateUserId": 0,
|
||||
"IsDelete": false,
|
||||
"Version": 0,
|
||||
"ParentId": 0,
|
||||
"Type": 0,
|
||||
"Name": "system",
|
||||
"Path": "/system",
|
||||
"Component": "layout/routerView/parent",
|
||||
"Redirect": "/system/menu",
|
||||
"Title": "message.router.system.system",
|
||||
"IsLink": "",
|
||||
"IsHide": false,
|
||||
"IsKeepAlive": true,
|
||||
"IsAffix": false,
|
||||
"IsIframe": false,
|
||||
"Permission": "system",
|
||||
"Icon": "iconfont icon-xitongshezhi",
|
||||
"Sort": 2
|
||||
},
|
||||
{
|
||||
"Id": 1,
|
||||
"Status": 0,
|
||||
"MerchantId": 0,
|
||||
"CreateTime": "2022-11-22T13:59:37.445Z",
|
||||
"UpdateTime": "2022-11-22T13:59:37.471Z",
|
||||
"OperatorId": 0,
|
||||
"UpdateUserId": 0,
|
||||
"IsDelete": false,
|
||||
"Version": 0,
|
||||
"ParentId": 0,
|
||||
"Type": 0,
|
||||
"Name": "home",
|
||||
"Path": "/home",
|
||||
"Component": "home/index",
|
||||
"Redirect": "",
|
||||
"Title": "message.router.home",
|
||||
"IsLink": "",
|
||||
"IsHide": false,
|
||||
"IsKeepAlive": true,
|
||||
"IsAffix": true,
|
||||
"IsIframe": false,
|
||||
"Permission": "home",
|
||||
"Icon": "iconfont icon-shouye",
|
||||
"Sort": 1
|
||||
}];
|
||||
|
|
@ -0,0 +1,179 @@
|
|||
/*
|
||||
* @Author: '490912587@qq.com' '490912587@qq.com'
|
||||
* @Date: 2022-11-24 09:23:07
|
||||
* @LastEditors: '490912587@qq.com' '490912587@qq.com'
|
||||
* @LastEditTime: 2022-11-24 10:04:17
|
||||
* @FilePath: \backend\src\SeedData\Role.ts
|
||||
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
|
||||
*/
|
||||
export const roles = [
|
||||
{
|
||||
"Id": 1,
|
||||
"Status": 0,
|
||||
"MerchantId": 0,
|
||||
"CreateTime": "2022-11-22T13:59:37.567Z",
|
||||
"UpdateTime": "2022-11-24T01:35:03.000Z",
|
||||
"OperatorId": 0,
|
||||
"UpdateUserId": 0,
|
||||
"IsDelete": false,
|
||||
"Version": 4,
|
||||
"Name": "超级管理员",
|
||||
"Remark": null
|
||||
},
|
||||
{
|
||||
"Id": 2,
|
||||
"Status": 0,
|
||||
"MerchantId": 0,
|
||||
"CreateTime": "2022-11-22T13:59:37.567Z",
|
||||
"UpdateTime": "2022-11-24T01:36:45.000Z",
|
||||
"OperatorId": 0,
|
||||
"UpdateUserId": 0,
|
||||
"IsDelete": false,
|
||||
"Version": 3,
|
||||
"Name": "普通用户",
|
||||
"Remark": null
|
||||
}
|
||||
];
|
||||
export const roleMenus = [{
|
||||
"Id": 1,
|
||||
"Status": 0,
|
||||
"MerchantId": 0,
|
||||
"CreateTime": "2022-11-24T01:35:03.437Z",
|
||||
"UpdateTime": "2022-11-24T01:35:03.437Z",
|
||||
"OperatorId": 0,
|
||||
"UpdateUserId": 0,
|
||||
"IsDelete": false,
|
||||
"Version": 1,
|
||||
"MenuId": 1,
|
||||
"RoleId": 1
|
||||
},
|
||||
{
|
||||
"Id": 2,
|
||||
"Status": 0,
|
||||
"MerchantId": 0,
|
||||
"CreateTime": "2022-11-24T01:35:03.437Z",
|
||||
"UpdateTime": "2022-11-24T01:35:03.437Z",
|
||||
"OperatorId": 0,
|
||||
"UpdateUserId": 0,
|
||||
"IsDelete": false,
|
||||
"Version": 1,
|
||||
"MenuId": 2,
|
||||
"RoleId": 1
|
||||
},
|
||||
{
|
||||
"Id": 3,
|
||||
"Status": 0,
|
||||
"MerchantId": 0,
|
||||
"CreateTime": "2022-11-24T01:35:03.437Z",
|
||||
"UpdateTime": "2022-11-24T01:35:03.437Z",
|
||||
"OperatorId": 0,
|
||||
"UpdateUserId": 0,
|
||||
"IsDelete": false,
|
||||
"Version": 1,
|
||||
"MenuId": 3,
|
||||
"RoleId": 1
|
||||
},
|
||||
{
|
||||
"Id": 4,
|
||||
"Status": 0,
|
||||
"MerchantId": 0,
|
||||
"CreateTime": "2022-11-24T01:35:03.437Z",
|
||||
"UpdateTime": "2022-11-24T01:35:03.437Z",
|
||||
"OperatorId": 0,
|
||||
"UpdateUserId": 0,
|
||||
"IsDelete": false,
|
||||
"Version": 1,
|
||||
"MenuId": 4,
|
||||
"RoleId": 1
|
||||
},
|
||||
{
|
||||
"Id": 5,
|
||||
"Status": 0,
|
||||
"MerchantId": 0,
|
||||
"CreateTime": "2022-11-24T01:35:03.437Z",
|
||||
"UpdateTime": "2022-11-24T01:35:03.437Z",
|
||||
"OperatorId": 0,
|
||||
"UpdateUserId": 0,
|
||||
"IsDelete": false,
|
||||
"Version": 1,
|
||||
"MenuId": 5,
|
||||
"RoleId": 1
|
||||
},
|
||||
{
|
||||
"Id": 6,
|
||||
"Status": 0,
|
||||
"MerchantId": 0,
|
||||
"CreateTime": "2022-11-24T01:35:03.437Z",
|
||||
"UpdateTime": "2022-11-24T01:35:03.437Z",
|
||||
"OperatorId": 0,
|
||||
"UpdateUserId": 0,
|
||||
"IsDelete": false,
|
||||
"Version": 1,
|
||||
"MenuId": 6,
|
||||
"RoleId": 1
|
||||
},
|
||||
{
|
||||
"Id": 7,
|
||||
"Status": 0,
|
||||
"MerchantId": 0,
|
||||
"CreateTime": "2022-11-24T01:35:03.437Z",
|
||||
"UpdateTime": "2022-11-24T01:35:03.437Z",
|
||||
"OperatorId": 0,
|
||||
"UpdateUserId": 0,
|
||||
"IsDelete": false,
|
||||
"Version": 1,
|
||||
"MenuId": 7,
|
||||
"RoleId": 1
|
||||
},
|
||||
{
|
||||
"Id": 8,
|
||||
"Status": 0,
|
||||
"MerchantId": 0,
|
||||
"CreateTime": "2022-11-24T01:35:03.437Z",
|
||||
"UpdateTime": "2022-11-24T01:35:03.437Z",
|
||||
"OperatorId": 0,
|
||||
"UpdateUserId": 0,
|
||||
"IsDelete": false,
|
||||
"Version": 1,
|
||||
"MenuId": 8,
|
||||
"RoleId": 1
|
||||
},
|
||||
{
|
||||
"Id": 9,
|
||||
"Status": 0,
|
||||
"MerchantId": 0,
|
||||
"CreateTime": "2022-11-24T01:36:45.486Z",
|
||||
"UpdateTime": "2022-11-24T01:36:45.486Z",
|
||||
"OperatorId": 0,
|
||||
"UpdateUserId": 0,
|
||||
"IsDelete": false,
|
||||
"Version": 1,
|
||||
"MenuId": 1,
|
||||
"RoleId": 2
|
||||
},
|
||||
{
|
||||
"Id": 10,
|
||||
"Status": 0,
|
||||
"MerchantId": 0,
|
||||
"CreateTime": "2022-11-24T01:36:45.486Z",
|
||||
"UpdateTime": "2022-11-24T01:36:45.486Z",
|
||||
"OperatorId": 0,
|
||||
"UpdateUserId": 0,
|
||||
"IsDelete": false,
|
||||
"Version": 1,
|
||||
"MenuId": 2,
|
||||
"RoleId": 2
|
||||
},
|
||||
{
|
||||
"Id": 11,
|
||||
"Status": 0,
|
||||
"MerchantId": 0,
|
||||
"CreateTime": "2022-11-24T01:36:45.486Z",
|
||||
"UpdateTime": "2022-11-24T01:36:45.486Z",
|
||||
"OperatorId": 0,
|
||||
"UpdateUserId": 0,
|
||||
"IsDelete": false,
|
||||
"Version": 1,
|
||||
"MenuId": 4,
|
||||
"RoleId": 2
|
||||
}];
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
* @Author: '490912587@qq.com' '490912587@qq.com'
|
||||
* @Date: 2022-11-24 09:22:58
|
||||
* @LastEditors: '490912587@qq.com' '490912587@qq.com'
|
||||
* @LastEditTime: 2022-11-24 10:04:55
|
||||
* @FilePath: \backend\src\SeedData\User.ts
|
||||
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
|
||||
*/
|
||||
export const users = [{
|
||||
"Id": 1,
|
||||
"Status": 0,
|
||||
"MerchantId": 0,
|
||||
"CreateTime": "2022-11-22T13:59:37.496Z",
|
||||
"UpdateTime": "2022-11-24T01:21:53.423Z",
|
||||
"OperatorId": 0,
|
||||
"UpdateUserId": 0,
|
||||
"IsDelete": false,
|
||||
"Version": 0,
|
||||
"UserType": 999,
|
||||
"UserName": "admin",
|
||||
"Password": "1a23c5066d05474304c03342e57850d9",
|
||||
"NickName": "甜蜜蜜",
|
||||
"Avatar": "https://img2.baidu.com/it/u=1978192862,2048448374&fm=253&fmt=auto&app=138&f=JPEG?w=504&h=500",
|
||||
"Birthday": null,
|
||||
"Sex": 0,
|
||||
"Email": "490912587@qq.com",
|
||||
"Phone": "13000000000",
|
||||
"RealName": null,
|
||||
"IdCard": null,
|
||||
"Signature": null,
|
||||
"Introduction": null,
|
||||
"Remark": null,
|
||||
"RoleId": 1
|
||||
},
|
||||
{
|
||||
"Id": 2,
|
||||
"Status": 0,
|
||||
"MerchantId": 0,
|
||||
"CreateTime": "2022-11-23T08:45:37.321Z",
|
||||
"UpdateTime": "2022-11-24T01:39:33.000Z",
|
||||
"OperatorId": 0,
|
||||
"UpdateUserId": 0,
|
||||
"IsDelete": false,
|
||||
"Version": 4,
|
||||
"UserType": 0,
|
||||
"UserName": "test",
|
||||
"Password": "7b0ea1aa91470cd870111415a94b475b",
|
||||
"NickName": "甜蜜蜜的小号",
|
||||
"Avatar": "https://img2.baidu.com/it/u=1978192862,2048448374&fm=253&fmt=auto&app=138&f=JPEG?w=504&h=500",
|
||||
"Birthday": null,
|
||||
"Sex": 1,
|
||||
"Email": "1844045442@qq.com",
|
||||
"Phone": "15000000000",
|
||||
"RealName": null,
|
||||
"IdCard": null,
|
||||
"Signature": null,
|
||||
"Introduction": null,
|
||||
"Remark": null,
|
||||
"RoleId": 2
|
||||
}];
|
||||
|
|
@ -0,0 +1,94 @@
|
|||
/*
|
||||
* @Author: '490912587@qq.com' '490912587@qq.com'
|
||||
* @Date: 2022-11-17 17:08:52
|
||||
* @LastEditors: '490912587@qq.com' '490912587@qq.com'
|
||||
* @LastEditTime: 2022-11-24 11:12:25
|
||||
* @FilePath: \tsplatform\backend\src\Service\UserService.ts
|
||||
* @Description: 省市区服务
|
||||
*/
|
||||
|
||||
import { Injectable, Logger } from '@nestjs/common';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
import { DeleteResult, In, InsertResult, Like, Repository } from 'typeorm';
|
||||
import { LoggerPrint } from 'src/Logging/LoggerPrint';
|
||||
import { SysCity } from 'src/Entity/SysCity';
|
||||
import { citys } from 'src/SeedData/City';
|
||||
@Injectable()
|
||||
export class CityService {
|
||||
private readonly tableName: string = "省市区";
|
||||
constructor(
|
||||
public readonly loggerPrint: LoggerPrint,
|
||||
public readonly logger: Logger,
|
||||
@InjectRepository(SysCity)
|
||||
public readonly repository: Repository<SysCity>
|
||||
) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
//#region 基础控制器
|
||||
// 初始化数据
|
||||
async seedData(): Promise<number> {
|
||||
let result: InsertResult;
|
||||
await this.repository.queryRunner?.startTransaction();
|
||||
try {
|
||||
await this.repository.clear();
|
||||
result = await this.repository.createQueryBuilder().insert().values(citys).execute();
|
||||
await this.repository.queryRunner?.commitTransaction();
|
||||
await this.repository.createQueryBuilder().useTransaction(true);
|
||||
return result.identifiers.length;
|
||||
} catch (err) {
|
||||
//如果遇到错误,可以回滚事务
|
||||
await this.repository.queryRunner?.rollbackTransaction();
|
||||
this.logger.warn(err);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
async getPage(
|
||||
page: number = 1,
|
||||
pageSize: number = 10,
|
||||
keywords: string = "",
|
||||
orderBy: string = ""
|
||||
): Promise<[SysCity[], number]> {
|
||||
const result = await this.repository.findAndCount({
|
||||
where: [{ RegionName: Like("%" + keywords + "%") }, { RegionShortName: Like("%" + keywords + "%") }],
|
||||
order: {
|
||||
Id: "ASC"
|
||||
},
|
||||
skip: page - 1,
|
||||
take: pageSize
|
||||
})
|
||||
return result;
|
||||
}
|
||||
async getList(
|
||||
keywords: string = "",
|
||||
orderBy: string = "",
|
||||
): Promise<SysCity[]> {
|
||||
const result = await this.repository.find({
|
||||
where: [{ RegionName: Like("%" + keywords + "%") }, { RegionShortName: Like("%" + keywords + "%") }],
|
||||
order: {
|
||||
Id: "ASC"
|
||||
},
|
||||
})
|
||||
return result;
|
||||
}
|
||||
async getById(id: number): Promise<SysCity> {
|
||||
const result = await this.repository.findOne({ where: { Id: id } });
|
||||
return result;
|
||||
}
|
||||
async getByIds(ids: number[]): Promise<SysCity[]> {
|
||||
const result = await this.repository.find({
|
||||
where: { Id: In(ids) },
|
||||
})
|
||||
return result;
|
||||
}
|
||||
async save(model: SysCity): Promise<SysCity> {
|
||||
const result = await this.repository.save(model);
|
||||
return result;
|
||||
}
|
||||
async destroy(id: number): Promise<DeleteResult> {
|
||||
const result = await this.repository.delete(id);
|
||||
return result;
|
||||
}
|
||||
//#endregion
|
||||
}
|
||||
|
|
@ -0,0 +1,94 @@
|
|||
/*
|
||||
* @Author: '490912587@qq.com' '490912587@qq.com'
|
||||
* @Date: 2022-11-17 17:08:52
|
||||
* @LastEditors: '490912587@qq.com' '490912587@qq.com'
|
||||
* @LastEditSysMenuime: 2022-11-18 11:31:43
|
||||
* @FilePath: \tsplatform\backend\src\Service\MenuService.ts
|
||||
* @Description: 系统菜单服务
|
||||
*/
|
||||
|
||||
import { Injectable, Logger } from '@nestjs/common';
|
||||
import { SysMenu } from 'src/Entity/SysMenu';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
import { DeleteResult, In, InsertResult, Like, Repository } from 'typeorm';
|
||||
import { LoggerPrint } from 'src/Logging/LoggerPrint';
|
||||
import { menus } from 'src/SeedData/Menu';
|
||||
@Injectable()
|
||||
export class MenuService {
|
||||
private readonly tableName: string = "系统菜单";
|
||||
constructor(
|
||||
public readonly loggerPrint: LoggerPrint,
|
||||
public readonly logger: Logger,
|
||||
|
||||
@InjectRepository(SysMenu)
|
||||
public readonly repository: Repository<SysMenu>
|
||||
) {
|
||||
}
|
||||
//#region 基础控制器
|
||||
// 初始化数据
|
||||
async seedData(): Promise<number> {
|
||||
let result: InsertResult;
|
||||
await this.repository.queryRunner?.startTransaction();
|
||||
try {
|
||||
await this.repository.clear();
|
||||
result = await this.repository.createQueryBuilder().insert().values(menus).execute();
|
||||
await this.repository.queryRunner?.commitTransaction();
|
||||
await this.repository.createQueryBuilder().useTransaction(true);
|
||||
return result.identifiers.length;
|
||||
} catch (err) {
|
||||
//如果遇到错误,可以回滚事务
|
||||
await this.repository.queryRunner?.rollbackTransaction();
|
||||
this.logger.warn(err);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
async getPage(
|
||||
page: number = 1,
|
||||
pageSize: number = 10,
|
||||
keywords: string = "",
|
||||
orderBy: string = ""
|
||||
): Promise<[SysMenu[], number]> {
|
||||
const result = await this.repository.findAndCount({
|
||||
where: [{ Title: Like("%" + keywords + "%") }, { Name: Like("%" + keywords + "%") }],
|
||||
order: {
|
||||
Id: "DESC"
|
||||
},
|
||||
skip: page - 1,
|
||||
take: pageSize
|
||||
})
|
||||
|
||||
return result;
|
||||
}
|
||||
async getList(
|
||||
keywords: string = "",
|
||||
orderBy: string = ""
|
||||
): Promise<SysMenu[]> {
|
||||
const result = await this.repository.find({
|
||||
where: [{ Name: Like("%" + keywords + "%") }],
|
||||
order: {
|
||||
Id: "DESC"
|
||||
},
|
||||
})
|
||||
return result;
|
||||
}
|
||||
async getById(id: number): Promise<SysMenu> {
|
||||
const result = await this.repository.findOne({ where: { Id: id } });
|
||||
return result;
|
||||
}
|
||||
async getByIds(ids: number[]): Promise<SysMenu[]> {
|
||||
const result = await this.repository.find({
|
||||
where: { Id: In(ids) },
|
||||
})
|
||||
return result;
|
||||
}
|
||||
async save(model: SysMenu): Promise<SysMenu> {
|
||||
const result = await this.repository.save(model);
|
||||
|
||||
return result;
|
||||
}
|
||||
async destroy(id: number): Promise<DeleteResult> {
|
||||
const result = await this.repository.delete(id);
|
||||
return result;
|
||||
}
|
||||
//#endregion
|
||||
}
|
||||
|
|
@ -0,0 +1,156 @@
|
|||
/*
|
||||
* @Author: '490912587@qq.com' '490912587@qq.com'
|
||||
* @Date: 2022-11-17 17:08:52
|
||||
* @LastEditors: '490912587@qq.com' '490912587@qq.com'
|
||||
* @LastEditTime: 2022-11-24 10:15:40
|
||||
* @FilePath: \tsplatform\backend\src\Service\RoleService.ts
|
||||
* @Description: 系统角色服务
|
||||
*/
|
||||
|
||||
import { Injectable, Logger } from '@nestjs/common';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
import { DeleteResult, In, InsertResult, Like, Repository } from 'typeorm';
|
||||
import { SysRole } from 'src/Entity/SysRole';
|
||||
import { LoggerPrint } from 'src/Logging/LoggerPrint';
|
||||
import { SysRoleMenu } from 'src/Entity/SysRoleMenu';
|
||||
import { roleMenus, roles } from 'src/SeedData/Role';
|
||||
// where: { Name: keywords },//and查询
|
||||
// where: [{ Name: keywords }],//or查询
|
||||
// where: { Name: Like("%out #%") },//like查询
|
||||
// where: { Id: In([0,1]) },//in查询
|
||||
// where: { Name: Like("%out #%") },//like查询
|
||||
@Injectable()
|
||||
export class RoleService {
|
||||
private readonly tableName: string = "系统角色";
|
||||
constructor(
|
||||
public readonly loggerPrint: LoggerPrint,
|
||||
public readonly logger: Logger,
|
||||
|
||||
@InjectRepository(SysRole)
|
||||
public readonly repository: Repository<SysRole>,
|
||||
@InjectRepository(SysRoleMenu)
|
||||
public readonly roleMenuRepository: Repository<SysRoleMenu>,
|
||||
) {
|
||||
}
|
||||
//根据角色Id获得路由菜单
|
||||
async getMenusByRoleId(id: number): Promise<SysRoleMenu[]> {
|
||||
//根据角色Id获得角色菜单映射数据
|
||||
const result = await this.roleMenuRepository.find({
|
||||
where: { RoleId: id }
|
||||
});
|
||||
return result;
|
||||
}
|
||||
//#region 基础控制器
|
||||
// 初始化数据
|
||||
async seedData(): Promise<number[]> {
|
||||
let result: InsertResult;
|
||||
let result1: InsertResult;
|
||||
await this.repository.queryRunner?.startTransaction();
|
||||
try {
|
||||
await this.repository.clear();
|
||||
result = await this.repository.createQueryBuilder().insert().values(roles).execute();
|
||||
result1 = await this.roleMenuRepository.createQueryBuilder().insert().values(roleMenus).execute();
|
||||
await this.repository.queryRunner?.commitTransaction();
|
||||
await this.repository.createQueryBuilder().useTransaction(true);
|
||||
return [result.identifiers.length, result1.identifiers.length]
|
||||
} catch (err) {
|
||||
//如果遇到错误,可以回滚事务
|
||||
await this.repository.queryRunner?.rollbackTransaction();
|
||||
this.logger.warn(err);
|
||||
return [0, 0];
|
||||
}
|
||||
}
|
||||
async getPage(
|
||||
page: number = 1,
|
||||
pageSize: number = 10,
|
||||
keywords: string = "",
|
||||
orderBy: string = ""
|
||||
): Promise<[SysRole[], number]> {
|
||||
const result = await this.repository.findAndCount({
|
||||
where: [{ Name: Like("%" + keywords + "%") }],
|
||||
order: {
|
||||
Id: "ASC"
|
||||
},
|
||||
skip: page - 1,
|
||||
take: pageSize
|
||||
})
|
||||
for await (let item of result[0]) {
|
||||
|
||||
const roleMenuResult = await this.roleMenuRepository.find({
|
||||
where: { RoleId: item.Id },
|
||||
})
|
||||
item.SysRoleMenu = roleMenuResult;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
async getList(
|
||||
keywords: string = "",
|
||||
orderBy: string = ""
|
||||
): Promise<SysRole[]> {
|
||||
const result = await this.repository.find({
|
||||
where: [{ Name: Like("%" + keywords + "%") }],
|
||||
order: {
|
||||
Id: "ASC"
|
||||
},
|
||||
})
|
||||
for await (let item of result) {
|
||||
const roleMenuResult = await this.roleMenuRepository.find({
|
||||
where: { RoleId: item.Id },
|
||||
})
|
||||
item.SysRoleMenu = roleMenuResult;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
async getById(id: number): Promise<SysRole> {
|
||||
const result = await this.repository.findOne({ where: { Id: id } });
|
||||
return result;
|
||||
}
|
||||
async getByIds(ids: number[]): Promise<SysRole[]> {
|
||||
const result = await this.repository.find({
|
||||
where: { Id: In(ids) }
|
||||
})
|
||||
return result;
|
||||
}
|
||||
async save(model: SysRole): Promise<boolean> {
|
||||
await this.repository.queryRunner?.startTransaction();
|
||||
try {
|
||||
//如果是编辑先删除主子表后,修改主表,新增子表
|
||||
if (model.Id > 0) {
|
||||
await this.repository.createQueryBuilder().update().set({ Name: model.Name, Remark: model.Remark, Status: model.Status }).where("Id = :Id", { Id: model.Id }).execute();
|
||||
await this.roleMenuRepository.delete({ RoleId: model.Id });
|
||||
for await (let item of model.SysRoleMenu) {
|
||||
item.RoleId = model.Id
|
||||
}
|
||||
} else {
|
||||
const result = await this.repository.createQueryBuilder().insert().values(model).execute();
|
||||
for await (let item of model.SysRoleMenu) {
|
||||
item.RoleId = result.identifiers[0].Id
|
||||
}
|
||||
}
|
||||
await this.roleMenuRepository.createQueryBuilder().insert().values(model.SysRoleMenu).execute();
|
||||
await this.repository.queryRunner?.commitTransaction();
|
||||
await this.repository.createQueryBuilder().useTransaction(true);
|
||||
return true;
|
||||
} catch (err) {
|
||||
await this.repository.queryRunner?.rollbackTransaction();
|
||||
this.logger.warn(err);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
async destroy(id: number): Promise<boolean> {
|
||||
await this.repository.queryRunner?.startTransaction();
|
||||
try {
|
||||
//删除主子表
|
||||
await this.repository.delete({ Id: id });
|
||||
await this.roleMenuRepository.delete({ RoleId: id });
|
||||
await this.repository.queryRunner?.commitTransaction();
|
||||
await this.repository.createQueryBuilder().useTransaction(true);
|
||||
return true;
|
||||
} catch (err) {
|
||||
await this.repository.queryRunner?.rollbackTransaction();
|
||||
this.logger.warn(err);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
//#endregion
|
||||
}
|
||||
|
|
@ -0,0 +1,93 @@
|
|||
/*
|
||||
* @Author: '490912587@qq.com' '490912587@qq.com'
|
||||
* @Date: 2022-11-17 17:08:52
|
||||
* @LastEditors: '490912587@qq.com' '490912587@qq.com'
|
||||
* @LastEditTime: 2022-11-24 10:15:57
|
||||
* @FilePath: \tsplatform\backend\src\Service\UserService.ts
|
||||
* @Description: 系统用户服务
|
||||
*/
|
||||
|
||||
import { Injectable, Logger } from '@nestjs/common';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
import { DeleteResult, In, InsertResult, Like, Repository } from 'typeorm';
|
||||
import { LoggerPrint } from 'src/Logging/LoggerPrint';
|
||||
import { SysUser } from 'src/Entity/SysUser';
|
||||
import { users } from 'src/SeedData/User';
|
||||
@Injectable()
|
||||
export class UserService {
|
||||
private readonly tableName: string = "系统用户";
|
||||
constructor(
|
||||
public readonly loggerPrint: LoggerPrint,
|
||||
public readonly logger: Logger,
|
||||
@InjectRepository(SysUser)
|
||||
public readonly repository: Repository<SysUser>
|
||||
) {
|
||||
|
||||
}
|
||||
//#region 基础控制器
|
||||
// 初始化数据
|
||||
async seedData(): Promise<number> {
|
||||
let result: InsertResult;
|
||||
await this.repository.queryRunner?.startTransaction();
|
||||
try {
|
||||
await this.repository.clear();
|
||||
result = await this.repository.createQueryBuilder().insert().values(users).execute();
|
||||
await this.repository.queryRunner?.commitTransaction();
|
||||
await this.repository.createQueryBuilder().useTransaction(true);
|
||||
return result.identifiers.length;
|
||||
} catch (err) {
|
||||
//如果遇到错误,可以回滚事务
|
||||
await this.repository.queryRunner?.rollbackTransaction();
|
||||
this.logger.warn(err);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
async getPage(
|
||||
page: number = 1,
|
||||
pageSize: number = 10,
|
||||
keywords: string = "",
|
||||
orderBy: string = ""
|
||||
): Promise<[SysUser[], number]> {
|
||||
const result = await this.repository.findAndCount({
|
||||
where: [{ Phone: Like("%" + keywords + "%") }, { UserName: Like("%" + keywords + "%") }, { NickName: Like("%" + keywords + "%") }],
|
||||
order: {
|
||||
Id: "ASC"
|
||||
},
|
||||
skip: page - 1,
|
||||
take: pageSize
|
||||
})
|
||||
|
||||
return result;
|
||||
}
|
||||
async getList(
|
||||
keywords: string = "",
|
||||
orderBy: string = ""
|
||||
): Promise<SysUser[]> {
|
||||
const result = await this.repository.find({
|
||||
where: [{ Phone: Like("%" + keywords + "%") }, { UserName: Like("%" + keywords + "%") }, { NickName: Like("%" + keywords + "%") }],
|
||||
order: {
|
||||
Id: "ASC"
|
||||
},
|
||||
})
|
||||
return result;
|
||||
}
|
||||
async getById(id: number): Promise<SysUser> {
|
||||
const result = await this.repository.findOne({ where: { Id: id } });
|
||||
return result;
|
||||
}
|
||||
async getByIds(ids: number[]): Promise<SysUser[]> {
|
||||
const result = await this.repository.find({
|
||||
where: { Id: In(ids) },
|
||||
})
|
||||
return result;
|
||||
}
|
||||
async save(model: SysUser): Promise<SysUser> {
|
||||
const result = await this.repository.save(model);
|
||||
return result;
|
||||
}
|
||||
async destroy(id: number): Promise<DeleteResult> {
|
||||
const result = await this.repository.delete(id);
|
||||
return result;
|
||||
}
|
||||
//#endregion
|
||||
}
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* @Author: '490912587@qq.com' '490912587@qq.com'
|
||||
* @Date: 2022-11-17 11:44:48
|
||||
* @LastEditors: '490912587@qq.com' '490912587@qq.com'
|
||||
* @LastEditTime: 2022-11-23 17:51:54
|
||||
* @FilePath: \tsplatform\backend\src\Utils\LoadModules.ts
|
||||
* @Description: 全局加载模块
|
||||
*/
|
||||
import { Logger } from '@nestjs/common';
|
||||
import { RestfulReturn } from 'src/Expand/RestfulReturn';
|
||||
import { LoggerPrint } from 'src/Logging/LoggerPrint';
|
||||
import { JwtService } from '@nestjs/jwt';
|
||||
|
||||
import { SysMenu } from 'src/Entity/SysMenu';
|
||||
import { SysCity } from 'src/Entity/SysCity';
|
||||
import { SysUser } from 'src/Entity/SysUser';
|
||||
import { SysRole } from 'src/Entity/SysRole';
|
||||
import { SysRoleMenu } from 'src/Entity/SysRoleMenu';
|
||||
|
||||
import { IndexController } from 'src/Controller/IndexController';
|
||||
import { MenuController } from 'src/Controller/MenuController';
|
||||
import { AuthController } from 'src/Controller/AuthController';
|
||||
import { UserController } from 'src/Controller/UserController';
|
||||
import { RoleController } from 'src/Controller/RoleController';
|
||||
import { CityController } from 'src/Controller/CityController';
|
||||
|
||||
import { MenuService } from 'src/Service/MenuService';
|
||||
import { UserService } from 'src/Service/UserService';
|
||||
import { RoleService } from 'src/Service/RoleService';
|
||||
import { Repository } from 'typeorm';
|
||||
import { CityService } from 'src/Service/CityService';
|
||||
|
||||
|
||||
//自动导入Entity
|
||||
export function LoadPlatFormEntity() {
|
||||
return [SysCity, SysMenu, SysUser, SysRole, SysRoleMenu];
|
||||
}
|
||||
//自动导入Controller
|
||||
export function LoadController() {
|
||||
return [IndexController, CityController, MenuController, UserController, AuthController, RoleController,];
|
||||
}
|
||||
//自动导入Service服务
|
||||
export function LoadService() {
|
||||
return [
|
||||
//特殊服务提供者
|
||||
RestfulReturn, Logger, LoggerPrint, Repository,JwtService,
|
||||
//Service服务提供者
|
||||
MenuService, UserService, RoleService, CityService
|
||||
];
|
||||
}
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* @Author: '490912587@qq.com' '490912587@qq.com'
|
||||
* @Date: 2022-11-17 09:19:20
|
||||
* @LastEditors: '490912587@qq.com' '490912587@qq.com'
|
||||
* @LastEditTime: 2022-11-24 10:16:52
|
||||
* @FilePath: \tsplatform\backend\src\app.module.ts
|
||||
* @Description: 全局模块入口
|
||||
*/
|
||||
|
||||
import { MiddlewareConsumer, Module, NestModule, RequestMethod } from '@nestjs/common';
|
||||
import { ConfigModule } from '@nestjs/config';
|
||||
import { TypeOrmModule } from '@nestjs/typeorm';
|
||||
import { LoadController, LoadPlatFormEntity, LoadService } from 'src/Utils/LoadModules';
|
||||
import { AppConfig, DataBaseConfig } from 'src/Config/Index';
|
||||
import { JwtHandle } from 'src/Middleware/JwtHandle';
|
||||
@Module({
|
||||
imports: [
|
||||
TypeOrmModule.forFeature(LoadPlatFormEntity()),
|
||||
TypeOrmModule.forRootAsync({
|
||||
useFactory: () => ({
|
||||
debug: false,
|
||||
//重试连接数据库的次数
|
||||
retryAttempts: 10,
|
||||
//两次重试连接的间隔(ms)
|
||||
retryDelay: 3000,
|
||||
//自动加载实体
|
||||
autoLoadEntities: true,
|
||||
type: 'mysql',
|
||||
host: DataBaseConfig.DataBase.host,
|
||||
port: DataBaseConfig.DataBase.port,
|
||||
username: DataBaseConfig.DataBase.username,
|
||||
password: DataBaseConfig.DataBase.password,
|
||||
database: DataBaseConfig.DataBase.database,
|
||||
entities: LoadPlatFormEntity(),
|
||||
logging: AppConfig.debug,
|
||||
synchronize: AppConfig.debug,
|
||||
})
|
||||
}),
|
||||
ConfigModule.forRoot({
|
||||
isGlobal: true,
|
||||
envFilePath: ['.env', '.env.development', '.env.production'],
|
||||
}),
|
||||
|
||||
],
|
||||
controllers: LoadController(),
|
||||
providers: LoadService()
|
||||
})
|
||||
export class AppModule implements NestModule {
|
||||
configure(consumer: MiddlewareConsumer) {
|
||||
consumer
|
||||
.apply(JwtHandle)
|
||||
.exclude(
|
||||
{ path: 'auth/login', method: RequestMethod.POST },
|
||||
{ path: 'auth/getUserInfo', method: RequestMethod.GET },
|
||||
{ path: '/seed', method: RequestMethod.GET },
|
||||
|
||||
)
|
||||
.forRoutes("*");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* @Author: '490912587@qq.com' '490912587@qq.com'
|
||||
* @Date: 2022-11-17 09:19:20
|
||||
* @LastEditors: '490912587@qq.com' '490912587@qq.com'
|
||||
* @LastEditTime: 2022-11-24 11:17:23
|
||||
* @FilePath: \tsplatform\backend\src\main.ts
|
||||
* @Description: 主程序入口
|
||||
*/
|
||||
|
||||
import { NestFactory } from '@nestjs/core';
|
||||
import { AppModule } from 'src/app.module';
|
||||
import { NestExpressApplication } from '@nestjs/platform-express';
|
||||
import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';
|
||||
import { AppConfig } from 'src/Config/Index';
|
||||
import { ValidationPipe } from '@nestjs/common';
|
||||
async function bootstrap() {
|
||||
const app = await NestFactory.create<NestExpressApplication>(AppModule, { logger: ['error', 'warn', "log", "debug", "verbose"], cors: true });
|
||||
|
||||
//全局Dto参数校验管道
|
||||
app.useGlobalPipes(new ValidationPipe());
|
||||
const config = new DocumentBuilder()
|
||||
//基础文档里添加安全定义
|
||||
.addBearerAuth()
|
||||
.setTitle('甜蜜蜜TS开发总平台')
|
||||
.setDescription('甜蜜蜜TS开发总平台')
|
||||
.setContact("甜蜜蜜", "https://gitee.com/tmm-top/vue-next-admin-ts", "490912587@qq.com")
|
||||
.setVersion('1.0')
|
||||
.build();
|
||||
const document = SwaggerModule.createDocument(app, config);
|
||||
SwaggerModule.setup('/api', app, document);
|
||||
await app.listen(AppConfig.port, '0.0.0.0');
|
||||
}
|
||||
bootstrap();
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
import { Test, TestingModule } from '@nestjs/testing';
|
||||
import { INestApplication } from '@nestjs/common';
|
||||
import * as request from 'supertest';
|
||||
import { AppModule } from './../src/app.module';
|
||||
|
||||
describe('AppController (e2e)', () => {
|
||||
let app: INestApplication;
|
||||
|
||||
beforeEach(async () => {
|
||||
const moduleFixture: TestingModule = await Test.createTestingModule({
|
||||
imports: [AppModule],
|
||||
}).compile();
|
||||
|
||||
app = moduleFixture.createNestApplication();
|
||||
await app.init();
|
||||
});
|
||||
|
||||
it('/ (GET)', () => {
|
||||
return request(app.getHttpServer())
|
||||
.get('/')
|
||||
.expect(200)
|
||||
.expect('Hello World!');
|
||||
});
|
||||
});
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"moduleFileExtensions": ["js", "json", "ts"],
|
||||
"rootDir": ".",
|
||||
"testEnvironment": "node",
|
||||
"testRegex": ".e2e-spec.ts$",
|
||||
"transform": {
|
||||
"^.+\\.(t|j)s$": "ts-jest"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"exclude": ["node_modules", "test", "dist", "**/*spec.ts"],
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"module": "commonjs",
|
||||
"declaration": true,
|
||||
"removeComments": true,
|
||||
"emitDecoratorMetadata": true,
|
||||
"experimentalDecorators": true,
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"target": "es2022",
|
||||
"sourceMap": true,
|
||||
"outDir": "./dist",
|
||||
"baseUrl": "./",
|
||||
"incremental": true,
|
||||
"skipLibCheck": true,
|
||||
"strictNullChecks": false,
|
||||
"noImplicitAny": false,
|
||||
"strictBindCallApply": false,
|
||||
"forceConsistentCasingInFileNames": false,
|
||||
"noFallthroughCasesInSwitch": false
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
.vscode/*
|
||||
!.vscode/settings.json
|
||||
!.vscode/tasks.json
|
||||
!.vscode/launch.json
|
||||
!.vscode/extensions.json
|
||||
*.code-workspace
|
||||
|
||||
# Local History for Visual Studio Code
|
||||
.history/
|
||||
|
After Width: | Height: | Size: 104 KiB |
|
After Width: | Height: | Size: 78 KiB |
|
After Width: | Height: | Size: 106 KiB |
|
After Width: | Height: | Size: 149 KiB |
|
After Width: | Height: | Size: 56 KiB |
|
|
@ -0,0 +1,25 @@
|
|||
.DS_Store
|
||||
node_modules
|
||||
/dist
|
||||
|
||||
|
||||
# local env files
|
||||
.env
|
||||
.env.development
|
||||
.env.production
|
||||
*.lock
|
||||
|
||||
# Log files
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
pnpm-debug.log*
|
||||
package-lock.json
|
||||
# Editor directories and files
|
||||
.idea
|
||||
.vscode
|
||||
*.suo
|
||||
*.ntvs*
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw?
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
{
|
||||
"name": "vue-next-admin",
|
||||
"version": "2.3.0",
|
||||
"name": "tsplatform",
|
||||
"version": "1.1.0",
|
||||
"description": "vue3 vite next admin template",
|
||||
"author": "lyt_20201208",
|
||||
"author": "SweetHoney",
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
"dev": "vite --force",
|
||||
|
|
@ -29,6 +29,7 @@
|
|||
"screenfull": "^6.0.2",
|
||||
"sortablejs": "^1.15.0",
|
||||
"splitpanes": "^3.1.5",
|
||||
"ts-md5": "^1.3.1",
|
||||
"vue": "^3.2.45",
|
||||
"vue-clipboard3": "^2.0.0",
|
||||
"vue-grid-layout": "^3.0.0-beta1",
|
||||
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
|
|
@ -1,3 +1,11 @@
|
|||
<!--
|
||||
* @Author: '490912587@qq.com' '490912587@qq.com'
|
||||
* @Date: 2022-11-17 09:19:20
|
||||
* @LastEditors: '490912587@qq.com' '490912587@qq.com'
|
||||
* @LastEditTime: 2022-11-23 17:25:54
|
||||
* @FilePath: \frontend\src\App.vue
|
||||
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
|
||||
-->
|
||||
<template>
|
||||
<el-config-provider :size="getGlobalComponentSize" :locale="getGlobalI18n">
|
||||
<router-view v-show="themeConfig.lockScreenTime > 1" />
|
||||
|
|
@ -89,3 +97,11 @@ export default defineComponent({
|
|||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.searchBox {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: flex-start;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
* @Author: '490912587@qq.com' '490912587@qq.com'
|
||||
* @Date: 2022-11-17 09:19:20
|
||||
* @LastEditors: '490912587@qq.com' '490912587@qq.com'
|
||||
* @LastEditTime: 2022-11-24 09:43:23
|
||||
* @FilePath: \tsplatform\frontend\src\api\menu\index.ts
|
||||
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
|
||||
*/
|
||||
import request from '/@/utils/request';
|
||||
export function getPage(params: object) {
|
||||
return request({
|
||||
url: '/city/getPage',
|
||||
method: 'get',
|
||||
params
|
||||
});
|
||||
}
|
||||
export function getList(params: object) {
|
||||
return request({
|
||||
url: '/city/getList',
|
||||
method: 'get',
|
||||
params
|
||||
});
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* @Author: '490912587@qq.com' '490912587@qq.com'
|
||||
* @Date: 2022-11-17 09:19:20
|
||||
* @LastEditors: '490912587@qq.com' '490912587@qq.com'
|
||||
* @LastEditTime: 2022-11-23 17:01:13
|
||||
* @FilePath: \tsplatform\frontend\src\api\login\index.ts
|
||||
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
|
||||
*/
|
||||
import request from '/@/utils/request';
|
||||
|
||||
/**
|
||||
* 登录api接口集合
|
||||
* @method signIn 用户登录
|
||||
* @method signOut 用户退出登录
|
||||
*/
|
||||
export function signIn(params: object) {
|
||||
return request({
|
||||
url: '/auth/login',
|
||||
method: 'post',
|
||||
data: params,
|
||||
});
|
||||
}
|
||||
export function getUserInfo() {
|
||||
return request({
|
||||
url: '/auth/getUserInfo',
|
||||
method: 'get'
|
||||
});
|
||||
}
|
||||
export function signOut() {
|
||||
return request({
|
||||
url: '/auth/loginOut',
|
||||
method: 'get'
|
||||
});
|
||||
}
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* @Author: '490912587@qq.com' '490912587@qq.com'
|
||||
* @Date: 2022-11-17 09:19:20
|
||||
* @LastEditors: '490912587@qq.com' '490912587@qq.com'
|
||||
* @LastEditTime: 2022-11-24 00:24:11
|
||||
* @FilePath: \tsplatform\frontend\src\api\menu\index.ts
|
||||
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
|
||||
*/
|
||||
import request from '/@/utils/request';
|
||||
export function getAuthMenu(params: object) {
|
||||
return request({
|
||||
url: '/menu/getAuthMenuTree',
|
||||
method: 'get',
|
||||
params,
|
||||
});
|
||||
}
|
||||
export function getMenuTree(params: object) {
|
||||
return request({
|
||||
url: '/menu/getMenuTree',
|
||||
method: 'get',
|
||||
params,
|
||||
});
|
||||
}
|
||||
export function add(params: object) {
|
||||
return request({
|
||||
url: '/menu/add',
|
||||
method: 'post',
|
||||
data: params
|
||||
});
|
||||
}
|
||||
export function edit(params: object) {
|
||||
return request({
|
||||
url: '/menu/edit',
|
||||
method: 'post',
|
||||
data: params
|
||||
});
|
||||
}
|
||||
export function del(params: object) {
|
||||
return request({
|
||||
url: '/menu/del',
|
||||
method: 'post',
|
||||
data: params
|
||||
});
|
||||
}
|
||||
export function setStatus(params: object) {
|
||||
return request({
|
||||
url: '/menu/setStatus',
|
||||
method: 'post',
|
||||
data: params
|
||||
});
|
||||
}
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* @Author: '490912587@qq.com' '490912587@qq.com'
|
||||
* @Date: 2022-11-17 09:19:20
|
||||
* @LastEditors: '490912587@qq.com' '490912587@qq.com'
|
||||
* @LastEditTime: 2022-11-23 21:35:46
|
||||
* @FilePath: \tsplatform\frontend\src\api\menu\index.ts
|
||||
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
|
||||
*/
|
||||
import request from '/@/utils/request';
|
||||
|
||||
export function getPage(params: object) {
|
||||
return request({
|
||||
url: '/role/getPage',
|
||||
method: 'get',
|
||||
params
|
||||
});
|
||||
}
|
||||
export function getList(params: object) {
|
||||
return request({
|
||||
url: '/role/getList',
|
||||
method: 'get',
|
||||
params
|
||||
});
|
||||
}
|
||||
export function add(params: object) {
|
||||
return request({
|
||||
url: '/role/add',
|
||||
method: 'post',
|
||||
data: params
|
||||
});
|
||||
}
|
||||
export function edit(params: object) {
|
||||
return request({
|
||||
url: '/role/edit',
|
||||
method: 'post',
|
||||
data: params
|
||||
});
|
||||
}
|
||||
export function del(params: object) {
|
||||
return request({
|
||||
url: '/role/del',
|
||||
method: 'post',
|
||||
data: params
|
||||
});
|
||||
}
|
||||
export function setStatus(params: object) {
|
||||
return request({
|
||||
url: '/role/setStatus',
|
||||
method: 'post',
|
||||
data: params
|
||||
});
|
||||
}
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* @Author: '490912587@qq.com' '490912587@qq.com'
|
||||
* @Date: 2022-11-17 09:19:20
|
||||
* @LastEditors: '490912587@qq.com' '490912587@qq.com'
|
||||
* @LastEditTime: 2022-11-23 21:35:53
|
||||
* @FilePath: \tsplatform\frontend\src\api\menu\index.ts
|
||||
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
|
||||
*/
|
||||
import request from '/@/utils/request';
|
||||
export function getPage(params: object) {
|
||||
return request({
|
||||
url: '/user/getPage',
|
||||
method: 'get',
|
||||
params
|
||||
});
|
||||
}
|
||||
export function getList(params: object) {
|
||||
return request({
|
||||
url: '/role/getList',
|
||||
method: 'get',
|
||||
params
|
||||
});
|
||||
}
|
||||
export function add(params: object) {
|
||||
return request({
|
||||
url: '/user/add',
|
||||
method: 'post',
|
||||
data: params
|
||||
});
|
||||
}
|
||||
export function edit(params: object) {
|
||||
return request({
|
||||
url: '/user/edit',
|
||||
method: 'post',
|
||||
data: params
|
||||
});
|
||||
}
|
||||
export function del(params: object) {
|
||||
return request({
|
||||
url: '/user/del',
|
||||
method: 'post',
|
||||
data: params
|
||||
});
|
||||
}
|
||||
export function setStatus(params: object) {
|
||||
return request({
|
||||
url: '/user/setStatus',
|
||||
method: 'post',
|
||||
data: params
|
||||
});
|
||||
}
|
||||
|
After Width: | Height: | Size: 2.1 KiB |
|
Before Width: | Height: | Size: 8.4 KiB After Width: | Height: | Size: 8.4 KiB |
|
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 26 KiB |
|
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 36 KiB |
|
Before Width: | Height: | Size: 3.2 KiB After Width: | Height: | Size: 3.2 KiB |
|
|
@ -2,77 +2,15 @@
|
|||
export default {
|
||||
router: {
|
||||
home: 'home',
|
||||
system: {
|
||||
system: 'system',
|
||||
systemMenu: 'systemMenu',
|
||||
systemRole: 'systemRole',
|
||||
systemUser: 'systemUser',
|
||||
systemDept: 'systemDept',
|
||||
systemDic: 'systemDic',
|
||||
limits: 'limits',
|
||||
limitsFrontEnd: 'FrontEnd',
|
||||
limitsFrontEndPage: 'FrontEndPage',
|
||||
limitsFrontEndBtn: 'FrontEndBtn',
|
||||
limitsBackEnd: 'BackEnd',
|
||||
limitsBackEndEndPage: 'BackEndEndPage',
|
||||
menu: 'menu',
|
||||
menu1: 'menu1',
|
||||
menu11: 'menu11',
|
||||
menu12: 'menu12',
|
||||
menu121: 'menu121',
|
||||
menu122: 'menu122',
|
||||
menu13: 'menu13',
|
||||
menu2: 'menu2',
|
||||
funIndex: 'function',
|
||||
funTagsView: 'funTagsView',
|
||||
funCountup: 'countup',
|
||||
funWangEditor: 'wangEditor',
|
||||
funCropper: 'cropper',
|
||||
funQrcode: 'qrcode',
|
||||
funEchartsMap: 'EchartsMap',
|
||||
funPrintJs: 'PrintJs',
|
||||
funClipboard: 'Copy cut',
|
||||
funGridLayout: 'Drag layout',
|
||||
funSplitpanes: 'Pane splitter',
|
||||
funDragVerify: 'Validator',
|
||||
pagesIndex: 'pages',
|
||||
pagesFiltering: 'Filtering',
|
||||
pagesFilteringDetails: 'FilteringDetails',
|
||||
pagesFilteringDetails1: 'FilteringDetails1',
|
||||
pagesIocnfont: 'iconfont icon',
|
||||
pagesElement: 'element icon',
|
||||
pagesAwesome: 'awesome icon',
|
||||
pagesFormAdapt: 'FormAdapt',
|
||||
pagesTableRules: 'pagesTableRules',
|
||||
pagesFormI18n: 'FormI18n',
|
||||
pagesFormRules: 'Multi form validation',
|
||||
pagesDynamicForm: 'Dynamic complex form',
|
||||
pagesWorkflow: 'Workflow',
|
||||
pagesListAdapt: 'ListAdapt',
|
||||
pagesWaterfall: 'Waterfall',
|
||||
pagesSteps: 'Steps',
|
||||
pagesPreview: 'Large preview',
|
||||
pagesWaves: 'Wave effect',
|
||||
pagesTree: 'tree alter table',
|
||||
pagesDrag: 'Drag command',
|
||||
pagesLazyImg: 'Image lazy loading',
|
||||
makeIndex: 'makeIndex',
|
||||
makeSelector: 'Icon selector',
|
||||
makeNoticeBar: 'notification bar',
|
||||
makeSvgDemo: 'Svgicon demo',
|
||||
paramsIndex: 'Routing parameters',
|
||||
paramsCommon: 'General routing',
|
||||
paramsDynamic: 'Dynamic routing',
|
||||
paramsCommonDetails: 'General routing details',
|
||||
paramsDynamicDetails: 'Dynamic routing details',
|
||||
chartIndex: 'chartIndex',
|
||||
visualizingIndex: 'visualizingIndex',
|
||||
visualizingLinkDemo1: 'visualizingLinkDemo1',
|
||||
visualizingLinkDemo2: 'visualizingLinkDemo2',
|
||||
menu: 'systemMenu',
|
||||
role: 'systemRole',
|
||||
user: 'systemUser',
|
||||
dic: 'systemDic',
|
||||
city: 'systemDept'
|
||||
},
|
||||
personal: 'personal',
|
||||
tools: 'tools',
|
||||
layoutLinkView: 'LinkView',
|
||||
layoutIframeViewOne: 'IframeViewOne',
|
||||
layoutIframeViewTwo: 'IframeViewTwo',
|
||||
},
|
||||
staticRoutes: {
|
||||
signIn: 'signIn',
|
||||
|
|
@ -2,77 +2,15 @@
|
|||
export default {
|
||||
router: {
|
||||
home: '首页',
|
||||
system: {
|
||||
system: '系统设置',
|
||||
systemMenu: '菜单管理',
|
||||
systemRole: '角色管理',
|
||||
systemUser: '用户管理',
|
||||
systemDept: '部门管理',
|
||||
systemDic: '字典管理',
|
||||
limits: '权限管理',
|
||||
limitsFrontEnd: '前端控制',
|
||||
limitsFrontEndPage: '页面权限',
|
||||
limitsFrontEndBtn: '按钮权限',
|
||||
limitsBackEnd: '后端控制',
|
||||
limitsBackEndEndPage: '页面权限',
|
||||
menu: '菜单嵌套',
|
||||
menu1: '菜单1',
|
||||
menu11: '菜单11',
|
||||
menu12: '菜单12',
|
||||
menu121: '菜单121',
|
||||
menu122: '菜单122',
|
||||
menu13: '菜单13',
|
||||
menu2: '菜单2',
|
||||
funIndex: '功能',
|
||||
funTagsView: 'tagsView 操作',
|
||||
funCountup: '数字滚动',
|
||||
funWangEditor: 'Editor 编辑器',
|
||||
funCropper: '图片裁剪',
|
||||
funQrcode: '二维码生成',
|
||||
funEchartsMap: '地理坐标/地图',
|
||||
funPrintJs: '页面打印',
|
||||
funClipboard: '复制剪切',
|
||||
funGridLayout: '拖拽布局',
|
||||
funSplitpanes: '窗格拆分器',
|
||||
funDragVerify: '验证器',
|
||||
pagesIndex: '页面',
|
||||
pagesFiltering: '过滤筛选组件',
|
||||
pagesFilteringDetails: '过滤筛选组件详情',
|
||||
pagesFilteringDetails1: '过滤筛选组件详情111',
|
||||
pagesIocnfont: 'ali 字体图标',
|
||||
pagesElement: 'ele 字体图标',
|
||||
pagesAwesome: 'awe 字体图标',
|
||||
pagesFormAdapt: '表单自适应',
|
||||
pagesTableRules: '表单表格验证',
|
||||
pagesFormI18n: '表单国际化',
|
||||
pagesFormRules: '多表单验证',
|
||||
pagesDynamicForm: '动态复杂表单',
|
||||
pagesWorkflow: '工作流',
|
||||
pagesListAdapt: '列表自适应',
|
||||
pagesWaterfall: '瀑布屏',
|
||||
pagesSteps: '步骤条',
|
||||
pagesPreview: '大图预览',
|
||||
pagesWaves: '波浪效果',
|
||||
pagesTree: '树形改表格',
|
||||
pagesDrag: '拖动指令',
|
||||
pagesLazyImg: '图片懒加载',
|
||||
makeIndex: '组件封装',
|
||||
makeSelector: '图标选择器',
|
||||
makeNoticeBar: '滚动通知栏',
|
||||
makeSvgDemo: 'svgIcon 演示',
|
||||
paramsIndex: '路由参数',
|
||||
paramsCommon: '普通路由',
|
||||
paramsDynamic: '动态路由',
|
||||
paramsCommonDetails: '普通路由详情',
|
||||
paramsDynamicDetails: '动态路由详情',
|
||||
chartIndex: '大数据图表',
|
||||
visualizingIndex: '数据可视化',
|
||||
visualizingLinkDemo1: '数据可视化演示1',
|
||||
visualizingLinkDemo2: '数据可视化演示2',
|
||||
menu: '菜单管理',
|
||||
role: '角色管理',
|
||||
user: '用户管理',
|
||||
dic: '字典管理',
|
||||
city: '城市管理'
|
||||
},
|
||||
personal: '个人中心',
|
||||
tools: '工具类集合',
|
||||
layoutLinkView: '外链',
|
||||
layoutIframeViewOne: '内嵌 iframe1',
|
||||
layoutIframeViewTwo: '内嵌 iframe2',
|
||||
},
|
||||
staticRoutes: {
|
||||
signIn: '登录',
|
||||
|
|
@ -2,77 +2,16 @@
|
|||
export default {
|
||||
router: {
|
||||
home: '首頁',
|
||||
system: {
|
||||
system: '系統設置',
|
||||
systemMenu: '選單管理',
|
||||
systemRole: '角色管理',
|
||||
systemUser: '用戶管理',
|
||||
systemDept: '部門管理',
|
||||
systemDic: '字典管理',
|
||||
limits: '許可權管理',
|
||||
limitsFrontEnd: '前端控制',
|
||||
limitsFrontEndPage: '頁面許可權',
|
||||
limitsFrontEndBtn: '按鈕許可權',
|
||||
limitsBackEnd: '後端控制',
|
||||
limitsBackEndEndPage: '頁面許可權',
|
||||
menu: '選單嵌套',
|
||||
menu1: '選單1',
|
||||
menu11: '選單11',
|
||||
menu12: '選單12',
|
||||
menu121: '選單121',
|
||||
menu122: '選單122',
|
||||
menu13: '選單13',
|
||||
menu2: '選單2',
|
||||
funIndex: '功能',
|
||||
funTagsView: 'tagsView 操作',
|
||||
funCountup: '數位滾動',
|
||||
funWangEditor: 'Editor 編輯器',
|
||||
funCropper: '圖片裁剪',
|
||||
funQrcode: '二維碼生成',
|
||||
funEchartsMap: '地理座標/地圖',
|
||||
funPrintJs: '頁面列印',
|
||||
funClipboard: '複製剪切',
|
||||
funGridLayout: '拖拽佈局',
|
||||
funSplitpanes: '窗格折開器',
|
||||
funDragVerify: '驗證器',
|
||||
pagesIndex: '頁面',
|
||||
pagesFiltering: '過濾篩選組件',
|
||||
pagesFilteringDetails: '過濾篩選組件詳情',
|
||||
pagesFilteringDetails1: '過濾篩選組件詳情111',
|
||||
pagesIocnfont: 'ali 字體圖標',
|
||||
pagesElement: 'ele 字體圖標',
|
||||
pagesAwesome: 'awe 字體圖標',
|
||||
pagesFormAdapt: '表單自我調整',
|
||||
pagesTableRules: '表單表格驗證',
|
||||
pagesFormI18n: '表單國際化',
|
||||
pagesFormRules: '多表單驗證',
|
||||
pagesDynamicForm: '動態複雜表單',
|
||||
pagesWorkflow: '工作流',
|
||||
pagesListAdapt: '清單自我調整',
|
||||
pagesWaterfall: '瀑布屏',
|
||||
pagesSteps: '步驟條',
|
||||
pagesPreview: '大圖預覽',
|
||||
pagesWaves: '波浪效果',
|
||||
pagesTree: '樹形改表格',
|
||||
pagesDrag: '拖動指令',
|
||||
pagesLazyImg: '圖片懶加載',
|
||||
makeIndex: '組件封裝',
|
||||
makeSelector: '圖標選擇器',
|
||||
makeNoticeBar: '滾動通知欄',
|
||||
makeSvgDemo: 'svgIcon 演示',
|
||||
paramsIndex: '路由參數',
|
||||
paramsCommon: '普通路由',
|
||||
paramsDynamic: '動態路由',
|
||||
paramsCommonDetails: '普通路由詳情',
|
||||
paramsDynamicDetails: '動態路由詳情',
|
||||
chartIndex: '大資料圖表',
|
||||
visualizingIndex: '數據視覺化',
|
||||
visualizingLinkDemo1: '數據視覺化演示1',
|
||||
visualizingLinkDemo2: '數據視覺化演示2',
|
||||
menu: '選單管理',
|
||||
role: '角色管理',
|
||||
user: '用戶管理',
|
||||
dic: '字典管理',
|
||||
city: '城市管理'
|
||||
},
|
||||
personal: '個人中心',
|
||||
tools: '工具類集合',
|
||||
layoutLinkView: '外鏈',
|
||||
layoutIframeViewOne: '内嵌 iframe1',
|
||||
layoutIframeViewTwo: '内嵌 iframe2',
|
||||
|
||||
},
|
||||
staticRoutes: {
|
||||
signIn: '登入',
|
||||